Add static library with nGraph reference implementations (#1810)
authorIlya Churaev <ilya.churaev@intel.com>
Mon, 17 Aug 2020 16:43:11 +0000 (19:43 +0300)
committerGitHub <noreply@github.com>
Mon, 17 Aug 2020 16:43:11 +0000 (19:43 +0300)
* Removed reference implementations from public API

* Remove coordinate_transform from public API

* Introduced static library with reference implementations

237 files changed:
CMakeLists.txt
inference-engine/tests/functional/plugin/shared/include/single_layer_tests/activation.hpp
inference-engine/tests/functional/plugin/shared/include/single_layer_tests/grn.hpp
ngraph/core/CMakeLists.txt
ngraph/core/include/ngraph/coordinate_transform.hpp [deleted file]
ngraph/core/include/ngraph/ngraph.hpp
ngraph/core/include/ngraph/runtime/opt_kernel/broadcast.hpp [deleted file]
ngraph/core/include/ngraph/runtime/opt_kernel/reshape.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/abs.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/acos.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/acosh.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/add.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/and.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/any.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/asin.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/asinh.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/atan.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/atan2.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/atanh.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/autobroadcast_binop.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/avg_pool.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/batch_norm.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/broadcast.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/ceiling.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/clamp.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/concat.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/constant.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/convert.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/convolution.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/copy.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/cos.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/cosh.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/cum_sum.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/dequantize.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/divide.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/dot.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/elu.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/embedding_bag_offsets_sum.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/embedding_bag_packed_sum.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/embedding_segments_sum.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/equal.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/erf.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/eval_helpers.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/exp.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/extract_image_patches.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/floor.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/gather.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/gather_nd.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/greater.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/greater_eq.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/less.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/less_eq.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/log.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/logical_reduction.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/lrn.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/matmul.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/max.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/max_pool.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/maximum.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/mean.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/min.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/minimum.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/mish.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/multiply.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/negate.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/non_zero.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/not.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/not_equal.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/one_hot.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/or.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/pad.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/power.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/prelu.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/prior_box.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/prior_box_clustered.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/product.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/quantize.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/range.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/reduce_l1.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/reduce_l2.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/relu.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/replace_slice.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/reshape.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/result.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/reverse.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/reverse_sequence.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/round.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/scatter_elements_update.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/select.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/shape_of.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/sigmoid.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/sign.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/sin.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/sinh.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/slice.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/softmax.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/sqrt.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/strided_slice.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/subtract.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/sum.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/swish.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/tan.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/tanh.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/tile.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/topk.hpp [deleted file]
ngraph/core/include/ngraph/runtime/reference/xor.hpp [deleted file]
ngraph/core/reference/CMakeLists.txt [new file with mode: 0644]
ngraph/core/reference/include/ngraph/coordinate_transform.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/opt_kernel/broadcast.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/opt_kernel/reshape.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/abs.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/acos.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/acosh.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/add.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/and.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/any.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/asin.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/asinh.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/atan.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/atan2.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/atanh.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/autobroadcast_binop.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/avg_pool.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/batch_norm.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/broadcast.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/ceiling.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/clamp.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/concat.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/constant.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/convert.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/convolution.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/copy.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/cos.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/cosh.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/ctc_loss.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/cum_sum.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/dequantize.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/detection_output.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/divide.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/dot.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/elu.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/embedding_bag_offsets_sum.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/embedding_bag_packed_sum.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/embedding_segments_sum.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/equal.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/erf.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/eval_helpers.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/exp.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/extract_image_patches.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/floor.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/gather.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/gather_nd.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/greater.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/greater_eq.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/less.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/less_eq.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/log.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/logical_reduction.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/lrn.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/matmul.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/max.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/max_pool.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/maximum.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/mean.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/min.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/minimum.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/mish.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/multiply.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/negate.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/non_zero.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/not.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/not_equal.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/one_hot.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/or.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/pad.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/power.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/prelu.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/prior_box.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/prior_box_clustered.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/product.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/quantize.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/range.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/reduce_l1.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/reduce_l2.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/relu.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/replace_slice.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/reshape.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/result.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/reverse.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/reverse_sequence.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/round.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/scatter_elements_update.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/scatter_nd_update.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/scatter_update.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/select.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/shape_of.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/sigmoid.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/sign.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/sin.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/sinh.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/slice.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/softmax.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/sqrt.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/strided_slice.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/subtract.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/sum.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/swish.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/tan.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/tanh.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/tile.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/topk.hpp [new file with mode: 0644]
ngraph/core/reference/include/ngraph/runtime/reference/xor.hpp [new file with mode: 0644]
ngraph/core/reference/src/coordinate_transform.cpp [new file with mode: 0644]
ngraph/core/reference/src/runtime/opt_kernel/reshape.cpp [new file with mode: 0644]
ngraph/core/reference/src/runtime/reference/eval_helpers.cpp [new file with mode: 0644]
ngraph/core/reference/src/runtime/reference/reshape.cpp [new file with mode: 0644]
ngraph/core/reference/src/runtime/reference/reverse.cpp [new file with mode: 0644]
ngraph/core/reference/src/runtime/reference/slice.cpp [new file with mode: 0644]
ngraph/core/reference/src/runtime/reference/strided_slice.cpp [new file with mode: 0644]
ngraph/core/reference/src/runtime/reference/tile.cpp [new file with mode: 0644]
ngraph/core/src/coordinate_transform.cpp [deleted file]
ngraph/core/src/op/prelu.cpp
ngraph/core/src/runtime/opt_kernel/reshape.cpp [deleted file]
ngraph/core/src/runtime/reference/eval_helpers.cpp [deleted file]
ngraph/core/src/runtime/reference/reshape.cpp [deleted file]
ngraph/core/src/runtime/reference/reverse.cpp [deleted file]
ngraph/core/src/runtime/reference/slice.cpp [deleted file]
ngraph/core/src/runtime/reference/strided_slice.cpp [deleted file]
ngraph/core/src/runtime/reference/tile.cpp [deleted file]
ngraph/test/coordinate.cpp
ngraph/test/runtime/CMakeLists.txt
ngraph/test/runtime/interpreter/int_executable.hpp
ngraph/test/runtime/interpreter/reference/ctc_loss.hpp [deleted file]
ngraph/test/runtime/interpreter/reference/detection_output.hpp [deleted file]
ngraph/test/runtime/interpreter/reference/scatter_nd_update.hpp [deleted file]
ngraph/test/runtime/interpreter/reference/scatter_update.hpp [deleted file]
openvino/CMakeLists.txt

index 0eff7fec3424273898fd83c28d2fc6f0796f5f53..a93455a541b1760a2bdebe2b55ec550ff404f610 100644 (file)
@@ -117,6 +117,32 @@ function(build_ngraph)
     set(NGRAPH_LIBRARIES ngraph PARENT_SCOPE)
 endfunction()
 
+file(REMOVE "${CMAKE_BINARY_DIR}/openvino_targets_developer.cmake")
+
+unset(OpenVINODeveloperPackageTargets CACHE)
+
+function(openvino_developer_export_targets)
+    set(OpenVINODeveloperPackageTargets "${OpenVINODeveloperPackageTargets};${ARGV}")
+
+    # to allow exporting of aliased targets with the original names
+    foreach(target_name ${OpenVINODeveloperPackageTargets})
+        if(TARGET "${target_name}")
+            get_target_property(original_name ${target_name} ALIASED_TARGET)
+            if(TARGET "${original_name}")
+                message(STATUS "The name ${target_name} is an ALIAS for ${original_name}. "
+                        "It will be exported to the InferenceEngineDeveloperPackage with the original name.")
+                list(REMOVE_ITEM OpenVINODeveloperPackageTargets ${target_name})
+                list(APPEND OpenVINODeveloperPackageTargets ${original_name})
+            endif()
+        endif()
+    endforeach()
+
+    list(REMOVE_DUPLICATES OpenVINODeveloperPackageTargets)
+    set(OpenVINODeveloperPackageTargets "${OpenVINODeveloperPackageTargets}" CACHE INTERNAL
+        "Paths to extra Inference Engine plugins" FORCE)
+endfunction()
+
+
 add_subdirectory(openvino)
 
 build_ngraph()
index a19bd218e6c45e704642dea2bf87f7c3a1979c3d..54288e4de8d3eb3c43ce13d56b68ce16c0389947 100644 (file)
@@ -19,7 +19,6 @@
 #include "details/ie_exception.hpp"
 
 #include "ngraph/opsets/opset1.hpp"
-#include "ngraph/runtime/reference/relu.hpp"
 
 #include "functional_test_utils/blob_utils.hpp"
 #include "functional_test_utils/layer_test_utils.hpp"
index 6dcf2c85dae7fee991878374abbd243289aea935..357361a21c4ab30c1d51f668218b73989cd82ffc 100644 (file)
@@ -19,7 +19,6 @@
 #include "details/ie_exception.hpp"
 
 #include "ngraph/opsets/opset1.hpp"
-#include "ngraph/runtime/reference/relu.hpp"
 
 #include "functional_test_utils/blob_utils.hpp"
 #include "functional_test_utils/layer_test_utils.hpp"
index 2f9830f120c777323ed1a0ef73889429289e33a8..665d66af59a78fc6e779b03a083c924524d54d3b 100644 (file)
 
 add_definitions(-DIN_NGRAPH_LIBRARY)
 
-file(GLOB_RECURSE LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
+file(GLOB_RECURSE LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp
+                              ${CMAKE_CURRENT_SOURCE_DIR}/src/*.hpp)
 file(GLOB_RECURSE PUBLIC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp)
 
 set(NGRAPH_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include/ngraph CACHE INTERNAL "")
 
+add_subdirectory(reference)
+
 # Create named folders for the sources within the .vcproj
 # Empty name lists them directly under the .vcproj
 
@@ -37,7 +40,7 @@ set_target_properties(ngraph PROPERTIES
                       C_VISIBILITY_PRESET hidden
                       VISIBILITY_INLINES_HIDDEN ON)
 
-target_link_libraries(ngraph PRIVATE openvino::itt)
+target_link_libraries(ngraph PRIVATE openvino::itt ngraph::reference)
 
 find_package(Graphviz QUIET)
 if (GRAPHVIZ_FOUND)
@@ -81,12 +84,12 @@ target_include_directories(ngraph PUBLIC $<BUILD_INTERFACE:${NGRAPH_INCLUDE_PATH
 target_include_directories(ngraph PRIVATE ${NGRAPH_INCLUDE_DIR}
                                           ${NGRAPH_INCLUDE_DIR}/builder
                                           ${NGRAPH_INCLUDE_DIR}/op
-                                          ${NGRAPH_INCLUDE_DIR}/op/fused
                                           ${NGRAPH_INCLUDE_DIR}/op/util
                                           ${NGRAPH_INCLUDE_DIR}/pass
                                           ${NGRAPH_INCLUDE_DIR}/pattern
                                           ${NGRAPH_INCLUDE_DIR}/pattern/op
                                           ${NGRAPH_INCLUDE_DIR}/runtime
+                                          ${CMAKE_CURRENT_SOURCE_DIR}/src
                                           )
 
 #Add an alias so that library can be used inside the build tree, e.g. when testing
diff --git a/ngraph/core/include/ngraph/coordinate_transform.hpp b/ngraph/core/include/ngraph/coordinate_transform.hpp
deleted file mode 100644 (file)
index ac67085..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include "ngraph/axis_vector.hpp"
-#include "ngraph/coordinate.hpp"
-#include "ngraph/coordinate_diff.hpp"
-#include "ngraph/shape.hpp"
-#include "ngraph/strides.hpp"
-
-namespace ngraph
-{
-    /// \brief A useful class that allows to iterate over the tensor coordinates.
-    ///        For example, for tensor with dimensions {2, 3} this iterator
-    ///        produces the following coordinates:
-    ///             {0,0}, {0,1}, {0,2},
-    ///             {1,0}, {1,1}, {2,2}
-    class NGRAPH_API CoordinateIterator
-    {
-    public:
-        /// \brief Coordinates iterator constructor
-        /// \param target_shape The target shape for coordinates iteration
-        /// \param is_end The flag indicates that the coordinate iterator is the last.
-        CoordinateIterator(const Shape& target_shape, bool is_end = false);
-
-        /// \brief The postfix operation increment the iterator by one.
-        void operator++();
-
-        /// \brief The prefix operation increment the iterator by one.
-        CoordinateIterator operator++(int);
-
-        /// \brief Increments iterator n times.
-        /// \param n number of elements it should be advanced
-        void operator+=(size_t n);
-
-        /// \brief Iterator dereferencing operator returns reference to current pointed coordinate.
-        const Coordinate& operator*() const noexcept;
-
-        /// \brief Checks for iterator inequality.
-        /// \param it second iterator to compare
-        bool operator!=(const CoordinateIterator& it) const noexcept;
-
-        /// \brief Checks for iterator equality.
-        /// \param it second iterator to compare
-        bool operator==(const CoordinateIterator& it) const noexcept;
-
-        /// \brief Increments iterator using specified axis of the shape n times.
-        /// \param axis index used for iteration
-        size_t advance(size_t axis) noexcept;
-
-        /// \brief Useful function to build the last iterator.
-        ///        Returns a singleton that points to the last iterator.
-        static const CoordinateIterator& end();
-
-    private:
-        const Shape& m_target_shape;
-        Coordinate m_coordinate;
-        bool m_oob;
-    };
-
-    /// \brief Class which allows to calculate item index with given coordinates in tensor
-    ///        and helps to iterate over all coordinates.
-    ///        Tensor items should be placed in memory in row-major order.
-    class NGRAPH_API CoordinateTransformBasic
-    {
-    public:
-        using Iterator = CoordinateIterator;
-
-        CoordinateTransformBasic(const Shape& source_shape);
-
-        /// \brief The tensor element index calculation by given coordinate.
-        /// \param c tensor element coordinate
-        size_t index(const Coordinate& c) const noexcept;
-
-        /// \brief Returns an iterator to the first coordinate of the tensor.
-        CoordinateIterator begin() const noexcept;
-
-        /// \brief Returns an iterator to the coordinate following the last element of the tensor.
-        const CoordinateIterator& end() const noexcept;
-
-    protected:
-        Shape m_source_shape;
-    };
-
-    /// \brief Class which allows to calculate item index with given coordinates in tensor
-    ///        and helps to iterate over the subset of coordinates.
-    ///        Tensor items should be placed in memory in row-major order.
-    class NGRAPH_API CoordinateTransform : protected CoordinateTransformBasic
-    {
-    public:
-        using Iterator = CoordinateIterator;
-
-        CoordinateTransform(const Shape& source_shape,
-                            const Coordinate& source_start_corner,
-                            const Coordinate& source_end_corner,
-                            const Strides& source_strides,
-                            const AxisVector& source_axis_order,
-                            const CoordinateDiff& target_padding_below,
-                            const CoordinateDiff& target_padding_above,
-                            const Strides& source_dilation_strides);
-
-        CoordinateTransform(const Shape& source_shape,
-                            const Coordinate& source_start_corner,
-                            const Coordinate& source_end_corner,
-                            const Strides& source_strides,
-                            const AxisVector& source_axis_order,
-                            const CoordinateDiff& target_padding_below,
-                            const CoordinateDiff& target_padding_above);
-
-        CoordinateTransform(const Shape& source_shape,
-                            const Coordinate& source_start_corner,
-                            const Coordinate& source_end_corner,
-                            const Strides& source_strides,
-                            const AxisVector& source_axis_order);
-
-        CoordinateTransform(const Shape& source_shape,
-                            const Coordinate& source_start_corner,
-                            const Coordinate& source_end_corner,
-                            const Strides& source_strides);
-
-        CoordinateTransform(const Shape& source_shape,
-                            const Coordinate& source_start_corner,
-                            const Coordinate& source_end_corner);
-
-        CoordinateTransform(const Shape& source_shape);
-
-        /// \brief The tensor element index calculation by given coordinate.
-        /// \param c tensor element coordinate
-        size_t index(const Coordinate& c) const;
-
-        /// \brief Checks that coordinate belongs to given coordinates subset.
-        /// \param c tensor element coordinate
-        bool has_source_coordinate(const Coordinate& c) const;
-
-        /// \brief Convert a target-space coordinate to a source-space coordinate.
-        /// \param c tensor element coordinate
-        Coordinate to_source_coordinate(const Coordinate& c) const;
-
-        const Shape& get_source_shape() const noexcept;
-        const Shape& get_target_shape() const noexcept;
-        const Coordinate& get_source_start_corner() const noexcept;
-        const Coordinate& get_source_end_corner() const noexcept;
-        const Strides& get_source_strides() const noexcept;
-        const AxisVector& get_source_axis_order() const noexcept;
-        const Strides& get_target_dilation_strides() const noexcept;
-
-        /// \brief Returns an iterator to the first coordinate of the tensor.
-        CoordinateIterator begin() const noexcept;
-
-        /// \brief Returns an iterator to the coordinate following the last element of the tensor.
-        const CoordinateIterator& end() const noexcept;
-
-    private:
-        Coordinate m_source_start_corner;
-        Coordinate m_source_end_corner;
-        Strides m_source_strides;
-        AxisVector m_source_axis_order;
-        CoordinateDiff m_target_padding_below;
-        CoordinateDiff m_target_padding_above;
-        Strides m_target_dilation_strides;
-
-        Shape m_target_shape;
-        size_t m_n_axes;
-    };
-}
index 35941355de07971116658f3b11f899828ed8999b..4d000f6cdc80b1ef1e53a88ddcbb62e502744aaf 100644 (file)
@@ -70,7 +70,6 @@ namespace ngraph
 #include "ngraph/builder/autobroadcast.hpp"
 #include "ngraph/builder/reduce_ops.hpp"
 #include "ngraph/builder/reshape.hpp"
-#include "ngraph/coordinate_transform.hpp"
 #include "ngraph/descriptor/input.hpp"
 #include "ngraph/descriptor/output.hpp"
 #include "ngraph/descriptor/tensor.hpp"
diff --git a/ngraph/core/include/ngraph/runtime/opt_kernel/broadcast.hpp b/ngraph/core/include/ngraph/runtime/opt_kernel/broadcast.hpp
deleted file mode 100644 (file)
index 7380a6c..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <utility>
-
-#include "ngraph/runtime/reference/broadcast.hpp"
-#include "ngraph/shape_util.hpp"
-#include "ngraph/util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace opt_kernel
-        {
-            template <typename T>
-            void broadcast_2d(
-                const T* in, T* out, const Shape& in_shape, const Shape& out_shape, size_t out_axis)
-            {
-                size_t index[2];
-                size_t& in_index = index[out_axis];
-                auto out_strides = row_major_strides(out_shape);
-                for (index[0] = 0; index[0] < out_shape[0]; ++index[0])
-                {
-                    for (index[1] = 0; index[1] < out_shape[1]; ++index[1])
-                    {
-                        // clang-format off
-                        out[index[0] * out_strides[0] +
-                            index[1]] =
-                                in[in_index];
-                        // clang-format on
-                    }
-                }
-            }
-
-            // #define PARALLEL
-            template <typename T>
-            void broadcast_3d(
-                const T* in, T* out, const Shape& in_shape, const Shape& out_shape, size_t out_axis)
-            {
-                size_t index[3];
-                size_t& in_index = index[out_axis];
-                auto out_strides = row_major_strides(out_shape);
-                for (index[0] = 0; index[0] < out_shape[0]; ++index[0])
-                {
-                    for (index[1] = 0; index[1] < out_shape[1]; ++index[1])
-                    {
-                        for (index[2] = 0; index[2] < out_shape[2]; ++index[2])
-                        {
-                            // clang-format off
-                            out[index[0] * out_strides[0] +
-                                index[1] * out_strides[1] +
-                                index[2]] =
-                                    in[in_index];
-                            // clang-format on
-                        }
-                    }
-                }
-            }
-
-            template <typename T>
-            void broadcast_4d(
-                const T* in, T* out, const Shape& in_shape, const Shape& out_shape, size_t out_axis)
-            {
-                size_t index[4];
-                size_t& in_index = index[out_axis];
-                auto out_strides = row_major_strides(out_shape);
-                for (index[0] = 0; index[0] < out_shape[0]; ++index[0])
-                {
-                    for (index[1] = 0; index[1] < out_shape[1]; ++index[1])
-                    {
-                        for (index[2] = 0; index[2] < out_shape[2]; ++index[2])
-                        {
-                            for (index[3] = 0; index[3] < out_shape[3]; ++index[3])
-                            {
-                                // clang-format off
-                                out[index[0] * out_strides[0] +
-                                    index[1] * out_strides[1] +
-                                    index[2] * out_strides[2] +
-                                    index[3]] =
-                                        in[in_index];
-                                // clang-format on
-                            }
-                        }
-                    }
-                }
-            }
-
-            template <typename T>
-            void broadcast_5d(
-                const T* in, T* out, const Shape& in_shape, const Shape& out_shape, size_t out_axis)
-            {
-                size_t index[5];
-                size_t& in_index = index[out_axis];
-                auto out_strides = row_major_strides(out_shape);
-                for (index[0] = 0; index[0] < out_shape[0]; ++index[0])
-                {
-                    for (index[1] = 0; index[1] < out_shape[1]; ++index[1])
-                    {
-                        for (index[2] = 0; index[2] < out_shape[2]; ++index[2])
-                        {
-                            for (index[3] = 0; index[3] < out_shape[3]; ++index[3])
-                            {
-                                for (index[4] = 0; index[4] < out_shape[4]; ++index[4])
-                                {
-                                    // clang-format off
-                                    out[index[0] * out_strides[0] +
-                                        index[1] * out_strides[1] +
-                                        index[2] * out_strides[2] +
-                                        index[3] * out_strides[3] +
-                                        index[4]] =
-                                            in[in_index];
-                                    // clang-format on
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-            template <typename T>
-            void broadcast_6d(
-                const T* in, T* out, const Shape& in_shape, const Shape& out_shape, size_t out_axis)
-            {
-                size_t index[6];
-                size_t& in_index = index[out_axis];
-                auto out_strides = row_major_strides(out_shape);
-                for (index[0] = 0; index[0] < out_shape[0]; ++index[0])
-                {
-                    for (index[1] = 0; index[1] < out_shape[1]; ++index[1])
-                    {
-                        for (index[2] = 0; index[2] < out_shape[2]; ++index[2])
-                        {
-                            for (index[3] = 0; index[3] < out_shape[3]; ++index[3])
-                            {
-                                for (index[4] = 0; index[4] < out_shape[4]; ++index[4])
-                                {
-                                    for (index[5] = 0; index[5] < out_shape[5]; ++index[5])
-                                    {
-                                        // clang-format off
-                                        out[index[0] * out_strides[0] +
-                                            index[1] * out_strides[1] +
-                                            index[2] * out_strides[2] +
-                                            index[3] * out_strides[3] +
-                                            index[4] * out_strides[4] +
-                                            index[5]] =
-                                                in[in_index];
-                                        // clang-format on
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-            template <typename T>
-            void broadcast(const T* in,
-                           T* out,
-                           const Shape& in_shape,
-                           const Shape& out_shape,
-                           const AxisSet& broadcast_axes)
-            {
-                if (is_scalar(in_shape))
-                {
-                    for (size_t i = 0; i < shape_size(out_shape); ++i)
-                    {
-                        out[i] = in[0];
-                    }
-                }
-                else if (in_shape.size() == 1)
-                {
-                    size_t output_axis = 0;
-                    for (size_t i = 0; i < out_shape.size(); i++)
-                    {
-                        if (broadcast_axes.count(i) == 0)
-                        {
-                            output_axis = i;
-                            break;
-                        }
-                    }
-                    switch (out_shape.size())
-                    {
-                    case 2: broadcast_2d<T>(in, out, in_shape, out_shape, output_axis); break;
-                    case 3: broadcast_3d<T>(in, out, in_shape, out_shape, output_axis); break;
-                    case 4: broadcast_4d<T>(in, out, in_shape, out_shape, output_axis); break;
-                    case 5: broadcast_5d<T>(in, out, in_shape, out_shape, output_axis); break;
-                    case 6: broadcast_6d<T>(in, out, in_shape, out_shape, output_axis); break;
-                    default:
-                        runtime::reference::broadcast<T>(
-                            in, out, in_shape, out_shape, broadcast_axes);
-                        break;
-                    }
-                }
-                else
-                {
-                    runtime::reference::broadcast<T>(in, out, in_shape, out_shape, broadcast_axes);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/opt_kernel/reshape.hpp b/ngraph/core/include/ngraph/runtime/opt_kernel/reshape.hpp
deleted file mode 100644 (file)
index 948ec9d..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include "ngraph/axis_vector.hpp"
-#include "ngraph/runtime/reference/reshape.hpp"
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace opt_kernel
-        {
-            void reshape(const char* in,
-                         char* out,
-                         const Shape& in_shape,
-                         const AxisVector& in_axis_order,
-                         const Shape& out_shape,
-                         size_t elem_size);
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/abs.hpp b/ngraph/core/include/ngraph/runtime/reference/abs.hpp
deleted file mode 100644 (file)
index 6ac8d0f..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void abs(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    // TODO: generic "abs" doesn't work here for some reason.
-                    out[i] = (arg[i] < T(0) ? T(-arg[i]) : arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/acos.hpp b/ngraph/core/include/ngraph/runtime/reference/acos.hpp
deleted file mode 100644 (file)
index 7988006..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void acos(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::acos(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/acosh.hpp b/ngraph/core/include/ngraph/runtime/reference/acosh.hpp
deleted file mode 100644 (file)
index 817ada4..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void acosh(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::acosh(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/add.hpp b/ngraph/core/include/ngraph/runtime/reference/add.hpp
deleted file mode 100644 (file)
index 56de3fe..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void add(const T* arg0, const T* arg1, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg0[i] + arg1[i];
-                }
-            }
-
-            template <typename T>
-            void add(const T* arg0,
-                     const T* arg1,
-                     T* out,
-                     const Shape& arg0_shape,
-                     const Shape& arg1_shape,
-                     const op::AutoBroadcastSpec& broadcast_spec)
-            {
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
-                        return x + y;
-                    });
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/and.hpp b/ngraph/core/include/ngraph/runtime/reference/and.hpp
deleted file mode 100644 (file)
index bd7c83a..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-#include "ngraph/op/util/attr_types.hpp"
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void logical_and(const T* arg0, const T* arg1, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = static_cast<T>(arg0[i] && arg1[i]);
-                }
-            }
-
-            template <typename T>
-            void logical_and(const T* arg0,
-                             const T* arg1,
-                             T* out,
-                             const Shape& arg0_shape,
-                             const Shape& arg1_shape,
-                             const op::AutoBroadcastSpec& broadcast_spec)
-            {
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
-                        return static_cast<T>(x && y);
-                    });
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/any.hpp b/ngraph/core/include/ngraph/runtime/reference/any.hpp
deleted file mode 100644 (file)
index 89b05b0..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            static inline void any(const char* arg,
-                                   char* out,
-                                   const Shape& in_shape,
-                                   const AxisSet& reduction_axes,
-                                   bool keep_dims)
-            {
-                CoordinateTransform output_transform(reduce(in_shape, reduction_axes, keep_dims));
-
-                for (const Coordinate& output_coord : output_transform)
-                {
-                    out[output_transform.index(output_coord)] = 0;
-                }
-
-                CoordinateTransform input_transform(in_shape);
-
-                for (const Coordinate& input_coord : input_transform)
-                {
-                    Coordinate output_coord = reduce(input_coord, reduction_axes, keep_dims);
-                    out[output_transform.index(output_coord)] =
-                        out[output_transform.index(output_coord)] ||
-                        arg[input_transform.index(input_coord)];
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/asin.hpp b/ngraph/core/include/ngraph/runtime/reference/asin.hpp
deleted file mode 100644 (file)
index 5a71312..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void asin(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::asin(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/asinh.hpp b/ngraph/core/include/ngraph/runtime/reference/asinh.hpp
deleted file mode 100644 (file)
index 8f38d37..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void asinh(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::asinh(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/atan.hpp b/ngraph/core/include/ngraph/runtime/reference/atan.hpp
deleted file mode 100644 (file)
index af9ee1f..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void atan(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::atan(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/atan2.hpp b/ngraph/core/include/ngraph/runtime/reference/atan2.hpp
deleted file mode 100644 (file)
index 86b3014..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename X, typename Y, typename Z>
-            void atan2(const X* py, const Y* px, Z* pout, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    *pout++ = static_cast<Z>(std::atan2(*py++, *px++));
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/atanh.hpp b/ngraph/core/include/ngraph/runtime/reference/atanh.hpp
deleted file mode 100644 (file)
index 647c739..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void atanh(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::atanh(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/autobroadcast_binop.hpp b/ngraph/core/include/ngraph/runtime/reference/autobroadcast_binop.hpp
deleted file mode 100644 (file)
index 7041078..0000000
+++ /dev/null
@@ -1,551 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-#include <utility>
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/op/util/attr_types.hpp"
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            namespace internal
-            {
-                inline void
-                    row_major_strides(const Shape& shape, size_t* strides, size_t size) noexcept
-                {
-                    size_t* st = strides + size - 1;
-                    size_t s = 1;
-                    for (auto d = shape.rbegin(); d != shape.rend(); d++)
-                    {
-                        *st-- = s;
-                        s *= *d;
-                    }
-                    std::fill(strides, st + 1, s);
-                }
-
-                template <typename C, typename T>
-                inline T value_with_padding_or(const C& arr,
-                                               size_t padding,
-                                               size_t idx,
-                                               T&& default_value)
-                {
-                    return idx < padding ? std::forward<T>(default_value) : arr[idx - padding];
-                }
-
-                template <int A0, int A1, typename T, typename U, typename Functor>
-                inline void numpy_autobroadcast_binop(const T* arg0,
-                                                      const T* arg1,
-                                                      U* out,
-                                                      const Shape& shape0,
-                                                      const Shape& shape1,
-                                                      const size_t* strides0,
-                                                      const size_t* strides1,
-                                                      const size_t padding0,
-                                                      const size_t padding1,
-                                                      const Shape& output_shape,
-                                                      const size_t axis,
-                                                      const size_t stride,
-                                                      Functor elementwise_functor)
-                {
-                    for (CoordinateIterator it(output_shape), ite = CoordinateIterator::end();;)
-                    {
-                        for (size_t i = 0; i < stride; ++i)
-                            *out++ = elementwise_functor(arg0[i * A0], arg1[i * A1]);
-
-                        arg0 += A0 ? stride : 1;
-                        arg1 += A1 ? stride : 1;
-
-                        auto p = it.advance(axis);
-
-                        if (it == ite)
-                            break;
-
-                        if (value_with_padding_or(shape0, padding0, p, 1) == 1)
-                            arg0 -= strides0[p];
-
-                        if (value_with_padding_or(shape1, padding1, p, 1) == 1)
-                            arg1 -= strides1[p];
-                    }
-                }
-
-                inline size_t calculate_fixed_axis(size_t axis, const size_t* strides)
-                {
-                    while (axis > 0 && strides[axis - 1] == 1)
-                        --axis;
-                    return axis;
-                }
-            }
-
-            /// \brief Helper function to implement autobroadcasting elementwise binop references.
-            ///
-            /// \tparam T Element type of the input tensors.
-            /// \tparam U Element type of the output tensor.
-            /// \tparam Functor Type of the functor for the elementwise operation. Must support
-            ///                 operator()(T,T), and operator()(T,T) must return a value of type
-            ///                 U.
-            ///
-            /// \param arg0 Pointer to the buffer for left operand input tensor.
-            /// \param arg1 Pointer to the buffer for right operand input tensor.
-            /// \param out Pointer to the buffer for output tensor. This must be pre-allocated by
-            ///            the caller, and must be large enough to hold a tensor of the correct
-            ///            shape.
-            /// \param broadcast_spec Specification of the auto-broadcasting scheme.
-            /// \param elementwise_functor Functor implementing the elementwise operation to be
-            ///                            applied across the input tensors. Must accept two
-            ///                            arguments of type T, and return a value of type U.
-            template <typename T, typename U, typename Functor>
-            void autobroadcast_binop(const T* arg0,
-                                     const T* arg1,
-                                     U* out,
-                                     const Shape& arg0_shape,
-                                     const Shape& arg1_shape,
-                                     const op::AutoBroadcastSpec& broadcast_spec,
-                                     Functor elementwise_functor)
-            {
-                switch (broadcast_spec.m_type)
-                {
-                case op::AutoBroadcastType::NONE:
-                    for (size_t i = 0; i < shape_size(arg0_shape); i++)
-                    {
-                        out[i] = elementwise_functor(arg0[i], arg1[i]);
-                    }
-                    break;
-                case op::AutoBroadcastType::NUMPY:
-                    // We'll be using CoordinateTransform to handle the broadcasting. The general
-                    // procedure is as follows:
-                    //
-                    // (1) Left pad the shorter of the two shapes with ones.
-                    // (2) Squeeze (remove ones from) both shapes, and record the squeezed axis
-                    //     indices.
-                    // (3) Using CoordinateTransform, broadcast both args to the final output
-                    //     shape. The "broadcasted axes" will be those that were squeezed in step
-                    //     2.
-                    //
-                    // Example:
-                    //
-                    //    Input shape->Padded shape->Squeezed Shape/Squeezed Axes
-                    //    -----------  ------------  ----------------------------
-                    // a: [ 3, 2, 1]   [ 3, 2, 1]    [ 3, 2   ]     {2}
-                    // b: [    1, 6]   [ 1, 1, 6]    [       6]     {0,1}
-                    //                   |  |  |
-                    //                   v  v  v
-                    //                 Output shape
-                    //                 ------------
-                    //                 [ 3, 2, 6]
-                    {
-                        using namespace internal;
-
-                        size_t const shape_rank =
-                            std::max(arg0_shape.size(), arg1_shape.size()) + 1;
-
-                        // TODO: Use compiler-specific alloca() or variable-length array
-                        std::vector<size_t> tmp(shape_rank * 2);
-
-                        size_t* strides0 = tmp.data();
-                        size_t* strides1 = tmp.data() + shape_rank;
-
-                        row_major_strides(arg0_shape, strides0, shape_rank);
-                        row_major_strides(arg1_shape, strides1, shape_rank);
-
-                        size_t const padding0 = shape_rank - arg0_shape.size();
-                        size_t const padding1 = shape_rank - arg1_shape.size();
-
-                        Shape output_shape(shape_rank, 0);
-
-                        size_t axis = 0;
-
-                        for (size_t i = 0; i < shape_rank; i++)
-                        {
-                            auto const dim0 = value_with_padding_or(arg0_shape, padding0, i, 1);
-                            auto const dim1 = value_with_padding_or(arg1_shape, padding1, i, 1);
-
-                            output_shape[i] = std::max(dim0, dim1);
-
-                            if (dim0 != dim1)
-                                axis = std::max(axis, i);
-                        }
-#if 0
-                        // Universal function without optimisations
-                        CoordinateTransformBasic arg0_transform(arg0_shape);
-                        CoordinateTransformBasic arg1_transform(arg1_shape);
-                        U *dst = out;
-
-                        for(CoordinateIterator it(output_shape),
-                            ite = CoordinateIterator::end();
-                            it != ite;
-                            ++it)
-                        {
-                            const Coordinate& output_coord = *it;
-                            size_t const idx0 = arg0_transform.index(output_coord);
-                            size_t const idx1 = arg1_transform.index(output_coord);
-                            *dst++ = elementwise_functor(arg0[idx0], arg1[idx1]);
-                        }
-#else
-
-                        if (axis == 0)
-                        {
-                            for (size_t i = 0, end = strides0[0]; i < end; ++i)
-                                out[i] = elementwise_functor(arg0[i], arg1[i]);
-                        }
-                        else if (strides0[axis] == 1 &&
-                                 value_with_padding_or(arg0_shape, padding0, axis, 1) == 1)
-                        {
-                            axis = calculate_fixed_axis(axis, strides0);
-
-                            numpy_autobroadcast_binop<0, 1>(arg0,
-                                                            arg1,
-                                                            out,
-                                                            arg0_shape,
-                                                            arg1_shape,
-                                                            strides0,
-                                                            strides1,
-                                                            padding0,
-                                                            padding1,
-                                                            output_shape,
-                                                            axis,
-                                                            strides1[axis],
-                                                            elementwise_functor);
-                        }
-                        else if (strides1[axis] == 1 &&
-                                 value_with_padding_or(arg1_shape, padding1, axis, 1) == 1)
-                        {
-                            axis = calculate_fixed_axis(axis, strides1);
-
-                            numpy_autobroadcast_binop<1, 0>(arg0,
-                                                            arg1,
-                                                            out,
-                                                            arg0_shape,
-                                                            arg1_shape,
-                                                            strides0,
-                                                            strides1,
-                                                            padding0,
-                                                            padding1,
-                                                            output_shape,
-                                                            axis,
-                                                            strides0[axis],
-                                                            elementwise_functor);
-                        }
-                        else
-                            numpy_autobroadcast_binop<1, 1>(arg0,
-                                                            arg1,
-                                                            out,
-                                                            arg0_shape,
-                                                            arg1_shape,
-                                                            strides0,
-                                                            strides1,
-                                                            padding0,
-                                                            padding1,
-                                                            output_shape,
-                                                            axis,
-                                                            strides0[axis],
-                                                            elementwise_functor);
-#endif
-                    }
-                    break;
-                case op::AutoBroadcastType::PDPD:
-                    // We'll be using CoordinateTransform to handle the broadcasting. No need to
-                    // process arg0 and output shape will be the same as arg0. We need to process
-                    // arg1 and the general procedure is as follows:
-                    //
-                    // (1) Trim trailing ones from arg1 shape.
-                    // (2) Left and right pad arg1 to match arg0 shape. Axis is the index start
-                    //     to align between arg0 and arg1.
-                    // (3) Squeeze (remove ones from) arg1 shape, and record the squeezed axis
-                    //     indices.
-                    // (3) Using CoordinateTransform, broadcast arg1 to the final output
-                    //     shape. The "broadcasted axes" will be those that were squeezed in step
-                    //     23.
-                    //
-                    // Example:
-                    //
-                    //    Input shape->   Padded shape->   Squeezed Shape/Squeezed Axes
-                    //    -----------  ------------  ----------------------------
-                    // a: [ 3, 4, 5, 6]   [ 3, 4, 5, 6]    [ 3, 4, 5, 6]
-                    // b: [    4, 5,  ]   [ 1, 4, 5, 1]    [    4, 5   ]     {0,3}
-                    //                      |  |  |
-                    //                      v  v  v
-                    //                     Output shape
-                    //                     ------------
-                    //                    [ 3, 4, 5, 6]
-                    {
-                        int64_t axis = broadcast_spec.m_axis;
-                        if (axis == -1)
-                        {
-                            axis = arg0_shape.size() - arg1_shape.size();
-                        }
-
-                        Shape arg1_padded_shape = arg1_shape;
-                        // Trim trailing ones
-                        while (arg1_padded_shape.size() > 0 && arg1_padded_shape.back() == 1)
-                        {
-                            arg1_padded_shape.pop_back();
-                        }
-
-                        for (int64_t i = 0; i < axis; ++i)
-                        {
-                            arg1_padded_shape.insert(arg1_padded_shape.begin(), 1);
-                        }
-
-                        while (arg1_padded_shape.size() < arg0_shape.size())
-                        {
-                            arg1_padded_shape.insert(arg1_padded_shape.end(), 1);
-                        }
-
-                        Shape arg1_squeezed_shape;
-                        AxisSet arg1_squeezed_axes;
-
-                        for (size_t i = 0; i < arg0_shape.size(); i++)
-                        {
-                            if (arg1_padded_shape[i] == 1)
-                            {
-                                arg1_squeezed_axes.insert(i);
-                            }
-                            else
-                            {
-                                arg1_squeezed_shape.push_back(arg1_padded_shape[i]);
-                            }
-                        }
-
-                        CoordinateTransform arg0_transform(arg0_shape);
-                        CoordinateTransform arg1_transform(arg1_squeezed_shape);
-                        CoordinateTransform output_transform(arg0_shape);
-
-                        for (const Coordinate& output_coord : output_transform)
-                        {
-                            Coordinate arg1_coord = reduce(output_coord, arg1_squeezed_axes, false);
-                            out[output_transform.index(output_coord)] =
-                                elementwise_functor(arg0[arg0_transform.index(output_coord)],
-                                                    arg1[arg1_transform.index(arg1_coord)]);
-                        }
-                    }
-                }
-            }
-
-            /// \brief Helper function to implement autobroadcasting elementwise ternaryop
-            /// references.
-            ///
-            /// \tparam U Element type of the selector tensor.
-            /// \tparam T Element type of the input tensors.
-            /// \tparam Functor Type of the functor for the elementwise operation. Must support
-            ///                 operator()(U,T,T), and operator()(U,T,T) must return a value of type
-            ///                 T.
-            ///
-            /// \param arg0 Pointer to the buffer for selector tensor.
-            /// \param arg1 Pointer to the buffer for left operand input tensor.
-            /// \param arg2 Pointer to the buffer for right operand input tensor.
-            /// \param out Pointer to the buffer for output tensor. This must be pre-allocated by
-            ///            the caller, and must be large enough to hold a tensor of the correct
-            ///            shape.
-            /// \param broadcast_spec Specification of the auto-broadcasting scheme.
-            /// \param elementwise_functor Functor implementing the elementwise operation to be
-            ///                            applied across the input tensors. Must accept an argument
-            ///                            of
-            ///                            type U and two of type T, and return a value of type T.
-            template <typename T, typename U, typename Functor>
-            void autobroadcast_select(const U* arg0,
-                                      const T* arg1,
-                                      const T* arg2,
-                                      T* out,
-                                      const Shape& arg0_shape,
-                                      const Shape& arg1_shape,
-                                      const Shape& arg2_shape,
-                                      const op::AutoBroadcastSpec& broadcast_spec,
-                                      Functor elementwise_functor)
-            {
-                switch (broadcast_spec.m_type)
-                {
-                case op::AutoBroadcastType::NONE:
-                    for (size_t i = 0; i < shape_size(arg0_shape); i++)
-                    {
-                        out[i] = elementwise_functor(arg0[i], arg1[i], arg2[i]);
-                    }
-                    break;
-                case op::AutoBroadcastType::NUMPY:
-                    // Uses same approach as autobroadcast_binop.
-                    {
-                        Shape arg0_padded_shape = arg0_shape;
-                        Shape arg1_padded_shape = arg1_shape;
-                        Shape arg2_padded_shape = arg2_shape;
-
-                        while (arg1_padded_shape.size() < arg2_padded_shape.size())
-                        {
-                            arg1_padded_shape.insert(arg1_padded_shape.begin(), 1);
-                        }
-
-                        while (arg2_padded_shape.size() < arg1_padded_shape.size())
-                        {
-                            arg2_padded_shape.insert(arg2_padded_shape.begin(), 1);
-                        }
-
-                        while (arg0_padded_shape.size() < arg1_padded_shape.size())
-                        {
-                            arg0_padded_shape.insert(arg0_padded_shape.begin(), 1);
-                        }
-
-                        Shape arg0_squeezed_shape;
-                        Shape arg1_squeezed_shape;
-                        Shape arg2_squeezed_shape;
-                        AxisSet arg0_squeezed_axes;
-                        AxisSet arg1_squeezed_axes;
-                        AxisSet arg2_squeezed_axes;
-                        Shape output_shape;
-
-                        for (size_t i = 0; i < arg1_padded_shape.size(); i++)
-                        {
-                            if (arg1_padded_shape[i] == 1)
-                            {
-                                arg1_squeezed_axes.insert(i);
-                            }
-                            else
-                            {
-                                arg1_squeezed_shape.push_back(arg1_padded_shape[i]);
-                            }
-
-                            if (arg2_padded_shape[i] == 1)
-                            {
-                                arg2_squeezed_axes.insert(i);
-                            }
-                            else
-                            {
-                                arg2_squeezed_shape.push_back(arg2_padded_shape[i]);
-                            }
-
-                            if (arg0_padded_shape[i] == 1)
-                            {
-                                arg0_squeezed_axes.insert(i);
-                            }
-                            else
-                            {
-                                arg0_squeezed_shape.push_back(arg0_padded_shape[i]);
-                            }
-
-                            output_shape.push_back(arg1_padded_shape[i] == 1
-                                                       ? arg2_padded_shape[i]
-                                                       : arg1_padded_shape[i]);
-                        }
-
-                        CoordinateTransform arg0_transform(arg0_squeezed_shape);
-                        CoordinateTransform arg1_transform(arg1_squeezed_shape);
-                        CoordinateTransform arg2_transform(arg2_squeezed_shape);
-                        CoordinateTransform output_transform(output_shape);
-
-                        for (const Coordinate& output_coord : output_transform)
-                        {
-                            Coordinate arg0_coord = reduce(output_coord, arg0_squeezed_axes, false);
-                            Coordinate arg1_coord = reduce(output_coord, arg1_squeezed_axes, false);
-                            Coordinate arg2_coord = reduce(output_coord, arg2_squeezed_axes, false);
-                            out[output_transform.index(output_coord)] =
-                                elementwise_functor(arg0[arg0_transform.index(arg0_coord)],
-                                                    arg1[arg1_transform.index(arg1_coord)],
-                                                    arg2[arg2_transform.index(arg2_coord)]);
-                        }
-                    }
-                    break;
-                case op::AutoBroadcastType::PDPD:
-                {
-                    // arg0 and arg2 are broadcast to arg1 shape
-                    int64_t axis = broadcast_spec.m_axis;
-                    if (axis == -1)
-                    {
-                        axis = arg1_shape.size() - arg2_shape.size();
-                    }
-
-                    Shape arg0_padded_shape = arg0_shape;
-                    Shape arg2_padded_shape = arg2_shape;
-                    // Trim trailing ones
-                    while (arg0_padded_shape.size() > 0 && arg0_padded_shape.back() == 1)
-                    {
-                        arg0_padded_shape.pop_back();
-                    }
-
-                    for (int64_t i = 0; i < axis; ++i)
-                    {
-                        arg0_padded_shape.insert(arg0_padded_shape.begin(), 1);
-                    }
-
-                    while (arg0_padded_shape.size() < arg1_shape.size())
-                    {
-                        arg0_padded_shape.insert(arg0_padded_shape.end(), 1);
-                    }
-
-                    while (arg2_padded_shape.size() > 0 && arg2_padded_shape.back() == 1)
-                    {
-                        arg2_padded_shape.pop_back();
-                    }
-
-                    for (int64_t i = 0; i < axis; ++i)
-                    {
-                        arg2_padded_shape.insert(arg2_padded_shape.begin(), 1);
-                    }
-
-                    while (arg2_padded_shape.size() < arg1_shape.size())
-                    {
-                        arg2_padded_shape.insert(arg2_padded_shape.end(), 1);
-                    }
-
-                    Shape arg0_squeezed_shape;
-                    AxisSet arg0_squeezed_axes;
-                    Shape arg2_squeezed_shape;
-                    AxisSet arg2_squeezed_axes;
-
-                    for (size_t i = 0; i < arg1_shape.size(); i++)
-                    {
-                        if (arg0_padded_shape[i] == 1)
-                        {
-                            arg0_squeezed_axes.insert(i);
-                        }
-                        else
-                        {
-                            arg0_squeezed_shape.push_back(arg0_padded_shape[i]);
-                        }
-                        if (arg2_padded_shape[i] == 1)
-                        {
-                            arg2_squeezed_axes.insert(i);
-                        }
-                        else
-                        {
-                            arg2_squeezed_shape.push_back(arg2_padded_shape[i]);
-                        }
-                    }
-
-                    CoordinateTransform arg0_transform(arg0_squeezed_shape);
-                    CoordinateTransform arg1_transform(arg1_shape);
-                    CoordinateTransform arg2_transform(arg2_squeezed_shape);
-                    CoordinateTransform output_transform(arg1_shape);
-
-                    for (const Coordinate& output_coord : output_transform)
-                    {
-                        Coordinate arg0_coord = reduce(output_coord, arg0_squeezed_axes, false);
-                        Coordinate arg2_coord = reduce(output_coord, arg2_squeezed_axes, false);
-                        out[output_transform.index(output_coord)] =
-                            elementwise_functor(arg0[arg0_transform.index(arg0_coord)],
-                                                arg1[arg1_transform.index(output_coord)],
-                                                arg2[arg2_transform.index(arg2_coord)]);
-                    }
-                }
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/avg_pool.hpp b/ngraph/core/include/ngraph/runtime/reference/avg_pool.hpp
deleted file mode 100644 (file)
index 6daa402..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cfenv>
-#include <cmath>
-#include <numeric>
-#include <stdexcept>
-#include <vector>
-
-#include "ngraph/axis_vector.hpp"
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void avg_pool_backprop(const T* delta,
-                                   T* out,
-                                   const Shape& delta_shape,
-                                   const Shape& out_shape,
-                                   const Shape& window_shape,
-                                   const Strides& window_movement_strides,
-                                   const Shape& padding_below,
-                                   const Shape& padding_above,
-                                   bool include_padding_in_avg_computation)
-            {
-                CoordinateTransform out_transform(out_shape);
-
-                for (const Coordinate& out_coord : out_transform)
-                {
-                    out[out_transform.index(out_coord)] = 0;
-                }
-
-                CoordinateTransform delta_transform(delta_shape);
-
-                for (const Coordinate& delta_coord : delta_transform)
-                {
-                    size_t img_index = delta_coord[0];
-                    size_t channel = delta_coord[1];
-
-                    size_t n_image_dimensions = out_shape.size() - 2;
-                    Coordinate source_window_transform_start(2 + n_image_dimensions);
-                    Coordinate source_window_transform_end(2 + n_image_dimensions);
-                    Strides source_window_transform_source_strides(2 + n_image_dimensions, 1);
-                    AxisVector source_window_transform_source_axis_order(2 + n_image_dimensions);
-                    CoordinateDiff source_window_transform_padding_below(2 + n_image_dimensions);
-                    CoordinateDiff source_window_transform_padding_above(2 + n_image_dimensions);
-
-                    source_window_transform_start[0] = img_index;
-                    source_window_transform_end[0] = img_index + 1;
-                    source_window_transform_start[1] = channel;
-                    source_window_transform_end[1] = channel + 1;
-                    source_window_transform_padding_below[0] = 0;
-                    source_window_transform_padding_below[1] = 0;
-                    source_window_transform_padding_above[0] = 0;
-                    source_window_transform_padding_above[1] = 0;
-
-                    for (size_t i = 2; i < n_image_dimensions + 2; i++)
-                    {
-                        size_t window_shape_this_dim = window_shape[i - 2];
-                        size_t movement_stride = window_movement_strides[i - 2];
-
-                        source_window_transform_start[i] = movement_stride * delta_coord[i];
-                        source_window_transform_end[i] =
-                            source_window_transform_start[i] + window_shape_this_dim;
-                        source_window_transform_padding_below[i] = padding_below[i - 2];
-                        source_window_transform_padding_above[i] = padding_above[i - 2];
-                    }
-                    std::iota(begin(source_window_transform_source_axis_order),
-                              end(source_window_transform_source_axis_order),
-                              0);
-
-                    CoordinateTransform source_window_transform(
-                        out_shape,
-                        source_window_transform_start,
-                        source_window_transform_end,
-                        source_window_transform_source_strides,
-                        source_window_transform_source_axis_order,
-                        source_window_transform_padding_below,
-                        source_window_transform_padding_above);
-
-                    size_t num_elements_in_window = 0;
-
-                    for (const Coordinate& source_window_coord : source_window_transform)
-                    {
-                        if (source_window_transform.has_source_coordinate(source_window_coord) ||
-                            include_padding_in_avg_computation)
-                        {
-                            num_elements_in_window++;
-                        }
-                    }
-
-                    for (const Coordinate& source_window_coord : source_window_transform)
-                    {
-                        if (source_window_transform.has_source_coordinate(source_window_coord))
-                        {
-                            size_t out_index = source_window_transform.index(source_window_coord);
-                            out[out_index] +=
-                                delta[delta_transform.index(delta_coord)] / num_elements_in_window;
-                        }
-                    }
-                }
-            }
-
-            template <typename T>
-            void avg_pool(const T* arg,
-                          T* out,
-                          const Shape& arg_shape,
-                          const Shape& out_shape,
-                          const Shape& window_shape,
-                          const Strides& window_movement_strides,
-                          const Shape& padding_below,
-                          const Shape& padding_above,
-                          bool include_padding_in_avg_computation)
-            {
-                auto old_mode = std::fegetround();
-                std::fesetround(FE_TONEAREST);
-                // At the outermost level we will walk over every output coordinate O.
-                CoordinateTransform output_transform(out_shape);
-
-                for (const Coordinate& out_coord : output_transform)
-                {
-                    // Our output coordinate O will have the form:
-                    //
-                    //   (N,chan,i_1,...,i_n)
-
-                    size_t batch_index = out_coord[0];
-                    size_t channel = out_coord[1];
-
-                    // For the input data we need to iterate the coordinate:
-                    //
-                    //   I:
-                    //
-                    // over the range (noninclusive on the right):
-                    //
-                    //   (N,chan,s_1*i_1,s_2*i_2,...,s_n*i_n) ->
-                    //
-                    //     (N+1,chan+1,s_1*i_1 + window_shape_1,...,s_n*i_n + window_shape_n)
-                    //
-                    // with unit stride.
-                    //
-                    // We iterate this over the *padded* data, so below we will need to check for
-                    // coordinates that fall in the padding area.
-
-                    size_t n_spatial_dimensions = arg_shape.size() - 2;
-
-                    Coordinate input_batch_transform_start(2 + n_spatial_dimensions);
-                    Coordinate input_batch_transform_end(2 + n_spatial_dimensions);
-                    Strides input_batch_transform_source_strides(2 + n_spatial_dimensions, 1);
-                    AxisVector input_batch_transform_source_axis_order(2 + n_spatial_dimensions);
-                    CoordinateDiff input_batch_transform_padding_below(2 + n_spatial_dimensions);
-                    CoordinateDiff input_batch_transform_padding_above(2 + n_spatial_dimensions);
-
-                    input_batch_transform_start[0] = batch_index;
-                    input_batch_transform_end[0] = batch_index + 1;
-                    input_batch_transform_start[1] = channel;
-                    input_batch_transform_end[1] = channel + 1;
-                    input_batch_transform_padding_below[0] = 0;
-                    input_batch_transform_padding_below[1] = 0;
-                    input_batch_transform_padding_above[0] = 0;
-                    input_batch_transform_padding_above[1] = 0;
-
-                    for (size_t i = 2; i < n_spatial_dimensions + 2; i++)
-                    {
-                        size_t window_shape_this_dim = window_shape[i - 2];
-                        size_t movement_stride = window_movement_strides[i - 2];
-
-                        input_batch_transform_start[i] = movement_stride * out_coord[i];
-                        input_batch_transform_end[i] =
-                            input_batch_transform_start[i] + window_shape_this_dim;
-                        input_batch_transform_padding_below[i] = padding_below[i - 2];
-                        input_batch_transform_padding_above[i] = padding_above[i - 2];
-                    }
-
-                    for (size_t i = 0; i < arg_shape.size(); i++)
-                    {
-                        input_batch_transform_source_axis_order[i] = i;
-                    }
-
-                    CoordinateTransform input_batch_transform(
-                        arg_shape,
-                        input_batch_transform_start,
-                        input_batch_transform_end,
-                        input_batch_transform_source_strides,
-                        input_batch_transform_source_axis_order,
-                        input_batch_transform_padding_below,
-                        input_batch_transform_padding_above);
-
-                    // As we go, we compute the sum value:
-                    //
-                    //   output[O] := output[O] + arg[I]
-                    //
-                    // and the number of elements:
-                    //
-                    //   n_elements := n_elements + 1
-
-                    T result = 0;
-                    size_t n_elements = 0;
-
-                    for (const Coordinate& input_batch_coord : input_batch_transform)
-                    {
-                        bool in_bounds =
-                            input_batch_transform.has_source_coordinate(input_batch_coord);
-
-                        if (in_bounds || include_padding_in_avg_computation)
-                        {
-                            T v =
-                                in_bounds ? arg[input_batch_transform.index(input_batch_coord)] : 0;
-                            result += v;
-                            n_elements++;
-                        }
-                    }
-
-                    if (n_elements == 0)
-                    {
-                        throw std::runtime_error("AvgPool elements == 0, must be non-zero");
-                    }
-
-                    if (std::is_same<T, int8_t>::value || std::is_same<T, uint8_t>::value)
-                    {
-                        out[output_transform.index(out_coord)] =
-                            static_cast<T>(std::nearbyint(static_cast<float>(result) / n_elements));
-                    }
-                    else
-                    {
-                        out[output_transform.index(out_coord)] = result / n_elements;
-                    }
-                    std::fesetround(old_mode);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/batch_norm.hpp b/ngraph/core/include/ngraph/runtime/reference/batch_norm.hpp
deleted file mode 100644 (file)
index 4f511c5..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <vector>
-
-#include "ngraph/axis_vector.hpp"
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/runtime/reference/add.hpp"
-#include "ngraph/runtime/reference/broadcast.hpp"
-#include "ngraph/runtime/reference/divide.hpp"
-#include "ngraph/runtime/reference/multiply.hpp"
-#include "ngraph/runtime/reference/sum.hpp"
-#include "ngraph/shape.hpp"
-#include "ngraph/util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void batch_norm_inference(float eps,
-                                      const T* gamma,
-                                      const T* beta,
-                                      const T* input,
-                                      const T* mean,
-                                      const T* variance,
-                                      T* normed_input,
-                                      const Shape& input_shape)
-            {
-                auto eps_casted = static_cast<T>(eps);
-                CoordinateTransform input_transform(input_shape);
-
-                for (Coordinate input_coord : input_transform)
-                {
-                    auto channel_num = input_coord[1];
-                    auto channel_gamma = gamma[channel_num];
-                    auto channel_beta = beta[channel_num];
-                    auto channel_mean = mean[channel_num];
-                    auto channel_var = variance[channel_num];
-
-                    auto input_index = input_transform.index(input_coord);
-                    auto normalized =
-                        (input[input_index] - channel_mean) / (std::sqrt(channel_var + eps_casted));
-                    normed_input[input_index] = normalized * channel_gamma + channel_beta;
-                }
-            }
-
-            template <typename T>
-            void batch_norm_training(float eps,
-                                     const T* gamma,
-                                     const T* beta,
-                                     const T* input,
-                                     T* normed_input,
-                                     T* mean,
-                                     T* variance,
-                                     const Shape& input_shape)
-            {
-                auto eps_casted = static_cast<T>(eps);
-                auto channels = input_shape[1];
-
-                // We use these objects to iterate over the indices in a channel.
-                // The start and end points for the channel axis are modified in the loop.
-                Coordinate start_corner;
-                Coordinate end_corner;
-                for (size_t i = 0; i < input_shape.size(); i++)
-                {
-                    start_corner.push_back(0);
-                    end_corner.push_back(input_shape[i]);
-                }
-
-                for (size_t c = 0; c < channels; c++)
-                {
-                    T channel_sum = 0;
-
-                    start_corner[1] = c;
-                    end_corner[1] = c + 1;
-
-                    // Compute the mean
-                    CoordinateTransform input_transform(input_shape, start_corner, end_corner);
-                    for (Coordinate input_coord : input_transform)
-                    {
-                        channel_sum += input[input_transform.index(input_coord)];
-                    }
-                    T channel_mean = channel_sum / (shape_size(input_shape) / channels);
-                    mean[c] = channel_mean;
-
-                    T channel_diff_square_sum = 0;
-                    for (Coordinate input_coord : input_transform)
-                    {
-                        auto centered = input[input_transform.index(input_coord)] - channel_mean;
-                        channel_diff_square_sum += centered * centered;
-                    }
-                    T channel_var = channel_diff_square_sum / (shape_size(input_shape) / channels);
-                    variance[c] = channel_var;
-
-                    auto channel_gamma = gamma[c];
-                    auto channel_beta = beta[c];
-                    T scale = channel_gamma / std::sqrt(channel_var + eps_casted);
-
-                    // Compute the normalized output
-                    for (Coordinate input_coord : input_transform)
-                    {
-                        auto input_index = input_transform.index(input_coord);
-                        normed_input[input_index] =
-                            (input[input_index] - channel_mean) * scale + channel_beta;
-                    }
-                }
-            }
-
-            template <typename T>
-            void batch_norm_backprop(float eps,
-                                     const T* gamma,
-                                     const T* /* beta */,
-                                     const T* input,
-                                     const T* mean,
-                                     const T* variance,
-                                     const T* delta_normed,
-                                     T* delta_input,
-                                     T* delta_gamma,
-                                     T* delta_beta,
-                                     const Shape& input_shape)
-            {
-                size_t channel_axis = 1;
-                auto num_channels = input_shape[channel_axis];
-                Shape moment_shape = Shape{num_channels};
-                auto input_num_elements = shape_size(input_shape);
-                auto elements_per_channel = input_num_elements / num_channels;
-
-                Coordinate start_corner;
-                Coordinate end_corner;
-                for (size_t i = 0; i < input_shape.size(); i++)
-                {
-                    start_corner.push_back(0);
-                    end_corner.push_back(input_shape[i]);
-                }
-                // The forward computation in gory detail
-                // input[., C, ...]
-                // gamma[C]
-                // beta[C]
-                // mu[c:C] = sum(input[., c, ...])/elements_per_channel
-                // var[c:C] = sum(input[., c, ...]^2 - mu[c])/elements_per_channel
-                // inv_sqrt[c:C] = 1/sqrt(var[c]+epsilon)
-                // gammad[c:C] = gamma[c]*inv_sqrt[c]
-                // normed[., c:C, ...] = (input[., c, ...]-mu)*gammad[c]+beta[c]
-
-                for (uint64_t c = 0; c < num_channels; ++c)
-                {
-                    start_corner[channel_axis] = c;
-                    end_corner[channel_axis] = c + 1;
-
-                    CoordinateTransform input_transform(input_shape, start_corner, end_corner);
-                    T delta_beta_sum = 0;
-                    T var = variance[c];
-                    T mu = mean[c];
-                    T var_eps = var + static_cast<T>(eps);
-                    T sqrt_var_eps = std::sqrt(var_eps);
-                    T inv_sqrt_var_eps = 1 / sqrt_var_eps;
-                    T gammad = gamma[c] * inv_sqrt_var_eps;
-                    T delta_gammad = 0;
-                    T delta_mu = 0;
-                    for (Coordinate input_coord : input_transform)
-                    {
-                        auto idx = input_transform.index(input_coord);
-                        auto delta_idx = delta_normed[idx];
-                        auto input_idx = input[idx];
-                        delta_beta_sum += delta_idx;
-                        delta_gammad += (input_idx - mu) * delta_idx;
-                        T delta_centered = gammad * delta_idx;
-                        delta_input[idx] = delta_centered;
-                        delta_mu -= delta_centered;
-                    }
-                    delta_beta[c] = delta_beta_sum;
-                    delta_gamma[c] = delta_gammad * inv_sqrt_var_eps;
-                    T delta_inv_sqrt = gamma[c] * delta_gammad;
-                    // y = x^(-1/2)
-                    // dy = -(1/2)x^(-3/2) = -y/(2x) dx
-                    T delta_var = -delta_inv_sqrt * inv_sqrt_var_eps / (2 * var_eps);
-                    T delta_two_var_sum = 2 * delta_var / elements_per_channel;
-                    T delta_mu_over_n = delta_mu / elements_per_channel;
-                    for (Coordinate input_coord : input_transform)
-                    {
-                        // v = 1/N sum(x_i - mu)^2
-                        // dv = 2/N sum[(x_i - mu)dx_i] - 2/N sum[(x_i - mu) dmu]
-                        //    = 2/N sum[(x_i - mu)dx_i] - 2/N (Nmu-Nmu) dmu
-                        //    = 2/N sum[(x_i - mu)dx_i]
-                        auto idx = input_transform.index(input_coord);
-                        // These two values mostly cancel out so add them first
-                        auto val = delta_input[idx] + delta_mu_over_n;
-                        delta_input[idx] = val + (input[idx] - mu) * delta_two_var_sum;
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/broadcast.hpp b/ngraph/core/include/ngraph/runtime/reference/broadcast.hpp
deleted file mode 100644 (file)
index 8c324fb..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void broadcast(const T* arg,
-                           T* out,
-                           const Shape& in_shape,
-                           const Shape& out_shape,
-                           const AxisSet& broadcast_axes)
-            {
-                // Remove all broadcast axes from in_shape
-                Shape adjusted_in_shape;
-                for (auto length : in_shape)
-                {
-                    if (length != 1)
-                    {
-                        adjusted_in_shape.push_back(length);
-                    }
-                }
-                // Remove 1s from out_shape
-                AxisSet adjusted_axes(broadcast_axes);
-                for (uint64_t axis = 0; axis < out_shape.size(); ++axis)
-                {
-                    auto length = out_shape.at(axis);
-                    if (length == 1)
-                    {
-                        adjusted_axes.insert(axis);
-                    }
-                }
-                CoordinateTransform input_transform(adjusted_in_shape);
-                CoordinateTransform output_transform(out_shape);
-
-                for (const Coordinate& output_coord : output_transform)
-                {
-                    Coordinate input_coord = reduce(output_coord, adjusted_axes, false);
-                    out[output_transform.index(output_coord)] =
-                        arg[input_transform.index(input_coord)];
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/ceiling.hpp b/ngraph/core/include/ngraph/runtime/reference/ceiling.hpp
deleted file mode 100644 (file)
index d8dec45..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void ceiling(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::ceil(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/clamp.hpp b/ngraph/core/include/ngraph/runtime/reference/clamp.hpp
deleted file mode 100644 (file)
index fc10734..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void clamp(const T* arg, T* out, T min, T max, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    if (arg[i] < min)
-                    {
-                        out[i] = min;
-                    }
-                    else if (arg[i] > max)
-                    {
-                        out[i] = max;
-                    }
-                    else
-                    {
-                        out[i] = arg[i];
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/concat.hpp b/ngraph/core/include/ngraph/runtime/reference/concat.hpp
deleted file mode 100644 (file)
index 4f95289..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/check.hpp"
-#include "ngraph/coordinate_transform.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void concat(const std::vector<const T*>& args,
-                        T* out,
-                        const std::vector<Shape>& in_shapes,
-                        const Shape& out_shape,
-                        int64_t concatenation_axis)
-            {
-                // We will copy the inputs to the output one at a time. As we go, we will move out
-                // along the concatenation axis, starting at 0.
-                size_t concatenation_pos = 0;
-                for (size_t i = 0; i < args.size(); i++)
-                {
-                    // CoordinateTransform gets confused when the last input has a zero-size dim, so
-                    // we will just skip for zero-element tensors.
-                    if (shape_size(in_shapes[i]) == 0)
-                    {
-                        continue;
-                    }
-
-                    // The start coordinate for the copy is (0,...,0) except at the concatenation
-                    // axis.
-                    Coordinate out_start_coord(out_shape.size(), 0);
-                    out_start_coord[concatenation_axis] = concatenation_pos;
-
-                    // The end coordinate for the copy is the same as the output shape except at the
-                    // concatenation axis.
-                    Coordinate out_end_coord = out_shape;
-                    out_end_coord[concatenation_axis] =
-                        concatenation_pos + in_shapes[i][concatenation_axis];
-
-                    CoordinateTransform input_transform(in_shapes[i]);
-                    CoordinateTransform output_chunk_transform(
-                        out_shape, out_start_coord, out_end_coord);
-
-                    NGRAPH_CHECK(shape_size(input_transform.get_target_shape()) ==
-                                 shape_size(output_chunk_transform.get_target_shape()));
-
-                    CoordinateTransform::Iterator output_chunk_it = output_chunk_transform.begin();
-
-                    for (const Coordinate& input_coord : input_transform)
-                    {
-                        size_t input_index = input_transform.index(input_coord);
-                        size_t output_chunk_index = output_chunk_transform.index(*output_chunk_it);
-                        ++output_chunk_it;
-
-                        out[output_chunk_index] = args[i][input_index];
-                    }
-
-                    concatenation_pos += in_shapes[i][concatenation_axis];
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/constant.hpp b/ngraph/core/include/ngraph/runtime/reference/constant.hpp
deleted file mode 100644 (file)
index fed77ac..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void constant(const T* arg0, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg0[i];
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/convert.hpp b/ngraph/core/include/ngraph/runtime/reference/convert.hpp
deleted file mode 100644 (file)
index 805562c..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename TI, typename TO>
-            void convert(const TI* arg, TO* out, size_t count)
-            {
-                for (size_t i = 0; i < count; ++i)
-                {
-                    out[i] = static_cast<TO>(arg[i]);
-                }
-            }
-
-            template <typename T>
-            void convert_to_bool(const T* arg, char* out, size_t count)
-            {
-                for (size_t i = 0; i < count; ++i)
-                {
-                    out[i] = static_cast<char>(static_cast<bool>(arg[i]));
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/convolution.hpp b/ngraph/core/include/ngraph/runtime/reference/convolution.hpp
deleted file mode 100644 (file)
index 2c002ec..0000000
+++ /dev/null
@@ -1,402 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cfenv>
-#include <cmath>
-#include <functional>
-
-#include "ngraph/axis_vector.hpp"
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/runtime/reference/reverse.hpp"
-#include "ngraph/util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            struct widen
-            {
-                using type = T;
-            };
-
-            template <>
-            struct widen<float>
-            {
-                using type = double;
-            };
-
-            template <>
-            struct widen<double>
-            {
-                using type = long double;
-            };
-
-            // in: NC_I...
-            // filter: C_OC_I...
-            // out: NC_O...
-            template <typename INPUT,
-                      typename FILTER,
-                      typename OUTPUT,
-                      typename ACCUMULATION = typename widen<OUTPUT>::type>
-            void general_convolution(const INPUT* in,
-                                     const FILTER* filter,
-                                     OUTPUT* out,
-                                     const Shape& in_shape,
-                                     const Shape& filter_shape,
-                                     const Shape& out_shape,
-                                     const Strides& stride,
-                                     const Strides& filter_dilation,
-                                     const CoordinateDiff& in_pad_below,
-                                     const CoordinateDiff& in_pad_above,
-                                     const Strides& in_dilation,
-                                     size_t in_batch_axis,
-                                     size_t in_channel_axis,
-                                     size_t filter_out_channel_axis,
-                                     size_t filter_in_channel_axis,
-                                     size_t out_batch_axis,
-                                     size_t out_channel_axis,
-                                     const float* input_scale = nullptr,
-                                     const INPUT* input_zero_point = nullptr,
-                                     const float* filter_scale = nullptr,
-                                     const FILTER* filter_zero_point = nullptr,
-                                     const float* output_scale = nullptr,
-                                     const OUTPUT* output_zero_point = nullptr)
-            {
-                bool is_quantized = false;
-                if (input_scale && input_zero_point && filter_scale && filter_zero_point &&
-                    output_scale && output_zero_point)
-                {
-                    is_quantized = true;
-                }
-
-                auto old_mode = std::fegetround();
-                std::fesetround(FE_TONEAREST);
-                // Comments throughout assume without loss of generality that:
-                //
-                // * batch axes for both in and out are 0
-                // * in channel axes for both in and filter are 1
-                // * out channel axes for filter is 0
-                // * out channel axis for out is 1
-
-                // At the outermost level we will walk over every out coordinate O.
-                CoordinateTransform out_transform(out_shape);
-
-                for (const Coordinate& out_coord : out_transform)
-                {
-                    // Our out coordinate O will have the form:
-                    //
-                    //   (N,chan_out,i_1,...,i_n)
-
-                    size_t batch_index = out_coord[out_batch_axis];
-                    size_t out_channel = out_coord[out_channel_axis];
-
-                    // For the in we need to iterate the coordinate:
-                    //
-                    //   I:
-                    //
-                    // over the range (noninclusive on the right):
-                    //
-                    //   (N,0,s_1*i_1,s_2*i_2,...,s_n*i_n) ->
-                    //
-                    //     (N+1,
-                    //      chans_in_count,
-                    //      s_1*i_1+ l_1*filter_dims_1,
-                    ///       ...,
-                    ///     s_n*i_n +l_n*filter_dims_n)
-                    //
-                    // with strides:
-                    //
-                    //   (1,l_1,...,l_n).
-                    //
-                    // Note that we are iterating within the *padded* and *dilated* in batch, so
-                    // further down we must check the current coordinate is in the pad or dilation
-                    // gap.
-
-                    size_t n_spatial_dimensions = in_shape.size() - 2;
-                    size_t n_in_channels = in_shape[in_channel_axis];
-
-                    Coordinate in_transform_start(2 + n_spatial_dimensions);
-                    Coordinate in_transform_end(2 + n_spatial_dimensions);
-                    Strides in_transform_movement_strides(2 + n_spatial_dimensions, 1);
-                    CoordinateDiff in_transform_pad_below(2 + n_spatial_dimensions, 0);
-                    CoordinateDiff in_transform_pad_above(2 + n_spatial_dimensions, 0);
-                    Strides in_transform_dilation_strides(2 + n_spatial_dimensions, 1);
-
-                    in_transform_start[in_batch_axis] = batch_index;
-                    in_transform_end[in_batch_axis] = batch_index + 1;
-                    in_transform_start[in_channel_axis] = 0;
-                    in_transform_end[in_channel_axis] = 1;
-
-                    for (size_t i = 2; i < n_spatial_dimensions + 2; i++)
-                    {
-                        size_t filter_dilation_stride = filter_dilation[i - 2];
-                        size_t filter_movement_stride = stride[i - 2];
-                        std::ptrdiff_t below_pad = in_pad_below[i - 2];
-                        std::ptrdiff_t above_pad = in_pad_above[i - 2];
-                        size_t in_dilation_stride = in_dilation[i - 2];
-
-                        in_transform_start[i] = filter_movement_stride * out_coord[i];
-                        in_transform_end[i] = in_transform_start[i] +
-                                              (filter_shape[i] - 1) * filter_dilation_stride + 1;
-                        in_transform_movement_strides[i] = filter_dilation_stride;
-                        in_transform_pad_below[i] = below_pad;
-                        in_transform_pad_above[i] = above_pad;
-                        in_transform_dilation_strides[i] = in_dilation_stride;
-                    }
-
-                    AxisVector in_transform_axis_order(2 + n_spatial_dimensions);
-                    for (size_t i = 0; i < in_transform_axis_order.size(); i++)
-                    {
-                        in_transform_axis_order[i] = i;
-                    }
-                    CoordinateTransform in_transform(in_shape,
-                                                     in_transform_start,
-                                                     in_transform_end,
-                                                     in_transform_movement_strides,
-                                                     in_transform_axis_order,
-                                                     in_transform_pad_below,
-                                                     in_transform_pad_above,
-                                                     in_transform_dilation_strides);
-
-                    // Simultaneously with iterating I, for the filter we need to iterate the
-                    // coordinate:
-                    //
-                    //   F
-                    //
-                    // over the range (noninclusive on the right):
-                    //
-                    //   (chan_out,0,0,...,0) ->
-                    //     (chan_out+1,
-                    //      chans_in_count,
-                    //      filter_dims_1,
-                    //        ...,
-                    //      filter_dims_n)
-                    //
-                    // with unit stride.
-
-                    Shape filter_transform_start(2 + n_spatial_dimensions);
-                    Shape filter_transform_end(2 + n_spatial_dimensions);
-
-                    filter_transform_start[filter_out_channel_axis] = out_channel;
-                    filter_transform_end[filter_out_channel_axis] = out_channel + 1;
-                    filter_transform_start[filter_in_channel_axis] = 0;
-                    filter_transform_end[filter_in_channel_axis] = 1;
-
-                    for (size_t i = 2; i < n_spatial_dimensions + 2; i++)
-                    {
-                        filter_transform_start[i] = 0;
-                        filter_transform_end[i] = filter_shape[i];
-                    }
-
-                    CoordinateTransform filter_transform(
-                        filter_shape, filter_transform_start, filter_transform_end);
-
-                    // As we go, we sum up:
-                    //
-                    //   out[O] += in[I] * filter[F].
-
-                    ACCUMULATION result = 0;
-
-                    CoordinateTransform::Iterator in_it = in_transform.begin();
-                    CoordinateTransform::Iterator filter_it = filter_transform.begin();
-                    CoordinateTransform::Iterator in_it_end = in_transform.end();
-                    CoordinateTransform::Iterator filter_it_end = filter_transform.end();
-
-                    size_t in_channel_stride = row_major_strides(in_shape).at(in_channel_axis);
-                    size_t filter_in_channel_stride =
-                        row_major_strides(filter_shape).at(filter_in_channel_axis);
-
-                    while (in_it != in_it_end && filter_it != filter_it_end)
-                    {
-                        const Coordinate& in_coord = *in_it;
-                        if (in_transform.has_source_coordinate(in_coord))
-                        {
-                            size_t in_idx = in_transform.index(in_coord);
-                            const Coordinate& filter_coord = *filter_it;
-                            size_t filter_idx = filter_transform.index(filter_coord);
-                            for (size_t in_channel = 0; in_channel < n_in_channels; ++in_channel)
-                            {
-                                ACCUMULATION in_v = static_cast<ACCUMULATION>(in[in_idx]);
-                                ACCUMULATION f_v = static_cast<ACCUMULATION>(filter[filter_idx]);
-                                if (is_quantized)
-                                {
-                                    in_v = in_v - static_cast<ACCUMULATION>(*input_zero_point);
-                                    f_v = f_v - static_cast<ACCUMULATION>(*filter_zero_point);
-                                }
-                                result += in_v * f_v;
-                                in_idx += in_channel_stride;
-                                filter_idx += filter_in_channel_stride;
-                            }
-                        }
-                        ++in_it;
-                        ++filter_it;
-                    }
-                    if (is_quantized)
-                    {
-                        float scale = *input_scale * *filter_scale / *output_scale;
-                        out[out_transform.index(out_coord)] =
-                            static_cast<OUTPUT>(std::round(static_cast<float>(result) * scale)) +
-                            *output_zero_point;
-                    }
-                    else
-                    {
-                        out[out_transform.index(out_coord)] = result;
-                    }
-                }
-                std::fesetround(old_mode);
-            }
-
-            template <typename INPUT,
-                      typename FILTER,
-                      typename OUTPUT,
-                      typename ACCUMULATION = typename widen<OUTPUT>::type>
-            void convolution(const INPUT* in,
-                             const FILTER* filter,
-                             OUTPUT* out,
-                             const Shape& in_shape,
-                             const Shape& filter_shape,
-                             const Shape& out_shape,
-                             const Strides& stride,
-                             const Strides& filter_dilation,
-                             const CoordinateDiff& in_pad_below,
-                             const CoordinateDiff& in_pad_above,
-                             const Strides& in_dilation,
-                             const float* input_scale = nullptr,
-                             const INPUT* input_zero_point = nullptr,
-                             const float* filter_scale = nullptr,
-                             const FILTER* filter_zero_point = nullptr,
-                             const float* output_scale = nullptr,
-                             const OUTPUT* output_zero_point = nullptr)
-
-            {
-                general_convolution<INPUT, FILTER, OUTPUT, ACCUMULATION>(in,
-                                                                         filter,
-                                                                         out,
-                                                                         in_shape,
-                                                                         filter_shape,
-                                                                         out_shape,
-                                                                         stride,
-                                                                         filter_dilation,
-                                                                         in_pad_below,
-                                                                         in_pad_above,
-                                                                         in_dilation,
-                                                                         0,
-                                                                         1,
-                                                                         0,
-                                                                         1,
-                                                                         0,
-                                                                         1,
-                                                                         input_scale,
-                                                                         input_zero_point,
-                                                                         filter_scale,
-                                                                         filter_zero_point,
-                                                                         output_scale,
-                                                                         output_zero_point);
-            }
-
-            template <typename INPUT,
-                      typename OUTPUT,
-                      typename FILTER,
-                      typename ACCUMULATION = typename widen<FILTER>::type>
-            void convolution_backprop_filter(const INPUT* in,
-                                             const OUTPUT* delta_out,
-                                             FILTER* delta_filter,
-                                             const Shape& in_shape,
-                                             const Shape& out_shape,
-                                             const Shape& filter_shape,
-                                             const Strides& filter_dilation,
-                                             const Strides& stride,
-                                             const CoordinateDiff& in_pad_below,
-                                             const CoordinateDiff& backprop_in_pad_above,
-                                             const Strides& in_dilation)
-            {
-                general_convolution<INPUT, OUTPUT, FILTER, ACCUMULATION>(in,
-                                                                         delta_out,
-                                                                         delta_filter,
-                                                                         in_shape,
-                                                                         out_shape,
-                                                                         filter_shape,
-                                                                         filter_dilation,
-                                                                         stride,
-                                                                         in_pad_below,
-                                                                         backprop_in_pad_above,
-                                                                         in_dilation,
-                                                                         1,
-                                                                         0,
-                                                                         1,
-                                                                         0,
-                                                                         1,
-                                                                         0);
-            }
-
-            template <typename OUTPUT,
-                      typename FILTER,
-                      typename INPUT,
-                      typename ACCUMULATION = typename widen<INPUT>::type>
-            void convolution_backprop_in(const OUTPUT* delta_out,
-                                         const FILTER* filter,
-                                         INPUT* delta_in,
-                                         const Shape& out_shape,
-                                         const Shape& filter_shape,
-                                         const Shape& in_shape,
-                                         const Strides& in_dilation,
-                                         const Strides& filter_dilation,
-                                         const CoordinateDiff& backward_delta_out_pad_below,
-                                         const CoordinateDiff& backward_delta_out_pad_above,
-                                         const Strides& stride)
-            {
-                // Note that we only reverse the spatial dimensions here (loop
-                // starts at 2)
-                std::vector<INPUT> reversed(shape_size(filter_shape));
-                AxisSet reverse_axes;
-                for (size_t i = 2; i < filter_shape.size(); ++i)
-                {
-                    reverse_axes.insert(i);
-                }
-                reverse(reinterpret_cast<const char*>(filter),
-                        reinterpret_cast<char*>(&reversed[0]),
-                        filter_shape,
-                        filter_shape,
-                        reverse_axes,
-                        sizeof(FILTER));
-
-                general_convolution<OUTPUT, FILTER, INPUT, ACCUMULATION>(
-                    delta_out,
-                    &reversed[0],
-                    delta_in,
-                    out_shape,
-                    filter_shape,
-                    in_shape,
-                    in_dilation,
-                    filter_dilation,
-                    backward_delta_out_pad_below,
-                    backward_delta_out_pad_above,
-                    stride,
-                    0,
-                    1,
-                    1,
-                    0,
-                    0,
-                    1);
-            }
-        } // namespace reference
-    }     // namespace runtime
-} // namespace ngraph
diff --git a/ngraph/core/include/ngraph/runtime/reference/copy.hpp b/ngraph/core/include/ngraph/runtime/reference/copy.hpp
deleted file mode 100644 (file)
index 60a98a5..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void copy(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg[i];
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/cos.hpp b/ngraph/core/include/ngraph/runtime/reference/cos.hpp
deleted file mode 100644 (file)
index 22e53e2..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void cos(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::cos(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/cosh.hpp b/ngraph/core/include/ngraph/runtime/reference/cosh.hpp
deleted file mode 100644 (file)
index 3d85385..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void cosh(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::cosh(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/cum_sum.hpp b/ngraph/core/include/ngraph/runtime/reference/cum_sum.hpp
deleted file mode 100644 (file)
index 6656bfe..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <map>
-#include <utility>
-#include <vector>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/type/bfloat16.hpp"
-#include "ngraph/type/float16.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T, typename P>
-            void cumsum(const T* arg,
-                        const P* axis_tensor,
-                        T* out,
-                        const Shape& tensor_shape,
-                        const bool exclusive,
-                        const bool reverse)
-            {
-                CoordinateTransform temp_transform(tensor_shape);
-                for (const Coordinate& output_coord : temp_transform)
-                {
-                    out[temp_transform.index(output_coord)] = 0;
-                }
-
-                P axis = axis_tensor[0];
-                P rank = tensor_shape.size();
-
-                if (axis < -rank || axis > rank)
-                {
-                    throw ngraph_error("axis must be in the range [-rank, rank]");
-                }
-                axis = axis < 0 ? rank + axis : axis;
-
-                auto get_key = [&, axis](const Coordinate& coord) -> Coordinate {
-                    Coordinate result(coord.size(), 0);
-                    result[axis] = coord[axis];
-
-                    for (size_t i = 0; i < coord.size(); i++)
-                    {
-                        result[i] = coord[i] - result[i];
-                    }
-                    return result;
-                };
-
-                auto update_output_buffer =
-                    [&](size_t input_index,
-                        size_t output_index,
-                        T& prev,
-                        std::vector<std::pair<size_t, T>>& tensor_vec) -> void {
-
-                    tensor_vec[input_index].second = prev + tensor_vec[input_index].second;
-                    out[tensor_vec[output_index].first] = tensor_vec[input_index].second;
-
-                    // update prev to hold the last result value to compute ruuning sum for
-                    // subsequent iter
-                    prev = out[tensor_vec[output_index].first];
-                };
-
-                auto cum_sum =
-                    [&, exclusive, reverse](std::vector<std::pair<size_t, T>>& tensor_vec) {
-                        if (!reverse)
-                        {
-                            T prev = 0;
-                            for (size_t i = 0; i < tensor_vec.size(); i++)
-                            {
-                                if (exclusive && i == 0)
-                                {
-                                    out[tensor_vec[i].first] = prev;
-                                    continue;
-                                }
-                                // we will compute running sum of j-1 elements if exlusive=1 or else
-                                // for j elements if exclusive = 0
-                                size_t arg_index = exclusive == 1 ? i - 1 : i;
-                                update_output_buffer(arg_index, i, prev, tensor_vec);
-                            }
-                        }
-                        else // reverse == true
-                        {
-                            T prev = 0;
-                            for (size_t i = tensor_vec.size(); i-- > 0;)
-                            {
-                                if (exclusive && i == tensor_vec.size() - 1)
-                                {
-                                    out[tensor_vec[i].first] = prev;
-                                    continue;
-                                }
-                                // we will compute running sum of j-1 elements if exlusive=1 or else
-                                // for j elements if exclusive = 0
-                                size_t arg_index = exclusive == 1 ? i + 1 : i;
-                                update_output_buffer(arg_index, i, prev, tensor_vec);
-                            }
-                        }
-                    };
-
-                // Map to collect tensor elements belonging to the same axis
-                std::map<Coordinate, std::vector<std::pair<size_t, T>>> map_cooord_to_val;
-                CoordinateTransform input_transform(tensor_shape);
-                for (const Coordinate& input_coord : input_transform)
-                {
-                    // points to the current element in the input tensor
-                    T current = arg[input_transform.index(input_coord)];
-                    auto key = get_key(input_coord);
-                    auto index = input_transform.index(input_coord);
-                    if (map_cooord_to_val.find(key) != map_cooord_to_val.end())
-                    {
-                        map_cooord_to_val[key].push_back(std::make_pair(index, current));
-                    }
-                    else
-                    {
-                        map_cooord_to_val.insert({key, std::vector<std::pair<size_t, T>>()});
-                        map_cooord_to_val[key].push_back(std::make_pair(index, current));
-                    }
-                }
-                // iterate the map and perform cumulative sum over the give axis
-                for (auto& it : map_cooord_to_val)
-                {
-                    cum_sum(it.second);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/dequantize.hpp b/ngraph/core/include/ngraph/runtime/reference/dequantize.hpp
deleted file mode 100644 (file)
index d76b7dd..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/axis_set.hpp"
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename QUANT, typename REAL>
-            void dequantize(const QUANT* input,
-                            const REAL* scale,
-                            const QUANT* zero_point,
-                            REAL* output,
-                            const Shape& input_shape,
-                            const Shape& scale_zero_point_shape,
-                            const AxisSet& axes)
-            {
-                CoordinateTransform input_transform(input_shape);
-                CoordinateTransform scale_zero_point_transform(scale_zero_point_shape);
-
-                for (const Coordinate& input_coord : input_transform)
-                {
-                    Coordinate scale_zero_point_coord = project(input_coord, axes);
-
-                    output[input_transform.index(input_coord)] =
-                        static_cast<REAL>((
-                            input[input_transform.index(input_coord)] -
-                            zero_point[scale_zero_point_transform.index(scale_zero_point_coord)])) *
-                        scale[scale_zero_point_transform.index(scale_zero_point_coord)];
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/divide.hpp b/ngraph/core/include/ngraph/runtime/reference/divide.hpp
deleted file mode 100644 (file)
index c7b5582..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-#include <stdexcept>
-#include <type_traits>
-
-#include "ngraph/op/util/attr_types.hpp"
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-#include "ngraph/shape.hpp"
-#include "ngraph/type/bfloat16.hpp"
-#include "ngraph/type/float16.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            // NOTE: Execution throws `std::domain_error` if either a non-integral value or an
-            // out-of-bounds value is detected in the input tensor.
-
-            // In English: return type is void and T must be an integral type.
-            template <typename T>
-            typename std::enable_if<std::is_integral<T>::value>::type
-                divide(const T* arg0, const T* arg1, T* out, size_t count, bool pythondiv)
-            {
-                if (pythondiv)
-                {
-                    for (size_t i = 0; i < count; i++)
-                    {
-                        if (arg1[i] == 0)
-                        {
-                            throw std::domain_error("integer division by zero");
-                        }
-                        T quot = arg0[i] / arg1[i];
-                        T rem = arg0[i] % arg1[i];
-                        if ((rem != 0) && ((arg0[i] < 0) != (arg1[i] < 0)))
-                        {
-                            out[i] = quot - 1;
-                        }
-                        else
-                        {
-                            out[i] = quot;
-                        }
-                    }
-                }
-                else
-                {
-                    for (size_t i = 0; i < count; i++)
-                    {
-                        if (arg1[i] == 0)
-                        {
-                            throw std::domain_error("integer division by zero");
-                        }
-                        out[i] = arg0[i] / arg1[i];
-                    }
-                }
-            }
-
-            template <typename T>
-            typename std::enable_if<std::is_integral<T>::value>::type
-                divide(const T* arg0,
-                       const T* arg1,
-                       T* out,
-                       const Shape& arg0_shape,
-                       const Shape& arg1_shape,
-                       const op::AutoBroadcastSpec& broadcast_spec,
-                       bool pythondiv)
-            {
-                auto functor = [pythondiv](T x, T y) -> T {
-                    if (pythondiv)
-                    {
-                        if (y == 0)
-                        {
-                            throw std::domain_error("integer division by zero");
-                        }
-                        T quot = x / y;
-                        T rem = x % y;
-                        if ((rem != 0) && ((x < 0) != (y < 0)))
-                        {
-                            return quot - 1;
-                        }
-                        else
-                        {
-                            return quot;
-                        }
-                    }
-                    else
-                    {
-                        if (y == 0)
-                        {
-                            throw std::domain_error("integer division by zero");
-                        }
-                        return x / y;
-                    }
-                };
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, functor);
-            }
-
-            // In English: return type is void and T must be a standard floating point type, or
-            // bfloat16, or float16.
-            template <typename T>
-            typename std::enable_if<std::is_floating_point<T>::value ||
-                                    std::is_same<T, bfloat16>::value ||
-                                    std::is_same<T, float16>::value>::type
-                divide(const T* arg0, const T* arg1, T* out, size_t count, bool pythondiv)
-            {
-                (void)pythondiv;
-                for (size_t i = 0; i < count; i++)
-                {
-                    // TODO: Here we do not check for div by zero, so we'll get +-inf here
-                    // if arg1[i] == 0. Is that the right thing to do? Jury's still out.
-                    out[i] = arg0[i] / arg1[i];
-                }
-            }
-
-            template <typename T>
-            typename std::enable_if<std::is_floating_point<T>::value ||
-                                    std::is_same<T, bfloat16>::value ||
-                                    std::is_same<T, float16>::value>::type
-                divide(const T* arg0,
-                       const T* arg1,
-                       T* out,
-                       const Shape& arg0_shape,
-                       const Shape& arg1_shape,
-                       const op::AutoBroadcastSpec& broadcast_spec,
-                       bool pythondiv)
-            {
-                (void)pythondiv;
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
-                        return x / y;
-                    });
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/dot.hpp b/ngraph/core/include/ngraph/runtime/reference/dot.hpp
deleted file mode 100644 (file)
index be8201b..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <utility>
-
-#include <cfenv>
-#include <functional>
-#include "convolution.hpp"
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename INPUT0,
-                      typename INPUT1,
-                      typename OUTPUT,
-                      typename ACCUMULATION = typename widen<OUTPUT>::type>
-            void dot(const INPUT0* arg0,
-                     const INPUT1* arg1,
-                     OUTPUT* out,
-                     const Shape& arg0_shape,
-                     const Shape& arg1_shape,
-                     const Shape& out_shape,
-                     size_t reduction_axes_count,
-                     const float* input0_scale = nullptr,
-                     const INPUT0* input0_zero_point = nullptr,
-                     const float* input1_scale = nullptr,
-                     const INPUT1* input1_zero_point = nullptr,
-                     const float* output_scale = nullptr,
-                     const OUTPUT* output_zero_point = nullptr)
-            {
-                bool is_quantized = false;
-                if (input0_scale && input0_zero_point && input1_scale && input1_zero_point &&
-                    output_scale && output_zero_point)
-                {
-                    is_quantized = true;
-                }
-
-                auto old_mode = std::fegetround();
-                std::fesetround(FE_TONEAREST);
-                // Get the sizes of the dot axes. It's easiest to pull them from arg1 because
-                // they're right up front.
-                Shape dot_axis_sizes(reduction_axes_count);
-                std::copy(arg1_shape.begin(),
-                          arg1_shape.begin() + reduction_axes_count,
-                          dot_axis_sizes.begin());
-
-                CoordinateTransform arg0_transform(arg0_shape);
-                CoordinateTransform arg1_transform(arg1_shape);
-                CoordinateTransform output_transform(out_shape);
-
-                // Create coordinate transforms for arg0 and arg1 that throw away the dotted axes.
-                size_t arg0_projected_rank = arg0_shape.size() - reduction_axes_count;
-                size_t arg1_projected_rank = arg1_shape.size() - reduction_axes_count;
-
-                Shape arg0_projected_shape(arg0_projected_rank);
-                std::copy(arg0_shape.begin(),
-                          arg0_shape.begin() + arg0_projected_rank,
-                          arg0_projected_shape.begin());
-
-                Shape arg1_projected_shape(arg1_projected_rank);
-                std::copy(arg1_shape.begin() + reduction_axes_count,
-                          arg1_shape.end(),
-                          arg1_projected_shape.begin());
-
-                CoordinateTransform arg0_projected_transform(arg0_projected_shape);
-                CoordinateTransform arg1_projected_transform(arg1_projected_shape);
-
-                // Create a coordinate transform that allows us to iterate over all possible values
-                // for the dotted axes.
-                CoordinateTransform dot_axes_transform(dot_axis_sizes);
-
-                for (const Coordinate& arg0_projected_coord : arg0_projected_transform)
-                {
-                    for (const Coordinate& arg1_projected_coord : arg1_projected_transform)
-                    {
-                        // The output coordinate is just the concatenation of the projected
-                        // coordinates.
-                        Coordinate out_coord(arg0_projected_coord.size() +
-                                             arg1_projected_coord.size());
-
-                        auto out_coord_it = std::copy(arg0_projected_coord.begin(),
-                                                      arg0_projected_coord.end(),
-                                                      out_coord.begin());
-                        std::copy(
-                            arg1_projected_coord.begin(), arg1_projected_coord.end(), out_coord_it);
-
-                        // Zero out to start the sum.
-                        ACCUMULATION sum = 0;
-
-                        size_t out_index = output_transform.index(out_coord);
-
-                        // Walk along the dotted axes.
-                        Coordinate arg0_coord(arg0_shape.size());
-                        Coordinate arg1_coord(arg1_shape.size());
-                        auto arg0_it = std::copy(arg0_projected_coord.begin(),
-                                                 arg0_projected_coord.end(),
-                                                 arg0_coord.begin());
-                        for (const Coordinate& dot_axis_positions : dot_axes_transform)
-                        {
-                            // In order to find the points to multiply together, we need to inject
-                            // our current positions along the dotted axes back into the projected
-                            // arg0 and arg1 coordinates.
-                            std::copy(
-                                dot_axis_positions.begin(), dot_axis_positions.end(), arg0_it);
-
-                            auto arg1_it = std::copy(dot_axis_positions.begin(),
-                                                     dot_axis_positions.end(),
-                                                     arg1_coord.begin());
-                            std::copy(
-                                arg1_projected_coord.begin(), arg1_projected_coord.end(), arg1_it);
-
-                            // Multiply and add to the sum.
-                            if (is_quantized)
-                            {
-                                sum = sum + ((static_cast<ACCUMULATION>(
-                                                  arg0[arg0_transform.index(arg0_coord)]) -
-                                              static_cast<ACCUMULATION>(*input0_zero_point)) *
-                                             (static_cast<ACCUMULATION>(
-                                                  arg1[arg1_transform.index(arg1_coord)]) -
-                                              static_cast<ACCUMULATION>(*input1_zero_point)));
-                            }
-                            else
-                            {
-                                sum = sum + (static_cast<ACCUMULATION>(
-                                                 arg0[arg0_transform.index(arg0_coord)]) *
-                                             static_cast<ACCUMULATION>(
-                                                 arg1[arg1_transform.index(arg1_coord)]));
-                            }
-                        }
-
-                        if (is_quantized)
-                        {
-                            float scale = *input0_scale * *input1_scale / *output_scale;
-                            // Write the sum back.
-                            out[out_index] =
-                                static_cast<OUTPUT>(std::round(static_cast<float>(sum) * scale)) +
-                                *output_zero_point;
-                        }
-                        else
-                        {
-                            out[out_index] = sum;
-                        }
-                    }
-                    std::fesetround(old_mode);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/elu.hpp b/ngraph/core/include/ngraph/runtime/reference/elu.hpp
deleted file mode 100644 (file)
index 3440ece..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void elu(const T* arg, T* out, size_t count, double alpha)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg[i] < 0 ? alpha * (std::exp(arg[i]) - 1.0) : arg[i];
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/embedding_bag_offsets_sum.hpp b/ngraph/core/include/ngraph/runtime/reference/embedding_bag_offsets_sum.hpp
deleted file mode 100644 (file)
index 98ad115..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (C) 2020 Intel Corporation
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#pragma once
-
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T, typename U>
-            void embeddingBagOffsetsSum(const T* emb_table,
-                                        const U* indices,
-                                        const U* offsets,
-                                        const U* default_index,
-                                        const T* weights,
-                                        T* out,
-                                        const size_t indices_count,
-                                        const Shape& outShape)
-            {
-                const size_t offsets_size = outShape[0];
-                std::vector<U> default_indices;
-                if (default_index)
-                    default_indices.push_back(default_index[0]);
-
-                size_t embDepth = 1;
-                for (size_t i = 1; i < outShape.size(); i++)
-                {
-                    embDepth *= outShape[i];
-                }
-                memset(out, 0, shape_size(outShape) * sizeof(T));
-
-                auto get_indices = [&](size_t emb_index,
-                                       const U*& indices_ref,
-                                       size_t& indices_num,
-                                       size_t& weights_idx,
-                                       bool& with_weights) {
-                    if (emb_index >= offsets_size)
-                        throw ngraph_error("Invalid embedding bag index.");
-                    if (offsets[emb_index] >= indices_count)
-                        throw ngraph_error(
-                            std::string(
-                                "Offset value exceeds indices size in the model.\noffset: ") +
-                            std::to_string(offsets[emb_index]) + "; indices size: " +
-                            std::to_string(indices_count));
-
-                    indices_ref = nullptr;
-                    indices_num = 0lu;
-                    with_weights = (weights != nullptr);
-
-                    if (emb_index == offsets_size - 1lu)
-                        indices_num = indices_count - offsets[emb_index];
-                    else
-                        indices_num = offsets[emb_index + 1lu] - offsets[emb_index];
-
-                    if (indices_num != 0lu)
-                    {
-                        indices_ref = indices + offsets[emb_index];
-                    }
-                    else
-                    {
-                        // Empty or default bag
-                        with_weights = false;
-                        if (default_indices.size() == 1lu)
-                        {
-                            indices_ref = default_indices.data();
-                            indices_num = 1lu;
-                        }
-                        return;
-                    }
-
-                    if (with_weights)
-                        weights_idx = offsets[emb_index];
-                };
-
-                size_t indices_size = 0lu;
-                const U* indices_emb = nullptr;
-                size_t weights_idx = 0lu;
-                bool with_weights_b = (weights != nullptr);
-                bool with_weights = with_weights_b;
-
-                for (size_t obi = 0lu; obi < outShape.at(0); obi++)
-                {
-                    size_t dst_index = obi * embDepth;
-                    get_indices(obi, indices_emb, indices_size, weights_idx, with_weights);
-                    if (indices_emb != nullptr)
-                    {
-                        with_weights = with_weights_b & with_weights;
-                        for (size_t in_idx = 0lu; in_idx < indices_size; in_idx++)
-                        {
-                            size_t src_index = indices_emb[in_idx] * embDepth;
-
-                            if (with_weights)
-                            {
-                                for (size_t i = 0lu; i < embDepth; i++)
-                                {
-                                    out[dst_index + i] +=
-                                        emb_table[src_index + i] * weights[weights_idx];
-                                }
-                                weights_idx++;
-                            }
-                            else
-                            {
-                                for (size_t i = 0lu; i < embDepth; i++)
-                                {
-                                    out[dst_index + i] += emb_table[src_index + i];
-                                }
-                            }
-                        }
-                    }
-                }
-
-            } // embeddingBagOffsetsSum
-
-        } // reference
-    }     // runtime
-} // ngraph
diff --git a/ngraph/core/include/ngraph/runtime/reference/embedding_bag_packed_sum.hpp b/ngraph/core/include/ngraph/runtime/reference/embedding_bag_packed_sum.hpp
deleted file mode 100644 (file)
index 35de940..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (C) 2020 Intel Corporation
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#pragma once
-
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T, typename U>
-            void embeddingBagPackedSum(const T* emb_table,
-                                       const U* indices,
-                                       const T* weights,
-                                       T* out,
-                                       const Shape& indicesShape,
-                                       const Shape& outShape)
-            {
-                const size_t indices_per_bag = indicesShape[1];
-
-                size_t embDepth = 1lu;
-                for (size_t i = 1; i < outShape.size(); i++)
-                {
-                    embDepth *= outShape[i];
-                }
-                memset(out, 0, shape_size(outShape) * sizeof(T));
-
-                bool with_weights = (weights != nullptr);
-                size_t idx_idx = 0lu;
-
-                for (size_t obi = 0lu; obi < outShape.at(0); obi++)
-                {
-                    size_t dst_index = obi * embDepth;
-                    for (size_t in_idx = 0lu; in_idx < indices_per_bag; in_idx++, idx_idx++)
-                    {
-                        size_t src_index = indices[idx_idx] * embDepth;
-
-                        if (with_weights)
-                        {
-                            for (size_t i = 0lu; i < embDepth; i++)
-                            {
-                                out[dst_index + i] += emb_table[src_index + i] * weights[idx_idx];
-                            }
-                        }
-                        else
-                        {
-                            for (size_t i = 0lu; i < embDepth; i++)
-                            {
-                                out[dst_index + i] += emb_table[src_index + i];
-                            }
-                        }
-                    }
-                }
-
-            } // embeddingBagPackedSum
-
-        } // reference
-    }     // runtime
-} // ngraph
diff --git a/ngraph/core/include/ngraph/runtime/reference/embedding_segments_sum.hpp b/ngraph/core/include/ngraph/runtime/reference/embedding_segments_sum.hpp
deleted file mode 100644 (file)
index 68f0c4d..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (C) 2020 Intel Corporation
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#pragma once
-
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T, typename U>
-            void embeddingSegmentsSum(const T* embTable,
-                                      const U* indices,
-                                      const U* segmentIds,
-                                      const U* defaultIndex,
-                                      const T* weights,
-                                      T* out,
-                                      const Shape& embTableShape,
-                                      const Shape& indicesShape,
-                                      const Shape& outShape)
-            {
-                const size_t indices_len = indicesShape[0];
-                const size_t segments_num = outShape[0];
-                const size_t inDimsSize = outShape.size();
-                const size_t embDimsNum = outShape.size() - 1;
-
-                size_t embDepth = 1lu;
-                for (size_t i = 1; i < outShape.size(); i++)
-                {
-                    embDepth *= outShape[i];
-                }
-                memset(out, 0, shape_size(outShape) * sizeof(T));
-
-                bool with_weights = (weights != nullptr);
-
-                for (size_t index = 0; index < indices_len; index++)
-                {
-                    size_t obi = segmentIds[index];
-                    if (obi >= segments_num)
-                        throw ngraph_error("Segment index could not be more than segments number");
-                    size_t dst_index = obi * embDepth;
-                    size_t src_index = indices[index] * embDepth;
-
-                    if (with_weights)
-                    {
-                        for (size_t i = 0lu; i < embDepth; i++)
-                        {
-                            out[dst_index + i] += embTable[src_index + i] * weights[index];
-                        }
-                    }
-                    else
-                    {
-                        for (size_t i = 0lu; i < embDepth; i++)
-                        {
-                            out[dst_index + i] += embTable[src_index + i];
-                        }
-                    }
-                }
-
-                if (defaultIndex != nullptr)
-                {
-                    U defIndex = defaultIndex[0];
-                    if (defIndex < U(0) && defIndex >= embTableShape[0])
-                        throw ngraph_error(std::string("Invalid default index") +
-                                           std::to_string(defIndex));
-                    for (size_t obi = 0; obi < segments_num; obi++)
-                    {
-                        bool found = false;
-                        for (size_t index = 0; index < indices_len; index++)
-                        {
-                            if (segmentIds[index] == obi)
-                            {
-                                found = true;
-                                break;
-                            }
-                        }
-                        if (found)
-                            continue;
-                        size_t src_index = defIndex * embDepth;
-                        size_t dst_index = obi * embDepth;
-                        for (size_t i = 0lu; i < embDepth; i++)
-                        {
-                            out[dst_index + i] = embTable[src_index + i];
-                        }
-                    }
-                }
-            } // embeddingSegmentsSum
-
-        } // reference
-    }     // runtime
-} // ngraph
diff --git a/ngraph/core/include/ngraph/runtime/reference/equal.hpp b/ngraph/core/include/ngraph/runtime/reference/equal.hpp
deleted file mode 100644 (file)
index 6ed5765..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wfloat-equal"
-#endif
-
-#include <cstddef>
-
-#include "ngraph/op/util/attr_types.hpp"
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void equal(const T* arg0,
-                       const T* arg1,
-                       char* out,
-                       size_t count) // TODO: using char for bool, is this right?
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg0[i] == arg1[i];
-                }
-            }
-
-            template <typename T, typename U>
-            void equal(const T* arg0,
-                       const T* arg1,
-                       U* out,
-                       const Shape& arg0_shape,
-                       const Shape& arg1_shape,
-                       const op::AutoBroadcastSpec& broadcast_spec)
-            {
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
-                        return x == y;
-                    });
-            }
-        }
-    }
-}
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
diff --git a/ngraph/core/include/ngraph/runtime/reference/erf.hpp b/ngraph/core/include/ngraph/runtime/reference/erf.hpp
deleted file mode 100644 (file)
index 86ef27c..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void erf(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::erf(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/eval_helpers.hpp b/ngraph/core/include/ngraph/runtime/reference/eval_helpers.hpp
deleted file mode 100644 (file)
index 6b90810..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include "ngraph/runtime/host_tensor.hpp"
-
-namespace ngraph
-{
-    namespace eval
-    {
-        AxisSet extract_reduction_axes(const HostTensorPtr& axes, const char* op_name);
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/exp.hpp b/ngraph/core/include/ngraph/runtime/reference/exp.hpp
deleted file mode 100644 (file)
index 2bd0878..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void exp(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::exp(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/extract_image_patches.hpp b/ngraph/core/include/ngraph/runtime/reference/extract_image_patches.hpp
deleted file mode 100644 (file)
index 4e16e1c..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (C) 2020 Intel Corporation
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T, typename U>
-            void extractImagePatches(const op::ExtractImagePatches* extImgPatches,
-                                     const T* input,
-                                     T* out,
-                                     const Shape& inShape,
-                                     const Shape& outShape)
-            {
-                const size_t dimsSize = inShape.size();
-                const size_t BATCH = 0, CHANNEL = 1, HIGHT = 0, WIDTH = 1;
-
-                const int64_t KH = extImgPatches->get_sizes()[HIGHT];
-                const int64_t KW = extImgPatches->get_sizes()[WIDTH];
-                const int64_t SH = extImgPatches->get_strides()[HIGHT];
-                const int64_t SW = extImgPatches->get_strides()[WIDTH];
-                const int64_t RH = extImgPatches->get_rates()[HIGHT];
-                const int64_t RW = extImgPatches->get_rates()[WIDTH];
-                const auto auto_pad = extImgPatches->get_auto_pad();
-
-                const int64_t IB = inShape[BATCH];
-                const int64_t IC = inShape[CHANNEL];
-                const int64_t IH = inShape[dimsSize - 2];
-                const int64_t IW = inShape[dimsSize - 1];
-
-                const int64_t OB = outShape[BATCH];
-                const int64_t OC = outShape[CHANNEL];
-                const int64_t OH = outShape[dimsSize - 2];
-                const int64_t OW = outShape[dimsSize - 1];
-
-                int64_t ihStart = 0;
-                int64_t iwStart = 0;
-
-                int64_t iwStep = KW + (RW - 1) * (KW - 1);
-                int64_t ihStep = KH + (RH - 1) * (KH - 1);
-
-                const int64_t OH_OW = OH * OW;
-                const int64_t OC_OH_OW = OC * OH_OW;
-                const int64_t OB_OC_OH_OW = OC_OH_OW * OB;
-                const int64_t IH_IW = IH * IW;
-                const int64_t IC_IH_IW = IC * IH_IW;
-                const int64_t IB_IC_IH_IW = IC_IH_IW * IB;
-                const int64_t KH_KW = KH * KW;
-
-                int64_t PL = 0, PT = 0;
-
-                if (auto_pad != op::PadType::VALID)
-                {
-                    int64_t PW = (std::ceil(1.f * IW / SW) - 1) * SW + iwStep - IW;
-                    int64_t PH = (std::ceil(1.f * IH / SH) - 1) * SH + ihStep - IH;
-
-                    if ((PW > 0) && (PW < iwStep))
-                    {
-                        if (PW % 2 == 1)
-                        {
-                            if (auto_pad == op::PadType::SAME_LOWER)
-                            {
-                                PL = (PW + 1) / 2;
-                            }
-                            else if (auto_pad == op::PadType::SAME_UPPER)
-                            {
-                                PL = (PW - 1) / 2;
-                            }
-                        }
-                        else
-                        {
-                            PL = PW / 2;
-                        }
-                    }
-                    if ((PH > 0) && (PH < ihStep))
-                    {
-                        if (PH % 2 == 1)
-                        {
-                            if (auto_pad == op::PadType::SAME_LOWER)
-                            {
-                                PT = (PH + 1) / 2;
-                            }
-                            else if (auto_pad == op::PadType::SAME_UPPER)
-                            {
-                                PT = (PH - 1) / 2;
-                            }
-                        }
-                        else
-                        {
-                            PT = PH / 2;
-                        }
-                    }
-                }
-
-                for (int64_t ob = 0; ob < OB; ob++)
-                {
-                    const int64_t ib_ICIHIW = ob * IC_IH_IW;
-                    const int64_t ob_OCOHOW = ob * OC_OH_OW;
-                    for (int64_t oh = 0; oh < OH; oh++)
-                    {
-                        const int64_t ob_OCOHOW_ohOW = ob_OCOHOW + oh * OW;
-                        int64_t ih0 = oh * SH - PT;
-                        for (int64_t ow = 0; ow < OW; ow++)
-                        {
-                            const int64_t ob_OCOHOW_ohOW_ow = ob_OCOHOW_ohOW + ow;
-                            int64_t iw0 = ow * SW - PL;
-                            int64_t oc = 0;
-
-                            for (int64_t kh = 0; kh < KH; kh++)
-                            {
-                                int64_t ihKH = ih0 + kh * RH;
-                                int64_t ib_ICIHIW_ihKH_IW = ib_ICIHIW + ihKH * IW;
-                                for (int64_t kw = 0; kw < KW; kw++)
-                                {
-                                    for (int64_t ic = 0; ic < IC; ic++, oc++)
-                                    {
-                                        int64_t iwKW = iw0 + kw * RW;
-                                        int64_t dst_idx = ob_OCOHOW_ohOW_ow + oc * OH_OW;
-                                        if (dst_idx >= OB_OC_OH_OW)
-                                            throw ngraph_error(
-                                                "ExtractImagePatches. Destination index is out of "
-                                                "bounds.");
-                                        if (ihKH < 0 || ihKH >= IH || iwKW < 0 || iwKW >= IW)
-                                        {
-                                            out[dst_idx] = T(0);
-                                        }
-                                        else
-                                        {
-                                            int64_t src_idx = ib_ICIHIW_ihKH_IW + ic * IH_IW + iwKW;
-                                            if (src_idx >= IB_IC_IH_IW)
-                                                throw ngraph_error(
-                                                    "ExtractImagePatches. Source index is out of "
-                                                    "bounds.");
-                                            out[dst_idx] = input[src_idx];
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            } // extractImagePatches
-
-        } // reference
-    }     // runtime
-} // ngraph
diff --git a/ngraph/core/include/ngraph/runtime/reference/floor.hpp b/ngraph/core/include/ngraph/runtime/reference/floor.hpp
deleted file mode 100644 (file)
index f33d4b4..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void floor(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::floor(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/gather.hpp b/ngraph/core/include/ngraph/runtime/reference/gather.hpp
deleted file mode 100644 (file)
index 4ad4aa9..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <numeric>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/runtime/reference/gather_nd.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            // Implement gather by calling gather_nd on sub-problems
-            // # prepare constant shapes for tensors used for sub problems
-            // indices'.shape  = indices.shape[-1] + [1]
-            // params'.shape = params.shape[axis:]
-            // out'.shape = params'.shape
-            // out'.shape[0] = indices.shape[-1]
-            // # call sub-problems
-            // foreach (params_index, out_index) in outer "axis" dimensions
-            //     # params_prime is shared by inner loop
-            //     params' = param[params_index] # rank(params') == rank(params) - axis
-            //     foreach indices_index in outer N-1 dimensions
-            //         indices' = indices[indices_index] # rank(indices') == 2
-            //         out_index = out_index + indices_index
-            //         out' = out[out_index] # rank(out') == rank(params')
-            //         gather_nd(params', indices'', out')
-            template <typename T, typename U>
-            void gather(const T* params,
-                        const U* indices,
-                        T* out,
-                        const Shape& params_shape,
-                        const Shape& indices_shape,
-                        const Shape& out_shape,
-                        size_t axis)
-            {
-                using namespace std;
-                // prepare shape of params_prime (remove first "axis" dimensions)
-                Shape params_prime_shape(params_shape);
-                params_prime_shape.erase(params_prime_shape.begin(),
-                                         params_prime_shape.begin() + axis);
-                // prepare shape of indices_prime
-                size_t indices_ndim = static_cast<size_t>(indices_shape.size());
-                Shape indices_prime_shape;
-                // prepare shape of out_prime (same as params_prime except for first dim)
-                Shape out_prime_shape(params_prime_shape);
-                if (indices_ndim > 0)
-                {
-                    out_prime_shape[0] = indices_shape[indices_ndim - 1];
-                    indices_prime_shape.emplace_back(indices_shape[indices_ndim - 1]);
-                }
-                else
-                {
-                    out_prime_shape[0] = 1;
-                }
-                indices_prime_shape.emplace_back(1);
-
-                // Create a CoordinateTransform for "out" that visits the outer "axis" dimensions
-                size_t out_ndim = static_cast<size_t>(out_shape.size());
-                Coordinate out_outer_start_corner(out_ndim, 0);
-                Coordinate out_outer_end_corner(out_shape);
-                for (size_t i = axis; i < out_ndim; i++)
-                {
-                    out_outer_end_corner[i] = 1;
-                }
-                Strides out_outer_strides(out_ndim, 1);
-                AxisVector out_outer_axis_order(out_ndim);
-                std::iota(out_outer_axis_order.begin(), out_outer_axis_order.end(), 0);
-                CoordinateTransform out_outer_transform(out_shape,
-                                                        out_outer_start_corner,
-                                                        out_outer_end_corner,
-                                                        out_outer_strides,
-                                                        out_outer_axis_order);
-
-                // Create a CoordinateTransform for "params" that visits the outer "axis" dimensions
-                size_t params_ndim = static_cast<size_t>(params_shape.size());
-                Coordinate params_outer_start_corner(params_ndim, 0);
-                Coordinate params_outer_end_corner(params_shape);
-                for (size_t i = axis; i < params_ndim; i++)
-                {
-                    params_outer_end_corner[i] = 1;
-                }
-                Strides params_outer_strides(params_ndim, 1);
-                AxisVector params_outer_axis_order(params_ndim);
-                std::iota(params_outer_axis_order.begin(), params_outer_axis_order.end(), 0);
-                CoordinateTransform params_outer_transform(params_shape,
-                                                           params_outer_start_corner,
-                                                           params_outer_end_corner,
-                                                           params_outer_strides,
-                                                           params_outer_axis_order);
-
-                // Create a CoordinateTransform for "indices" that visits only the first element
-                // along inner most axis
-                Coordinate indices_outer_start_corner(indices_ndim, 0);
-                Coordinate indices_outer_end_corner(indices_shape);
-                if (indices_ndim > 0)
-                {
-                    indices_outer_end_corner[indices_ndim - 1] = 1;
-                }
-                Strides indices_outer_strides(indices_ndim, 1);
-                AxisVector indices_outer_axis_order(indices_ndim);
-                std::iota(indices_outer_axis_order.begin(), indices_outer_axis_order.end(), 0);
-                CoordinateTransform indices_outer_transform(indices_shape,
-                                                            indices_outer_start_corner,
-                                                            indices_outer_end_corner,
-                                                            indices_outer_strides,
-                                                            indices_outer_axis_order);
-
-                // Create an inner CoordinateTransfrom for "out"
-                size_t out_inner_ndim = out_ndim - axis;
-                Shape out_inner_shape(out_shape);
-                out_inner_shape.erase(out_inner_shape.begin(), out_inner_shape.begin() + axis);
-                Coordinate out_inner_start_corner(out_inner_ndim, 0);
-                Coordinate out_inner_end_corner(out_inner_shape);
-                if (indices_ndim > 0)
-                {
-                    out_inner_end_corner[indices_ndim - 1] = 1;
-                }
-                for (size_t i = indices_ndim; i < out_inner_ndim; i++)
-                {
-                    out_inner_end_corner[i] = 1;
-                }
-                Strides out_inner_strides(out_inner_ndim, 1);
-                AxisVector out_inner_axis_order(out_inner_ndim);
-                std::iota(out_inner_axis_order.begin(), out_inner_axis_order.end(), 0);
-                CoordinateTransform out_inner_transform(out_inner_shape,
-                                                        out_inner_start_corner,
-                                                        out_inner_end_corner,
-                                                        out_inner_strides,
-                                                        out_inner_axis_order);
-
-                auto out_outer_coord_iter = out_outer_transform.begin();
-                for (const Coordinate& params_outer_coord : params_outer_transform)
-                {
-                    const T* params_prime =
-                        &params[params_outer_transform.index(params_outer_coord)];
-                    T* out_outer = &out[out_outer_transform.index(*out_outer_coord_iter)];
-
-                    auto out_inner_coord_iter = out_inner_transform.begin();
-                    for (const Coordinate& indices_outer_coord : indices_outer_transform)
-                    {
-                        const U* indices_prime =
-                            &indices[indices_outer_transform.index(indices_outer_coord)];
-                        T* out_prime = &out_outer[out_inner_transform.index(*out_inner_coord_iter)];
-                        gather_nd<T, U>(params_prime,
-                                        indices_prime,
-                                        out_prime,
-                                        params_prime_shape,
-                                        indices_prime_shape,
-                                        out_prime_shape);
-                        out_inner_coord_iter++;
-                    }
-                    out_outer_coord_iter++;
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/gather_nd.hpp b/ngraph/core/include/ngraph/runtime/reference/gather_nd.hpp
deleted file mode 100644 (file)
index a596098..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <numeric>
-
-#include "ngraph/coordinate_transform.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            // foreach leaf_vector_index in indices.shape[:-1]
-            //     vector = indices[leaf_vector_index]
-            //     out[leaf_vector_index:] = params[vector]
-            template <typename T, typename U>
-            void gather_nd(const T* params,
-                           const U* indices,
-                           T* out,
-                           const Shape& params_shape,
-                           const Shape& indices_shape,
-                           const Shape& out_shape)
-            {
-                using namespace std;
-                // Create a CoordinateTransform for "indices" that visits only the first element
-                // along inner most axis
-                size_t indices_ndim = static_cast<size_t>(indices_shape.size());
-                Coordinate indices_outer_start_corner(indices_ndim, 0);
-                Coordinate indices_outer_end_corner(indices_shape);
-                size_t slice_rank = indices_shape[indices_ndim - 1];
-                indices_outer_end_corner[indices_ndim - 1] = 1;
-                Strides indices_strides(indices_ndim, 1);
-                AxisVector indices_axis_order(indices_ndim);
-                std::iota(indices_axis_order.begin(), indices_axis_order.end(), 0);
-                CoordinateTransform indices_outer_transform(indices_shape,
-                                                            indices_outer_start_corner,
-                                                            indices_outer_end_corner,
-                                                            indices_strides,
-                                                            indices_axis_order);
-
-                // Create a matching CoordinateTransform for "out" that visits the same outer
-                // coordinates
-                size_t out_ndim = static_cast<size_t>(out_shape.size());
-                Coordinate out_start_corner(out_ndim, 0);
-                Coordinate out_end_corner(out_shape);
-                for (size_t i = indices_ndim - 1; i < out_ndim; i++)
-                {
-                    out_end_corner[i] = 1;
-                }
-                Strides out_strides(out_ndim, 1);
-                AxisVector out_axis_order(out_ndim);
-                std::iota(out_axis_order.begin(), out_axis_order.end(), 0);
-                CoordinateTransform out_transform(
-                    out_shape, out_start_corner, out_end_corner, out_strides, out_axis_order);
-                size_t params_ndim = static_cast<size_t>(params_shape.size());
-                Strides params_strides(params_ndim, 1);
-                AxisVector params_axis_order(params_ndim);
-                std::iota(params_axis_order.begin(), params_axis_order.end(), 0);
-
-                // Gather slices from "params" and copy to "out"
-                auto out_coord_iter = out_transform.begin();
-                for (const Coordinate& indices_coord : indices_outer_transform)
-                {
-                    Coordinate params_start_corner(params_ndim, 0);
-                    Coordinate params_end_corner(params_shape);
-                    auto indices_index = indices_outer_transform.index(indices_coord);
-                    for (size_t i = 0; i < slice_rank; i++)
-                    {
-                        U index = indices[indices_index];
-                        // take care of negative indices
-                        index = index >= 0 ? index : index + params_shape[i];
-                        params_start_corner[i] = index;
-                        params_end_corner[i] = index + 1;
-                        indices_index++;
-                    }
-                    CoordinateTransform params_transform(params_shape,
-                                                         params_start_corner,
-                                                         params_end_corner,
-                                                         params_strides,
-                                                         params_axis_order);
-                    auto out_index = out_transform.index(*out_coord_iter);
-                    for (const Coordinate& params_coord : params_transform)
-                    {
-                        out[out_index] = params[params_transform.index(params_coord)];
-                        out_index++;
-                    }
-                    out_coord_iter++;
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/greater.hpp b/ngraph/core/include/ngraph/runtime/reference/greater.hpp
deleted file mode 100644 (file)
index 1586a48..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-#include "ngraph/op/util/attr_types.hpp"
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void greater(const T* arg0,
-                         const T* arg1,
-                         char* out,
-                         size_t count) // TODO: using char for bool, is this right?
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg0[i] > arg1[i];
-                }
-            }
-
-            template <typename T, typename U>
-            void greater(const T* arg0,
-                         const T* arg1,
-                         U* out,
-                         const Shape& arg0_shape,
-                         const Shape& arg1_shape,
-                         const op::AutoBroadcastSpec& broadcast_spec)
-            {
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
-                        return x > y;
-                    });
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/greater_eq.hpp b/ngraph/core/include/ngraph/runtime/reference/greater_eq.hpp
deleted file mode 100644 (file)
index 380177b..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-#include "ngraph/op/util/attr_types.hpp"
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void greater_eq(const T* arg0,
-                            const T* arg1,
-                            char* out,
-                            size_t count) // TODO: using char for bool, is this right?
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg0[i] >= arg1[i];
-                }
-            }
-
-            template <typename T, typename U>
-            void greater_eq(const T* arg0,
-                            const T* arg1,
-                            U* out,
-                            const Shape& arg0_shape,
-                            const Shape& arg1_shape,
-                            const op::AutoBroadcastSpec& broadcast_spec)
-            {
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
-                        return x >= y;
-                    });
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/less.hpp b/ngraph/core/include/ngraph/runtime/reference/less.hpp
deleted file mode 100644 (file)
index 0f41890..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-#include "ngraph/op/util/attr_types.hpp"
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void less(const T* arg0,
-                      const T* arg1,
-                      char* out,
-                      size_t count) // TODO: using char for bool, is this right?
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg0[i] < arg1[i];
-                }
-            }
-
-            template <typename T, typename U>
-            void less(const T* arg0,
-                      const T* arg1,
-                      U* out,
-                      const Shape& arg0_shape,
-                      const Shape& arg1_shape,
-                      const op::AutoBroadcastSpec& broadcast_spec)
-            {
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
-                        return x < y;
-                    });
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/less_eq.hpp b/ngraph/core/include/ngraph/runtime/reference/less_eq.hpp
deleted file mode 100644 (file)
index a4fb0a3..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-#include "ngraph/op/util/attr_types.hpp"
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void less_eq(const T* arg0,
-                         const T* arg1,
-                         char* out,
-                         size_t count) // TODO: using char for bool, is this right?
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg0[i] <= arg1[i];
-                }
-            }
-
-            template <typename T, typename U>
-            void less_eq(const T* arg0,
-                         const T* arg1,
-                         U* out,
-                         const Shape& arg0_shape,
-                         const Shape& arg1_shape,
-                         const op::AutoBroadcastSpec& broadcast_spec)
-            {
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
-                        return x <= y;
-                    });
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/log.hpp b/ngraph/core/include/ngraph/runtime/reference/log.hpp
deleted file mode 100644 (file)
index 10a0db2..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void log(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::log(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/logical_reduction.hpp b/ngraph/core/include/ngraph/runtime/reference/logical_reduction.hpp
deleted file mode 100644 (file)
index 2c06329..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/runtime/reference/any.hpp"
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            static inline void reduce_logical_and(const char* arg,
-                                                  char* out,
-                                                  const Shape& input_shape,
-                                                  const AxisSet& reduction_axes,
-                                                  bool keep_dims)
-            {
-                CoordinateTransform output_transform(
-                    reduce(input_shape, reduction_axes, keep_dims));
-
-                for (const Coordinate& output_coord : output_transform)
-                {
-                    out[output_transform.index(output_coord)] = 1;
-                }
-
-                CoordinateTransform input_transform(input_shape);
-
-                for (const Coordinate& input_coord : input_transform)
-                {
-                    Coordinate output_coord = reduce(input_coord, reduction_axes, keep_dims);
-                    out[output_transform.index(output_coord)] =
-                        out[output_transform.index(output_coord)] &&
-                        arg[input_transform.index(input_coord)];
-                }
-            }
-
-            static inline void reduce_logical_or(const char* arg,
-                                                 char* out,
-                                                 const Shape& input_shape,
-                                                 const AxisSet& reduction_axes,
-                                                 bool keep_dims)
-            {
-                runtime::reference::any(arg, out, input_shape, reduction_axes, keep_dims);
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/lrn.hpp b/ngraph/core/include/ngraph/runtime/reference/lrn.hpp
deleted file mode 100644 (file)
index 2494c6a..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <algorithm>
-#include <cmath>
-#include <numeric>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void sum_region_across_axes(const T* arg,
-                                        size_t current_axis_index,
-                                        const std::vector<size_t>& axes,
-                                        Coordinate& sum_coord,
-                                        T& square_sum,
-                                        const std::vector<size_t>& begin_area,
-                                        const std::vector<size_t>& end_area,
-                                        const CoordinateTransform& input_transform)
-            {
-                // all nested axes were visited
-                if (current_axis_index == axes.size())
-                {
-                    square_sum += arg[input_transform.index(sum_coord)] *
-                                  arg[input_transform.index(sum_coord)];
-                    return;
-                }
-                auto current_axis = axes[current_axis_index];
-                for (auto current_axis_coord = begin_area[current_axis];
-                     current_axis_coord < end_area[current_axis];
-                     ++current_axis_coord)
-                {
-                    sum_coord.at(current_axis) = current_axis_coord;
-                    sum_region_across_axes(arg,
-                                           current_axis_index + 1,
-                                           axes,
-                                           sum_coord,
-                                           square_sum,
-                                           begin_area,
-                                           end_area,
-                                           input_transform);
-                }
-            }
-
-            template <typename T>
-            void lrn(const T* arg,
-                     const AxisSet& axes,
-                     T* out,
-                     const Shape& arg_shape,
-                     double dalpha,
-                     double dbeta,
-                     double dbias,
-                     size_t size)
-            {
-                T alpha = static_cast<T>(dalpha);
-                T beta = static_cast<T>(dbeta);
-                T bias = static_cast<T>(dbias);
-
-                std::vector<size_t> begin_area(arg_shape.size());
-                std::vector<size_t> end_area(arg_shape.size());
-
-                CoordinateTransform input_transform(arg_shape);
-                for (const Coordinate& in_coord : input_transform)
-                {
-                    // area determined by in_coord local neighborhood
-                    for (const auto& axis_coord : axes)
-                    {
-                        begin_area[axis_coord] =
-                            std::max<int>(0, in_coord.at(axis_coord) - (size - 1) / 2);
-                        end_area[axis_coord] = std::min<int>(
-                            arg_shape.at(axis_coord), in_coord.at(axis_coord) + (size - 1) / 2 + 1);
-                    }
-
-                    T square_sum = 0;
-                    auto sum_coord = in_coord;
-                    auto axes_vec = std::vector<size_t>(axes.begin(), axes.end());
-                    sum_region_across_axes(arg,
-                                           0,
-                                           axes_vec,
-                                           sum_coord,
-                                           square_sum,
-                                           begin_area,
-                                           end_area,
-                                           input_transform);
-
-                    T x = arg[input_transform.index(in_coord)];
-                    out[input_transform.index(in_coord)] =
-                        x / (std::pow(bias + (alpha / size) * square_sum, beta));
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/matmul.hpp b/ngraph/core/include/ngraph/runtime/reference/matmul.hpp
deleted file mode 100644 (file)
index 17de94b..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <numeric>
-#include <utility>
-#include <vector>
-
-#include "ngraph/axis_vector.hpp"
-#include "ngraph/builder/autobroadcast.hpp"
-#include "ngraph/runtime/opt_kernel/reshape.hpp"
-#include "ngraph/runtime/reference/broadcast.hpp"
-#include "ngraph/runtime/reference/dot.hpp"
-#include "ngraph/shape_util.hpp"
-
-using namespace std;
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            /// \brief Reference kernel for matmul computation.
-            ///
-            /// \tparam T Type of input and output tensors.
-            ///
-            /// \param arg0 Pointer to the buffer for left operand input tensor.
-            /// \param arg1 Pointer to the buffer for right operand input tensor.
-            /// \param out Pointer to the buffer for output tensor. This must be pre-allocated by
-            ///            the caller, and must be large enough to hold a tensor of the correct
-            ///            shape.
-            /// \param arg0_shape Shape of arg0.
-            /// \param arg1_shape Shape of arg1.
-            /// \param out_shape Shape of out.
-            /// \param transpose_arg0 Flag to indicate if transpose on arg0.
-            /// \param transpose_arg1 Flag to indicate if transpose on arg1.
-            template <typename T>
-            void matmul(const T* arg0,
-                        const T* arg1,
-                        T* out,
-                        const Shape& arg0_shape,
-                        const Shape& arg1_shape,
-                        const Shape& out_shape,
-                        bool transpose_arg0,
-                        bool transpose_arg1)
-            {
-                // Steps to compute matmul:
-                // 1) Check inputs and perform transpose on arg if applicable
-                // 2) If ranks of both args are 2D and below (no batch dim),
-                //    perform dot and return result; otherwise, continue next
-                // 3) Check if auto broadcast is needed on args or transposed args,
-                //    and perform broadcast if applicable
-                // 4) Perform dot on the args or updated args and return result
-
-                size_t arg0_rank = arg0_shape.size();
-                size_t arg1_rank = arg1_shape.size();
-                size_t out_rank = out_shape.size();
-
-                // vector vars to hold pontential intermediate transpose,
-                // broadcast result
-                vector<T> arg0_transpose_vec;
-                vector<T> arg1_transpose_vec;
-                vector<T> arg0_broadcast_vec;
-                vector<T> arg1_broadcast_vec;
-
-                // pointers to updated inputs
-                const T* arg0_update = arg0;
-                const T* arg1_update = arg1;
-
-                // vars for updated inputs shapes
-                Shape wip_arg0_shape = arg0_shape;
-                Shape wip_arg1_shape = arg1_shape;
-
-                auto get_transpose_order = [](const Shape& input_shape) {
-                    size_t rank = input_shape.size();
-                    NGRAPH_CHECK(rank > 1, "Invalid input for transpose");
-                    vector<size_t> axes_order(rank);
-                    iota(axes_order.begin(), axes_order.end(), 0);
-                    swap(axes_order[rank - 1], axes_order[rank - 2]);
-                    return AxisVector{begin(axes_order), end(axes_order)};
-                };
-
-                auto get_broadcast_axes = [](const Shape& marker_shape, const Shape& target_shape) {
-                    NGRAPH_CHECK(marker_shape.size() == target_shape.size(),
-                                 "Incompatible input shapes");
-                    AxisSet broadcast_axes;
-                    for (size_t i = 0; i < marker_shape.size(); i++)
-                    {
-                        if (marker_shape[i] == 1 && target_shape[i] != 1)
-                        {
-                            broadcast_axes.insert(i);
-                        }
-                    }
-                    return broadcast_axes;
-                };
-
-                // Perform transpose if requested
-                if (transpose_arg0 && arg0_rank > 1)
-                {
-                    arg0_transpose_vec.reserve(shape_size(arg0_shape));
-                    auto axis_vector = get_transpose_order(arg0_shape);
-                    swap(wip_arg0_shape[arg0_rank - 1], wip_arg0_shape[arg0_rank - 2]);
-                    opt_kernel::reshape(reinterpret_cast<const char*>(arg0),
-                                        reinterpret_cast<char*>(arg0_transpose_vec.data()),
-                                        arg0_shape,
-                                        axis_vector,
-                                        wip_arg0_shape,
-                                        sizeof(T));
-
-                    arg0_update = arg0_transpose_vec.data();
-                }
-
-                if (transpose_arg1 && arg1_rank > 1)
-                {
-                    arg1_transpose_vec.reserve(shape_size(arg1_shape));
-                    auto axis_vector = get_transpose_order(arg1_shape);
-                    swap(wip_arg1_shape[arg1_rank - 1], wip_arg1_shape[arg1_rank - 2]);
-                    opt_kernel::reshape(reinterpret_cast<const char*>(arg1),
-                                        reinterpret_cast<char*>(arg1_transpose_vec.data()),
-                                        arg1_shape,
-                                        axis_vector,
-                                        wip_arg1_shape,
-                                        sizeof(T));
-
-                    arg1_update = arg1_transpose_vec.data();
-                }
-
-                // Inputs are 2D and below, perform dot directly
-                if (arg0_rank <= 2 && arg1_rank <= 2)
-                {
-                    return dot(arg0_update,
-                               arg1_update,
-                               out,
-                               wip_arg0_shape,
-                               wip_arg1_shape,
-                               out_shape,
-                               1);
-                }
-
-                // Check and perform auto-broadcast if needed
-                // If one of the arg is 2D or below, no need to
-                // do broadcast on it, just use its value for
-                // every batch of dot compuatation later
-
-                if (arg0_rank > 2 && arg1_rank > 2)
-                {
-                    const auto& broadcast_shapes = builder::get_numpy_broadcast_shapes(
-                        {Shape{begin(wip_arg0_shape), next(end(wip_arg0_shape), -2)},
-                         Shape{begin(wip_arg1_shape), next(end(wip_arg1_shape), -2)}});
-
-                    Shape arg0_br_target_shape = broadcast_shapes.first;
-                    Shape arg1_br_target_shape = broadcast_shapes.first;
-                    Shape arg0_br_marker_shape = broadcast_shapes.second.at(0);
-                    Shape arg1_br_marker_shape = broadcast_shapes.second.at(1);
-
-                    arg0_br_target_shape.insert(
-                        end(arg0_br_target_shape),
-                        next(begin(wip_arg0_shape), wip_arg0_shape.size() - 2),
-                        end(wip_arg0_shape));
-                    arg1_br_target_shape.insert(
-                        end(arg1_br_target_shape),
-                        next(begin(wip_arg1_shape), wip_arg1_shape.size() - 2),
-                        end(wip_arg1_shape));
-
-                    arg0_br_marker_shape.insert(
-                        end(arg0_br_marker_shape),
-                        next(begin(wip_arg0_shape), wip_arg0_shape.size() - 2),
-                        end(wip_arg0_shape));
-                    arg1_br_marker_shape.insert(
-                        end(arg1_br_marker_shape),
-                        next(begin(wip_arg1_shape), wip_arg1_shape.size() - 2),
-                        end(wip_arg1_shape));
-
-                    if (arg0_br_target_shape != wip_arg0_shape)
-                    {
-                        auto broadcast_axes =
-                            get_broadcast_axes(arg0_br_marker_shape, arg0_br_target_shape);
-                        if (!broadcast_axes.empty())
-                        {
-                            arg0_broadcast_vec.reserve(shape_size(arg0_br_target_shape));
-                            broadcast(arg0_update,
-                                      arg0_broadcast_vec.data(),
-                                      wip_arg0_shape,
-                                      arg0_br_target_shape,
-                                      broadcast_axes);
-
-                            arg0_update = arg0_broadcast_vec.data();
-                            wip_arg0_shape = arg0_br_target_shape;
-                            arg0_rank = wip_arg0_shape.size();
-                        }
-                    }
-
-                    if (arg1_br_target_shape != wip_arg1_shape)
-                    {
-                        auto broadcast_axes =
-                            get_broadcast_axes(arg1_br_marker_shape, arg1_br_target_shape);
-                        if (!broadcast_axes.empty())
-                        {
-                            arg1_broadcast_vec.reserve(shape_size(arg1_br_target_shape));
-                            broadcast(arg1_update,
-                                      arg1_broadcast_vec.data(),
-                                      wip_arg1_shape,
-                                      arg1_br_target_shape,
-                                      broadcast_axes);
-
-                            arg1_update = arg1_broadcast_vec.data();
-                            wip_arg1_shape = arg1_br_target_shape;
-                            arg1_rank = wip_arg1_shape.size();
-                        }
-                    }
-                }
-
-                // Perform batched dot
-
-                size_t output_batch_size = 1;
-
-                // Calculate number of batches
-                if (out_rank < 3)
-                {
-                    // Output is {batch_size, dot_result}, i.e.,
-                    // arg 0 shape {2}, arg1 shape {3, 2, 1}, output shape {3, 1}
-                    output_batch_size = out_shape[0];
-                }
-                else
-                {
-                    for (size_t i = 0; i < (out_rank - 2); i++)
-                    {
-                        output_batch_size *= out_shape[i];
-                    }
-                }
-
-                Shape dot_arg0_shape = (arg0_rank > 2) ? Shape{wip_arg0_shape[arg0_rank - 2],
-                                                               wip_arg0_shape[arg0_rank - 1]}
-                                                       : wip_arg0_shape;
-                Shape dot_arg1_shape = (arg1_rank > 2) ? Shape{wip_arg1_shape[arg1_rank - 2],
-                                                               wip_arg1_shape[arg1_rank - 1]}
-                                                       : wip_arg1_shape;
-                Shape dot_output_shape =
-                    (out_rank > 2) ? Shape{out_shape[out_rank - 2], out_shape[out_rank - 1]}
-                                   : Shape{out_shape[out_rank - 1]};
-
-                const size_t arg0_offset = (arg0_rank > 2) ? shape_size(dot_arg0_shape) : 0;
-                const size_t arg1_offset = (arg1_rank > 2) ? shape_size(dot_arg1_shape) : 0;
-                const size_t output_offset = shape_size(dot_output_shape);
-                for (size_t i = 0; i < output_batch_size; i++)
-                {
-                    dot(arg0_update + i * arg0_offset,
-                        arg1_update + i * arg1_offset,
-                        out + i * output_offset,
-                        dot_arg0_shape,
-                        dot_arg1_shape,
-                        dot_output_shape,
-                        1);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/max.hpp b/ngraph/core/include/ngraph/runtime/reference/max.hpp
deleted file mode 100644 (file)
index cd62a09..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <limits>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void max(const T* arg,
-                     T* out,
-                     const Shape& in_shape,
-                     const AxisSet& reduction_axes,
-                     bool keep_dims)
-            {
-                T minval = std::numeric_limits<T>::has_infinity
-                               ? T(-std::numeric_limits<T>::infinity())
-                               : std::numeric_limits<T>::min();
-
-                auto out_shape = reduce(in_shape, reduction_axes, keep_dims);
-                CoordinateTransform output_transform(out_shape);
-
-                for (const Coordinate& output_coord : output_transform)
-                {
-                    out[output_transform.index(output_coord)] = minval;
-                }
-
-                CoordinateTransform input_transform(in_shape);
-
-                for (const Coordinate& input_coord : input_transform)
-                {
-                    Coordinate output_coord = reduce(input_coord, reduction_axes, keep_dims);
-
-                    T x = arg[input_transform.index(input_coord)];
-                    T max = out[output_transform.index(output_coord)];
-                    if (x > max)
-                    {
-                        out[output_transform.index(output_coord)] = x;
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/max_pool.hpp b/ngraph/core/include/ngraph/runtime/reference/max_pool.hpp
deleted file mode 100644 (file)
index 1f37535..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <numeric>
-
-#include "ngraph/coordinate_transform.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void max_pool_backprop(const T* arg_forward,
-                                   const T* delta,
-                                   T* out,
-                                   const Shape& delta_shape,
-                                   const Shape& out_shape, // same as arg_forward_shape
-                                   const Shape& window_shape,
-                                   const Strides& window_movement_strides,
-                                   const Shape& padding_below,
-                                   const Shape& padding_above)
-            {
-                CoordinateTransform out_transform(out_shape);
-
-                for (const Coordinate& out_coord : out_transform)
-                {
-                    out[out_transform.index(out_coord)] = 0;
-                }
-
-                CoordinateTransform delta_transform(delta_shape);
-
-                for (const Coordinate& delta_coord : delta_transform)
-                {
-                    size_t img_index = delta_coord[0];
-                    size_t channel = delta_coord[1];
-
-                    size_t n_image_dimensions = out_shape.size() - 2;
-                    Coordinate source_window_transform_start(2 + n_image_dimensions);
-                    Coordinate source_window_transform_end(2 + n_image_dimensions);
-                    Strides source_window_transform_source_strides(2 + n_image_dimensions, 1);
-                    AxisVector source_window_transform_source_axis_order(2 + n_image_dimensions);
-                    CoordinateDiff source_window_transform_padding_below(2 + n_image_dimensions);
-                    CoordinateDiff source_window_transform_padding_above(2 + n_image_dimensions);
-
-                    source_window_transform_start[0] = img_index;
-                    source_window_transform_end[0] = img_index + 1;
-                    source_window_transform_start[1] = channel;
-                    source_window_transform_end[1] = channel + 1;
-                    source_window_transform_padding_below[0] = 0;
-                    source_window_transform_padding_below[1] = 0;
-                    source_window_transform_padding_above[0] = 0;
-                    source_window_transform_padding_above[1] = 0;
-
-                    for (size_t i = 2; i < n_image_dimensions + 2; i++)
-                    {
-                        size_t window_shape_this_dim = window_shape[i - 2];
-                        size_t movement_stride = window_movement_strides[i - 2];
-
-                        source_window_transform_start[i] = movement_stride * delta_coord[i];
-                        source_window_transform_end[i] =
-                            source_window_transform_start[i] + window_shape_this_dim;
-                        source_window_transform_padding_below[i] = padding_below[i - 2];
-                        source_window_transform_padding_above[i] = padding_above[i - 2];
-                    }
-                    std::iota(begin(source_window_transform_source_axis_order),
-                              end(source_window_transform_source_axis_order),
-                              0);
-
-                    CoordinateTransform source_window_transform(
-                        out_shape,
-                        source_window_transform_start,
-                        source_window_transform_end,
-                        source_window_transform_source_strides,
-                        source_window_transform_source_axis_order,
-                        source_window_transform_padding_below,
-                        source_window_transform_padding_above);
-
-                    Coordinate argmax_coord;
-                    bool argmax_coord_valid = false;
-                    T max_val = 0; // just initializing to keep compiler happy, this 0 is ignored
-
-                    for (const Coordinate& source_window_coord : source_window_transform)
-                    {
-                        if (source_window_transform.has_source_coordinate(source_window_coord))
-                        {
-                            T candidate =
-                                arg_forward[source_window_transform.index(source_window_coord)];
-
-                            if (!argmax_coord_valid || candidate > max_val)
-                            {
-                                max_val = candidate;
-                                argmax_coord = source_window_coord;
-                                argmax_coord_valid = true;
-                            }
-                        }
-                    }
-
-                    if (argmax_coord_valid)
-                    {
-                        out[source_window_transform.index(argmax_coord)] +=
-                            delta[delta_transform.index(delta_coord)];
-                    }
-                }
-            }
-
-            template <typename T>
-            void max_pool(const T* arg,
-                          T* out,
-                          const Shape& arg_shape,
-                          const Shape& out_shape,
-                          const Shape& window_shape,
-                          const Strides& window_movement_strides,
-                          const Shape& padding_below,
-                          const Shape& padding_above)
-            {
-                // At the outermost level we will walk over every output coordinate O.
-                CoordinateTransform output_transform(out_shape);
-
-                for (const Coordinate& out_coord : output_transform)
-                {
-                    // Our output coordinate O will have the form:
-                    //
-                    //   (N,chan,i_1,...,i_n)
-
-                    size_t batch_index = out_coord[0];
-                    size_t channel = out_coord[1];
-
-                    // For the input data we need to iterate the coordinate:
-                    //
-                    //   I:
-                    //
-                    // over the range (noninclusive on the right):
-                    //
-                    //   (N,chan,s_1*i_1,s_2*i_2,...,s_n*i_n) ->
-                    //
-                    //     (N+1,chan+1,s_1*i_1 + window_shape_1,...,s_n*i_n + window_shape_n)
-                    //
-                    // with unit stride.
-                    //
-                    // We iterate this over the *padded* data, so below we will need to check for
-                    // coordinates that fall in the padding area.
-
-                    size_t n_spatial_dimensions = arg_shape.size() - 2;
-
-                    Coordinate input_batch_transform_start(2 + n_spatial_dimensions);
-                    Coordinate input_batch_transform_end(2 + n_spatial_dimensions);
-                    Strides input_batch_transform_source_strides(2 + n_spatial_dimensions, 1);
-                    AxisVector input_batch_transform_source_axis_order(2 + n_spatial_dimensions);
-                    CoordinateDiff input_batch_transform_padding_below(2 + n_spatial_dimensions);
-                    CoordinateDiff input_batch_transform_padding_above(2 + n_spatial_dimensions);
-
-                    input_batch_transform_start[0] = batch_index;
-                    input_batch_transform_end[0] = batch_index + 1;
-                    input_batch_transform_start[1] = channel;
-                    input_batch_transform_end[1] = channel + 1;
-                    input_batch_transform_padding_below[0] = 0;
-                    input_batch_transform_padding_below[1] = 0;
-                    input_batch_transform_padding_above[0] = 0;
-                    input_batch_transform_padding_above[1] = 0;
-
-                    for (size_t i = 2; i < n_spatial_dimensions + 2; i++)
-                    {
-                        size_t window_shape_this_dim = window_shape[i - 2];
-                        size_t movement_stride = window_movement_strides[i - 2];
-
-                        input_batch_transform_start[i] = movement_stride * out_coord[i];
-                        input_batch_transform_end[i] =
-                            input_batch_transform_start[i] + window_shape_this_dim;
-                        input_batch_transform_padding_below[i] = padding_below[i - 2];
-                        input_batch_transform_padding_above[i] = padding_above[i - 2];
-                    }
-
-                    for (size_t i = 0; i < arg_shape.size(); i++)
-                    {
-                        input_batch_transform_source_axis_order[i] = i;
-                    }
-
-                    CoordinateTransform input_batch_transform(
-                        arg_shape,
-                        input_batch_transform_start,
-                        input_batch_transform_end,
-                        input_batch_transform_source_strides,
-                        input_batch_transform_source_axis_order,
-                        input_batch_transform_padding_below,
-                        input_batch_transform_padding_above);
-
-                    // As we go, we compute the maximum value:
-                    //
-                    //   output[O] = max(output[O],arg[I])
-
-                    T result = std::numeric_limits<T>::lowest();
-
-                    for (const Coordinate& input_batch_coord : input_batch_transform)
-                    {
-                        if (input_batch_transform.has_source_coordinate(input_batch_coord))
-                        {
-                            T x = arg[input_batch_transform.index(input_batch_coord)];
-                            result = x > result ? x : result;
-                        }
-                    }
-
-                    out[output_transform.index(out_coord)] = result;
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/maximum.hpp b/ngraph/core/include/ngraph/runtime/reference/maximum.hpp
deleted file mode 100644 (file)
index 8eef0d1..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-#include "ngraph/op/util/attr_types.hpp"
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void maximum(const T* arg0, const T* arg1, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg0[i] > arg1[i] ? arg0[i] : arg1[i];
-                }
-            }
-
-            template <typename T>
-            void maximum(const T* arg0,
-                         const T* arg1,
-                         T* out,
-                         const Shape& arg0_shape,
-                         const Shape& arg1_shape,
-                         const op::AutoBroadcastSpec& broadcast_spec)
-            {
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
-                        return x > y ? x : y;
-                    });
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/mean.hpp b/ngraph/core/include/ngraph/runtime/reference/mean.hpp
deleted file mode 100644 (file)
index 28bc579..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <map>
-#include <vector>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/runtime/reference/sum.hpp"
-#include "ngraph/shape_util.hpp"
-#include "ngraph/type/bfloat16.hpp"
-#include "ngraph/type/float16.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void mean(const T* arg,
-                      T* out,
-                      const Shape& in_shape,
-                      const AxisSet& reduction_axes,
-                      bool keep_dims)
-            {
-                auto out_shape = reduce(in_shape, reduction_axes, keep_dims);
-                CoordinateTransform output_transform(out_shape);
-                std::vector<T> cs(shape_size(out_shape));
-
-                for (const Coordinate& output_coord : output_transform)
-                {
-                    out[output_transform.index(output_coord)] = 0;
-                    cs[output_transform.index(output_coord)] = 0;
-                }
-
-                CoordinateTransform input_transform(in_shape);
-                std::map<size_t, int> index_to_count_map;
-
-                for (const Coordinate& input_coord : input_transform)
-                {
-                    Coordinate output_coord = reduce(input_coord, reduction_axes, keep_dims);
-
-                    T x = arg[input_transform.index(input_coord)];
-                    T& z = out[output_transform.index(output_coord)];
-                    auto index = output_transform.index(output_coord);
-                    if (index_to_count_map.find(index) == index_to_count_map.end())
-                    {
-                        index_to_count_map[index] = 1;
-                    }
-                    else
-                    {
-                        index_to_count_map[index]++;
-                    }
-
-                    if (is_finite(x) && is_finite(z))
-                    {
-                        T& c = cs[output_transform.index(output_coord)];
-                        T t = z + (x - c);
-                        c = (t - z) - (x - c);
-                        z = t;
-                    }
-                    else
-                    {
-                        z = z + x;
-                    }
-                }
-
-                for (const Coordinate& output_coord : output_transform)
-                {
-                    auto count = index_to_count_map[output_transform.index(output_coord)];
-                    out[output_transform.index(output_coord)] =
-                        out[output_transform.index(output_coord)] / count;
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/min.hpp b/ngraph/core/include/ngraph/runtime/reference/min.hpp
deleted file mode 100644 (file)
index 5a39533..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <limits>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/shape_util.hpp"
-
-#ifdef _WIN32
-#undef min
-#endif
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void min(const T* arg, T* out, const Shape& in_shape, const AxisSet& reduction_axes)
-            {
-                T minval = std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity()
-                                                                : std::numeric_limits<T>::max();
-
-                auto out_shape = reduce(in_shape, reduction_axes, false);
-                CoordinateTransform output_transform(out_shape);
-
-                for (const Coordinate& output_coord : output_transform)
-                {
-                    out[output_transform.index(output_coord)] = minval;
-                }
-
-                CoordinateTransform input_transform(in_shape);
-
-                for (const Coordinate& input_coord : input_transform)
-                {
-                    Coordinate output_coord = reduce(input_coord, reduction_axes, false);
-
-                    T x = arg[input_transform.index(input_coord)];
-                    T min = out[output_transform.index(output_coord)];
-                    if (x < min)
-                    {
-                        out[output_transform.index(output_coord)] = x;
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/minimum.hpp b/ngraph/core/include/ngraph/runtime/reference/minimum.hpp
deleted file mode 100644 (file)
index 4a6f9d0..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-#include "ngraph/op/util/attr_types.hpp"
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void minimum(const T* arg0, const T* arg1, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg0[i] < arg1[i] ? arg0[i] : arg1[i];
-                }
-            }
-
-            template <typename T>
-            void minimum(const T* arg0,
-                         const T* arg1,
-                         T* out,
-                         const Shape& arg0_shape,
-                         const Shape& arg1_shape,
-                         const op::AutoBroadcastSpec& broadcast_spec)
-            {
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
-                        return x < y ? x : y;
-                    });
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/mish.hpp b/ngraph/core/include/ngraph/runtime/reference/mish.hpp
deleted file mode 100644 (file)
index 3bc1202..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void mish(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg[i] * std::tanh(std::log((std::exp(arg[i]) + 1.0)));
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/multiply.hpp b/ngraph/core/include/ngraph/runtime/reference/multiply.hpp
deleted file mode 100644 (file)
index 78976d3..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-#include "ngraph/op/util/attr_types.hpp"
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void multiply(const T* arg0, const T* arg1, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg0[i] * arg1[i];
-                }
-            }
-
-            template <typename T>
-            void multiply(const T* arg0,
-                          const T* arg1,
-                          T* out,
-                          const Shape& arg0_shape,
-                          const Shape& arg1_shape,
-                          const op::AutoBroadcastSpec& broadcast_spec)
-            {
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
-                        return x * y;
-                    });
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/negate.hpp b/ngraph/core/include/ngraph/runtime/reference/negate.hpp
deleted file mode 100644 (file)
index bf9019f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void negate(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = -arg[i];
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/non_zero.hpp b/ngraph/core/include/ngraph/runtime/reference/non_zero.hpp
deleted file mode 100644 (file)
index a5b0970..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            /// \brief Return number of non-zero entries in the input argument.
-            ///
-            /// \param arg Input tensor
-            /// \param arg_shape Input tensor shape
-            /// Output number of non-zero entries in arg
-            template <typename T>
-            size_t non_zero_get_count(const T* arg, const Shape& arg_shape)
-            {
-                T zero = 0;
-                size_t arg_rank = arg_shape.size();
-                size_t arg_count = shape_size(arg_shape);
-                size_t non_zero_count = 0;
-
-                // Input arg is scalar
-                if (arg_rank == 0)
-                {
-                    if (*arg != zero)
-                    {
-                        non_zero_count = 1;
-                    }
-                }
-                else // Input is non scalar case
-                {
-                    for (size_t i = 0; i < arg_count; i++)
-                    {
-                        if (arg[i] != zero)
-                        {
-                            non_zero_count++;
-                        }
-                    }
-                }
-
-                return non_zero_count;
-            }
-
-            /// \brief Return indices of non-zero entries in input argument.
-            ///
-            /// \param arg Input tensor
-            /// \param arg_shape Input tensor shape
-            /// \param out Output containing indices of non-zero entries in arg
-            template <typename T, typename U>
-            void non_zero(const T* arg, U* out, const Shape& arg_shape)
-            {
-                T zero = 0;
-                size_t arg_rank = arg_shape.size();
-                size_t arg_count = shape_size(arg_shape);
-
-                size_t non_zero_count = non_zero_get_count(arg, arg_shape);
-
-                // Input arg only contains 0s
-                if (non_zero_count == 0)
-                {
-                    return;
-                }
-
-                // Input arg is non-zero scalar
-                if (arg_rank == 0)
-                {
-                    out[0] = static_cast<U>(0);
-                    return;
-                }
-
-                // Dimensional size for the arg_shape. This is used to map one-dimentional
-                // arg array indices to corresponding arg_rank-dimentional shape indices.
-                // i.e., arg_shape {2, 3, 2} => elem_per_axis {6, 2, 1}.
-                // Array index 4 in arg (arg[4]) correspond to 3-D index of [0][2][0]
-                std::vector<size_t> elem_per_axis;
-                elem_per_axis.reserve(arg_rank);
-
-                size_t temp = arg_count;
-                for (size_t i = 0; i < arg_rank; i++)
-                {
-                    temp = temp / arg_shape[i];
-                    elem_per_axis.push_back(temp);
-                }
-
-                // Column index in out to record a non-zero entry
-                size_t col_index = 0;
-
-                // Array index in out to write non-zero index value
-                size_t out_index = 0;
-
-                // Find non-zero entries in arg and write the indices info in out.
-                // For a non-zero entry, map its array index to corresponding indices
-                // in arg_shape, then, write each of the arg_shape index value to
-                // out array at the position that is determined by entry's dimension
-                // distance and number of non-zero entries prior to it.
-                // i,e., Given input with shape{2, 3, 2}, rank = 3
-                // input [[[0, 2], [0, 0], [3, 4]],
-                //        [[5, 0], [6, 0], [7, 8]]]
-                //
-                // output shape {3, 7}, rank = 2
-                // output [[0, 0, 0, 1, 1, 1, 1],
-                //         [0, 2, 2, 0, 1, 2, 2],
-                //         [1, 0, 1, 0, 0, 0, 1]]
-                //
-                // input[0][2][0] = 3 is arg[4]
-                // output for this entry out[1] = 0, out[8] = 2, out[15] = 0
-                for (size_t i = 0; i < arg_count; i++)
-                {
-                    if (arg[i] != zero)
-                    {
-                        temp = i;
-
-                        for (size_t j = 0; j < arg_rank; j++)
-                        {
-                            out_index = j * non_zero_count + col_index;
-                            out[out_index] = static_cast<U>(temp / elem_per_axis[j]);
-
-                            temp = temp % elem_per_axis[j];
-                        }
-
-                        col_index++;
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/not.hpp b/ngraph/core/include/ngraph/runtime/reference/not.hpp
deleted file mode 100644 (file)
index d31e0ac..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void logical_not(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = static_cast<T>(!(arg[i]));
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/not_equal.hpp b/ngraph/core/include/ngraph/runtime/reference/not_equal.hpp
deleted file mode 100644 (file)
index 1cc32dd..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wfloat-equal"
-#endif
-
-#include <cstddef>
-
-#include "ngraph/op/util/attr_types.hpp"
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void not_equal(const T* arg0,
-                           const T* arg1,
-                           char* out,
-                           size_t count) // TODO: using char for bool, is this right?
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg0[i] != arg1[i];
-                }
-            }
-
-            template <typename T, typename U>
-            void not_equal(const T* arg0,
-                           const T* arg1,
-                           U* out,
-                           const Shape& arg0_shape,
-                           const Shape& arg1_shape,
-                           const op::AutoBroadcastSpec& broadcast_spec)
-            {
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
-                        return x != y;
-                    });
-            }
-        }
-    }
-}
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
diff --git a/ngraph/core/include/ngraph/runtime/reference/one_hot.hpp b/ngraph/core/include/ngraph/runtime/reference/one_hot.hpp
deleted file mode 100644 (file)
index 99a9d41..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename INDICES_TYPE, typename OUTPUT_TYPE>
-            void one_hot(const INDICES_TYPE* arg,
-                         OUTPUT_TYPE* out,
-                         const Shape& in_shape,
-                         const Shape& out_shape,
-                         size_t one_hot_axis,
-                         const OUTPUT_TYPE on_value,
-                         const OUTPUT_TYPE off_value)
-            {
-                // Step 1: Set off_value to the output.
-                CoordinateTransform output_transform(out_shape);
-
-                for (const Coordinate& output_coord : output_transform)
-                {
-                    out[output_transform.index(output_coord)] = off_value;
-                }
-
-                // Step 2: Write off_value at needed positions, throwing exceptions when invalid
-                // conditions are encountered.
-                CoordinateTransform input_transform(in_shape);
-
-                for (const Coordinate& input_coord : input_transform)
-                {
-                    INDICES_TYPE val = arg[input_transform.index(input_coord)];
-
-                    if (std::floor(val) < val || std::floor(val) > val)
-                    {
-                        continue;
-                    }
-
-                    size_t one_hot_pos = static_cast<size_t>(val);
-
-                    if (one_hot_pos >= out_shape[one_hot_axis])
-                    {
-                        continue;
-                    }
-
-                    Coordinate one_hot_coord = inject(input_coord, one_hot_axis, one_hot_pos);
-
-                    out[output_transform.index(one_hot_coord)] = on_value;
-                }
-            }
-
-            template <typename T>
-            void one_hot(const T* arg,
-                         T* out,
-                         const Shape& in_shape,
-                         const Shape& out_shape,
-                         size_t one_hot_axis)
-            {
-                const T on_value = 1;
-                const T off_value = 0;
-                one_hot<T, T>(arg, out, in_shape, out_shape, one_hot_axis, on_value, off_value);
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/or.hpp b/ngraph/core/include/ngraph/runtime/reference/or.hpp
deleted file mode 100644 (file)
index 6dcf9ed..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-#include "ngraph/op/util/attr_types.hpp"
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void logical_or(const T* arg0, const T* arg1, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = static_cast<T>(arg0[i] || arg1[i]);
-                }
-            }
-
-            template <typename T>
-            void logical_or(const T* arg0,
-                            const T* arg1,
-                            T* out,
-                            const Shape& arg0_shape,
-                            const Shape& arg1_shape,
-                            const op::AutoBroadcastSpec& broadcast_spec)
-            {
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
-                        return static_cast<T>(x || y);
-                    });
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/pad.hpp b/ngraph/core/include/ngraph/runtime/reference/pad.hpp
deleted file mode 100644 (file)
index f9ada12..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/axis_vector.hpp"
-#include "ngraph/check.hpp"
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/op/pad.hpp" // for op::PadMode
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void pad(const T* arg0,
-                     const T* arg1,
-                     T* out,
-                     const Shape& arg0_shape,
-                     const Shape& out_shape,
-                     const CoordinateDiff& padding_below,
-                     const CoordinateDiff& padding_above,
-                     op::PadMode pad_mode)
-            {
-                Coordinate input_start(arg0_shape.size(), 0); // start at (0,0,...,0)
-                Coordinate input_end = out_shape; // end at (d'0,d'1,...,d'n), the outer corner of
-                                                  // the post-padding shape
-
-                Strides input_strides(arg0_shape.size(), 1);
-
-                AxisVector input_axis_order(arg0_shape.size());
-                for (size_t i = 0; i < arg0_shape.size(); i++)
-                {
-                    input_axis_order[i] = i;
-                }
-
-                CoordinateTransform input_transform(arg0_shape,
-                                                    input_start,
-                                                    input_end,
-                                                    input_strides,
-                                                    input_axis_order,
-                                                    padding_below,
-                                                    padding_above);
-                CoordinateTransform output_transform(out_shape);
-
-                CoordinateTransform::Iterator output_it = output_transform.begin();
-
-                NGRAPH_CHECK(shape_size(input_transform.get_target_shape()) ==
-                             shape_size(output_transform.get_target_shape()));
-
-                for (const Coordinate& in_coord : input_transform)
-                {
-                    const Coordinate& out_coord = *output_it;
-
-                    T v(0);
-
-                    switch (pad_mode)
-                    {
-                    case op::PadMode::CONSTANT:
-                        // If the coordinate is out of bounds, substitute *arg1.
-                        v = input_transform.has_source_coordinate(in_coord)
-                                ? arg0[input_transform.index(in_coord)]
-                                : *arg1;
-                        break;
-                    case op::PadMode::EDGE:
-                    {
-                        Coordinate c = in_coord; // have to copy because in_coord is const
-
-                        // Truncate each out-of-bound dimension.
-                        for (size_t i = 0; i < c.size(); i++)
-                        {
-                            if (static_cast<ptrdiff_t>(c[i]) < padding_below[i])
-                            {
-                                c[i] = padding_below[i];
-                            }
-
-                            if (static_cast<ptrdiff_t>(c[i]) >=
-                                (padding_below[i] + static_cast<ptrdiff_t>(arg0_shape[i])))
-                            {
-                                c[i] = static_cast<size_t>(
-                                    padding_below[i] + static_cast<ptrdiff_t>(arg0_shape[i]) - 1);
-                            }
-                        }
-                        v = arg0[input_transform.index(c)];
-                        break;
-                    }
-                    case op::PadMode::REFLECT:
-                    {
-                        // clang-format off
-                        // The algorithm here is a bit complicated because if the padding is
-                        // bigger than the tensor, we may reflect multiple times.
-                        //
-                        // Example:
-                        //
-                        // Input shape:     [2]
-                        // Padding:         6 below, 6 above
-                        // Output shape:    [14]
-                        //
-                        // Input:                       a b
-                        // Expected output: a b a b a b a b a b a b a b
-                        //
-                        // Computation for coordinate 13 of output:
-                        //
-                        //         . . . . . . a b . . . . .[.] -> (oob above by 6 spaces, so reflection is at top-6)
-                        //         .[.]. . . . a b . . . . . .  -> (oob below by 5 spaces, so reflection is at bottom+5)
-                        //         . . . . . . a b . . .[.]. .  -> (oob above by 4 spaces, so reflection is at top-4)
-                        //         . . .[.]. . a b . . . . . .  -> (oob below by 3 spaces, so reflection is at bottom+3)
-                        //         . . . . . . a b .[.]. . . .  -> (oob above by 2 spaces, so reflection is at top-2)
-                        //         . . . . .[.]a b . . . . . .  -> (oob below by 1 space,  so reflection is at bottom+1)
-                        //         . . . . . . a[b]. . . . . .  -> (no longer oob, so copy from here)
-                        //
-                        // Note that this algorithm works because REFLECT padding only makes sense
-                        // if each dim is >= 2.
-                        // clang-format on
-                        Coordinate c = in_coord; // have to copy because in_coord is const
-
-                        for (size_t i = 0; i < c.size(); i++)
-                        {
-                            ptrdiff_t new_dim = c[i];
-                            bool done_reflecting = false;
-
-                            while (!done_reflecting)
-                            {
-                                if (new_dim < padding_below[i])
-                                {
-                                    ptrdiff_t distance_oob = padding_below[i] - new_dim;
-                                    new_dim = padding_below[i] + distance_oob;
-                                }
-                                else if (new_dim >=
-                                         padding_below[i] + static_cast<ptrdiff_t>(arg0_shape[i]))
-                                {
-                                    ptrdiff_t distance_oob =
-                                        new_dim - padding_below[i] -
-                                        (static_cast<ptrdiff_t>(arg0_shape[i]) - 1);
-                                    new_dim = padding_below[i] +
-                                              static_cast<ptrdiff_t>(arg0_shape[i]) - distance_oob -
-                                              1;
-                                }
-                                else
-                                {
-                                    done_reflecting = true;
-                                }
-                            }
-
-                            c[i] = static_cast<size_t>(new_dim);
-                        }
-                        v = arg0[input_transform.index(c)];
-                        break;
-                    }
-                    case op::PadMode::SYMMETRIC:
-                    {
-                        Coordinate c = in_coord; // have to copy because in_coord is const
-                        for (size_t i = 0; i < c.size(); i++)
-                        {
-                            ptrdiff_t pos = padding_below[i] - (c[i] + 1);
-                            if (pos >= 0)
-                            {
-                                c[i] = static_cast<size_t>(pos + padding_below[i]);
-                            }
-                            else
-                            {
-                                pos = -(pos + 1);
-                                ptrdiff_t src_dim = static_cast<ptrdiff_t>(arg0_shape[i]);
-                                if (pos < src_dim)
-                                {
-                                    c[i] = static_cast<size_t>(pos + padding_below[i]);
-                                }
-                                else
-                                {
-                                    c[i] = static_cast<size_t>(padding_below[i] + src_dim +
-                                                               padding_above[i] - pos);
-                                }
-                            }
-                        }
-                        v = arg0[input_transform.index(c)];
-                        break;
-                    }
-                    }
-
-                    out[output_transform.index(out_coord)] = v;
-
-                    ++output_it;
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/power.hpp b/ngraph/core/include/ngraph/runtime/reference/power.hpp
deleted file mode 100644 (file)
index 52af243..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-#include "ngraph/op/util/attr_types.hpp"
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void power(const T* arg0, const T* arg1, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::pow(arg0[i], arg1[i]);
-                }
-            }
-
-            template <typename T>
-            void power(const T* arg0,
-                       const T* arg1,
-                       T* out,
-                       const Shape& arg0_shape,
-                       const Shape& arg1_shape,
-                       const op::AutoBroadcastSpec& broadcast_spec)
-            {
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
-                        return std::pow(x, y);
-                    });
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/prelu.hpp b/ngraph/core/include/ngraph/runtime/reference/prelu.hpp
deleted file mode 100644 (file)
index 47e4b7f..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-//*****************************************************************************
-// Copyright 2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-#include <op/util/attr_types.hpp>
-#include <shape.hpp>
-
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void prelu(const T* arg,
-                       const T* slope,
-                       T* out,
-                       const Shape& arg_shape,
-                       const Shape& slope_shape)
-            {
-                int cnt = 0;
-                for (size_t i = 0; i < shape_size(arg_shape); ++i)
-                {
-                    out[i] =
-                        arg[i] < T(0) ? T(arg[i] * slope[cnt++ % shape_size(slope_shape)]) : arg[i];
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/prior_box.hpp b/ngraph/core/include/ngraph/runtime/reference/prior_box.hpp
deleted file mode 100644 (file)
index f9402f0..0000000
+++ /dev/null
@@ -1,296 +0,0 @@
-//*****************************************************************************
-// Copyright 2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/axis_vector.hpp"
-#include "ngraph/check.hpp"
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/op/prior_box.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            static inline float clip_great(float x, float threshold)
-            {
-                return x < threshold ? x : threshold;
-            }
-
-            static inline float clip_less(float x, float threshold)
-            {
-                return x > threshold ? x : threshold;
-            }
-
-            template <typename T>
-            void prior_box(const T* data,
-                           const T* img,
-                           float* dst_data,
-                           const Shape& out_shape,
-                           const op::PriorBoxAttrs& attrs)
-            {
-                const int64_t W = data[1];
-                const int64_t H = data[0];
-                const int64_t IW = img[1];
-                const int64_t IH = img[0];
-
-                const int64_t OH = out_shape[1];
-                const int64_t OW = 1;
-
-                std::vector<float> aspect_ratios = {1.0f};
-                for (const auto& aspect_ratio : attrs.aspect_ratio)
-                {
-                    bool exist = false;
-                    for (const auto existed_value : aspect_ratios)
-                        exist |= std::fabs(aspect_ratio - existed_value) < 1e-6;
-
-                    if (!exist)
-                    {
-                        aspect_ratios.push_back(aspect_ratio);
-                        if (attrs.flip)
-                        {
-                            aspect_ratios.push_back(1.0f / aspect_ratio);
-                        }
-                    }
-                }
-
-                std::vector<float> variance = attrs.variance;
-                NGRAPH_CHECK(variance.size() == 1 || variance.size() == 4 || variance.empty());
-                if (variance.empty())
-                    variance.push_back(0.1f);
-
-                int64_t num_priors = op::PriorBox::number_of_priors(attrs);
-
-                float step = attrs.step;
-                auto min_size = attrs.min_size;
-                if (!attrs.scale_all_sizes)
-                {
-                    // mxnet-like PriorBox
-                    if (step == -1)
-                        step = 1.f * IH / H;
-                    else
-                        step *= IH;
-                    for (auto& size : min_size)
-                        size *= IH;
-                }
-
-                int64_t idx = 0;
-                float center_x, center_y, box_width, box_height, step_x, step_y;
-                float IWI = 1.0f / static_cast<float>(IW);
-                float IHI = 1.0f / static_cast<float>(IH);
-
-                if (step == 0)
-                {
-                    step_x = static_cast<float>(IW) / W;
-                    step_y = static_cast<float>(IH) / H;
-                }
-                else
-                {
-                    step_x = step;
-                    step_y = step;
-                }
-
-                auto calculate_data = [&dst_data, &IWI, &IHI, &idx](
-                    float center_x, float center_y, float box_width, float box_height, bool clip) {
-                    if (clip)
-                    {
-                        // order: xmin, ymin, xmax, ymax
-                        dst_data[idx++] = clip_less((center_x - box_width) * IWI, 0);
-                        dst_data[idx++] = clip_less((center_y - box_height) * IHI, 0);
-                        dst_data[idx++] = clip_great((center_x + box_width) * IWI, 1);
-                        dst_data[idx++] = clip_great((center_y + box_height) * IHI, 1);
-                    }
-                    else
-                    {
-                        dst_data[idx++] = (center_x - box_width) * IWI;
-                        dst_data[idx++] = (center_y - box_height) * IHI;
-                        dst_data[idx++] = (center_x + box_width) * IWI;
-                        dst_data[idx++] = (center_y + box_height) * IHI;
-                    }
-                };
-
-                for (int64_t h = 0; h < H; ++h)
-                {
-                    for (int64_t w = 0; w < W; ++w)
-                    {
-                        if (step == 0)
-                        {
-                            center_x = (w + 0.5f) * step_x;
-                            center_y = (h + 0.5f) * step_y;
-                        }
-                        else
-                        {
-                            center_x = (attrs.offset + w) * step;
-                            center_y = (attrs.offset + h) * step;
-                        }
-
-                        for (size_t s = 0; s < attrs.fixed_size.size(); ++s)
-                        {
-                            auto fixed_size_ = static_cast<size_t>(attrs.fixed_size[s]);
-                            box_width = box_height = fixed_size_ * 0.5f;
-
-                            if (!attrs.fixed_ratio.empty())
-                            {
-                                for (float ar : attrs.fixed_ratio)
-                                {
-                                    auto density_ = static_cast<int64_t>(attrs.density[s]);
-                                    auto shift =
-                                        static_cast<int64_t>(attrs.fixed_size[s] / density_);
-                                    ar = std::sqrt(ar);
-                                    float box_width_ratio = attrs.fixed_size[s] * 0.5f * ar;
-                                    float box_height_ratio = attrs.fixed_size[s] * 0.5f / ar;
-                                    for (size_t r = 0; r < density_; ++r)
-                                    {
-                                        for (size_t c = 0; c < density_; ++c)
-                                        {
-                                            float center_x_temp = center_x - fixed_size_ / 2 +
-                                                                  shift / 2.f + c * shift;
-                                            float center_y_temp = center_y - fixed_size_ / 2 +
-                                                                  shift / 2.f + r * shift;
-                                            calculate_data(center_x_temp,
-                                                           center_y_temp,
-                                                           box_width_ratio,
-                                                           box_height_ratio,
-                                                           true);
-                                        }
-                                    }
-                                }
-                            }
-                            else
-                            {
-                                if (!attrs.density.empty())
-                                {
-                                    auto density_ = static_cast<int64_t>(attrs.density[s]);
-                                    auto shift =
-                                        static_cast<int64_t>(attrs.fixed_size[s] / density_);
-                                    for (int64_t r = 0; r < density_; ++r)
-                                    {
-                                        for (int64_t c = 0; c < density_; ++c)
-                                        {
-                                            float center_x_temp = center_x - fixed_size_ / 2 +
-                                                                  shift / 2.f + c * shift;
-                                            float center_y_temp = center_y - fixed_size_ / 2 +
-                                                                  shift / 2.f + r * shift;
-                                            calculate_data(center_x_temp,
-                                                           center_y_temp,
-                                                           box_width,
-                                                           box_height,
-                                                           true);
-                                        }
-                                    }
-                                }
-                                //  Rest of priors
-                                for (float ar : aspect_ratios)
-                                {
-                                    if (fabs(ar - 1.) < 1e-6)
-                                    {
-                                        continue;
-                                    }
-
-                                    auto density_ = static_cast<int64_t>(attrs.density[s]);
-                                    auto shift =
-                                        static_cast<int64_t>(attrs.fixed_size[s] / density_);
-                                    ar = std::sqrt(ar);
-                                    float box_width_ratio = attrs.fixed_size[s] * 0.5f * ar;
-                                    float box_height_ratio = attrs.fixed_size[s] * 0.5f / ar;
-                                    for (int64_t r = 0; r < density_; ++r)
-                                    {
-                                        for (int64_t c = 0; c < density_; ++c)
-                                        {
-                                            float center_x_temp = center_x - fixed_size_ / 2 +
-                                                                  shift / 2.f + c * shift;
-                                            float center_y_temp = center_y - fixed_size_ / 2 +
-                                                                  shift / 2.f + r * shift;
-                                            calculate_data(center_x_temp,
-                                                           center_y_temp,
-                                                           box_width_ratio,
-                                                           box_height_ratio,
-                                                           true);
-                                        }
-                                    }
-                                }
-                            }
-                        }
-
-                        for (size_t ms_idx = 0; ms_idx < min_size.size(); ms_idx++)
-                        {
-                            box_width = min_size[ms_idx] * 0.5f;
-                            box_height = min_size[ms_idx] * 0.5f;
-                            calculate_data(center_x, center_y, box_width, box_height, false);
-
-                            if (attrs.max_size.size() > ms_idx)
-                            {
-                                box_width = box_height =
-                                    std::sqrt(min_size[ms_idx] * attrs.max_size[ms_idx]) * 0.5f;
-                                calculate_data(center_x, center_y, box_width, box_height, false);
-                            }
-
-                            if (attrs.scale_all_sizes ||
-                                (!attrs.scale_all_sizes && (ms_idx == min_size.size() - 1)))
-                            {
-                                size_t s_idx = attrs.scale_all_sizes ? ms_idx : 0;
-                                for (float ar : aspect_ratios)
-                                {
-                                    if (std::fabs(ar - 1.0f) < 1e-6)
-                                    {
-                                        continue;
-                                    }
-
-                                    ar = std::sqrt(ar);
-                                    box_width = min_size[s_idx] * 0.5f * ar;
-                                    box_height = min_size[s_idx] * 0.5f / ar;
-                                    calculate_data(
-                                        center_x, center_y, box_width, box_height, false);
-                                }
-                            }
-                        }
-                    }
-                }
-
-                if (attrs.clip)
-                {
-                    for (uint64_t i = 0; i < H * W * num_priors * 4; ++i)
-                    {
-                        dst_data[i] = (std::min)((std::max)(dst_data[i], 0.0f), 1.0f);
-                    }
-                }
-
-                uint64_t channel_size = OH * OW;
-                if (variance.size() == 1)
-                {
-                    for (uint64_t i = 0; i < channel_size; ++i)
-                    {
-                        dst_data[i + channel_size] = variance[0];
-                    }
-                }
-                else
-                {
-                    for (uint64_t i = 0; i < H * W * num_priors; ++i)
-                    {
-                        for (size_t j = 0; j < 4; ++j)
-                        {
-                            dst_data[i * 4 + j + channel_size] = variance[j];
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/prior_box_clustered.hpp b/ngraph/core/include/ngraph/runtime/reference/prior_box_clustered.hpp
deleted file mode 100644 (file)
index f6b76a6..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-//*****************************************************************************
-// Copyright 2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/axis_vector.hpp"
-#include "ngraph/check.hpp"
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/op/prior_box_clustered.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void prior_box_clustered(const T* data,
-                                     const T* img,
-                                     float* dst_data,
-                                     const Shape& out_shape,
-                                     const op::PriorBoxClusteredAttrs& attrs)
-            {
-                size_t num_priors_ = attrs.widths.size();
-
-                auto variances = attrs.variances;
-                if (variances.empty())
-                    variances.push_back(0.1f);
-
-                // Execute
-                const int64_t layer_width = data[1];
-                const int64_t layer_height = data[0];
-
-                int64_t img_width = img[1];
-                int64_t img_height = img[0];
-
-                // TODO: Uncomment after PriorBoxClustered is aligned with the specification.
-
-                //                int img_width = img_w_ == 0 ? img[1] : img_w_;
-                //                int img_height = img_h_ == 0 ? img[0] : img_h_;
-
-                //                float step_w = attrs.step_widths == 0 ? step_ : attrs.step_widths;
-                //                float step_h = attrs.step_heights == 0 ? step_ :
-                //                attrs.step_heights;
-
-                float step_w = attrs.step_widths;
-                float step_h = attrs.step_heights;
-
-                if (step_w == 0 && step_h == 0)
-                {
-                    step_w = static_cast<float>(img_width) / layer_width;
-                    step_h = static_cast<float>(img_height) / layer_height;
-                }
-
-                size_t var_size = variances.size();
-                for (int64_t h = 0; h < layer_height; ++h)
-                {
-                    for (int64_t w = 0; w < layer_width; ++w)
-                    {
-                        float center_x = (w + attrs.offset) * step_w;
-                        float center_y = (h + attrs.offset) * step_h;
-
-                        for (size_t s = 0; s < num_priors_; ++s)
-                        {
-                            float box_width = attrs.widths[s];
-                            float box_height = attrs.heights[s];
-
-                            float xmin = (center_x - box_width / 2.0f) / img_width;
-                            float ymin = (center_y - box_height / 2.0f) / img_height;
-                            float xmax = (center_x + box_width / 2.0f) / img_width;
-                            float ymax = (center_y + box_height / 2.0f) / img_height;
-
-                            if (attrs.clip)
-                            {
-                                xmin = (std::min)((std::max)(xmin, 0.0f), 1.0f);
-                                ymin = (std::min)((std::max)(ymin, 0.0f), 1.0f);
-                                xmax = (std::min)((std::max)(xmax, 0.0f), 1.0f);
-                                ymax = (std::min)((std::max)(ymax, 0.0f), 1.0f);
-                            }
-
-                            auto get_idx = [&](uint64_t cnt) -> uint64_t {
-                                return h * layer_width * num_priors_ * cnt + w * num_priors_ * cnt +
-                                       s * cnt;
-                            };
-
-                            uint64_t idx = get_idx(4);
-                            dst_data[idx + 0] = xmin;
-                            dst_data[idx + 1] = ymin;
-                            dst_data[idx + 2] = xmax;
-                            dst_data[idx + 3] = ymax;
-
-                            idx = get_idx(var_size);
-                            for (size_t j = 0; j < var_size; j++)
-                                dst_data[idx + j + out_shape[1]] = variances[j];
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/product.hpp b/ngraph/core/include/ngraph/runtime/reference/product.hpp
deleted file mode 100644 (file)
index 057424f..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void product(const T* arg,
-                         T* out,
-                         const Shape& in_shape,
-                         const AxisSet& reduction_axes,
-                         bool keep_dims)
-            {
-                auto out_shape = reduce(in_shape, reduction_axes, keep_dims);
-                CoordinateTransform output_transform(out_shape);
-
-                for (const Coordinate& output_coord : output_transform)
-                {
-                    out[output_transform.index(output_coord)] = 1;
-                }
-
-                CoordinateTransform input_transform(in_shape);
-
-                for (const Coordinate& input_coord : input_transform)
-                {
-                    Coordinate output_coord = reduce(input_coord, reduction_axes, keep_dims);
-
-                    size_t output_index = output_transform.index(output_coord);
-
-                    out[output_index] = out[output_index] * arg[input_transform.index(input_coord)];
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/quantize.hpp b/ngraph/core/include/ngraph/runtime/reference/quantize.hpp
deleted file mode 100644 (file)
index 99afe2e..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/op/quantize.hpp"
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename REAL, typename QUANT>
-            void quantize(const REAL* input,
-                          const REAL* scale,
-                          const QUANT* zero_point,
-                          QUANT* output,
-                          const Shape& input_shape,
-                          const Shape& scale_zero_point_shape,
-                          const AxisSet& axes,
-                          op::Quantize::RoundMode round_mode)
-            {
-                CoordinateTransform input_transform(input_shape);
-                CoordinateTransform scale_zero_point_transform(scale_zero_point_shape);
-
-                for (const Coordinate& input_coord : input_transform)
-                {
-                    Coordinate scale_zero_point_coord = project(input_coord, axes);
-
-                    // apply scale
-                    REAL qvalue = input[input_transform.index(input_coord)] /
-                                  scale[scale_zero_point_transform.index(scale_zero_point_coord)];
-
-                    // round
-                    if (round_mode == op::Quantize::RoundMode::ROUND_NEAREST_TOWARD_INFINITY)
-                    {
-                        REAL abs_qvalue = std::fabs(qvalue);
-                        REAL abs_qvalue_toward_inf =
-                            std::floor(abs_qvalue + static_cast<REAL>(0.5));
-                        qvalue = (qvalue < static_cast<REAL>(0.0)) ? -abs_qvalue_toward_inf
-                                                                   : abs_qvalue_toward_inf;
-                    }
-                    else if (round_mode == op::Quantize::RoundMode::ROUND_NEAREST_TOWARD_ZERO)
-                    {
-                        auto abs_qvalue = std::fabs(qvalue);
-                        auto abs_qvalue_toward_zero =
-                            std::ceil(abs_qvalue - static_cast<REAL>(0.5));
-                        qvalue = (qvalue < static_cast<REAL>(0.0)) ? -abs_qvalue_toward_zero
-                                                                   : abs_qvalue_toward_zero;
-                    }
-                    else if (round_mode == op::Quantize::RoundMode::ROUND_NEAREST_UPWARD)
-                    {
-                        qvalue = std::floor(qvalue + static_cast<REAL>(0.5));
-                    }
-                    else if (round_mode == op::Quantize::RoundMode::ROUND_NEAREST_DOWNWARD)
-                    {
-                        qvalue = std::ceil(qvalue - static_cast<REAL>(0.5));
-                    }
-                    else if (round_mode == op::Quantize::RoundMode::ROUND_NEAREST_TOWARD_EVEN)
-                    {
-                        auto up_qvalue = std::floor(qvalue + static_cast<REAL>(0.5));
-                        auto dn_qvalue = std::ceil(qvalue - static_cast<REAL>(0.5));
-                        auto rem = std::fmod(up_qvalue, 2.0);
-                        qvalue = (rem == 0.0) ? up_qvalue : dn_qvalue;
-                    }
-                    else if (round_mode == op::Quantize::RoundMode::ROUND_TOWARD_INFINITY)
-                    {
-                        auto abs_qvalue = std::fabs(qvalue);
-                        auto abs_qvalue_toward_inf = std::ceil(abs_qvalue);
-                        qvalue = (qvalue < static_cast<REAL>(0.0)) ? -abs_qvalue_toward_inf
-                                                                   : abs_qvalue_toward_inf;
-                    }
-                    else if (round_mode == op::Quantize::RoundMode::ROUND_TOWARD_ZERO)
-                    {
-                        auto abs_qvalue = std::fabs(qvalue);
-                        auto abs_qvalue_toward_zero = std::floor(abs_qvalue);
-                        qvalue = (qvalue < static_cast<REAL>(0.0)) ? -abs_qvalue_toward_zero
-                                                                   : abs_qvalue_toward_zero;
-                    }
-                    else if (round_mode == op::Quantize::RoundMode::ROUND_UP)
-                    {
-                        qvalue = std::ceil(qvalue);
-                    }
-                    else if (round_mode == op::Quantize::RoundMode::ROUND_DOWN)
-                    {
-                        qvalue = std::floor(qvalue);
-                    }
-
-                    // apply zero_point
-                    qvalue += zero_point[scale_zero_point_transform.index(scale_zero_point_coord)];
-
-                    // clamp
-                    qvalue = std::max<REAL>(qvalue,
-                                            static_cast<REAL>(std::numeric_limits<QUANT>::min()));
-                    qvalue = std::min<REAL>(qvalue,
-                                            static_cast<REAL>(std::numeric_limits<QUANT>::max()));
-
-                    // cast
-                    output[input_transform.index(input_coord)] = static_cast<QUANT>(qvalue);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/range.hpp b/ngraph/core/include/ngraph/runtime/reference/range.hpp
deleted file mode 100644 (file)
index 4897522..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <type_traits>
-
-#include "ngraph/axis_vector.hpp"
-#include "ngraph/check.hpp"
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/type/bfloat16.hpp"
-#include "ngraph/type/float16.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            // Return type is `void`, only enabled if `T` is a built-in FP
-            // type, or nGraph's `bfloat16` or `float16` type.
-            template <typename T>
-            typename std::enable_if<std::is_floating_point<T>::value ||
-                                    std::is_same<T, bfloat16>::value ||
-                                    std::is_same<T, float16>::value>::type
-                range(const T* start, const T* step, const Shape& out_shape, T* out)
-            {
-                for (size_t i = 0; i < shape_size(out_shape); i++)
-                {
-                    out[i] = *start + (static_cast<T>(i) * (*step));
-                }
-            }
-
-            // Return type is `void`, only enabled if `T` is `is_integral`.
-            template <typename T>
-            typename std::enable_if<std::is_integral<T>::value>::type
-                range(const T* start, const T* step, const Shape& out_shape, T* out)
-            {
-                T val = *start;
-
-                for (size_t i = 0; i < shape_size(out_shape); i++)
-                {
-                    out[i] = val;
-                    val += *step;
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/reduce_l1.hpp b/ngraph/core/include/ngraph/runtime/reference/reduce_l1.hpp
deleted file mode 100644 (file)
index 21bc8c5..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void reduce_l1(const T* arg,
-                           T* out,
-                           const Shape& in_shape,
-                           const AxisSet& reduction_axes,
-                           bool keep_dims)
-            {
-                auto out_shape = reduce(in_shape, reduction_axes, keep_dims);
-                CoordinateTransform output_transform(out_shape);
-
-                for (const Coordinate& output_coord : output_transform)
-                {
-                    out[output_transform.index(output_coord)] = 0;
-                }
-
-                CoordinateTransform input_transform(in_shape);
-
-                for (const Coordinate& input_coord : input_transform)
-                {
-                    Coordinate output_coord = reduce(input_coord, reduction_axes, keep_dims);
-
-                    size_t output_index = output_transform.index(output_coord);
-
-                    out[output_index] =
-                        out[output_index] + abs(arg[input_transform.index(input_coord)]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/reduce_l2.hpp b/ngraph/core/include/ngraph/runtime/reference/reduce_l2.hpp
deleted file mode 100644 (file)
index 2623a04..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void reduce_l2(const T* arg,
-                           T* out,
-                           const Shape& in_shape,
-                           const AxisSet& reduction_axes,
-                           bool keep_dims)
-            {
-                auto out_shape = reduce(in_shape, reduction_axes, keep_dims);
-                CoordinateTransform output_transform(out_shape);
-
-                for (const Coordinate& output_coord : output_transform)
-                {
-                    out[output_transform.index(output_coord)] = 0;
-                }
-
-                CoordinateTransform input_transform(in_shape);
-
-                for (const Coordinate& input_coord : input_transform)
-                {
-                    Coordinate output_coord = reduce(input_coord, reduction_axes, keep_dims);
-
-                    size_t output_index = output_transform.index(output_coord);
-
-                    out[output_index] = out[output_index] +
-                                        arg[input_transform.index(input_coord)] *
-                                            arg[input_transform.index(input_coord)];
-                }
-                for (const Coordinate& output_coord : output_transform)
-                {
-                    out[output_transform.index(output_coord)] =
-                        sqrt(out[output_transform.index(output_coord)]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/relu.hpp b/ngraph/core/include/ngraph/runtime/reference/relu.hpp
deleted file mode 100644 (file)
index 0fabf4b..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void relu(const T* arg, T* out, size_t count)
-            {
-                T zero = 0;
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg[i] > zero ? arg[i] : zero;
-                }
-            }
-            template <typename T>
-            void relu_backprop(const T* arg, const T* delta_arg, T* out, size_t count)
-            {
-                T zero = 0;
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg[i] > zero ? delta_arg[i] : zero;
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/replace_slice.hpp b/ngraph/core/include/ngraph/runtime/reference/replace_slice.hpp
deleted file mode 100644 (file)
index 6cf444f..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/check.hpp"
-#include "ngraph/coordinate_transform.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void replace_slice(const T* arg0, // replacement context
-                               const T* arg1, // replacement value
-                               T* out,
-                               const Shape& arg1_shape,
-                               const Coordinate& lower_bounds,
-                               const Coordinate& upper_bounds,
-                               const Strides& strides,
-                               const Shape& out_shape)
-            {
-                // Step 1: Copy the entire replacement context to the output.
-                CoordinateTransform copy_transform(out_shape);
-
-                for (Coordinate copy_coord : copy_transform)
-                {
-                    out[copy_transform.index(copy_coord)] = arg0[copy_transform.index(copy_coord)];
-                }
-
-                // Step 2: Overwrite the slice for replacement.
-                CoordinateTransform input_transform(arg1_shape);
-                CoordinateTransform output_transform(
-                    out_shape, lower_bounds, upper_bounds, strides);
-
-                NGRAPH_CHECK(shape_size(input_transform.get_target_shape()) ==
-                             shape_size(output_transform.get_target_shape()));
-
-                CoordinateTransform::Iterator output_it = output_transform.begin();
-
-                for (const Coordinate& input_coord : input_transform)
-                {
-                    const Coordinate& output_coord = *output_it;
-
-                    out[output_transform.index(output_coord)] =
-                        arg1[input_transform.index(input_coord)];
-
-                    ++output_it;
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/reshape.hpp b/ngraph/core/include/ngraph/runtime/reference/reshape.hpp
deleted file mode 100644 (file)
index e4711d6..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/axis_vector.hpp"
-#include "ngraph/check.hpp"
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/type/element_type.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            void reshape(const char* arg,
-                         char* out,
-                         const Shape& in_shape,
-                         const AxisVector& in_axis_order,
-                         const Shape& out_shape,
-                         size_t elem_size);
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/result.hpp b/ngraph/core/include/ngraph/runtime/reference/result.hpp
deleted file mode 100644 (file)
index a6081bd..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <algorithm>
-#include <cmath>
-#include <numeric>
-#include <vector>
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void result(const T* arg, T* out, size_t count)
-            {
-                memcpy(out, arg, sizeof(T) * count);
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/reverse.hpp b/ngraph/core/include/ngraph/runtime/reference/reverse.hpp
deleted file mode 100644 (file)
index ac41124..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/coordinate_transform.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            NGRAPH_API
-            void reverse(const char* arg,
-                         char* out,
-                         const Shape& arg_shape,
-                         const Shape& out_shape,
-                         const AxisSet& reversed_axes,
-                         size_t elem_size);
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/reverse_sequence.hpp b/ngraph/core/include/ngraph/runtime/reference/reverse_sequence.hpp
deleted file mode 100644 (file)
index 15f6398..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <numeric>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T, typename U>
-            void reverse_sequence(const T* arg,
-                                  T* out,
-                                  const Shape& arg_shape,
-                                  size_t batch_axis,
-                                  size_t sequence_axis,
-                                  const U* sequence_lengths)
-            {
-                CoordinateTransform input_transform(arg_shape);
-                for (const Coordinate& in_coord : input_transform)
-                {
-                    size_t batch_index = in_coord[batch_axis];
-                    auto orig_seq_index = static_cast<size_t>(sequence_lengths[batch_index]);
-
-                    if (orig_seq_index > arg_shape.at(sequence_axis))
-                    {
-                        throw ngraph_error(
-                            "One of the elements of sequence lengths is greater than sequence axis "
-                            "dimension");
-                    }
-
-                    if (orig_seq_index == 0)
-                    {
-                        orig_seq_index = 1;
-                    }
-
-                    size_t sequence_index = in_coord[sequence_axis] < orig_seq_index
-                                                ? orig_seq_index - in_coord[sequence_axis] - 1
-                                                : in_coord[sequence_axis];
-
-                    // make a copy of in_coord and update sequence_index
-                    Coordinate out_coord = in_coord;
-                    out_coord[sequence_axis] = sequence_index;
-                    out[input_transform.index(out_coord)] = arg[input_transform.index(in_coord)];
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/round.hpp b/ngraph/core/include/ngraph/runtime/reference/round.hpp
deleted file mode 100644 (file)
index 50949ab..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            T round_to_nearest_even(const T arg)
-            {
-                const auto floor_arg = std::floor(arg);
-                const auto diff = arg - floor_arg;
-                if (diff < 0.5f || (diff == 0.5f && static_cast<int>(floor_arg) % 2 == 0))
-                {
-                    return floor_arg;
-                }
-                else
-                {
-                    return floor_arg + 1.0f;
-                }
-            }
-
-            template <typename T>
-            void round(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; ++i)
-                {
-                    out[i] = round_to_nearest_even(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/scatter_elements_update.hpp b/ngraph/core/include/ngraph/runtime/reference/scatter_elements_update.hpp
deleted file mode 100644 (file)
index c0f239d..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstring>
-
-#include "ngraph/check.hpp"
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename DataType, typename IndicesType>
-            void scatter_elem_update(const DataType* input_data,
-                                     const IndicesType* indices,
-                                     const DataType* updates,
-                                     const int64_t& axis,
-                                     DataType* out_buf,
-                                     const Shape& data_shape,
-                                     const Shape& indices_shape)
-            {
-                // Copy inputs to out
-                std::memcpy(out_buf, input_data, sizeof(DataType) * shape_size(data_shape));
-
-                // 3D example
-                // output[indices[i][j][k]][j][k] = updates[i][j][k] if axis = 0,
-                // output[i][indices[i][j][k]][k] = updates[i][j][k] if axis = 1,
-                // output[i][j][indices[i][j][k]] = updates[i][j][k] if axis = 2
-
-                CoordinateTransform indices_transform{indices_shape};
-                CoordinateTransform data_transform{data_shape};
-
-                for (const Coordinate& indices_cord : indices_transform)
-                {
-                    const size_t indices_idx = indices_transform.index(indices_cord);
-                    Coordinate out_cord(indices_cord);
-                    out_cord.at(axis) = indices[indices_idx];
-                    NGRAPH_CHECK(data_transform.has_source_coordinate(out_cord),
-                                 "Provided index coordinates are out of input data bounds: ",
-                                 out_cord,
-                                 ".");
-                    out_buf[data_transform.index(out_cord)] = updates[indices_idx];
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/select.hpp b/ngraph/core/include/ngraph/runtime/reference/select.hpp
deleted file mode 100644 (file)
index 3f6da66..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-#include <iostream>
-
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void select(const char* arg0,
-                        const T* arg1,
-                        const T* arg2,
-                        T* out,
-                        size_t count) // TODO: using char for bool, is this right?
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg0[i] ? arg1[i] : arg2[i];
-                }
-            }
-
-            template <typename T>
-            void select(const char* arg0,
-                        const T* arg1,
-                        const T* arg2,
-                        T* out,
-                        const Shape& arg0_shape,
-                        const Shape& arg1_shape,
-                        const Shape& arg2_shape,
-                        const op::AutoBroadcastSpec& broadcast_spec)
-            {
-                autobroadcast_select(
-                    arg0,
-                    arg1,
-                    arg2,
-                    out,
-                    arg0_shape,
-                    arg1_shape,
-                    arg2_shape,
-                    broadcast_spec,
-                    [](char s, T x, T y) -> T { return static_cast<T>(s ? x : y); });
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/shape_of.hpp b/ngraph/core/include/ngraph/runtime/reference/shape_of.hpp
deleted file mode 100644 (file)
index 57621af..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            inline void shape_of(const Shape& arg_shape, T* out)
-            {
-                for (size_t i = 0; i < arg_shape.size(); i++)
-                {
-                    out[i] = static_cast<T>(arg_shape[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/sigmoid.hpp b/ngraph/core/include/ngraph/runtime/reference/sigmoid.hpp
deleted file mode 100644 (file)
index 5c10b5f..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void sigmoid(const T* arg, T* out, size_t count)
-            {
-                T exp_value;
-                for (size_t i = 0; i < count; i++)
-                {
-                    exp_value = std::exp(-arg[i]);
-                    out[i] = 1 / (1 + exp_value);
-                }
-            }
-
-            template <typename T>
-            void sigmoid_backprop(const T* arg, const T* delta_arg, T* out, size_t count)
-            {
-                T exp_value;
-                T func_x;
-                for (size_t i = 0; i < count; i++)
-                {
-                    exp_value = std::exp(-arg[i]);
-                    func_x = 1 / (1 + exp_value);
-                    out[i] = delta_arg[i] * func_x * (1 - func_x);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/sign.hpp b/ngraph/core/include/ngraph/runtime/reference/sign.hpp
deleted file mode 100644 (file)
index 72bcdd4..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void sign(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = (arg[i] < T(0) ? T(-1) : (arg[i] > T(0) ? T(1) : T(0)));
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/sin.hpp b/ngraph/core/include/ngraph/runtime/reference/sin.hpp
deleted file mode 100644 (file)
index d7935ff..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void sin(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::sin(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/sinh.hpp b/ngraph/core/include/ngraph/runtime/reference/sinh.hpp
deleted file mode 100644 (file)
index 1515aa6..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void sinh(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::sinh(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/slice.hpp b/ngraph/core/include/ngraph/runtime/reference/slice.hpp
deleted file mode 100644 (file)
index f59ec7c..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/type/element_type.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            void slice(const char* arg,
-                       char* out,
-                       const Shape& arg_shape,
-                       const Coordinate& lower_bounds,
-                       const Coordinate& upper_bounds,
-                       const Strides& strides,
-                       const Shape& out_shape,
-                       size_t elem_size);
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/softmax.hpp b/ngraph/core/include/ngraph/runtime/reference/softmax.hpp
deleted file mode 100644 (file)
index 9c83a56..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/runtime/reference/max.hpp"
-#include "ngraph/runtime/reference/sum.hpp"
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void softmax(const T* arg, T* out, const Shape& shape, const AxisSet& axes)
-            {
-                auto temp_shape = reduce(shape, axes, true);
-                auto temp_elements = shape_size(temp_shape);
-                auto temp_ptr = new T[temp_elements];
-
-                max(arg, temp_ptr, shape, axes, true);
-
-                CoordinateTransform transform(shape);
-                CoordinateTransform temp_transform(temp_shape);
-                for (const Coordinate& coord : transform)
-                {
-                    Coordinate temp_coord = reduce(coord, axes, true);
-                    out[transform.index(coord)] = std::exp(
-                        arg[transform.index(coord)] - temp_ptr[temp_transform.index(temp_coord)]);
-                }
-
-                sum(out, temp_ptr, shape, axes, true);
-
-                for (const Coordinate& coord : transform)
-                {
-                    Coordinate temp_coord = reduce(coord, axes, true);
-                    out[transform.index(coord)] /= temp_ptr[temp_transform.index(temp_coord)];
-                }
-
-                delete[] temp_ptr;
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/sqrt.hpp b/ngraph/core/include/ngraph/runtime/reference/sqrt.hpp
deleted file mode 100644 (file)
index 4661f65..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void sqrt(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::sqrt(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/strided_slice.hpp b/ngraph/core/include/ngraph/runtime/reference/strided_slice.hpp
deleted file mode 100644 (file)
index 3c606a7..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/check.hpp"
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/runtime/host_tensor.hpp"
-#include "ngraph/runtime/opt_kernel/reshape.hpp"
-#include "ngraph/runtime/reference/reverse.hpp"
-#include "ngraph/runtime/reference/slice.hpp"
-#include "ngraph/slice_plan.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            void strided_slice(const char* arg,
-                               char* out,
-                               const Shape& arg_shape,
-                               const SlicePlan& sp,
-                               size_t elem_type);
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/subtract.hpp b/ngraph/core/include/ngraph/runtime/reference/subtract.hpp
deleted file mode 100644 (file)
index bc3b63f..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-#include "ngraph/op/util/attr_types.hpp"
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void subtract(const T* arg0, const T* arg1, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg0[i] - arg1[i];
-                }
-            }
-
-            template <typename T>
-            void subtract(const T* arg0,
-                          const T* arg1,
-                          T* out,
-                          const Shape& arg0_shape,
-                          const Shape& arg1_shape,
-                          const op::AutoBroadcastSpec& broadcast_spec)
-            {
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
-                        return x - y;
-                    });
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/sum.hpp b/ngraph/core/include/ngraph/runtime/reference/sum.hpp
deleted file mode 100644 (file)
index a67cbac..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/shape_util.hpp"
-#include "ngraph/type/bfloat16.hpp"
-#include "ngraph/type/float16.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            // Windows doesn't seem to like it if we directly use std::isfinite on integer types,
-            // so we will roll our own thing here.
-            template <typename T>
-            typename std::enable_if<std::is_floating_point<T>::value, bool>::type is_finite(T x)
-            {
-                return std::isfinite(x);
-            }
-
-            template <typename T>
-            typename std::enable_if<std::is_same<T, bfloat16>::value ||
-                                        std::is_same<T, float16>::value,
-                                    bool>::type
-                is_finite(T x)
-            {
-                return std::isfinite(static_cast<float>(x));
-            }
-
-            template <typename T>
-            typename std::enable_if<std::is_integral<T>::value, bool>::type is_finite(T /* x */)
-            {
-                return true;
-            }
-
-            template <typename T>
-            void sum(const T* arg,
-                     T* out,
-                     const Shape& in_shape,
-                     const AxisSet& reduction_axes,
-                     bool keep_dims)
-            {
-                auto out_shape = reduce(in_shape, reduction_axes, keep_dims);
-                CoordinateTransform output_transform(out_shape);
-                std::vector<T> cs(shape_size(out_shape));
-
-                for (const Coordinate& output_coord : output_transform)
-                {
-                    out[output_transform.index(output_coord)] = 0;
-                    cs[output_transform.index(output_coord)] = 0;
-                }
-
-                CoordinateTransform input_transform(in_shape);
-
-                for (const Coordinate& input_coord : input_transform)
-                {
-                    Coordinate output_coord = reduce(input_coord, reduction_axes, keep_dims);
-
-                    T x = arg[input_transform.index(input_coord)];
-                    T& z = out[output_transform.index(output_coord)];
-
-                    if (is_finite(x) && is_finite(z))
-                    {
-                        T& c = cs[output_transform.index(output_coord)];
-                        T t = z + (x - c);
-                        c = (t - z) - (x - c);
-                        z = t;
-                    }
-                    else
-                    {
-                        z = z + x;
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/swish.hpp b/ngraph/core/include/ngraph/runtime/reference/swish.hpp
deleted file mode 100644 (file)
index 14bb42e..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void swish(const T* arg, const T* beta, T* out, size_t count)
-            {
-                T beta_value = static_cast<T>(1.0);
-                if (beta != nullptr)
-                {
-                    beta_value = beta[0];
-                }
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = arg[i] / (1.0 + std::exp(-arg[i] * beta_value));
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/tan.hpp b/ngraph/core/include/ngraph/runtime/reference/tan.hpp
deleted file mode 100644 (file)
index 49e1dbb..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void tan(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::tan(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/tanh.hpp b/ngraph/core/include/ngraph/runtime/reference/tanh.hpp
deleted file mode 100644 (file)
index 9c71c9c..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-#include <cstddef>
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void tanh(const T* arg, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = std::tanh(arg[i]);
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/tile.hpp b/ngraph/core/include/ngraph/runtime/reference/tile.hpp
deleted file mode 100644 (file)
index 53d25ee..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cmath>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/type/element_type.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            void tile(const char* arg,
-                      char* out,
-                      const Shape& in_shape,
-                      const Shape& out_shape,
-                      size_t elem_size);
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/topk.hpp b/ngraph/core/include/ngraph/runtime/reference/topk.hpp
deleted file mode 100644 (file)
index cb5c5bf..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <algorithm>
-#include <cmath>
-#include <numeric>
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/op/topk.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            // Had to split out these two functions. They used to be lambda expressions but
-            // MSVC had difficulty compiling. This way is more explicit.
-            template <typename T, typename U>
-            inline bool compare_max(const std::tuple<T, U>& a, const std::tuple<T, U>& b)
-            {
-// this is intentional to be able to compare floats directly
-// without using relative or absolute tolerance
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wfloat-equal"
-#endif
-                if (std::get<0>(a) == std::get<0>(b))
-                {
-                    return std::get<1>(a) < std::get<1>(b);
-                }
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
-                return a > b;
-            }
-
-            template <typename T, typename U>
-            inline bool compare_min(const std::tuple<T, U>& a, const std::tuple<T, U>& b)
-            {
-                return a < b;
-            }
-
-            template <typename T, typename U>
-            inline bool sort_indices_descending(const std::tuple<T, U>& a,
-                                                const std::tuple<T, U>& b)
-            {
-                return std::get<1>(a) < std::get<1>(b);
-            }
-
-            template <typename T, typename U>
-            inline bool sort_indices_ascending(const std::tuple<T, U>& a, const std::tuple<T, U>& b)
-            {
-                return std::get<1>(a) > std::get<1>(b);
-            }
-
-            template <typename T, typename U>
-            void topk(const T* arg,
-                      U* out_indices,
-                      T* out_values,
-                      const Shape& in_shape,
-                      const Shape& out_shape,
-                      size_t axis,
-                      size_t k,
-                      bool compute_max,
-                      op::TopK::SortType sort = op::TopK::SortType::NONE)
-            {
-                using namespace std;
-                // reorder source axis visit order and make "axis" inner most
-                size_t ndim = static_cast<size_t>(in_shape.size());
-                Coordinate start_corner(ndim, 0);
-                Coordinate end_corner(in_shape);
-                end_corner[axis] = 1;
-                Strides strides(ndim, 1);
-                AxisVector axis_order(ndim);
-                iota(axis_order.begin(), axis_order.end(), 0);
-                axis_order.erase(axis_order.begin() + axis);
-                axis_order.push_back(axis);
-                // Create CoordinateTransforms that visits only the first element along "axis"
-                CoordinateTransform input_transform(
-                    in_shape, start_corner, end_corner, strides, axis_order);
-                CoordinateTransform output_transform(
-                    out_shape, start_corner, end_corner, strides, axis_order);
-                // Create temp vector for sorting.
-                vector<tuple<T, U>> workspace(in_shape[axis]);
-                vector<size_t> in_strides = ngraph::row_major_strides(in_shape);
-                vector<size_t> out_strides = ngraph::row_major_strides(out_shape);
-                auto in_axis_stride = in_strides[axis];
-                auto out_axis_stride = out_strides[axis];
-                for (const Coordinate& coord : input_transform)
-                {
-                    auto arg_index = input_transform.index(coord);
-                    auto out_index = output_transform.index(coord);
-                    // Fill the temp vector
-                    U i = 0;
-                    for (tuple<T, U>& entry : workspace)
-                    {
-                        get<0>(entry) = arg[arg_index];
-                        get<1>(entry) = i;
-                        arg_index += in_axis_stride;
-                        i++;
-                    }
-                    // Sort the temp vector
-                    if (compute_max)
-                    {
-                        nth_element(workspace.begin(),
-                                    workspace.begin() + k,
-                                    workspace.end(),
-                                    compare_max<T, U>);
-                    }
-                    else
-                    {
-                        nth_element(workspace.begin(),
-                                    workspace.begin() + k,
-                                    workspace.end(),
-                                    compare_min<T, U>);
-                    }
-                    // Write temp vector to output
-                    if (compute_max)
-                    {
-                        switch (sort)
-                        {
-                        case op::TopK::SortType::NONE: break;
-                        case op::TopK::SortType::SORT_INDICES:
-                            std::sort(workspace.begin(),
-                                      workspace.begin() + k,
-                                      sort_indices_descending<T, U>);
-                            break;
-                        case op::TopK::SortType::SORT_VALUES:
-                            std::sort(workspace.begin(), workspace.begin() + k, compare_max<T, U>);
-                            break;
-                        }
-                    }
-                    else
-                    {
-                        switch (sort)
-                        {
-                        case op::TopK::SortType::NONE: break;
-                        case op::TopK::SortType::SORT_INDICES:
-                            std::sort(workspace.begin(),
-                                      workspace.begin() + k,
-                                      sort_indices_ascending<T, U>);
-                            break;
-                        case op::TopK::SortType::SORT_VALUES:
-                            std::sort(workspace.begin(), workspace.begin() + k, compare_min<T, U>);
-                            break;
-                        }
-                    }
-                    for (size_t j = 0; j < k; j++)
-                    {
-                        tuple<T, U> entry = workspace[j];
-                        out_values[out_index] = get<0>(entry);
-                        out_indices[out_index] = get<1>(entry);
-                        out_index += out_axis_stride;
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/include/ngraph/runtime/reference/xor.hpp b/ngraph/core/include/ngraph/runtime/reference/xor.hpp
deleted file mode 100644 (file)
index 87e7e1f..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#pragma once
-
-#include <cstddef>
-
-#include "ngraph/op/util/attr_types.hpp"
-#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T>
-            void logical_xor(const T* arg0, const T* arg1, T* out, size_t count)
-            {
-                for (size_t i = 0; i < count; i++)
-                {
-                    out[i] = static_cast<T>((arg0[i] || arg1[i]) && !(arg0[i] && arg1[i]));
-                }
-            }
-
-            template <typename T>
-            void logical_xor(const T* arg0,
-                             const T* arg1,
-                             T* out,
-                             const Shape& arg0_shape,
-                             const Shape& arg1_shape,
-                             const op::AutoBroadcastSpec& broadcast_spec)
-            {
-                autobroadcast_binop(
-                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
-                        return static_cast<T>((x || y) && !(x && y));
-                    });
-            }
-        }
-    }
-}
diff --git a/ngraph/core/reference/CMakeLists.txt b/ngraph/core/reference/CMakeLists.txt
new file mode 100644 (file)
index 0000000..7e48ce6
--- /dev/null
@@ -0,0 +1,43 @@
+# ******************************************************************************
+# Copyright 2017-2020 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ******************************************************************************
+
+set(TARGET_NAME "ngraph_reference")
+
+file(GLOB_RECURSE LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
+file(GLOB_RECURSE PUBLIC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp)
+
+set(REF_IMPL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include/ CACHE INTERNAL "")
+
+# Create named folders for the sources within the .vcproj
+# Empty name lists them directly under the .vcproj
+
+source_group("src" FILES ${LIBRARY_SRC})
+source_group("include" FILES ${PUBLIC_HEADERS})
+
+# Create shared library
+add_library(${TARGET_NAME} STATIC ${LIBRARY_SRC} ${PUBLIC_HEADERS})
+
+# Defines macro in C++ to load backend plugin
+target_include_directories(${TARGET_NAME} PUBLIC ${REF_IMPL_INCLUDE_DIR})
+target_include_directories(${TARGET_NAME} PRIVATE ${NGRAPH_INCLUDE_PATH}
+                                                  ${REF_IMPL_INCLUDE_DIR}/ngraph)
+
+#Add an alias so that library can be used inside the build tree, e.g. when testing
+add_library(ngraph::reference ALIAS ${TARGET_NAME})
+
+# developer package
+
+openvino_developer_export_targets(ngraph::reference)
diff --git a/ngraph/core/reference/include/ngraph/coordinate_transform.hpp b/ngraph/core/reference/include/ngraph/coordinate_transform.hpp
new file mode 100644 (file)
index 0000000..ac67085
--- /dev/null
@@ -0,0 +1,179 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include "ngraph/axis_vector.hpp"
+#include "ngraph/coordinate.hpp"
+#include "ngraph/coordinate_diff.hpp"
+#include "ngraph/shape.hpp"
+#include "ngraph/strides.hpp"
+
+namespace ngraph
+{
+    /// \brief A useful class that allows to iterate over the tensor coordinates.
+    ///        For example, for tensor with dimensions {2, 3} this iterator
+    ///        produces the following coordinates:
+    ///             {0,0}, {0,1}, {0,2},
+    ///             {1,0}, {1,1}, {2,2}
+    class NGRAPH_API CoordinateIterator
+    {
+    public:
+        /// \brief Coordinates iterator constructor
+        /// \param target_shape The target shape for coordinates iteration
+        /// \param is_end The flag indicates that the coordinate iterator is the last.
+        CoordinateIterator(const Shape& target_shape, bool is_end = false);
+
+        /// \brief The postfix operation increment the iterator by one.
+        void operator++();
+
+        /// \brief The prefix operation increment the iterator by one.
+        CoordinateIterator operator++(int);
+
+        /// \brief Increments iterator n times.
+        /// \param n number of elements it should be advanced
+        void operator+=(size_t n);
+
+        /// \brief Iterator dereferencing operator returns reference to current pointed coordinate.
+        const Coordinate& operator*() const noexcept;
+
+        /// \brief Checks for iterator inequality.
+        /// \param it second iterator to compare
+        bool operator!=(const CoordinateIterator& it) const noexcept;
+
+        /// \brief Checks for iterator equality.
+        /// \param it second iterator to compare
+        bool operator==(const CoordinateIterator& it) const noexcept;
+
+        /// \brief Increments iterator using specified axis of the shape n times.
+        /// \param axis index used for iteration
+        size_t advance(size_t axis) noexcept;
+
+        /// \brief Useful function to build the last iterator.
+        ///        Returns a singleton that points to the last iterator.
+        static const CoordinateIterator& end();
+
+    private:
+        const Shape& m_target_shape;
+        Coordinate m_coordinate;
+        bool m_oob;
+    };
+
+    /// \brief Class which allows to calculate item index with given coordinates in tensor
+    ///        and helps to iterate over all coordinates.
+    ///        Tensor items should be placed in memory in row-major order.
+    class NGRAPH_API CoordinateTransformBasic
+    {
+    public:
+        using Iterator = CoordinateIterator;
+
+        CoordinateTransformBasic(const Shape& source_shape);
+
+        /// \brief The tensor element index calculation by given coordinate.
+        /// \param c tensor element coordinate
+        size_t index(const Coordinate& c) const noexcept;
+
+        /// \brief Returns an iterator to the first coordinate of the tensor.
+        CoordinateIterator begin() const noexcept;
+
+        /// \brief Returns an iterator to the coordinate following the last element of the tensor.
+        const CoordinateIterator& end() const noexcept;
+
+    protected:
+        Shape m_source_shape;
+    };
+
+    /// \brief Class which allows to calculate item index with given coordinates in tensor
+    ///        and helps to iterate over the subset of coordinates.
+    ///        Tensor items should be placed in memory in row-major order.
+    class NGRAPH_API CoordinateTransform : protected CoordinateTransformBasic
+    {
+    public:
+        using Iterator = CoordinateIterator;
+
+        CoordinateTransform(const Shape& source_shape,
+                            const Coordinate& source_start_corner,
+                            const Coordinate& source_end_corner,
+                            const Strides& source_strides,
+                            const AxisVector& source_axis_order,
+                            const CoordinateDiff& target_padding_below,
+                            const CoordinateDiff& target_padding_above,
+                            const Strides& source_dilation_strides);
+
+        CoordinateTransform(const Shape& source_shape,
+                            const Coordinate& source_start_corner,
+                            const Coordinate& source_end_corner,
+                            const Strides& source_strides,
+                            const AxisVector& source_axis_order,
+                            const CoordinateDiff& target_padding_below,
+                            const CoordinateDiff& target_padding_above);
+
+        CoordinateTransform(const Shape& source_shape,
+                            const Coordinate& source_start_corner,
+                            const Coordinate& source_end_corner,
+                            const Strides& source_strides,
+                            const AxisVector& source_axis_order);
+
+        CoordinateTransform(const Shape& source_shape,
+                            const Coordinate& source_start_corner,
+                            const Coordinate& source_end_corner,
+                            const Strides& source_strides);
+
+        CoordinateTransform(const Shape& source_shape,
+                            const Coordinate& source_start_corner,
+                            const Coordinate& source_end_corner);
+
+        CoordinateTransform(const Shape& source_shape);
+
+        /// \brief The tensor element index calculation by given coordinate.
+        /// \param c tensor element coordinate
+        size_t index(const Coordinate& c) const;
+
+        /// \brief Checks that coordinate belongs to given coordinates subset.
+        /// \param c tensor element coordinate
+        bool has_source_coordinate(const Coordinate& c) const;
+
+        /// \brief Convert a target-space coordinate to a source-space coordinate.
+        /// \param c tensor element coordinate
+        Coordinate to_source_coordinate(const Coordinate& c) const;
+
+        const Shape& get_source_shape() const noexcept;
+        const Shape& get_target_shape() const noexcept;
+        const Coordinate& get_source_start_corner() const noexcept;
+        const Coordinate& get_source_end_corner() const noexcept;
+        const Strides& get_source_strides() const noexcept;
+        const AxisVector& get_source_axis_order() const noexcept;
+        const Strides& get_target_dilation_strides() const noexcept;
+
+        /// \brief Returns an iterator to the first coordinate of the tensor.
+        CoordinateIterator begin() const noexcept;
+
+        /// \brief Returns an iterator to the coordinate following the last element of the tensor.
+        const CoordinateIterator& end() const noexcept;
+
+    private:
+        Coordinate m_source_start_corner;
+        Coordinate m_source_end_corner;
+        Strides m_source_strides;
+        AxisVector m_source_axis_order;
+        CoordinateDiff m_target_padding_below;
+        CoordinateDiff m_target_padding_above;
+        Strides m_target_dilation_strides;
+
+        Shape m_target_shape;
+        size_t m_n_axes;
+    };
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/opt_kernel/broadcast.hpp b/ngraph/core/reference/include/ngraph/runtime/opt_kernel/broadcast.hpp
new file mode 100644 (file)
index 0000000..7380a6c
--- /dev/null
@@ -0,0 +1,218 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <utility>
+
+#include "ngraph/runtime/reference/broadcast.hpp"
+#include "ngraph/shape_util.hpp"
+#include "ngraph/util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace opt_kernel
+        {
+            template <typename T>
+            void broadcast_2d(
+                const T* in, T* out, const Shape& in_shape, const Shape& out_shape, size_t out_axis)
+            {
+                size_t index[2];
+                size_t& in_index = index[out_axis];
+                auto out_strides = row_major_strides(out_shape);
+                for (index[0] = 0; index[0] < out_shape[0]; ++index[0])
+                {
+                    for (index[1] = 0; index[1] < out_shape[1]; ++index[1])
+                    {
+                        // clang-format off
+                        out[index[0] * out_strides[0] +
+                            index[1]] =
+                                in[in_index];
+                        // clang-format on
+                    }
+                }
+            }
+
+            // #define PARALLEL
+            template <typename T>
+            void broadcast_3d(
+                const T* in, T* out, const Shape& in_shape, const Shape& out_shape, size_t out_axis)
+            {
+                size_t index[3];
+                size_t& in_index = index[out_axis];
+                auto out_strides = row_major_strides(out_shape);
+                for (index[0] = 0; index[0] < out_shape[0]; ++index[0])
+                {
+                    for (index[1] = 0; index[1] < out_shape[1]; ++index[1])
+                    {
+                        for (index[2] = 0; index[2] < out_shape[2]; ++index[2])
+                        {
+                            // clang-format off
+                            out[index[0] * out_strides[0] +
+                                index[1] * out_strides[1] +
+                                index[2]] =
+                                    in[in_index];
+                            // clang-format on
+                        }
+                    }
+                }
+            }
+
+            template <typename T>
+            void broadcast_4d(
+                const T* in, T* out, const Shape& in_shape, const Shape& out_shape, size_t out_axis)
+            {
+                size_t index[4];
+                size_t& in_index = index[out_axis];
+                auto out_strides = row_major_strides(out_shape);
+                for (index[0] = 0; index[0] < out_shape[0]; ++index[0])
+                {
+                    for (index[1] = 0; index[1] < out_shape[1]; ++index[1])
+                    {
+                        for (index[2] = 0; index[2] < out_shape[2]; ++index[2])
+                        {
+                            for (index[3] = 0; index[3] < out_shape[3]; ++index[3])
+                            {
+                                // clang-format off
+                                out[index[0] * out_strides[0] +
+                                    index[1] * out_strides[1] +
+                                    index[2] * out_strides[2] +
+                                    index[3]] =
+                                        in[in_index];
+                                // clang-format on
+                            }
+                        }
+                    }
+                }
+            }
+
+            template <typename T>
+            void broadcast_5d(
+                const T* in, T* out, const Shape& in_shape, const Shape& out_shape, size_t out_axis)
+            {
+                size_t index[5];
+                size_t& in_index = index[out_axis];
+                auto out_strides = row_major_strides(out_shape);
+                for (index[0] = 0; index[0] < out_shape[0]; ++index[0])
+                {
+                    for (index[1] = 0; index[1] < out_shape[1]; ++index[1])
+                    {
+                        for (index[2] = 0; index[2] < out_shape[2]; ++index[2])
+                        {
+                            for (index[3] = 0; index[3] < out_shape[3]; ++index[3])
+                            {
+                                for (index[4] = 0; index[4] < out_shape[4]; ++index[4])
+                                {
+                                    // clang-format off
+                                    out[index[0] * out_strides[0] +
+                                        index[1] * out_strides[1] +
+                                        index[2] * out_strides[2] +
+                                        index[3] * out_strides[3] +
+                                        index[4]] =
+                                            in[in_index];
+                                    // clang-format on
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            template <typename T>
+            void broadcast_6d(
+                const T* in, T* out, const Shape& in_shape, const Shape& out_shape, size_t out_axis)
+            {
+                size_t index[6];
+                size_t& in_index = index[out_axis];
+                auto out_strides = row_major_strides(out_shape);
+                for (index[0] = 0; index[0] < out_shape[0]; ++index[0])
+                {
+                    for (index[1] = 0; index[1] < out_shape[1]; ++index[1])
+                    {
+                        for (index[2] = 0; index[2] < out_shape[2]; ++index[2])
+                        {
+                            for (index[3] = 0; index[3] < out_shape[3]; ++index[3])
+                            {
+                                for (index[4] = 0; index[4] < out_shape[4]; ++index[4])
+                                {
+                                    for (index[5] = 0; index[5] < out_shape[5]; ++index[5])
+                                    {
+                                        // clang-format off
+                                        out[index[0] * out_strides[0] +
+                                            index[1] * out_strides[1] +
+                                            index[2] * out_strides[2] +
+                                            index[3] * out_strides[3] +
+                                            index[4] * out_strides[4] +
+                                            index[5]] =
+                                                in[in_index];
+                                        // clang-format on
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            template <typename T>
+            void broadcast(const T* in,
+                           T* out,
+                           const Shape& in_shape,
+                           const Shape& out_shape,
+                           const AxisSet& broadcast_axes)
+            {
+                if (is_scalar(in_shape))
+                {
+                    for (size_t i = 0; i < shape_size(out_shape); ++i)
+                    {
+                        out[i] = in[0];
+                    }
+                }
+                else if (in_shape.size() == 1)
+                {
+                    size_t output_axis = 0;
+                    for (size_t i = 0; i < out_shape.size(); i++)
+                    {
+                        if (broadcast_axes.count(i) == 0)
+                        {
+                            output_axis = i;
+                            break;
+                        }
+                    }
+                    switch (out_shape.size())
+                    {
+                    case 2: broadcast_2d<T>(in, out, in_shape, out_shape, output_axis); break;
+                    case 3: broadcast_3d<T>(in, out, in_shape, out_shape, output_axis); break;
+                    case 4: broadcast_4d<T>(in, out, in_shape, out_shape, output_axis); break;
+                    case 5: broadcast_5d<T>(in, out, in_shape, out_shape, output_axis); break;
+                    case 6: broadcast_6d<T>(in, out, in_shape, out_shape, output_axis); break;
+                    default:
+                        runtime::reference::broadcast<T>(
+                            in, out, in_shape, out_shape, broadcast_axes);
+                        break;
+                    }
+                }
+                else
+                {
+                    runtime::reference::broadcast<T>(in, out, in_shape, out_shape, broadcast_axes);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/opt_kernel/reshape.hpp b/ngraph/core/reference/include/ngraph/runtime/opt_kernel/reshape.hpp
new file mode 100644 (file)
index 0000000..948ec9d
--- /dev/null
@@ -0,0 +1,37 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include "ngraph/axis_vector.hpp"
+#include "ngraph/runtime/reference/reshape.hpp"
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace opt_kernel
+        {
+            void reshape(const char* in,
+                         char* out,
+                         const Shape& in_shape,
+                         const AxisVector& in_axis_order,
+                         const Shape& out_shape,
+                         size_t elem_size);
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/abs.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/abs.hpp
new file mode 100644 (file)
index 0000000..6ac8d0f
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void abs(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    // TODO: generic "abs" doesn't work here for some reason.
+                    out[i] = (arg[i] < T(0) ? T(-arg[i]) : arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/acos.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/acos.hpp
new file mode 100644 (file)
index 0000000..7988006
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void acos(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::acos(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/acosh.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/acosh.hpp
new file mode 100644 (file)
index 0000000..817ada4
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void acosh(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::acosh(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/add.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/add.hpp
new file mode 100644 (file)
index 0000000..56de3fe
--- /dev/null
@@ -0,0 +1,54 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void add(const T* arg0, const T* arg1, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg0[i] + arg1[i];
+                }
+            }
+
+            template <typename T>
+            void add(const T* arg0,
+                     const T* arg1,
+                     T* out,
+                     const Shape& arg0_shape,
+                     const Shape& arg1_shape,
+                     const op::AutoBroadcastSpec& broadcast_spec)
+            {
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
+                        return x + y;
+                    });
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/and.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/and.hpp
new file mode 100644 (file)
index 0000000..bd7c83a
--- /dev/null
@@ -0,0 +1,55 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+#include "ngraph/op/util/attr_types.hpp"
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void logical_and(const T* arg0, const T* arg1, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = static_cast<T>(arg0[i] && arg1[i]);
+                }
+            }
+
+            template <typename T>
+            void logical_and(const T* arg0,
+                             const T* arg1,
+                             T* out,
+                             const Shape& arg0_shape,
+                             const Shape& arg1_shape,
+                             const op::AutoBroadcastSpec& broadcast_spec)
+            {
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
+                        return static_cast<T>(x && y);
+                    });
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/any.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/any.hpp
new file mode 100644 (file)
index 0000000..89b05b0
--- /dev/null
@@ -0,0 +1,55 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            static inline void any(const char* arg,
+                                   char* out,
+                                   const Shape& in_shape,
+                                   const AxisSet& reduction_axes,
+                                   bool keep_dims)
+            {
+                CoordinateTransform output_transform(reduce(in_shape, reduction_axes, keep_dims));
+
+                for (const Coordinate& output_coord : output_transform)
+                {
+                    out[output_transform.index(output_coord)] = 0;
+                }
+
+                CoordinateTransform input_transform(in_shape);
+
+                for (const Coordinate& input_coord : input_transform)
+                {
+                    Coordinate output_coord = reduce(input_coord, reduction_axes, keep_dims);
+                    out[output_transform.index(output_coord)] =
+                        out[output_transform.index(output_coord)] ||
+                        arg[input_transform.index(input_coord)];
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/asin.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/asin.hpp
new file mode 100644 (file)
index 0000000..5a71312
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void asin(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::asin(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/asinh.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/asinh.hpp
new file mode 100644 (file)
index 0000000..8f38d37
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void asinh(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::asinh(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/atan.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/atan.hpp
new file mode 100644 (file)
index 0000000..af9ee1f
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void atan(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::atan(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/atan2.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/atan2.hpp
new file mode 100644 (file)
index 0000000..86b3014
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename X, typename Y, typename Z>
+            void atan2(const X* py, const Y* px, Z* pout, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    *pout++ = static_cast<Z>(std::atan2(*py++, *px++));
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/atanh.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/atanh.hpp
new file mode 100644 (file)
index 0000000..647c739
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void atanh(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::atanh(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/autobroadcast_binop.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/autobroadcast_binop.hpp
new file mode 100644 (file)
index 0000000..7041078
--- /dev/null
@@ -0,0 +1,551 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+#include <utility>
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/op/util/attr_types.hpp"
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            namespace internal
+            {
+                inline void
+                    row_major_strides(const Shape& shape, size_t* strides, size_t size) noexcept
+                {
+                    size_t* st = strides + size - 1;
+                    size_t s = 1;
+                    for (auto d = shape.rbegin(); d != shape.rend(); d++)
+                    {
+                        *st-- = s;
+                        s *= *d;
+                    }
+                    std::fill(strides, st + 1, s);
+                }
+
+                template <typename C, typename T>
+                inline T value_with_padding_or(const C& arr,
+                                               size_t padding,
+                                               size_t idx,
+                                               T&& default_value)
+                {
+                    return idx < padding ? std::forward<T>(default_value) : arr[idx - padding];
+                }
+
+                template <int A0, int A1, typename T, typename U, typename Functor>
+                inline void numpy_autobroadcast_binop(const T* arg0,
+                                                      const T* arg1,
+                                                      U* out,
+                                                      const Shape& shape0,
+                                                      const Shape& shape1,
+                                                      const size_t* strides0,
+                                                      const size_t* strides1,
+                                                      const size_t padding0,
+                                                      const size_t padding1,
+                                                      const Shape& output_shape,
+                                                      const size_t axis,
+                                                      const size_t stride,
+                                                      Functor elementwise_functor)
+                {
+                    for (CoordinateIterator it(output_shape), ite = CoordinateIterator::end();;)
+                    {
+                        for (size_t i = 0; i < stride; ++i)
+                            *out++ = elementwise_functor(arg0[i * A0], arg1[i * A1]);
+
+                        arg0 += A0 ? stride : 1;
+                        arg1 += A1 ? stride : 1;
+
+                        auto p = it.advance(axis);
+
+                        if (it == ite)
+                            break;
+
+                        if (value_with_padding_or(shape0, padding0, p, 1) == 1)
+                            arg0 -= strides0[p];
+
+                        if (value_with_padding_or(shape1, padding1, p, 1) == 1)
+                            arg1 -= strides1[p];
+                    }
+                }
+
+                inline size_t calculate_fixed_axis(size_t axis, const size_t* strides)
+                {
+                    while (axis > 0 && strides[axis - 1] == 1)
+                        --axis;
+                    return axis;
+                }
+            }
+
+            /// \brief Helper function to implement autobroadcasting elementwise binop references.
+            ///
+            /// \tparam T Element type of the input tensors.
+            /// \tparam U Element type of the output tensor.
+            /// \tparam Functor Type of the functor for the elementwise operation. Must support
+            ///                 operator()(T,T), and operator()(T,T) must return a value of type
+            ///                 U.
+            ///
+            /// \param arg0 Pointer to the buffer for left operand input tensor.
+            /// \param arg1 Pointer to the buffer for right operand input tensor.
+            /// \param out Pointer to the buffer for output tensor. This must be pre-allocated by
+            ///            the caller, and must be large enough to hold a tensor of the correct
+            ///            shape.
+            /// \param broadcast_spec Specification of the auto-broadcasting scheme.
+            /// \param elementwise_functor Functor implementing the elementwise operation to be
+            ///                            applied across the input tensors. Must accept two
+            ///                            arguments of type T, and return a value of type U.
+            template <typename T, typename U, typename Functor>
+            void autobroadcast_binop(const T* arg0,
+                                     const T* arg1,
+                                     U* out,
+                                     const Shape& arg0_shape,
+                                     const Shape& arg1_shape,
+                                     const op::AutoBroadcastSpec& broadcast_spec,
+                                     Functor elementwise_functor)
+            {
+                switch (broadcast_spec.m_type)
+                {
+                case op::AutoBroadcastType::NONE:
+                    for (size_t i = 0; i < shape_size(arg0_shape); i++)
+                    {
+                        out[i] = elementwise_functor(arg0[i], arg1[i]);
+                    }
+                    break;
+                case op::AutoBroadcastType::NUMPY:
+                    // We'll be using CoordinateTransform to handle the broadcasting. The general
+                    // procedure is as follows:
+                    //
+                    // (1) Left pad the shorter of the two shapes with ones.
+                    // (2) Squeeze (remove ones from) both shapes, and record the squeezed axis
+                    //     indices.
+                    // (3) Using CoordinateTransform, broadcast both args to the final output
+                    //     shape. The "broadcasted axes" will be those that were squeezed in step
+                    //     2.
+                    //
+                    // Example:
+                    //
+                    //    Input shape->Padded shape->Squeezed Shape/Squeezed Axes
+                    //    -----------  ------------  ----------------------------
+                    // a: [ 3, 2, 1]   [ 3, 2, 1]    [ 3, 2   ]     {2}
+                    // b: [    1, 6]   [ 1, 1, 6]    [       6]     {0,1}
+                    //                   |  |  |
+                    //                   v  v  v
+                    //                 Output shape
+                    //                 ------------
+                    //                 [ 3, 2, 6]
+                    {
+                        using namespace internal;
+
+                        size_t const shape_rank =
+                            std::max(arg0_shape.size(), arg1_shape.size()) + 1;
+
+                        // TODO: Use compiler-specific alloca() or variable-length array
+                        std::vector<size_t> tmp(shape_rank * 2);
+
+                        size_t* strides0 = tmp.data();
+                        size_t* strides1 = tmp.data() + shape_rank;
+
+                        row_major_strides(arg0_shape, strides0, shape_rank);
+                        row_major_strides(arg1_shape, strides1, shape_rank);
+
+                        size_t const padding0 = shape_rank - arg0_shape.size();
+                        size_t const padding1 = shape_rank - arg1_shape.size();
+
+                        Shape output_shape(shape_rank, 0);
+
+                        size_t axis = 0;
+
+                        for (size_t i = 0; i < shape_rank; i++)
+                        {
+                            auto const dim0 = value_with_padding_or(arg0_shape, padding0, i, 1);
+                            auto const dim1 = value_with_padding_or(arg1_shape, padding1, i, 1);
+
+                            output_shape[i] = std::max(dim0, dim1);
+
+                            if (dim0 != dim1)
+                                axis = std::max(axis, i);
+                        }
+#if 0
+                        // Universal function without optimisations
+                        CoordinateTransformBasic arg0_transform(arg0_shape);
+                        CoordinateTransformBasic arg1_transform(arg1_shape);
+                        U *dst = out;
+
+                        for(CoordinateIterator it(output_shape),
+                            ite = CoordinateIterator::end();
+                            it != ite;
+                            ++it)
+                        {
+                            const Coordinate& output_coord = *it;
+                            size_t const idx0 = arg0_transform.index(output_coord);
+                            size_t const idx1 = arg1_transform.index(output_coord);
+                            *dst++ = elementwise_functor(arg0[idx0], arg1[idx1]);
+                        }
+#else
+
+                        if (axis == 0)
+                        {
+                            for (size_t i = 0, end = strides0[0]; i < end; ++i)
+                                out[i] = elementwise_functor(arg0[i], arg1[i]);
+                        }
+                        else if (strides0[axis] == 1 &&
+                                 value_with_padding_or(arg0_shape, padding0, axis, 1) == 1)
+                        {
+                            axis = calculate_fixed_axis(axis, strides0);
+
+                            numpy_autobroadcast_binop<0, 1>(arg0,
+                                                            arg1,
+                                                            out,
+                                                            arg0_shape,
+                                                            arg1_shape,
+                                                            strides0,
+                                                            strides1,
+                                                            padding0,
+                                                            padding1,
+                                                            output_shape,
+                                                            axis,
+                                                            strides1[axis],
+                                                            elementwise_functor);
+                        }
+                        else if (strides1[axis] == 1 &&
+                                 value_with_padding_or(arg1_shape, padding1, axis, 1) == 1)
+                        {
+                            axis = calculate_fixed_axis(axis, strides1);
+
+                            numpy_autobroadcast_binop<1, 0>(arg0,
+                                                            arg1,
+                                                            out,
+                                                            arg0_shape,
+                                                            arg1_shape,
+                                                            strides0,
+                                                            strides1,
+                                                            padding0,
+                                                            padding1,
+                                                            output_shape,
+                                                            axis,
+                                                            strides0[axis],
+                                                            elementwise_functor);
+                        }
+                        else
+                            numpy_autobroadcast_binop<1, 1>(arg0,
+                                                            arg1,
+                                                            out,
+                                                            arg0_shape,
+                                                            arg1_shape,
+                                                            strides0,
+                                                            strides1,
+                                                            padding0,
+                                                            padding1,
+                                                            output_shape,
+                                                            axis,
+                                                            strides0[axis],
+                                                            elementwise_functor);
+#endif
+                    }
+                    break;
+                case op::AutoBroadcastType::PDPD:
+                    // We'll be using CoordinateTransform to handle the broadcasting. No need to
+                    // process arg0 and output shape will be the same as arg0. We need to process
+                    // arg1 and the general procedure is as follows:
+                    //
+                    // (1) Trim trailing ones from arg1 shape.
+                    // (2) Left and right pad arg1 to match arg0 shape. Axis is the index start
+                    //     to align between arg0 and arg1.
+                    // (3) Squeeze (remove ones from) arg1 shape, and record the squeezed axis
+                    //     indices.
+                    // (3) Using CoordinateTransform, broadcast arg1 to the final output
+                    //     shape. The "broadcasted axes" will be those that were squeezed in step
+                    //     23.
+                    //
+                    // Example:
+                    //
+                    //    Input shape->   Padded shape->   Squeezed Shape/Squeezed Axes
+                    //    -----------  ------------  ----------------------------
+                    // a: [ 3, 4, 5, 6]   [ 3, 4, 5, 6]    [ 3, 4, 5, 6]
+                    // b: [    4, 5,  ]   [ 1, 4, 5, 1]    [    4, 5   ]     {0,3}
+                    //                      |  |  |
+                    //                      v  v  v
+                    //                     Output shape
+                    //                     ------------
+                    //                    [ 3, 4, 5, 6]
+                    {
+                        int64_t axis = broadcast_spec.m_axis;
+                        if (axis == -1)
+                        {
+                            axis = arg0_shape.size() - arg1_shape.size();
+                        }
+
+                        Shape arg1_padded_shape = arg1_shape;
+                        // Trim trailing ones
+                        while (arg1_padded_shape.size() > 0 && arg1_padded_shape.back() == 1)
+                        {
+                            arg1_padded_shape.pop_back();
+                        }
+
+                        for (int64_t i = 0; i < axis; ++i)
+                        {
+                            arg1_padded_shape.insert(arg1_padded_shape.begin(), 1);
+                        }
+
+                        while (arg1_padded_shape.size() < arg0_shape.size())
+                        {
+                            arg1_padded_shape.insert(arg1_padded_shape.end(), 1);
+                        }
+
+                        Shape arg1_squeezed_shape;
+                        AxisSet arg1_squeezed_axes;
+
+                        for (size_t i = 0; i < arg0_shape.size(); i++)
+                        {
+                            if (arg1_padded_shape[i] == 1)
+                            {
+                                arg1_squeezed_axes.insert(i);
+                            }
+                            else
+                            {
+                                arg1_squeezed_shape.push_back(arg1_padded_shape[i]);
+                            }
+                        }
+
+                        CoordinateTransform arg0_transform(arg0_shape);
+                        CoordinateTransform arg1_transform(arg1_squeezed_shape);
+                        CoordinateTransform output_transform(arg0_shape);
+
+                        for (const Coordinate& output_coord : output_transform)
+                        {
+                            Coordinate arg1_coord = reduce(output_coord, arg1_squeezed_axes, false);
+                            out[output_transform.index(output_coord)] =
+                                elementwise_functor(arg0[arg0_transform.index(output_coord)],
+                                                    arg1[arg1_transform.index(arg1_coord)]);
+                        }
+                    }
+                }
+            }
+
+            /// \brief Helper function to implement autobroadcasting elementwise ternaryop
+            /// references.
+            ///
+            /// \tparam U Element type of the selector tensor.
+            /// \tparam T Element type of the input tensors.
+            /// \tparam Functor Type of the functor for the elementwise operation. Must support
+            ///                 operator()(U,T,T), and operator()(U,T,T) must return a value of type
+            ///                 T.
+            ///
+            /// \param arg0 Pointer to the buffer for selector tensor.
+            /// \param arg1 Pointer to the buffer for left operand input tensor.
+            /// \param arg2 Pointer to the buffer for right operand input tensor.
+            /// \param out Pointer to the buffer for output tensor. This must be pre-allocated by
+            ///            the caller, and must be large enough to hold a tensor of the correct
+            ///            shape.
+            /// \param broadcast_spec Specification of the auto-broadcasting scheme.
+            /// \param elementwise_functor Functor implementing the elementwise operation to be
+            ///                            applied across the input tensors. Must accept an argument
+            ///                            of
+            ///                            type U and two of type T, and return a value of type T.
+            template <typename T, typename U, typename Functor>
+            void autobroadcast_select(const U* arg0,
+                                      const T* arg1,
+                                      const T* arg2,
+                                      T* out,
+                                      const Shape& arg0_shape,
+                                      const Shape& arg1_shape,
+                                      const Shape& arg2_shape,
+                                      const op::AutoBroadcastSpec& broadcast_spec,
+                                      Functor elementwise_functor)
+            {
+                switch (broadcast_spec.m_type)
+                {
+                case op::AutoBroadcastType::NONE:
+                    for (size_t i = 0; i < shape_size(arg0_shape); i++)
+                    {
+                        out[i] = elementwise_functor(arg0[i], arg1[i], arg2[i]);
+                    }
+                    break;
+                case op::AutoBroadcastType::NUMPY:
+                    // Uses same approach as autobroadcast_binop.
+                    {
+                        Shape arg0_padded_shape = arg0_shape;
+                        Shape arg1_padded_shape = arg1_shape;
+                        Shape arg2_padded_shape = arg2_shape;
+
+                        while (arg1_padded_shape.size() < arg2_padded_shape.size())
+                        {
+                            arg1_padded_shape.insert(arg1_padded_shape.begin(), 1);
+                        }
+
+                        while (arg2_padded_shape.size() < arg1_padded_shape.size())
+                        {
+                            arg2_padded_shape.insert(arg2_padded_shape.begin(), 1);
+                        }
+
+                        while (arg0_padded_shape.size() < arg1_padded_shape.size())
+                        {
+                            arg0_padded_shape.insert(arg0_padded_shape.begin(), 1);
+                        }
+
+                        Shape arg0_squeezed_shape;
+                        Shape arg1_squeezed_shape;
+                        Shape arg2_squeezed_shape;
+                        AxisSet arg0_squeezed_axes;
+                        AxisSet arg1_squeezed_axes;
+                        AxisSet arg2_squeezed_axes;
+                        Shape output_shape;
+
+                        for (size_t i = 0; i < arg1_padded_shape.size(); i++)
+                        {
+                            if (arg1_padded_shape[i] == 1)
+                            {
+                                arg1_squeezed_axes.insert(i);
+                            }
+                            else
+                            {
+                                arg1_squeezed_shape.push_back(arg1_padded_shape[i]);
+                            }
+
+                            if (arg2_padded_shape[i] == 1)
+                            {
+                                arg2_squeezed_axes.insert(i);
+                            }
+                            else
+                            {
+                                arg2_squeezed_shape.push_back(arg2_padded_shape[i]);
+                            }
+
+                            if (arg0_padded_shape[i] == 1)
+                            {
+                                arg0_squeezed_axes.insert(i);
+                            }
+                            else
+                            {
+                                arg0_squeezed_shape.push_back(arg0_padded_shape[i]);
+                            }
+
+                            output_shape.push_back(arg1_padded_shape[i] == 1
+                                                       ? arg2_padded_shape[i]
+                                                       : arg1_padded_shape[i]);
+                        }
+
+                        CoordinateTransform arg0_transform(arg0_squeezed_shape);
+                        CoordinateTransform arg1_transform(arg1_squeezed_shape);
+                        CoordinateTransform arg2_transform(arg2_squeezed_shape);
+                        CoordinateTransform output_transform(output_shape);
+
+                        for (const Coordinate& output_coord : output_transform)
+                        {
+                            Coordinate arg0_coord = reduce(output_coord, arg0_squeezed_axes, false);
+                            Coordinate arg1_coord = reduce(output_coord, arg1_squeezed_axes, false);
+                            Coordinate arg2_coord = reduce(output_coord, arg2_squeezed_axes, false);
+                            out[output_transform.index(output_coord)] =
+                                elementwise_functor(arg0[arg0_transform.index(arg0_coord)],
+                                                    arg1[arg1_transform.index(arg1_coord)],
+                                                    arg2[arg2_transform.index(arg2_coord)]);
+                        }
+                    }
+                    break;
+                case op::AutoBroadcastType::PDPD:
+                {
+                    // arg0 and arg2 are broadcast to arg1 shape
+                    int64_t axis = broadcast_spec.m_axis;
+                    if (axis == -1)
+                    {
+                        axis = arg1_shape.size() - arg2_shape.size();
+                    }
+
+                    Shape arg0_padded_shape = arg0_shape;
+                    Shape arg2_padded_shape = arg2_shape;
+                    // Trim trailing ones
+                    while (arg0_padded_shape.size() > 0 && arg0_padded_shape.back() == 1)
+                    {
+                        arg0_padded_shape.pop_back();
+                    }
+
+                    for (int64_t i = 0; i < axis; ++i)
+                    {
+                        arg0_padded_shape.insert(arg0_padded_shape.begin(), 1);
+                    }
+
+                    while (arg0_padded_shape.size() < arg1_shape.size())
+                    {
+                        arg0_padded_shape.insert(arg0_padded_shape.end(), 1);
+                    }
+
+                    while (arg2_padded_shape.size() > 0 && arg2_padded_shape.back() == 1)
+                    {
+                        arg2_padded_shape.pop_back();
+                    }
+
+                    for (int64_t i = 0; i < axis; ++i)
+                    {
+                        arg2_padded_shape.insert(arg2_padded_shape.begin(), 1);
+                    }
+
+                    while (arg2_padded_shape.size() < arg1_shape.size())
+                    {
+                        arg2_padded_shape.insert(arg2_padded_shape.end(), 1);
+                    }
+
+                    Shape arg0_squeezed_shape;
+                    AxisSet arg0_squeezed_axes;
+                    Shape arg2_squeezed_shape;
+                    AxisSet arg2_squeezed_axes;
+
+                    for (size_t i = 0; i < arg1_shape.size(); i++)
+                    {
+                        if (arg0_padded_shape[i] == 1)
+                        {
+                            arg0_squeezed_axes.insert(i);
+                        }
+                        else
+                        {
+                            arg0_squeezed_shape.push_back(arg0_padded_shape[i]);
+                        }
+                        if (arg2_padded_shape[i] == 1)
+                        {
+                            arg2_squeezed_axes.insert(i);
+                        }
+                        else
+                        {
+                            arg2_squeezed_shape.push_back(arg2_padded_shape[i]);
+                        }
+                    }
+
+                    CoordinateTransform arg0_transform(arg0_squeezed_shape);
+                    CoordinateTransform arg1_transform(arg1_shape);
+                    CoordinateTransform arg2_transform(arg2_squeezed_shape);
+                    CoordinateTransform output_transform(arg1_shape);
+
+                    for (const Coordinate& output_coord : output_transform)
+                    {
+                        Coordinate arg0_coord = reduce(output_coord, arg0_squeezed_axes, false);
+                        Coordinate arg2_coord = reduce(output_coord, arg2_squeezed_axes, false);
+                        out[output_transform.index(output_coord)] =
+                            elementwise_functor(arg0[arg0_transform.index(arg0_coord)],
+                                                arg1[arg1_transform.index(output_coord)],
+                                                arg2[arg2_transform.index(arg2_coord)]);
+                    }
+                }
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/avg_pool.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/avg_pool.hpp
new file mode 100644 (file)
index 0000000..6daa402
--- /dev/null
@@ -0,0 +1,252 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cfenv>
+#include <cmath>
+#include <numeric>
+#include <stdexcept>
+#include <vector>
+
+#include "ngraph/axis_vector.hpp"
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void avg_pool_backprop(const T* delta,
+                                   T* out,
+                                   const Shape& delta_shape,
+                                   const Shape& out_shape,
+                                   const Shape& window_shape,
+                                   const Strides& window_movement_strides,
+                                   const Shape& padding_below,
+                                   const Shape& padding_above,
+                                   bool include_padding_in_avg_computation)
+            {
+                CoordinateTransform out_transform(out_shape);
+
+                for (const Coordinate& out_coord : out_transform)
+                {
+                    out[out_transform.index(out_coord)] = 0;
+                }
+
+                CoordinateTransform delta_transform(delta_shape);
+
+                for (const Coordinate& delta_coord : delta_transform)
+                {
+                    size_t img_index = delta_coord[0];
+                    size_t channel = delta_coord[1];
+
+                    size_t n_image_dimensions = out_shape.size() - 2;
+                    Coordinate source_window_transform_start(2 + n_image_dimensions);
+                    Coordinate source_window_transform_end(2 + n_image_dimensions);
+                    Strides source_window_transform_source_strides(2 + n_image_dimensions, 1);
+                    AxisVector source_window_transform_source_axis_order(2 + n_image_dimensions);
+                    CoordinateDiff source_window_transform_padding_below(2 + n_image_dimensions);
+                    CoordinateDiff source_window_transform_padding_above(2 + n_image_dimensions);
+
+                    source_window_transform_start[0] = img_index;
+                    source_window_transform_end[0] = img_index + 1;
+                    source_window_transform_start[1] = channel;
+                    source_window_transform_end[1] = channel + 1;
+                    source_window_transform_padding_below[0] = 0;
+                    source_window_transform_padding_below[1] = 0;
+                    source_window_transform_padding_above[0] = 0;
+                    source_window_transform_padding_above[1] = 0;
+
+                    for (size_t i = 2; i < n_image_dimensions + 2; i++)
+                    {
+                        size_t window_shape_this_dim = window_shape[i - 2];
+                        size_t movement_stride = window_movement_strides[i - 2];
+
+                        source_window_transform_start[i] = movement_stride * delta_coord[i];
+                        source_window_transform_end[i] =
+                            source_window_transform_start[i] + window_shape_this_dim;
+                        source_window_transform_padding_below[i] = padding_below[i - 2];
+                        source_window_transform_padding_above[i] = padding_above[i - 2];
+                    }
+                    std::iota(begin(source_window_transform_source_axis_order),
+                              end(source_window_transform_source_axis_order),
+                              0);
+
+                    CoordinateTransform source_window_transform(
+                        out_shape,
+                        source_window_transform_start,
+                        source_window_transform_end,
+                        source_window_transform_source_strides,
+                        source_window_transform_source_axis_order,
+                        source_window_transform_padding_below,
+                        source_window_transform_padding_above);
+
+                    size_t num_elements_in_window = 0;
+
+                    for (const Coordinate& source_window_coord : source_window_transform)
+                    {
+                        if (source_window_transform.has_source_coordinate(source_window_coord) ||
+                            include_padding_in_avg_computation)
+                        {
+                            num_elements_in_window++;
+                        }
+                    }
+
+                    for (const Coordinate& source_window_coord : source_window_transform)
+                    {
+                        if (source_window_transform.has_source_coordinate(source_window_coord))
+                        {
+                            size_t out_index = source_window_transform.index(source_window_coord);
+                            out[out_index] +=
+                                delta[delta_transform.index(delta_coord)] / num_elements_in_window;
+                        }
+                    }
+                }
+            }
+
+            template <typename T>
+            void avg_pool(const T* arg,
+                          T* out,
+                          const Shape& arg_shape,
+                          const Shape& out_shape,
+                          const Shape& window_shape,
+                          const Strides& window_movement_strides,
+                          const Shape& padding_below,
+                          const Shape& padding_above,
+                          bool include_padding_in_avg_computation)
+            {
+                auto old_mode = std::fegetround();
+                std::fesetround(FE_TONEAREST);
+                // At the outermost level we will walk over every output coordinate O.
+                CoordinateTransform output_transform(out_shape);
+
+                for (const Coordinate& out_coord : output_transform)
+                {
+                    // Our output coordinate O will have the form:
+                    //
+                    //   (N,chan,i_1,...,i_n)
+
+                    size_t batch_index = out_coord[0];
+                    size_t channel = out_coord[1];
+
+                    // For the input data we need to iterate the coordinate:
+                    //
+                    //   I:
+                    //
+                    // over the range (noninclusive on the right):
+                    //
+                    //   (N,chan,s_1*i_1,s_2*i_2,...,s_n*i_n) ->
+                    //
+                    //     (N+1,chan+1,s_1*i_1 + window_shape_1,...,s_n*i_n + window_shape_n)
+                    //
+                    // with unit stride.
+                    //
+                    // We iterate this over the *padded* data, so below we will need to check for
+                    // coordinates that fall in the padding area.
+
+                    size_t n_spatial_dimensions = arg_shape.size() - 2;
+
+                    Coordinate input_batch_transform_start(2 + n_spatial_dimensions);
+                    Coordinate input_batch_transform_end(2 + n_spatial_dimensions);
+                    Strides input_batch_transform_source_strides(2 + n_spatial_dimensions, 1);
+                    AxisVector input_batch_transform_source_axis_order(2 + n_spatial_dimensions);
+                    CoordinateDiff input_batch_transform_padding_below(2 + n_spatial_dimensions);
+                    CoordinateDiff input_batch_transform_padding_above(2 + n_spatial_dimensions);
+
+                    input_batch_transform_start[0] = batch_index;
+                    input_batch_transform_end[0] = batch_index + 1;
+                    input_batch_transform_start[1] = channel;
+                    input_batch_transform_end[1] = channel + 1;
+                    input_batch_transform_padding_below[0] = 0;
+                    input_batch_transform_padding_below[1] = 0;
+                    input_batch_transform_padding_above[0] = 0;
+                    input_batch_transform_padding_above[1] = 0;
+
+                    for (size_t i = 2; i < n_spatial_dimensions + 2; i++)
+                    {
+                        size_t window_shape_this_dim = window_shape[i - 2];
+                        size_t movement_stride = window_movement_strides[i - 2];
+
+                        input_batch_transform_start[i] = movement_stride * out_coord[i];
+                        input_batch_transform_end[i] =
+                            input_batch_transform_start[i] + window_shape_this_dim;
+                        input_batch_transform_padding_below[i] = padding_below[i - 2];
+                        input_batch_transform_padding_above[i] = padding_above[i - 2];
+                    }
+
+                    for (size_t i = 0; i < arg_shape.size(); i++)
+                    {
+                        input_batch_transform_source_axis_order[i] = i;
+                    }
+
+                    CoordinateTransform input_batch_transform(
+                        arg_shape,
+                        input_batch_transform_start,
+                        input_batch_transform_end,
+                        input_batch_transform_source_strides,
+                        input_batch_transform_source_axis_order,
+                        input_batch_transform_padding_below,
+                        input_batch_transform_padding_above);
+
+                    // As we go, we compute the sum value:
+                    //
+                    //   output[O] := output[O] + arg[I]
+                    //
+                    // and the number of elements:
+                    //
+                    //   n_elements := n_elements + 1
+
+                    T result = 0;
+                    size_t n_elements = 0;
+
+                    for (const Coordinate& input_batch_coord : input_batch_transform)
+                    {
+                        bool in_bounds =
+                            input_batch_transform.has_source_coordinate(input_batch_coord);
+
+                        if (in_bounds || include_padding_in_avg_computation)
+                        {
+                            T v =
+                                in_bounds ? arg[input_batch_transform.index(input_batch_coord)] : 0;
+                            result += v;
+                            n_elements++;
+                        }
+                    }
+
+                    if (n_elements == 0)
+                    {
+                        throw std::runtime_error("AvgPool elements == 0, must be non-zero");
+                    }
+
+                    if (std::is_same<T, int8_t>::value || std::is_same<T, uint8_t>::value)
+                    {
+                        out[output_transform.index(out_coord)] =
+                            static_cast<T>(std::nearbyint(static_cast<float>(result) / n_elements));
+                    }
+                    else
+                    {
+                        out[output_transform.index(out_coord)] = result / n_elements;
+                    }
+                    std::fesetround(old_mode);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/batch_norm.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/batch_norm.hpp
new file mode 100644 (file)
index 0000000..4f511c5
--- /dev/null
@@ -0,0 +1,213 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <vector>
+
+#include "ngraph/axis_vector.hpp"
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/runtime/reference/add.hpp"
+#include "ngraph/runtime/reference/broadcast.hpp"
+#include "ngraph/runtime/reference/divide.hpp"
+#include "ngraph/runtime/reference/multiply.hpp"
+#include "ngraph/runtime/reference/sum.hpp"
+#include "ngraph/shape.hpp"
+#include "ngraph/util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void batch_norm_inference(float eps,
+                                      const T* gamma,
+                                      const T* beta,
+                                      const T* input,
+                                      const T* mean,
+                                      const T* variance,
+                                      T* normed_input,
+                                      const Shape& input_shape)
+            {
+                auto eps_casted = static_cast<T>(eps);
+                CoordinateTransform input_transform(input_shape);
+
+                for (Coordinate input_coord : input_transform)
+                {
+                    auto channel_num = input_coord[1];
+                    auto channel_gamma = gamma[channel_num];
+                    auto channel_beta = beta[channel_num];
+                    auto channel_mean = mean[channel_num];
+                    auto channel_var = variance[channel_num];
+
+                    auto input_index = input_transform.index(input_coord);
+                    auto normalized =
+                        (input[input_index] - channel_mean) / (std::sqrt(channel_var + eps_casted));
+                    normed_input[input_index] = normalized * channel_gamma + channel_beta;
+                }
+            }
+
+            template <typename T>
+            void batch_norm_training(float eps,
+                                     const T* gamma,
+                                     const T* beta,
+                                     const T* input,
+                                     T* normed_input,
+                                     T* mean,
+                                     T* variance,
+                                     const Shape& input_shape)
+            {
+                auto eps_casted = static_cast<T>(eps);
+                auto channels = input_shape[1];
+
+                // We use these objects to iterate over the indices in a channel.
+                // The start and end points for the channel axis are modified in the loop.
+                Coordinate start_corner;
+                Coordinate end_corner;
+                for (size_t i = 0; i < input_shape.size(); i++)
+                {
+                    start_corner.push_back(0);
+                    end_corner.push_back(input_shape[i]);
+                }
+
+                for (size_t c = 0; c < channels; c++)
+                {
+                    T channel_sum = 0;
+
+                    start_corner[1] = c;
+                    end_corner[1] = c + 1;
+
+                    // Compute the mean
+                    CoordinateTransform input_transform(input_shape, start_corner, end_corner);
+                    for (Coordinate input_coord : input_transform)
+                    {
+                        channel_sum += input[input_transform.index(input_coord)];
+                    }
+                    T channel_mean = channel_sum / (shape_size(input_shape) / channels);
+                    mean[c] = channel_mean;
+
+                    T channel_diff_square_sum = 0;
+                    for (Coordinate input_coord : input_transform)
+                    {
+                        auto centered = input[input_transform.index(input_coord)] - channel_mean;
+                        channel_diff_square_sum += centered * centered;
+                    }
+                    T channel_var = channel_diff_square_sum / (shape_size(input_shape) / channels);
+                    variance[c] = channel_var;
+
+                    auto channel_gamma = gamma[c];
+                    auto channel_beta = beta[c];
+                    T scale = channel_gamma / std::sqrt(channel_var + eps_casted);
+
+                    // Compute the normalized output
+                    for (Coordinate input_coord : input_transform)
+                    {
+                        auto input_index = input_transform.index(input_coord);
+                        normed_input[input_index] =
+                            (input[input_index] - channel_mean) * scale + channel_beta;
+                    }
+                }
+            }
+
+            template <typename T>
+            void batch_norm_backprop(float eps,
+                                     const T* gamma,
+                                     const T* /* beta */,
+                                     const T* input,
+                                     const T* mean,
+                                     const T* variance,
+                                     const T* delta_normed,
+                                     T* delta_input,
+                                     T* delta_gamma,
+                                     T* delta_beta,
+                                     const Shape& input_shape)
+            {
+                size_t channel_axis = 1;
+                auto num_channels = input_shape[channel_axis];
+                Shape moment_shape = Shape{num_channels};
+                auto input_num_elements = shape_size(input_shape);
+                auto elements_per_channel = input_num_elements / num_channels;
+
+                Coordinate start_corner;
+                Coordinate end_corner;
+                for (size_t i = 0; i < input_shape.size(); i++)
+                {
+                    start_corner.push_back(0);
+                    end_corner.push_back(input_shape[i]);
+                }
+                // The forward computation in gory detail
+                // input[., C, ...]
+                // gamma[C]
+                // beta[C]
+                // mu[c:C] = sum(input[., c, ...])/elements_per_channel
+                // var[c:C] = sum(input[., c, ...]^2 - mu[c])/elements_per_channel
+                // inv_sqrt[c:C] = 1/sqrt(var[c]+epsilon)
+                // gammad[c:C] = gamma[c]*inv_sqrt[c]
+                // normed[., c:C, ...] = (input[., c, ...]-mu)*gammad[c]+beta[c]
+
+                for (uint64_t c = 0; c < num_channels; ++c)
+                {
+                    start_corner[channel_axis] = c;
+                    end_corner[channel_axis] = c + 1;
+
+                    CoordinateTransform input_transform(input_shape, start_corner, end_corner);
+                    T delta_beta_sum = 0;
+                    T var = variance[c];
+                    T mu = mean[c];
+                    T var_eps = var + static_cast<T>(eps);
+                    T sqrt_var_eps = std::sqrt(var_eps);
+                    T inv_sqrt_var_eps = 1 / sqrt_var_eps;
+                    T gammad = gamma[c] * inv_sqrt_var_eps;
+                    T delta_gammad = 0;
+                    T delta_mu = 0;
+                    for (Coordinate input_coord : input_transform)
+                    {
+                        auto idx = input_transform.index(input_coord);
+                        auto delta_idx = delta_normed[idx];
+                        auto input_idx = input[idx];
+                        delta_beta_sum += delta_idx;
+                        delta_gammad += (input_idx - mu) * delta_idx;
+                        T delta_centered = gammad * delta_idx;
+                        delta_input[idx] = delta_centered;
+                        delta_mu -= delta_centered;
+                    }
+                    delta_beta[c] = delta_beta_sum;
+                    delta_gamma[c] = delta_gammad * inv_sqrt_var_eps;
+                    T delta_inv_sqrt = gamma[c] * delta_gammad;
+                    // y = x^(-1/2)
+                    // dy = -(1/2)x^(-3/2) = -y/(2x) dx
+                    T delta_var = -delta_inv_sqrt * inv_sqrt_var_eps / (2 * var_eps);
+                    T delta_two_var_sum = 2 * delta_var / elements_per_channel;
+                    T delta_mu_over_n = delta_mu / elements_per_channel;
+                    for (Coordinate input_coord : input_transform)
+                    {
+                        // v = 1/N sum(x_i - mu)^2
+                        // dv = 2/N sum[(x_i - mu)dx_i] - 2/N sum[(x_i - mu) dmu]
+                        //    = 2/N sum[(x_i - mu)dx_i] - 2/N (Nmu-Nmu) dmu
+                        //    = 2/N sum[(x_i - mu)dx_i]
+                        auto idx = input_transform.index(input_coord);
+                        // These two values mostly cancel out so add them first
+                        auto val = delta_input[idx] + delta_mu_over_n;
+                        delta_input[idx] = val + (input[idx] - mu) * delta_two_var_sum;
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/broadcast.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/broadcast.hpp
new file mode 100644 (file)
index 0000000..8c324fb
--- /dev/null
@@ -0,0 +1,68 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void broadcast(const T* arg,
+                           T* out,
+                           const Shape& in_shape,
+                           const Shape& out_shape,
+                           const AxisSet& broadcast_axes)
+            {
+                // Remove all broadcast axes from in_shape
+                Shape adjusted_in_shape;
+                for (auto length : in_shape)
+                {
+                    if (length != 1)
+                    {
+                        adjusted_in_shape.push_back(length);
+                    }
+                }
+                // Remove 1s from out_shape
+                AxisSet adjusted_axes(broadcast_axes);
+                for (uint64_t axis = 0; axis < out_shape.size(); ++axis)
+                {
+                    auto length = out_shape.at(axis);
+                    if (length == 1)
+                    {
+                        adjusted_axes.insert(axis);
+                    }
+                }
+                CoordinateTransform input_transform(adjusted_in_shape);
+                CoordinateTransform output_transform(out_shape);
+
+                for (const Coordinate& output_coord : output_transform)
+                {
+                    Coordinate input_coord = reduce(output_coord, adjusted_axes, false);
+                    out[output_transform.index(output_coord)] =
+                        arg[input_transform.index(input_coord)];
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/ceiling.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/ceiling.hpp
new file mode 100644 (file)
index 0000000..d8dec45
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void ceiling(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::ceil(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/clamp.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/clamp.hpp
new file mode 100644 (file)
index 0000000..fc10734
--- /dev/null
@@ -0,0 +1,49 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void clamp(const T* arg, T* out, T min, T max, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    if (arg[i] < min)
+                    {
+                        out[i] = min;
+                    }
+                    else if (arg[i] > max)
+                    {
+                        out[i] = max;
+                    }
+                    else
+                    {
+                        out[i] = arg[i];
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/concat.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/concat.hpp
new file mode 100644 (file)
index 0000000..4f95289
--- /dev/null
@@ -0,0 +1,83 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/check.hpp"
+#include "ngraph/coordinate_transform.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void concat(const std::vector<const T*>& args,
+                        T* out,
+                        const std::vector<Shape>& in_shapes,
+                        const Shape& out_shape,
+                        int64_t concatenation_axis)
+            {
+                // We will copy the inputs to the output one at a time. As we go, we will move out
+                // along the concatenation axis, starting at 0.
+                size_t concatenation_pos = 0;
+                for (size_t i = 0; i < args.size(); i++)
+                {
+                    // CoordinateTransform gets confused when the last input has a zero-size dim, so
+                    // we will just skip for zero-element tensors.
+                    if (shape_size(in_shapes[i]) == 0)
+                    {
+                        continue;
+                    }
+
+                    // The start coordinate for the copy is (0,...,0) except at the concatenation
+                    // axis.
+                    Coordinate out_start_coord(out_shape.size(), 0);
+                    out_start_coord[concatenation_axis] = concatenation_pos;
+
+                    // The end coordinate for the copy is the same as the output shape except at the
+                    // concatenation axis.
+                    Coordinate out_end_coord = out_shape;
+                    out_end_coord[concatenation_axis] =
+                        concatenation_pos + in_shapes[i][concatenation_axis];
+
+                    CoordinateTransform input_transform(in_shapes[i]);
+                    CoordinateTransform output_chunk_transform(
+                        out_shape, out_start_coord, out_end_coord);
+
+                    NGRAPH_CHECK(shape_size(input_transform.get_target_shape()) ==
+                                 shape_size(output_chunk_transform.get_target_shape()));
+
+                    CoordinateTransform::Iterator output_chunk_it = output_chunk_transform.begin();
+
+                    for (const Coordinate& input_coord : input_transform)
+                    {
+                        size_t input_index = input_transform.index(input_coord);
+                        size_t output_chunk_index = output_chunk_transform.index(*output_chunk_it);
+                        ++output_chunk_it;
+
+                        out[output_chunk_index] = args[i][input_index];
+                    }
+
+                    concatenation_pos += in_shapes[i][concatenation_axis];
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/constant.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/constant.hpp
new file mode 100644 (file)
index 0000000..fed77ac
--- /dev/null
@@ -0,0 +1,37 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void constant(const T* arg0, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg0[i];
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/convert.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/convert.hpp
new file mode 100644 (file)
index 0000000..805562c
--- /dev/null
@@ -0,0 +1,46 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename TI, typename TO>
+            void convert(const TI* arg, TO* out, size_t count)
+            {
+                for (size_t i = 0; i < count; ++i)
+                {
+                    out[i] = static_cast<TO>(arg[i]);
+                }
+            }
+
+            template <typename T>
+            void convert_to_bool(const T* arg, char* out, size_t count)
+            {
+                for (size_t i = 0; i < count; ++i)
+                {
+                    out[i] = static_cast<char>(static_cast<bool>(arg[i]));
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/convolution.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/convolution.hpp
new file mode 100644 (file)
index 0000000..2c002ec
--- /dev/null
@@ -0,0 +1,402 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cfenv>
+#include <cmath>
+#include <functional>
+
+#include "ngraph/axis_vector.hpp"
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/runtime/reference/reverse.hpp"
+#include "ngraph/util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            struct widen
+            {
+                using type = T;
+            };
+
+            template <>
+            struct widen<float>
+            {
+                using type = double;
+            };
+
+            template <>
+            struct widen<double>
+            {
+                using type = long double;
+            };
+
+            // in: NC_I...
+            // filter: C_OC_I...
+            // out: NC_O...
+            template <typename INPUT,
+                      typename FILTER,
+                      typename OUTPUT,
+                      typename ACCUMULATION = typename widen<OUTPUT>::type>
+            void general_convolution(const INPUT* in,
+                                     const FILTER* filter,
+                                     OUTPUT* out,
+                                     const Shape& in_shape,
+                                     const Shape& filter_shape,
+                                     const Shape& out_shape,
+                                     const Strides& stride,
+                                     const Strides& filter_dilation,
+                                     const CoordinateDiff& in_pad_below,
+                                     const CoordinateDiff& in_pad_above,
+                                     const Strides& in_dilation,
+                                     size_t in_batch_axis,
+                                     size_t in_channel_axis,
+                                     size_t filter_out_channel_axis,
+                                     size_t filter_in_channel_axis,
+                                     size_t out_batch_axis,
+                                     size_t out_channel_axis,
+                                     const float* input_scale = nullptr,
+                                     const INPUT* input_zero_point = nullptr,
+                                     const float* filter_scale = nullptr,
+                                     const FILTER* filter_zero_point = nullptr,
+                                     const float* output_scale = nullptr,
+                                     const OUTPUT* output_zero_point = nullptr)
+            {
+                bool is_quantized = false;
+                if (input_scale && input_zero_point && filter_scale && filter_zero_point &&
+                    output_scale && output_zero_point)
+                {
+                    is_quantized = true;
+                }
+
+                auto old_mode = std::fegetround();
+                std::fesetround(FE_TONEAREST);
+                // Comments throughout assume without loss of generality that:
+                //
+                // * batch axes for both in and out are 0
+                // * in channel axes for both in and filter are 1
+                // * out channel axes for filter is 0
+                // * out channel axis for out is 1
+
+                // At the outermost level we will walk over every out coordinate O.
+                CoordinateTransform out_transform(out_shape);
+
+                for (const Coordinate& out_coord : out_transform)
+                {
+                    // Our out coordinate O will have the form:
+                    //
+                    //   (N,chan_out,i_1,...,i_n)
+
+                    size_t batch_index = out_coord[out_batch_axis];
+                    size_t out_channel = out_coord[out_channel_axis];
+
+                    // For the in we need to iterate the coordinate:
+                    //
+                    //   I:
+                    //
+                    // over the range (noninclusive on the right):
+                    //
+                    //   (N,0,s_1*i_1,s_2*i_2,...,s_n*i_n) ->
+                    //
+                    //     (N+1,
+                    //      chans_in_count,
+                    //      s_1*i_1+ l_1*filter_dims_1,
+                    ///       ...,
+                    ///     s_n*i_n +l_n*filter_dims_n)
+                    //
+                    // with strides:
+                    //
+                    //   (1,l_1,...,l_n).
+                    //
+                    // Note that we are iterating within the *padded* and *dilated* in batch, so
+                    // further down we must check the current coordinate is in the pad or dilation
+                    // gap.
+
+                    size_t n_spatial_dimensions = in_shape.size() - 2;
+                    size_t n_in_channels = in_shape[in_channel_axis];
+
+                    Coordinate in_transform_start(2 + n_spatial_dimensions);
+                    Coordinate in_transform_end(2 + n_spatial_dimensions);
+                    Strides in_transform_movement_strides(2 + n_spatial_dimensions, 1);
+                    CoordinateDiff in_transform_pad_below(2 + n_spatial_dimensions, 0);
+                    CoordinateDiff in_transform_pad_above(2 + n_spatial_dimensions, 0);
+                    Strides in_transform_dilation_strides(2 + n_spatial_dimensions, 1);
+
+                    in_transform_start[in_batch_axis] = batch_index;
+                    in_transform_end[in_batch_axis] = batch_index + 1;
+                    in_transform_start[in_channel_axis] = 0;
+                    in_transform_end[in_channel_axis] = 1;
+
+                    for (size_t i = 2; i < n_spatial_dimensions + 2; i++)
+                    {
+                        size_t filter_dilation_stride = filter_dilation[i - 2];
+                        size_t filter_movement_stride = stride[i - 2];
+                        std::ptrdiff_t below_pad = in_pad_below[i - 2];
+                        std::ptrdiff_t above_pad = in_pad_above[i - 2];
+                        size_t in_dilation_stride = in_dilation[i - 2];
+
+                        in_transform_start[i] = filter_movement_stride * out_coord[i];
+                        in_transform_end[i] = in_transform_start[i] +
+                                              (filter_shape[i] - 1) * filter_dilation_stride + 1;
+                        in_transform_movement_strides[i] = filter_dilation_stride;
+                        in_transform_pad_below[i] = below_pad;
+                        in_transform_pad_above[i] = above_pad;
+                        in_transform_dilation_strides[i] = in_dilation_stride;
+                    }
+
+                    AxisVector in_transform_axis_order(2 + n_spatial_dimensions);
+                    for (size_t i = 0; i < in_transform_axis_order.size(); i++)
+                    {
+                        in_transform_axis_order[i] = i;
+                    }
+                    CoordinateTransform in_transform(in_shape,
+                                                     in_transform_start,
+                                                     in_transform_end,
+                                                     in_transform_movement_strides,
+                                                     in_transform_axis_order,
+                                                     in_transform_pad_below,
+                                                     in_transform_pad_above,
+                                                     in_transform_dilation_strides);
+
+                    // Simultaneously with iterating I, for the filter we need to iterate the
+                    // coordinate:
+                    //
+                    //   F
+                    //
+                    // over the range (noninclusive on the right):
+                    //
+                    //   (chan_out,0,0,...,0) ->
+                    //     (chan_out+1,
+                    //      chans_in_count,
+                    //      filter_dims_1,
+                    //        ...,
+                    //      filter_dims_n)
+                    //
+                    // with unit stride.
+
+                    Shape filter_transform_start(2 + n_spatial_dimensions);
+                    Shape filter_transform_end(2 + n_spatial_dimensions);
+
+                    filter_transform_start[filter_out_channel_axis] = out_channel;
+                    filter_transform_end[filter_out_channel_axis] = out_channel + 1;
+                    filter_transform_start[filter_in_channel_axis] = 0;
+                    filter_transform_end[filter_in_channel_axis] = 1;
+
+                    for (size_t i = 2; i < n_spatial_dimensions + 2; i++)
+                    {
+                        filter_transform_start[i] = 0;
+                        filter_transform_end[i] = filter_shape[i];
+                    }
+
+                    CoordinateTransform filter_transform(
+                        filter_shape, filter_transform_start, filter_transform_end);
+
+                    // As we go, we sum up:
+                    //
+                    //   out[O] += in[I] * filter[F].
+
+                    ACCUMULATION result = 0;
+
+                    CoordinateTransform::Iterator in_it = in_transform.begin();
+                    CoordinateTransform::Iterator filter_it = filter_transform.begin();
+                    CoordinateTransform::Iterator in_it_end = in_transform.end();
+                    CoordinateTransform::Iterator filter_it_end = filter_transform.end();
+
+                    size_t in_channel_stride = row_major_strides(in_shape).at(in_channel_axis);
+                    size_t filter_in_channel_stride =
+                        row_major_strides(filter_shape).at(filter_in_channel_axis);
+
+                    while (in_it != in_it_end && filter_it != filter_it_end)
+                    {
+                        const Coordinate& in_coord = *in_it;
+                        if (in_transform.has_source_coordinate(in_coord))
+                        {
+                            size_t in_idx = in_transform.index(in_coord);
+                            const Coordinate& filter_coord = *filter_it;
+                            size_t filter_idx = filter_transform.index(filter_coord);
+                            for (size_t in_channel = 0; in_channel < n_in_channels; ++in_channel)
+                            {
+                                ACCUMULATION in_v = static_cast<ACCUMULATION>(in[in_idx]);
+                                ACCUMULATION f_v = static_cast<ACCUMULATION>(filter[filter_idx]);
+                                if (is_quantized)
+                                {
+                                    in_v = in_v - static_cast<ACCUMULATION>(*input_zero_point);
+                                    f_v = f_v - static_cast<ACCUMULATION>(*filter_zero_point);
+                                }
+                                result += in_v * f_v;
+                                in_idx += in_channel_stride;
+                                filter_idx += filter_in_channel_stride;
+                            }
+                        }
+                        ++in_it;
+                        ++filter_it;
+                    }
+                    if (is_quantized)
+                    {
+                        float scale = *input_scale * *filter_scale / *output_scale;
+                        out[out_transform.index(out_coord)] =
+                            static_cast<OUTPUT>(std::round(static_cast<float>(result) * scale)) +
+                            *output_zero_point;
+                    }
+                    else
+                    {
+                        out[out_transform.index(out_coord)] = result;
+                    }
+                }
+                std::fesetround(old_mode);
+            }
+
+            template <typename INPUT,
+                      typename FILTER,
+                      typename OUTPUT,
+                      typename ACCUMULATION = typename widen<OUTPUT>::type>
+            void convolution(const INPUT* in,
+                             const FILTER* filter,
+                             OUTPUT* out,
+                             const Shape& in_shape,
+                             const Shape& filter_shape,
+                             const Shape& out_shape,
+                             const Strides& stride,
+                             const Strides& filter_dilation,
+                             const CoordinateDiff& in_pad_below,
+                             const CoordinateDiff& in_pad_above,
+                             const Strides& in_dilation,
+                             const float* input_scale = nullptr,
+                             const INPUT* input_zero_point = nullptr,
+                             const float* filter_scale = nullptr,
+                             const FILTER* filter_zero_point = nullptr,
+                             const float* output_scale = nullptr,
+                             const OUTPUT* output_zero_point = nullptr)
+
+            {
+                general_convolution<INPUT, FILTER, OUTPUT, ACCUMULATION>(in,
+                                                                         filter,
+                                                                         out,
+                                                                         in_shape,
+                                                                         filter_shape,
+                                                                         out_shape,
+                                                                         stride,
+                                                                         filter_dilation,
+                                                                         in_pad_below,
+                                                                         in_pad_above,
+                                                                         in_dilation,
+                                                                         0,
+                                                                         1,
+                                                                         0,
+                                                                         1,
+                                                                         0,
+                                                                         1,
+                                                                         input_scale,
+                                                                         input_zero_point,
+                                                                         filter_scale,
+                                                                         filter_zero_point,
+                                                                         output_scale,
+                                                                         output_zero_point);
+            }
+
+            template <typename INPUT,
+                      typename OUTPUT,
+                      typename FILTER,
+                      typename ACCUMULATION = typename widen<FILTER>::type>
+            void convolution_backprop_filter(const INPUT* in,
+                                             const OUTPUT* delta_out,
+                                             FILTER* delta_filter,
+                                             const Shape& in_shape,
+                                             const Shape& out_shape,
+                                             const Shape& filter_shape,
+                                             const Strides& filter_dilation,
+                                             const Strides& stride,
+                                             const CoordinateDiff& in_pad_below,
+                                             const CoordinateDiff& backprop_in_pad_above,
+                                             const Strides& in_dilation)
+            {
+                general_convolution<INPUT, OUTPUT, FILTER, ACCUMULATION>(in,
+                                                                         delta_out,
+                                                                         delta_filter,
+                                                                         in_shape,
+                                                                         out_shape,
+                                                                         filter_shape,
+                                                                         filter_dilation,
+                                                                         stride,
+                                                                         in_pad_below,
+                                                                         backprop_in_pad_above,
+                                                                         in_dilation,
+                                                                         1,
+                                                                         0,
+                                                                         1,
+                                                                         0,
+                                                                         1,
+                                                                         0);
+            }
+
+            template <typename OUTPUT,
+                      typename FILTER,
+                      typename INPUT,
+                      typename ACCUMULATION = typename widen<INPUT>::type>
+            void convolution_backprop_in(const OUTPUT* delta_out,
+                                         const FILTER* filter,
+                                         INPUT* delta_in,
+                                         const Shape& out_shape,
+                                         const Shape& filter_shape,
+                                         const Shape& in_shape,
+                                         const Strides& in_dilation,
+                                         const Strides& filter_dilation,
+                                         const CoordinateDiff& backward_delta_out_pad_below,
+                                         const CoordinateDiff& backward_delta_out_pad_above,
+                                         const Strides& stride)
+            {
+                // Note that we only reverse the spatial dimensions here (loop
+                // starts at 2)
+                std::vector<INPUT> reversed(shape_size(filter_shape));
+                AxisSet reverse_axes;
+                for (size_t i = 2; i < filter_shape.size(); ++i)
+                {
+                    reverse_axes.insert(i);
+                }
+                reverse(reinterpret_cast<const char*>(filter),
+                        reinterpret_cast<char*>(&reversed[0]),
+                        filter_shape,
+                        filter_shape,
+                        reverse_axes,
+                        sizeof(FILTER));
+
+                general_convolution<OUTPUT, FILTER, INPUT, ACCUMULATION>(
+                    delta_out,
+                    &reversed[0],
+                    delta_in,
+                    out_shape,
+                    filter_shape,
+                    in_shape,
+                    in_dilation,
+                    filter_dilation,
+                    backward_delta_out_pad_below,
+                    backward_delta_out_pad_above,
+                    stride,
+                    0,
+                    1,
+                    1,
+                    0,
+                    0,
+                    1);
+            }
+        } // namespace reference
+    }     // namespace runtime
+} // namespace ngraph
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/copy.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/copy.hpp
new file mode 100644 (file)
index 0000000..60a98a5
--- /dev/null
@@ -0,0 +1,37 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void copy(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg[i];
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/cos.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/cos.hpp
new file mode 100644 (file)
index 0000000..22e53e2
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void cos(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::cos(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/cosh.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/cosh.hpp
new file mode 100644 (file)
index 0000000..3d85385
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void cosh(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::cosh(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/ctc_loss.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/ctc_loss.hpp
new file mode 100644 (file)
index 0000000..895f7f4
--- /dev/null
@@ -0,0 +1,181 @@
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#pragma once
+
+#include <math.h>
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T, typename U>
+            void CTCLoss(const T* logits,
+                         const Shape& logitsShape,
+                         const U* logitsLength,
+                         const U* labels,
+                         const U* labelsLength,
+                         const U* blankIndexP,
+                         const bool preprocessCollapseRepeated,
+                         const bool ctcMergeRepeated,
+                         const bool unique,
+                         T* output)
+            {
+                const size_t batchNum = logitsShape[0];
+                const size_t maxTime = logitsShape[1];
+                const size_t classesNum = logitsShape[2];
+                U blankIndex = classesNum - 1;
+                if (blankIndexP != nullptr)
+                {
+                    blankIndex = blankIndexP[0];
+                }
+
+                std::vector<U> targetD(maxTime);
+                std::vector<U> pathS(maxTime);
+
+                const size_t TC = maxTime * classesNum;
+
+                for (size_t b = 0; b < batchNum; b++)
+                {
+                    U actualLogitLen = logitsLength[b];
+                    U actualTargetLen = labelsLength[b];
+                    if (actualLogitLen >= maxTime || actualTargetLen >= maxTime ||
+                        actualTargetLen > actualLogitLen)
+                    {
+                        throw ngraph_error(
+                            std::string("Logit or label length cannot be more than max sequence"
+                                        "length. Also a label length cannot be greater than a"
+                                        "logit length.\nMaxSeqLen: ") +
+                            std::to_string(maxTime) + "; Logit len: " +
+                            std::to_string(actualLogitLen) + "; Label len: " +
+                            std::to_string(actualTargetLen));
+                    }
+
+                    const U* target = &labels[b * maxTime];
+                    // Decoding target:
+                    // merge repeated characters if preprocess_collapse_repeated == True,
+                    // find unique elemnts if unique == True
+                    size_t decodedTargetLen = 0lu;
+                    if (unique)
+                    {
+                        std::unordered_set<U> uniqVals;
+                        for (size_t t = 0lu; t < actualTargetLen; t++)
+                        {
+                            if (uniqVals.find(target[t]) != uniqVals.end())
+                            {
+                                continue;
+                            }
+                            uniqVals.insert(target[t]);
+                            targetD[decodedTargetLen++] = target[t];
+                        }
+                    }
+                    else if (preprocessCollapseRepeated)
+                    {
+                        U prevValue = target[0];
+                        targetD[decodedTargetLen++] = target[0];
+                        for (size_t t = 1lu; t < actualTargetLen; t++)
+                        {
+                            if (target[t] == prevValue)
+                            {
+                                continue;
+                            }
+                            targetD[decodedTargetLen++] = target[t];
+                            prevValue = target[t];
+                        }
+                    }
+                    else
+                    {
+                        std::copy(target, target + actualTargetLen, targetD.data());
+                        decodedTargetLen = actualTargetLen;
+                    }
+
+                    const size_t BTC = b * TC;
+
+                    std::vector<T> kExp(actualLogitLen, 0);
+                    for (size_t t = 0; t < actualLogitLen; t++)
+                    {
+                        size_t btcT = BTC + classesNum * t;
+                        for (size_t c = 0; c < classesNum; c++)
+                        {
+                            kExp[t] += std::exp(logits[btcT + c]);
+                        }
+                    }
+
+                    T res = -std::numeric_limits<T>::infinity();
+
+                    // Looking for aligned paths
+                    std::function<void(size_t targetIdx, size_t start, size_t end)> findPaths = [&](
+                        size_t targetIdx, size_t start, size_t end) {
+                        if (end > actualLogitLen)
+                        {
+                            T prod = 0;
+                            for (size_t t = 0; t < actualLogitLen; t++)
+                            {
+                                prod += std::log(std::exp(logits[BTC + classesNum * t + pathS[t]]) /
+                                                 kExp[t]);
+                            }
+                            if (res == -std::numeric_limits<T>::infinity())
+                                res = prod;
+                            else if (prod != -std::numeric_limits<T>::infinity())
+                                res = res + std::log1pf(std::exp(prod - res));
+
+                            return;
+                        }
+
+                        size_t nextIdx = targetIdx + 1;
+                        int64_t st64 = start;
+                        if (!ctcMergeRepeated)
+                        {
+                            for (size_t pos = start; pos < end; pos++)
+                            {
+                                for (size_t bl = start; bl < pos; bl++)
+                                {
+                                    pathS[bl] = blankIndex;
+                                }
+                                pathS[pos] = targetD[targetIdx];
+                                findPaths(nextIdx, pos + 1, end + 1);
+                            }
+                        }
+                        else
+                        {
+                            for (size_t pos = start; pos < end; pos++)
+                            {
+                                for (size_t bl = start; bl < pos; bl++)
+                                {
+                                    pathS[bl] = blankIndex;
+                                }
+                                for (int64_t bl = pos; bl >= st64; bl--)
+                                {
+                                    pathS[bl] = targetD[targetIdx];
+                                    if (end == actualLogitLen)
+                                    {
+                                        for (int64_t ble = pos + 1; ble < actualLogitLen; ble++)
+                                        {
+                                            pathS[ble] = blankIndex;
+                                        }
+                                    }
+                                    size_t next_start = pos + 1;
+                                    if (targetIdx < decodedTargetLen - 1 &&
+                                        targetD[targetIdx] == targetD[targetIdx + 1])
+                                    {
+                                        pathS[next_start++] = blankIndex;
+                                    }
+                                    findPaths(nextIdx, next_start, end + 1);
+                                }
+                            }
+                        }
+                    }; // findPaths
+
+                    findPaths(0lu, 0lu, actualLogitLen - decodedTargetLen + 1lu);
+
+                    output[b] = -res;
+
+                } // for (size_t b = 0; b < batchNum; b++)
+            }     // CTCLoss
+        }         // reference
+    }             // runtime
+} // ngraph
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/cum_sum.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/cum_sum.hpp
new file mode 100644 (file)
index 0000000..6656bfe
--- /dev/null
@@ -0,0 +1,145 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <map>
+#include <utility>
+#include <vector>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/type/bfloat16.hpp"
+#include "ngraph/type/float16.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T, typename P>
+            void cumsum(const T* arg,
+                        const P* axis_tensor,
+                        T* out,
+                        const Shape& tensor_shape,
+                        const bool exclusive,
+                        const bool reverse)
+            {
+                CoordinateTransform temp_transform(tensor_shape);
+                for (const Coordinate& output_coord : temp_transform)
+                {
+                    out[temp_transform.index(output_coord)] = 0;
+                }
+
+                P axis = axis_tensor[0];
+                P rank = tensor_shape.size();
+
+                if (axis < -rank || axis > rank)
+                {
+                    throw ngraph_error("axis must be in the range [-rank, rank]");
+                }
+                axis = axis < 0 ? rank + axis : axis;
+
+                auto get_key = [&, axis](const Coordinate& coord) -> Coordinate {
+                    Coordinate result(coord.size(), 0);
+                    result[axis] = coord[axis];
+
+                    for (size_t i = 0; i < coord.size(); i++)
+                    {
+                        result[i] = coord[i] - result[i];
+                    }
+                    return result;
+                };
+
+                auto update_output_buffer =
+                    [&](size_t input_index,
+                        size_t output_index,
+                        T& prev,
+                        std::vector<std::pair<size_t, T>>& tensor_vec) -> void {
+
+                    tensor_vec[input_index].second = prev + tensor_vec[input_index].second;
+                    out[tensor_vec[output_index].first] = tensor_vec[input_index].second;
+
+                    // update prev to hold the last result value to compute ruuning sum for
+                    // subsequent iter
+                    prev = out[tensor_vec[output_index].first];
+                };
+
+                auto cum_sum =
+                    [&, exclusive, reverse](std::vector<std::pair<size_t, T>>& tensor_vec) {
+                        if (!reverse)
+                        {
+                            T prev = 0;
+                            for (size_t i = 0; i < tensor_vec.size(); i++)
+                            {
+                                if (exclusive && i == 0)
+                                {
+                                    out[tensor_vec[i].first] = prev;
+                                    continue;
+                                }
+                                // we will compute running sum of j-1 elements if exlusive=1 or else
+                                // for j elements if exclusive = 0
+                                size_t arg_index = exclusive == 1 ? i - 1 : i;
+                                update_output_buffer(arg_index, i, prev, tensor_vec);
+                            }
+                        }
+                        else // reverse == true
+                        {
+                            T prev = 0;
+                            for (size_t i = tensor_vec.size(); i-- > 0;)
+                            {
+                                if (exclusive && i == tensor_vec.size() - 1)
+                                {
+                                    out[tensor_vec[i].first] = prev;
+                                    continue;
+                                }
+                                // we will compute running sum of j-1 elements if exlusive=1 or else
+                                // for j elements if exclusive = 0
+                                size_t arg_index = exclusive == 1 ? i + 1 : i;
+                                update_output_buffer(arg_index, i, prev, tensor_vec);
+                            }
+                        }
+                    };
+
+                // Map to collect tensor elements belonging to the same axis
+                std::map<Coordinate, std::vector<std::pair<size_t, T>>> map_cooord_to_val;
+                CoordinateTransform input_transform(tensor_shape);
+                for (const Coordinate& input_coord : input_transform)
+                {
+                    // points to the current element in the input tensor
+                    T current = arg[input_transform.index(input_coord)];
+                    auto key = get_key(input_coord);
+                    auto index = input_transform.index(input_coord);
+                    if (map_cooord_to_val.find(key) != map_cooord_to_val.end())
+                    {
+                        map_cooord_to_val[key].push_back(std::make_pair(index, current));
+                    }
+                    else
+                    {
+                        map_cooord_to_val.insert({key, std::vector<std::pair<size_t, T>>()});
+                        map_cooord_to_val[key].push_back(std::make_pair(index, current));
+                    }
+                }
+                // iterate the map and perform cumulative sum over the give axis
+                for (auto& it : map_cooord_to_val)
+                {
+                    cum_sum(it.second);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/dequantize.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/dequantize.hpp
new file mode 100644 (file)
index 0000000..d76b7dd
--- /dev/null
@@ -0,0 +1,56 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/axis_set.hpp"
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename QUANT, typename REAL>
+            void dequantize(const QUANT* input,
+                            const REAL* scale,
+                            const QUANT* zero_point,
+                            REAL* output,
+                            const Shape& input_shape,
+                            const Shape& scale_zero_point_shape,
+                            const AxisSet& axes)
+            {
+                CoordinateTransform input_transform(input_shape);
+                CoordinateTransform scale_zero_point_transform(scale_zero_point_shape);
+
+                for (const Coordinate& input_coord : input_transform)
+                {
+                    Coordinate scale_zero_point_coord = project(input_coord, axes);
+
+                    output[input_transform.index(input_coord)] =
+                        static_cast<REAL>((
+                            input[input_transform.index(input_coord)] -
+                            zero_point[scale_zero_point_transform.index(scale_zero_point_coord)])) *
+                        scale[scale_zero_point_transform.index(scale_zero_point_coord)];
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/detection_output.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/detection_output.hpp
new file mode 100644 (file)
index 0000000..8379d79
--- /dev/null
@@ -0,0 +1,669 @@
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#pragma once
+
+#include <cstddef>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            enum
+            {
+                idxLocation,
+                idxConfidence,
+                idxPriors,
+                idxArmConfidence,
+                idxArmLocation,
+                numInputs
+            };
+
+            template <typename dataType>
+            class referenceDetectionOutput
+            {
+            private:
+                struct NormalizedBBox
+                {
+                    dataType xmin = 0;
+                    dataType ymin = 0;
+                    dataType xmax = 0;
+                    dataType ymax = 0;
+                    dataType size = 0;
+                };
+                using LabelBBox = std::map<int, std::vector<NormalizedBBox>>;
+
+                ngraph::op::DetectionOutputAttrs attrs;
+                size_t numImages;
+                size_t priorSize;
+                size_t numPriors;
+                size_t numLocClasses;
+                size_t offset;
+
+                void GetLocPredictions(const dataType* locData, std::vector<LabelBBox>& locations)
+                {
+                    locations.resize(numImages);
+                    for (size_t i = 0; i < numImages; ++i)
+                    {
+                        LabelBBox& labelBbox = locations[i];
+                        for (size_t p = 0; p < numPriors; ++p)
+                        {
+                            size_t startIdx = p * numLocClasses * 4;
+                            for (size_t c = 0; c < numLocClasses; ++c)
+                            {
+                                int label = attrs.share_location ? -1 : c;
+                                if (labelBbox.find(label) == labelBbox.end())
+                                {
+                                    labelBbox[label].resize(numPriors);
+                                }
+                                labelBbox[label][p].xmin = locData[startIdx + c * 4];
+                                labelBbox[label][p].ymin = locData[startIdx + c * 4 + 1];
+                                labelBbox[label][p].xmax = locData[startIdx + c * 4 + 2];
+                                labelBbox[label][p].ymax = locData[startIdx + c * 4 + 3];
+                            }
+                        }
+                        locData += numPriors * numLocClasses * 4;
+                    }
+                }
+
+                void GetConfidenceScores(
+                    const dataType* confData,
+                    std::vector<std::map<int, std::vector<dataType>>>& confPreds)
+                {
+                    confPreds.resize(numImages);
+                    for (int i = 0; i < numImages; ++i)
+                    {
+                        std::map<int, std::vector<dataType>>& labelScores = confPreds[i];
+                        for (int p = 0; p < numPriors; ++p)
+                        {
+                            int startIdx = p * attrs.num_classes;
+                            for (int c = 0; c < attrs.num_classes; ++c)
+                            {
+                                labelScores[c].push_back(confData[startIdx + c]);
+                            }
+                        }
+                        confData += numPriors * attrs.num_classes;
+                    }
+                }
+
+                void OSGetConfidenceScores(
+                    const dataType* confData,
+                    const dataType* armConfData,
+                    std::vector<std::map<int, std::vector<dataType>>>& confPreds)
+                {
+                    confPreds.resize(numImages);
+                    for (int i = 0; i < numImages; ++i)
+                    {
+                        std::map<int, std::vector<dataType>>& labelScores = confPreds[i];
+                        for (int p = 0; p < numPriors; ++p)
+                        {
+                            int startIdx = p * attrs.num_classes;
+                            if (armConfData[p * 2 + 1] < attrs.objectness_score)
+                            {
+                                for (int c = 0; c < attrs.num_classes; ++c)
+                                {
+                                    c == attrs.background_label_id ? labelScores[c].push_back(1)
+                                                                   : labelScores[c].push_back(0);
+                                }
+                            }
+                            else
+                            {
+                                for (int c = 0; c < attrs.num_classes; ++c)
+                                {
+                                    labelScores[c].push_back(confData[startIdx + c]);
+                                }
+                            }
+                        }
+                        confData += numPriors * attrs.num_classes;
+                        armConfData += numPriors * 2;
+                    }
+                }
+
+                dataType BBoxSize(const NormalizedBBox& bbox)
+                {
+                    if (bbox.xmax < bbox.xmin || bbox.ymax < bbox.ymin)
+                    {
+                        return 0;
+                    }
+                    else
+                    {
+                        dataType width = bbox.xmax - bbox.xmin;
+                        dataType height = bbox.ymax - bbox.ymin;
+                        return width * height;
+                    }
+                }
+
+                void GetPriorBBoxes(const dataType* priorData,
+                                    std::vector<std::vector<NormalizedBBox>>& priorBboxes,
+                                    std::vector<std::vector<std::vector<dataType>>>& priorVariances)
+                {
+                    priorBboxes.resize(numImages);
+                    priorVariances.resize(numImages);
+                    for (int n = 0; n < numImages; n++)
+                    {
+                        priorData += attrs.variance_encoded_in_target
+                                         ? n * numPriors * priorSize
+                                         : 2 * n * numPriors * priorSize;
+                        std::vector<NormalizedBBox>& currPrBbox = priorBboxes[n];
+                        std::vector<std::vector<dataType>>& currPrVar = priorVariances[n];
+                        for (int i = 0; i < numPriors; ++i)
+                        {
+                            int start_idx = i * priorSize;
+                            NormalizedBBox bbox;
+                            bbox.xmin = priorData[start_idx + 0 + offset];
+                            bbox.ymin = priorData[start_idx + 1 + offset];
+                            bbox.xmax = priorData[start_idx + 2 + offset];
+                            bbox.ymax = priorData[start_idx + 3 + offset];
+                            dataType bbox_size = BBoxSize(bbox);
+                            bbox.size = bbox_size;
+                            currPrBbox.push_back(bbox);
+                        }
+                        if (!attrs.variance_encoded_in_target)
+                        {
+                            const dataType* priorVar = priorData + numPriors * priorSize;
+                            for (int i = 0; i < numPriors; ++i)
+                            {
+                                int start_idx = i * 4;
+                                std::vector<dataType> var;
+                                for (int j = 0; j < 4; ++j)
+                                {
+                                    var.push_back(priorVar[start_idx + j]);
+                                }
+                                currPrVar.push_back(var);
+                            }
+                        }
+                    }
+                }
+
+                void DecodeBBox(const NormalizedBBox& priorBboxes,
+                                const std::vector<dataType>& priorVariances,
+                                const NormalizedBBox& bbox,
+                                NormalizedBBox& decodeBbox)
+                {
+                    dataType priorXmin = priorBboxes.xmin;
+                    dataType priorYmin = priorBboxes.ymin;
+                    dataType priorXmax = priorBboxes.xmax;
+                    dataType priorYmax = priorBboxes.ymax;
+
+                    if (!attrs.normalized)
+                    {
+                        priorXmin /= attrs.input_width;
+                        priorYmin /= attrs.input_height;
+                        priorXmax /= attrs.input_width;
+                        priorYmax /= attrs.input_height;
+                    }
+                    if (attrs.code_type == "caffe.PriorBoxParameter.CORNER")
+                    {
+                        if (attrs.variance_encoded_in_target)
+                        {
+                            decodeBbox.xmin = priorXmin + bbox.xmin;
+                            decodeBbox.ymin = priorYmin + bbox.ymin;
+                            decodeBbox.xmax = priorXmax + bbox.xmax;
+                            decodeBbox.ymax = priorYmax + bbox.ymax;
+                        }
+                        else
+                        {
+                            decodeBbox.xmin = priorXmin + priorVariances[0] * bbox.xmin;
+                            decodeBbox.ymin = priorYmin + priorVariances[1] * bbox.ymin;
+                            decodeBbox.xmax = priorXmax + priorVariances[2] * bbox.xmax;
+                            decodeBbox.ymax = priorYmax + priorVariances[3] * bbox.ymax;
+                        }
+                    }
+                    else if (attrs.code_type == "caffe.PriorBoxParameter.CENTER_SIZE")
+                    {
+                        dataType priorWidth = priorXmax - priorXmin;
+                        dataType priorHeight = priorYmax - priorYmin;
+                        dataType priorCenterX = (priorXmin + priorXmax) / 2;
+                        dataType priorCenterY = (priorYmin + priorYmax) / 2;
+                        dataType decodeBboxCenterX, decodeBboxCenterY;
+                        dataType decodeBboxWidth, decodeBboxHeight;
+                        if (attrs.variance_encoded_in_target)
+                        {
+                            decodeBboxCenterX = bbox.xmin * priorWidth + priorCenterX;
+                            decodeBboxCenterY = bbox.ymin * priorHeight + priorCenterY;
+                            decodeBboxWidth = std::exp(bbox.xmax) * priorWidth;
+                            decodeBboxHeight = std::exp(bbox.ymax) * priorHeight;
+                        }
+                        else
+                        {
+                            decodeBboxCenterX =
+                                priorVariances[0] * bbox.xmin * priorWidth + priorCenterX;
+                            decodeBboxCenterY =
+                                priorVariances[1] * bbox.ymin * priorHeight + priorCenterY;
+                            decodeBboxWidth = std::exp(priorVariances[2] * bbox.xmax) * priorWidth;
+                            decodeBboxHeight =
+                                std::exp(priorVariances[3] * bbox.ymax) * priorHeight;
+                        }
+                        decodeBbox.xmin = decodeBboxCenterX - decodeBboxWidth / 2;
+                        decodeBbox.ymin = decodeBboxCenterY - decodeBboxHeight / 2;
+                        decodeBbox.xmax = decodeBboxCenterX + decodeBboxWidth / 2;
+                        decodeBbox.ymax = decodeBboxCenterY + decodeBboxHeight / 2;
+                    }
+                    if (attrs.clip_before_nms)
+                    {
+                        decodeBbox.xmin =
+                            std::max<dataType>(0, std::min<dataType>(1, decodeBbox.xmin));
+                        decodeBbox.ymin =
+                            std::max<dataType>(0, std::min<dataType>(1, decodeBbox.ymin));
+                        decodeBbox.xmax =
+                            std::max<dataType>(0, std::min<dataType>(1, decodeBbox.xmax));
+                        decodeBbox.ymax =
+                            std::max<dataType>(0, std::min<dataType>(1, decodeBbox.ymax));
+                    }
+                    dataType bboxSize = BBoxSize(decodeBbox);
+                    decodeBbox.size = bboxSize;
+                }
+
+                void DecodeBBoxes(const std::vector<NormalizedBBox>& priorBboxes,
+                                  const std::vector<std::vector<dataType>>& priorVariances,
+                                  const std::vector<NormalizedBBox>& labelLocPreds,
+                                  std::vector<NormalizedBBox>& decodeBboxes)
+                {
+                    int numBboxes = priorBboxes.size();
+                    for (int i = 0; i < numBboxes; ++i)
+                    {
+                        NormalizedBBox decodeBbox;
+                        DecodeBBox(priorBboxes[i], priorVariances[i], labelLocPreds[i], decodeBbox);
+                        decodeBboxes.push_back(decodeBbox);
+                    }
+                }
+
+                void DecodeBBoxesAll(
+                    const std::vector<LabelBBox>& locPreds,
+                    const std::vector<std::vector<NormalizedBBox>>& priorBboxes,
+                    const std::vector<std::vector<std::vector<dataType>>>& priorVariances,
+                    std::vector<LabelBBox>& decodeBboxes)
+                {
+                    decodeBboxes.resize(numImages);
+                    for (int i = 0; i < numImages; ++i)
+                    {
+                        LabelBBox& decodeBboxesImage = decodeBboxes[i];
+                        const std::vector<NormalizedBBox>& currPrBbox = priorBboxes[i];
+                        const std::vector<std::vector<dataType>>& currPrVar = priorVariances[i];
+                        for (int c = 0; c < numLocClasses; ++c)
+                        {
+                            int label = attrs.share_location ? -1 : c;
+                            if (label == attrs.background_label_id)
+                            {
+                                continue;
+                            }
+                            const std::vector<NormalizedBBox>& labelLocPreds =
+                                locPreds[i].find(label)->second;
+                            DecodeBBoxes(
+                                currPrBbox, currPrVar, labelLocPreds, decodeBboxesImage[label]);
+                        }
+                    }
+                }
+
+                void CasRegDecodeBBoxesAll(
+                    const std::vector<LabelBBox>& locPreds,
+                    const std::vector<std::vector<NormalizedBBox>>& priorBboxes,
+                    const std::vector<std::vector<std::vector<dataType>>>& priorVariances,
+                    std::vector<LabelBBox>& decodeBboxes,
+                    const std::vector<LabelBBox>& armLocPreds)
+                {
+                    decodeBboxes.resize(numImages);
+                    for (int i = 0; i < numImages; ++i)
+                    {
+                        LabelBBox& decodeBboxesImage = decodeBboxes[i];
+                        const std::vector<NormalizedBBox>& currPrBbox = priorBboxes[i];
+                        const std::vector<std::vector<dataType>>& currPrVar = priorVariances[i];
+                        for (int c = 0; c < numLocClasses; ++c)
+                        {
+                            int label = attrs.share_location ? -1 : c;
+                            if (label == attrs.background_label_id)
+                            {
+                                continue;
+                            }
+                            const std::vector<NormalizedBBox>& labelArmLocPreds =
+                                armLocPreds[i].find(label)->second;
+                            std::vector<NormalizedBBox> decodePriorBboxes;
+                            DecodeBBoxes(
+                                currPrBbox, currPrVar, labelArmLocPreds, decodePriorBboxes);
+                            const std::vector<NormalizedBBox>& labelLocPreds =
+                                locPreds[i].find(label)->second;
+                            DecodeBBoxes(decodePriorBboxes,
+                                         currPrVar,
+                                         labelLocPreds,
+                                         decodeBboxesImage[label]);
+                        }
+                    }
+                }
+
+                template <typename T>
+                static bool SortScorePairDescend(const std::pair<dataType, T>& pair1,
+                                                 const std::pair<dataType, T>& pair2)
+                {
+                    return pair1.first > pair2.first;
+                }
+
+                void GetMaxScoreIndex(const std::vector<dataType>& scores,
+                                      const dataType threshold,
+                                      const int topK,
+                                      std::vector<std::pair<dataType, int>>& scoreIndexVec)
+                {
+                    for (int i = 0; i < scores.size(); ++i)
+                    {
+                        if (scores[i] > threshold)
+                        {
+                            scoreIndexVec.push_back(std::make_pair(scores[i], i));
+                        }
+                    }
+
+                    std::stable_sort(
+                        scoreIndexVec.begin(), scoreIndexVec.end(), SortScorePairDescend<int>);
+                    if (topK > -1 && topK < scoreIndexVec.size())
+                    {
+                        scoreIndexVec.resize(topK);
+                    }
+                }
+
+                void IntersectBBox(const NormalizedBBox& bbox1,
+                                   const NormalizedBBox& bbox2,
+                                   NormalizedBBox& intersectBbox)
+                {
+                    if (bbox2.xmin > bbox1.xmax || bbox2.xmax < bbox1.xmin ||
+                        bbox2.ymin > bbox1.ymax || bbox2.ymax < bbox1.ymin)
+                    {
+                        intersectBbox.xmin = 0;
+                        intersectBbox.ymin = 0;
+                        intersectBbox.xmax = 0;
+                        intersectBbox.ymax = 0;
+                    }
+                    else
+                    {
+                        intersectBbox.xmin = std::max<dataType>(bbox1.xmin, bbox2.xmin);
+                        intersectBbox.ymin = std::max<dataType>(bbox1.ymin, bbox2.ymin);
+                        intersectBbox.xmax = std::min<dataType>(bbox1.xmax, bbox2.xmax);
+                        intersectBbox.ymax = std::min<dataType>(bbox1.ymax, bbox2.ymax);
+                    }
+                }
+
+                dataType JaccardOverlap(const NormalizedBBox& bbox1, const NormalizedBBox& bbox2)
+                {
+                    NormalizedBBox intersectBbox;
+                    IntersectBBox(bbox1, bbox2, intersectBbox);
+                    dataType intersectWidth, intersectHeight;
+                    intersectWidth = intersectBbox.xmax - intersectBbox.xmin;
+                    intersectHeight = intersectBbox.ymax - intersectBbox.ymin;
+                    if (intersectWidth > 0 && intersectHeight > 0)
+                    {
+                        dataType intersect_size = intersectWidth * intersectHeight;
+                        dataType bbox1_size = BBoxSize(bbox1);
+                        dataType bbox2_size = BBoxSize(bbox2);
+
+                        return intersect_size / (bbox1_size + bbox2_size - intersect_size);
+                    }
+                    else
+                    {
+                        return 0.0f;
+                    }
+                }
+
+                void caffeNMS(const std::vector<NormalizedBBox>& bboxes,
+                              const std::vector<dataType>& scores,
+                              std::vector<int>& indices)
+                {
+                    std::vector<std::pair<dataType, int>> scoreIndexVec;
+                    GetMaxScoreIndex(
+                        scores, attrs.confidence_threshold, attrs.top_k, scoreIndexVec);
+                    while (scoreIndexVec.size() != 0)
+                    {
+                        const int idx = scoreIndexVec.front().second;
+                        bool keep = true;
+                        for (int k = 0; k < indices.size(); ++k)
+                        {
+                            const int kept_idx = indices[k];
+                            dataType overlap = JaccardOverlap(bboxes[idx], bboxes[kept_idx]);
+                            if (overlap > attrs.nms_threshold)
+                            {
+                                keep = false;
+                                break;
+                            }
+                        }
+                        if (keep)
+                        {
+                            indices.push_back(idx);
+                        }
+                        scoreIndexVec.erase(scoreIndexVec.begin());
+                    }
+                }
+
+                void mxNetNms(const LabelBBox& decodeBboxesImage,
+                              const std::map<int, std::vector<dataType>>& confScores,
+                              std::map<int, std::vector<int>>& indices)
+                {
+                    std::vector<std::pair<dataType, std::pair<int, int>>> scoreIndexPairs;
+                    for (int p = 0; p < numPriors; p++)
+                    {
+                        dataType conf = -1;
+                        int id = 0;
+                        for (int c = 1; c < attrs.num_classes; c++)
+                        {
+                            dataType temp = confScores.at(c)[p];
+                            if (temp > conf)
+                            {
+                                conf = temp;
+                                id = c;
+                            }
+                        }
+                        if (id > 0 && conf >= attrs.confidence_threshold)
+                        {
+                            scoreIndexPairs.push_back(std::make_pair(conf, std::make_pair(id, p)));
+                        }
+                    }
+                    std::sort(scoreIndexPairs.begin(),
+                              scoreIndexPairs.end(),
+                              SortScorePairDescend<std::pair<int, int>>);
+
+                    if (attrs.top_k != -1)
+                        if (scoreIndexPairs.size() > attrs.top_k)
+                            scoreIndexPairs.resize(attrs.top_k);
+
+                    while (scoreIndexPairs.size() != 0)
+                    {
+                        const int cls = scoreIndexPairs.front().second.first;
+                        const int prior = scoreIndexPairs.front().second.second;
+                        std::vector<int>& currInd = indices[cls];
+                        bool keep = true;
+                        for (int i = 0; i < currInd.size(); i++)
+                        {
+                            const int keptIdx = currInd[i];
+                            auto currBbox = attrs.share_location ? decodeBboxesImage.at(-1)
+                                                                 : decodeBboxesImage.at(cls);
+                            dataType overlap = JaccardOverlap(currBbox[prior], currBbox[keptIdx]);
+                            if (overlap > attrs.nms_threshold)
+                            {
+                                keep = false;
+                                break;
+                            }
+                        }
+                        if (keep)
+                        {
+                            currInd.push_back(prior);
+                        }
+                        scoreIndexPairs.erase(scoreIndexPairs.begin());
+                    }
+                }
+
+            public:
+                referenceDetectionOutput(const ngraph::op::DetectionOutputAttrs& _attrs,
+                                         const ngraph::Shape& locShape,
+                                         const ngraph::Shape& priorsShape)
+                    : attrs(_attrs)
+                {
+                    numImages = locShape[0];
+                    priorSize = _attrs.normalized ? 4 : 5;
+                    offset = _attrs.normalized ? 0 : 1;
+                    numPriors = priorsShape[2] / priorSize;
+                    numLocClasses =
+                        _attrs.share_location ? 1 : static_cast<size_t>(_attrs.num_classes);
+                }
+
+                void run(const dataType* _location,
+                         const dataType* _confidence,
+                         const dataType* _priors,
+                         const dataType* _armConfidence,
+                         const dataType* _armLocation,
+                         dataType* result)
+                {
+                    bool withAddBoxPred = _armConfidence != nullptr && _armLocation != nullptr;
+                    std::vector<LabelBBox> armLocPreds;
+                    if (withAddBoxPred)
+                    {
+                        GetLocPredictions(_armLocation, armLocPreds);
+                    }
+                    std::vector<LabelBBox> locPreds;
+                    GetLocPredictions(_location, locPreds);
+                    std::vector<std::map<int, std::vector<dataType>>> confPreds;
+                    if (withAddBoxPred)
+                    {
+                        OSGetConfidenceScores(_confidence, _armConfidence, confPreds);
+                    }
+                    else
+                    {
+                        GetConfidenceScores(_confidence, confPreds);
+                    }
+                    std::vector<std::vector<NormalizedBBox>> priorBboxes;
+                    std::vector<std::vector<std::vector<dataType>>> priorVariances;
+                    GetPriorBBoxes(_priors, priorBboxes, priorVariances);
+                    std::vector<LabelBBox> decodeBboxes;
+                    if (withAddBoxPred)
+                    {
+                        CasRegDecodeBBoxesAll(
+                            locPreds, priorBboxes, priorVariances, decodeBboxes, armLocPreds);
+                    }
+                    else
+                    {
+                        DecodeBBoxesAll(locPreds, priorBboxes, priorVariances, decodeBboxes);
+                    }
+
+                    int numKept = 0;
+                    std::vector<std::map<int, std::vector<int>>> allIndices;
+                    for (int i = 0; i < numImages; ++i)
+                    {
+                        const LabelBBox& decodeBboxesImage = decodeBboxes[i];
+                        const std::map<int, std::vector<dataType>>& confScores = confPreds[i];
+                        std::map<int, std::vector<int>> indices;
+                        int numDet = 0;
+                        if (!attrs.decrease_label_id)
+                        {
+                            // Caffe style
+                            for (int c = 0; c < attrs.num_classes; ++c)
+                            {
+                                if (c == attrs.background_label_id)
+                                {
+                                    continue;
+                                }
+                                const std::vector<dataType>& scores = confScores.find(c)->second;
+                                int label = attrs.share_location ? -1 : c;
+                                const std::vector<NormalizedBBox>& bboxes =
+                                    decodeBboxesImage.find(label)->second;
+                                caffeNMS(bboxes, scores, indices[c]);
+                                numDet += indices[c].size();
+                            }
+                        }
+                        else
+                        {
+                            // MXNet style
+                            mxNetNms(decodeBboxesImage, confScores, indices);
+                            for (auto it = indices.begin(); it != indices.end(); it++)
+                                numDet += it->second.size();
+                        }
+                        if (attrs.keep_top_k[0] > -1 && numDet > attrs.keep_top_k[0])
+                        {
+                            std::vector<std::pair<dataType, std::pair<int, int>>> scoreIndexPairs;
+                            for (auto it = indices.begin(); it != indices.end(); ++it)
+                            {
+                                int label = it->first;
+                                const std::vector<int>& labelIndices = it->second;
+                                const std::vector<dataType>& scores =
+                                    confScores.find(label)->second;
+                                for (int j = 0; j < labelIndices.size(); ++j)
+                                {
+                                    int idx = labelIndices[j];
+                                    scoreIndexPairs.push_back(
+                                        std::make_pair(scores[idx], std::make_pair(label, idx)));
+                                }
+                            }
+                            std::sort(scoreIndexPairs.begin(),
+                                      scoreIndexPairs.end(),
+                                      SortScorePairDescend<std::pair<int, int>>);
+                            scoreIndexPairs.resize(attrs.keep_top_k[0]);
+                            std::map<int, std::vector<int>> newIndices;
+                            for (int j = 0; j < scoreIndexPairs.size(); ++j)
+                            {
+                                int label = scoreIndexPairs[j].second.first;
+                                int idx = scoreIndexPairs[j].second.second;
+                                newIndices[label].push_back(idx);
+                            }
+                            allIndices.push_back(newIndices);
+                            numKept += attrs.top_k;
+                        }
+                        else
+                        {
+                            allIndices.push_back(indices);
+                            numKept += numDet;
+                        }
+                    }
+
+                    int count = 0;
+                    for (int i = 0; i < numImages; ++i)
+                    {
+                        const std::map<int, std::vector<dataType>>& confScores = confPreds[i];
+                        const LabelBBox& decodeBboxesImage = decodeBboxes[i];
+                        for (auto it = allIndices[i].begin(); it != allIndices[i].end(); ++it)
+                        {
+                            int label = it->first;
+                            const std::vector<dataType>& scores = confScores.find(label)->second;
+                            int loc_label = attrs.share_location ? -1 : label;
+                            const std::vector<NormalizedBBox>& bboxes =
+                                decodeBboxesImage.find(loc_label)->second;
+                            std::vector<int>& indices = it->second;
+                            for (int j = 0; j < indices.size(); ++j)
+                            {
+                                int idx = indices[j];
+                                result[count * 7 + 0] = i;
+                                result[count * 7 + 1] =
+                                    attrs.decrease_label_id ? (label - 1) : label;
+                                result[count * 7 + 2] = scores[idx];
+                                const NormalizedBBox& bbox = bboxes[idx];
+
+                                dataType xmin = bbox.xmin;
+                                dataType ymin = bbox.ymin;
+                                dataType xmax = bbox.xmax;
+                                dataType ymax = bbox.ymax;
+
+                                if (attrs.clip_after_nms)
+                                {
+                                    xmin = std::max<dataType>(0, std::min<dataType>(1, xmin));
+                                    ymin = std::max<dataType>(0, std::min<dataType>(1, ymin));
+                                    xmax = std::max<dataType>(0, std::min<dataType>(1, xmax));
+                                    ymax = std::max<dataType>(0, std::min<dataType>(1, ymax));
+                                }
+
+                                result[count * 7 + 3] = xmin;
+                                result[count * 7 + 4] = ymin;
+                                result[count * 7 + 5] = xmax;
+                                result[count * 7 + 6] = ymax;
+                                ++count;
+                            }
+                        }
+                    }
+                    if (count < numImages * attrs.keep_top_k[0])
+                    {
+                        result[count * 7 + 0] = -1;
+                    }
+                }
+            };
+        } // namespace reference
+    }     // namespace runtime
+} // namespace ngraph
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/divide.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/divide.hpp
new file mode 100644 (file)
index 0000000..c7b5582
--- /dev/null
@@ -0,0 +1,154 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+#include <stdexcept>
+#include <type_traits>
+
+#include "ngraph/op/util/attr_types.hpp"
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+#include "ngraph/shape.hpp"
+#include "ngraph/type/bfloat16.hpp"
+#include "ngraph/type/float16.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            // NOTE: Execution throws `std::domain_error` if either a non-integral value or an
+            // out-of-bounds value is detected in the input tensor.
+
+            // In English: return type is void and T must be an integral type.
+            template <typename T>
+            typename std::enable_if<std::is_integral<T>::value>::type
+                divide(const T* arg0, const T* arg1, T* out, size_t count, bool pythondiv)
+            {
+                if (pythondiv)
+                {
+                    for (size_t i = 0; i < count; i++)
+                    {
+                        if (arg1[i] == 0)
+                        {
+                            throw std::domain_error("integer division by zero");
+                        }
+                        T quot = arg0[i] / arg1[i];
+                        T rem = arg0[i] % arg1[i];
+                        if ((rem != 0) && ((arg0[i] < 0) != (arg1[i] < 0)))
+                        {
+                            out[i] = quot - 1;
+                        }
+                        else
+                        {
+                            out[i] = quot;
+                        }
+                    }
+                }
+                else
+                {
+                    for (size_t i = 0; i < count; i++)
+                    {
+                        if (arg1[i] == 0)
+                        {
+                            throw std::domain_error("integer division by zero");
+                        }
+                        out[i] = arg0[i] / arg1[i];
+                    }
+                }
+            }
+
+            template <typename T>
+            typename std::enable_if<std::is_integral<T>::value>::type
+                divide(const T* arg0,
+                       const T* arg1,
+                       T* out,
+                       const Shape& arg0_shape,
+                       const Shape& arg1_shape,
+                       const op::AutoBroadcastSpec& broadcast_spec,
+                       bool pythondiv)
+            {
+                auto functor = [pythondiv](T x, T y) -> T {
+                    if (pythondiv)
+                    {
+                        if (y == 0)
+                        {
+                            throw std::domain_error("integer division by zero");
+                        }
+                        T quot = x / y;
+                        T rem = x % y;
+                        if ((rem != 0) && ((x < 0) != (y < 0)))
+                        {
+                            return quot - 1;
+                        }
+                        else
+                        {
+                            return quot;
+                        }
+                    }
+                    else
+                    {
+                        if (y == 0)
+                        {
+                            throw std::domain_error("integer division by zero");
+                        }
+                        return x / y;
+                    }
+                };
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, functor);
+            }
+
+            // In English: return type is void and T must be a standard floating point type, or
+            // bfloat16, or float16.
+            template <typename T>
+            typename std::enable_if<std::is_floating_point<T>::value ||
+                                    std::is_same<T, bfloat16>::value ||
+                                    std::is_same<T, float16>::value>::type
+                divide(const T* arg0, const T* arg1, T* out, size_t count, bool pythondiv)
+            {
+                (void)pythondiv;
+                for (size_t i = 0; i < count; i++)
+                {
+                    // TODO: Here we do not check for div by zero, so we'll get +-inf here
+                    // if arg1[i] == 0. Is that the right thing to do? Jury's still out.
+                    out[i] = arg0[i] / arg1[i];
+                }
+            }
+
+            template <typename T>
+            typename std::enable_if<std::is_floating_point<T>::value ||
+                                    std::is_same<T, bfloat16>::value ||
+                                    std::is_same<T, float16>::value>::type
+                divide(const T* arg0,
+                       const T* arg1,
+                       T* out,
+                       const Shape& arg0_shape,
+                       const Shape& arg1_shape,
+                       const op::AutoBroadcastSpec& broadcast_spec,
+                       bool pythondiv)
+            {
+                (void)pythondiv;
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
+                        return x / y;
+                    });
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/dot.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/dot.hpp
new file mode 100644 (file)
index 0000000..be8201b
--- /dev/null
@@ -0,0 +1,170 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <utility>
+
+#include <cfenv>
+#include <functional>
+#include "convolution.hpp"
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename INPUT0,
+                      typename INPUT1,
+                      typename OUTPUT,
+                      typename ACCUMULATION = typename widen<OUTPUT>::type>
+            void dot(const INPUT0* arg0,
+                     const INPUT1* arg1,
+                     OUTPUT* out,
+                     const Shape& arg0_shape,
+                     const Shape& arg1_shape,
+                     const Shape& out_shape,
+                     size_t reduction_axes_count,
+                     const float* input0_scale = nullptr,
+                     const INPUT0* input0_zero_point = nullptr,
+                     const float* input1_scale = nullptr,
+                     const INPUT1* input1_zero_point = nullptr,
+                     const float* output_scale = nullptr,
+                     const OUTPUT* output_zero_point = nullptr)
+            {
+                bool is_quantized = false;
+                if (input0_scale && input0_zero_point && input1_scale && input1_zero_point &&
+                    output_scale && output_zero_point)
+                {
+                    is_quantized = true;
+                }
+
+                auto old_mode = std::fegetround();
+                std::fesetround(FE_TONEAREST);
+                // Get the sizes of the dot axes. It's easiest to pull them from arg1 because
+                // they're right up front.
+                Shape dot_axis_sizes(reduction_axes_count);
+                std::copy(arg1_shape.begin(),
+                          arg1_shape.begin() + reduction_axes_count,
+                          dot_axis_sizes.begin());
+
+                CoordinateTransform arg0_transform(arg0_shape);
+                CoordinateTransform arg1_transform(arg1_shape);
+                CoordinateTransform output_transform(out_shape);
+
+                // Create coordinate transforms for arg0 and arg1 that throw away the dotted axes.
+                size_t arg0_projected_rank = arg0_shape.size() - reduction_axes_count;
+                size_t arg1_projected_rank = arg1_shape.size() - reduction_axes_count;
+
+                Shape arg0_projected_shape(arg0_projected_rank);
+                std::copy(arg0_shape.begin(),
+                          arg0_shape.begin() + arg0_projected_rank,
+                          arg0_projected_shape.begin());
+
+                Shape arg1_projected_shape(arg1_projected_rank);
+                std::copy(arg1_shape.begin() + reduction_axes_count,
+                          arg1_shape.end(),
+                          arg1_projected_shape.begin());
+
+                CoordinateTransform arg0_projected_transform(arg0_projected_shape);
+                CoordinateTransform arg1_projected_transform(arg1_projected_shape);
+
+                // Create a coordinate transform that allows us to iterate over all possible values
+                // for the dotted axes.
+                CoordinateTransform dot_axes_transform(dot_axis_sizes);
+
+                for (const Coordinate& arg0_projected_coord : arg0_projected_transform)
+                {
+                    for (const Coordinate& arg1_projected_coord : arg1_projected_transform)
+                    {
+                        // The output coordinate is just the concatenation of the projected
+                        // coordinates.
+                        Coordinate out_coord(arg0_projected_coord.size() +
+                                             arg1_projected_coord.size());
+
+                        auto out_coord_it = std::copy(arg0_projected_coord.begin(),
+                                                      arg0_projected_coord.end(),
+                                                      out_coord.begin());
+                        std::copy(
+                            arg1_projected_coord.begin(), arg1_projected_coord.end(), out_coord_it);
+
+                        // Zero out to start the sum.
+                        ACCUMULATION sum = 0;
+
+                        size_t out_index = output_transform.index(out_coord);
+
+                        // Walk along the dotted axes.
+                        Coordinate arg0_coord(arg0_shape.size());
+                        Coordinate arg1_coord(arg1_shape.size());
+                        auto arg0_it = std::copy(arg0_projected_coord.begin(),
+                                                 arg0_projected_coord.end(),
+                                                 arg0_coord.begin());
+                        for (const Coordinate& dot_axis_positions : dot_axes_transform)
+                        {
+                            // In order to find the points to multiply together, we need to inject
+                            // our current positions along the dotted axes back into the projected
+                            // arg0 and arg1 coordinates.
+                            std::copy(
+                                dot_axis_positions.begin(), dot_axis_positions.end(), arg0_it);
+
+                            auto arg1_it = std::copy(dot_axis_positions.begin(),
+                                                     dot_axis_positions.end(),
+                                                     arg1_coord.begin());
+                            std::copy(
+                                arg1_projected_coord.begin(), arg1_projected_coord.end(), arg1_it);
+
+                            // Multiply and add to the sum.
+                            if (is_quantized)
+                            {
+                                sum = sum + ((static_cast<ACCUMULATION>(
+                                                  arg0[arg0_transform.index(arg0_coord)]) -
+                                              static_cast<ACCUMULATION>(*input0_zero_point)) *
+                                             (static_cast<ACCUMULATION>(
+                                                  arg1[arg1_transform.index(arg1_coord)]) -
+                                              static_cast<ACCUMULATION>(*input1_zero_point)));
+                            }
+                            else
+                            {
+                                sum = sum + (static_cast<ACCUMULATION>(
+                                                 arg0[arg0_transform.index(arg0_coord)]) *
+                                             static_cast<ACCUMULATION>(
+                                                 arg1[arg1_transform.index(arg1_coord)]));
+                            }
+                        }
+
+                        if (is_quantized)
+                        {
+                            float scale = *input0_scale * *input1_scale / *output_scale;
+                            // Write the sum back.
+                            out[out_index] =
+                                static_cast<OUTPUT>(std::round(static_cast<float>(sum) * scale)) +
+                                *output_zero_point;
+                        }
+                        else
+                        {
+                            out[out_index] = sum;
+                        }
+                    }
+                    std::fesetround(old_mode);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/elu.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/elu.hpp
new file mode 100644 (file)
index 0000000..3440ece
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void elu(const T* arg, T* out, size_t count, double alpha)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg[i] < 0 ? alpha * (std::exp(arg[i]) - 1.0) : arg[i];
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/embedding_bag_offsets_sum.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/embedding_bag_offsets_sum.hpp
new file mode 100644 (file)
index 0000000..98ad115
--- /dev/null
@@ -0,0 +1,121 @@
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#pragma once
+
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T, typename U>
+            void embeddingBagOffsetsSum(const T* emb_table,
+                                        const U* indices,
+                                        const U* offsets,
+                                        const U* default_index,
+                                        const T* weights,
+                                        T* out,
+                                        const size_t indices_count,
+                                        const Shape& outShape)
+            {
+                const size_t offsets_size = outShape[0];
+                std::vector<U> default_indices;
+                if (default_index)
+                    default_indices.push_back(default_index[0]);
+
+                size_t embDepth = 1;
+                for (size_t i = 1; i < outShape.size(); i++)
+                {
+                    embDepth *= outShape[i];
+                }
+                memset(out, 0, shape_size(outShape) * sizeof(T));
+
+                auto get_indices = [&](size_t emb_index,
+                                       const U*& indices_ref,
+                                       size_t& indices_num,
+                                       size_t& weights_idx,
+                                       bool& with_weights) {
+                    if (emb_index >= offsets_size)
+                        throw ngraph_error("Invalid embedding bag index.");
+                    if (offsets[emb_index] >= indices_count)
+                        throw ngraph_error(
+                            std::string(
+                                "Offset value exceeds indices size in the model.\noffset: ") +
+                            std::to_string(offsets[emb_index]) + "; indices size: " +
+                            std::to_string(indices_count));
+
+                    indices_ref = nullptr;
+                    indices_num = 0lu;
+                    with_weights = (weights != nullptr);
+
+                    if (emb_index == offsets_size - 1lu)
+                        indices_num = indices_count - offsets[emb_index];
+                    else
+                        indices_num = offsets[emb_index + 1lu] - offsets[emb_index];
+
+                    if (indices_num != 0lu)
+                    {
+                        indices_ref = indices + offsets[emb_index];
+                    }
+                    else
+                    {
+                        // Empty or default bag
+                        with_weights = false;
+                        if (default_indices.size() == 1lu)
+                        {
+                            indices_ref = default_indices.data();
+                            indices_num = 1lu;
+                        }
+                        return;
+                    }
+
+                    if (with_weights)
+                        weights_idx = offsets[emb_index];
+                };
+
+                size_t indices_size = 0lu;
+                const U* indices_emb = nullptr;
+                size_t weights_idx = 0lu;
+                bool with_weights_b = (weights != nullptr);
+                bool with_weights = with_weights_b;
+
+                for (size_t obi = 0lu; obi < outShape.at(0); obi++)
+                {
+                    size_t dst_index = obi * embDepth;
+                    get_indices(obi, indices_emb, indices_size, weights_idx, with_weights);
+                    if (indices_emb != nullptr)
+                    {
+                        with_weights = with_weights_b & with_weights;
+                        for (size_t in_idx = 0lu; in_idx < indices_size; in_idx++)
+                        {
+                            size_t src_index = indices_emb[in_idx] * embDepth;
+
+                            if (with_weights)
+                            {
+                                for (size_t i = 0lu; i < embDepth; i++)
+                                {
+                                    out[dst_index + i] +=
+                                        emb_table[src_index + i] * weights[weights_idx];
+                                }
+                                weights_idx++;
+                            }
+                            else
+                            {
+                                for (size_t i = 0lu; i < embDepth; i++)
+                                {
+                                    out[dst_index + i] += emb_table[src_index + i];
+                                }
+                            }
+                        }
+                    }
+                }
+
+            } // embeddingBagOffsetsSum
+
+        } // reference
+    }     // runtime
+} // ngraph
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/embedding_bag_packed_sum.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/embedding_bag_packed_sum.hpp
new file mode 100644 (file)
index 0000000..35de940
--- /dev/null
@@ -0,0 +1,63 @@
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#pragma once
+
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T, typename U>
+            void embeddingBagPackedSum(const T* emb_table,
+                                       const U* indices,
+                                       const T* weights,
+                                       T* out,
+                                       const Shape& indicesShape,
+                                       const Shape& outShape)
+            {
+                const size_t indices_per_bag = indicesShape[1];
+
+                size_t embDepth = 1lu;
+                for (size_t i = 1; i < outShape.size(); i++)
+                {
+                    embDepth *= outShape[i];
+                }
+                memset(out, 0, shape_size(outShape) * sizeof(T));
+
+                bool with_weights = (weights != nullptr);
+                size_t idx_idx = 0lu;
+
+                for (size_t obi = 0lu; obi < outShape.at(0); obi++)
+                {
+                    size_t dst_index = obi * embDepth;
+                    for (size_t in_idx = 0lu; in_idx < indices_per_bag; in_idx++, idx_idx++)
+                    {
+                        size_t src_index = indices[idx_idx] * embDepth;
+
+                        if (with_weights)
+                        {
+                            for (size_t i = 0lu; i < embDepth; i++)
+                            {
+                                out[dst_index + i] += emb_table[src_index + i] * weights[idx_idx];
+                            }
+                        }
+                        else
+                        {
+                            for (size_t i = 0lu; i < embDepth; i++)
+                            {
+                                out[dst_index + i] += emb_table[src_index + i];
+                            }
+                        }
+                    }
+                }
+
+            } // embeddingBagPackedSum
+
+        } // reference
+    }     // runtime
+} // ngraph
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/embedding_segments_sum.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/embedding_segments_sum.hpp
new file mode 100644 (file)
index 0000000..68f0c4d
--- /dev/null
@@ -0,0 +1,95 @@
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#pragma once
+
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T, typename U>
+            void embeddingSegmentsSum(const T* embTable,
+                                      const U* indices,
+                                      const U* segmentIds,
+                                      const U* defaultIndex,
+                                      const T* weights,
+                                      T* out,
+                                      const Shape& embTableShape,
+                                      const Shape& indicesShape,
+                                      const Shape& outShape)
+            {
+                const size_t indices_len = indicesShape[0];
+                const size_t segments_num = outShape[0];
+                const size_t inDimsSize = outShape.size();
+                const size_t embDimsNum = outShape.size() - 1;
+
+                size_t embDepth = 1lu;
+                for (size_t i = 1; i < outShape.size(); i++)
+                {
+                    embDepth *= outShape[i];
+                }
+                memset(out, 0, shape_size(outShape) * sizeof(T));
+
+                bool with_weights = (weights != nullptr);
+
+                for (size_t index = 0; index < indices_len; index++)
+                {
+                    size_t obi = segmentIds[index];
+                    if (obi >= segments_num)
+                        throw ngraph_error("Segment index could not be more than segments number");
+                    size_t dst_index = obi * embDepth;
+                    size_t src_index = indices[index] * embDepth;
+
+                    if (with_weights)
+                    {
+                        for (size_t i = 0lu; i < embDepth; i++)
+                        {
+                            out[dst_index + i] += embTable[src_index + i] * weights[index];
+                        }
+                    }
+                    else
+                    {
+                        for (size_t i = 0lu; i < embDepth; i++)
+                        {
+                            out[dst_index + i] += embTable[src_index + i];
+                        }
+                    }
+                }
+
+                if (defaultIndex != nullptr)
+                {
+                    U defIndex = defaultIndex[0];
+                    if (defIndex < U(0) && defIndex >= embTableShape[0])
+                        throw ngraph_error(std::string("Invalid default index") +
+                                           std::to_string(defIndex));
+                    for (size_t obi = 0; obi < segments_num; obi++)
+                    {
+                        bool found = false;
+                        for (size_t index = 0; index < indices_len; index++)
+                        {
+                            if (segmentIds[index] == obi)
+                            {
+                                found = true;
+                                break;
+                            }
+                        }
+                        if (found)
+                            continue;
+                        size_t src_index = defIndex * embDepth;
+                        size_t dst_index = obi * embDepth;
+                        for (size_t i = 0lu; i < embDepth; i++)
+                        {
+                            out[dst_index + i] = embTable[src_index + i];
+                        }
+                    }
+                }
+            } // embeddingSegmentsSum
+
+        } // reference
+    }     // runtime
+} // ngraph
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/equal.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/equal.hpp
new file mode 100644 (file)
index 0000000..6ed5765
--- /dev/null
@@ -0,0 +1,67 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+
+#include <cstddef>
+
+#include "ngraph/op/util/attr_types.hpp"
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void equal(const T* arg0,
+                       const T* arg1,
+                       char* out,
+                       size_t count) // TODO: using char for bool, is this right?
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg0[i] == arg1[i];
+                }
+            }
+
+            template <typename T, typename U>
+            void equal(const T* arg0,
+                       const T* arg1,
+                       U* out,
+                       const Shape& arg0_shape,
+                       const Shape& arg1_shape,
+                       const op::AutoBroadcastSpec& broadcast_spec)
+            {
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
+                        return x == y;
+                    });
+            }
+        }
+    }
+}
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/erf.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/erf.hpp
new file mode 100644 (file)
index 0000000..86ef27c
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void erf(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::erf(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/eval_helpers.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/eval_helpers.hpp
new file mode 100644 (file)
index 0000000..6b90810
--- /dev/null
@@ -0,0 +1,27 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include "ngraph/runtime/host_tensor.hpp"
+
+namespace ngraph
+{
+    namespace eval
+    {
+        AxisSet extract_reduction_axes(const HostTensorPtr& axes, const char* op_name);
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/exp.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/exp.hpp
new file mode 100644 (file)
index 0000000..2bd0878
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void exp(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::exp(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/extract_image_patches.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/extract_image_patches.hpp
new file mode 100644 (file)
index 0000000..4e16e1c
--- /dev/null
@@ -0,0 +1,151 @@
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T, typename U>
+            void extractImagePatches(const op::ExtractImagePatches* extImgPatches,
+                                     const T* input,
+                                     T* out,
+                                     const Shape& inShape,
+                                     const Shape& outShape)
+            {
+                const size_t dimsSize = inShape.size();
+                const size_t BATCH = 0, CHANNEL = 1, HIGHT = 0, WIDTH = 1;
+
+                const int64_t KH = extImgPatches->get_sizes()[HIGHT];
+                const int64_t KW = extImgPatches->get_sizes()[WIDTH];
+                const int64_t SH = extImgPatches->get_strides()[HIGHT];
+                const int64_t SW = extImgPatches->get_strides()[WIDTH];
+                const int64_t RH = extImgPatches->get_rates()[HIGHT];
+                const int64_t RW = extImgPatches->get_rates()[WIDTH];
+                const auto auto_pad = extImgPatches->get_auto_pad();
+
+                const int64_t IB = inShape[BATCH];
+                const int64_t IC = inShape[CHANNEL];
+                const int64_t IH = inShape[dimsSize - 2];
+                const int64_t IW = inShape[dimsSize - 1];
+
+                const int64_t OB = outShape[BATCH];
+                const int64_t OC = outShape[CHANNEL];
+                const int64_t OH = outShape[dimsSize - 2];
+                const int64_t OW = outShape[dimsSize - 1];
+
+                int64_t ihStart = 0;
+                int64_t iwStart = 0;
+
+                int64_t iwStep = KW + (RW - 1) * (KW - 1);
+                int64_t ihStep = KH + (RH - 1) * (KH - 1);
+
+                const int64_t OH_OW = OH * OW;
+                const int64_t OC_OH_OW = OC * OH_OW;
+                const int64_t OB_OC_OH_OW = OC_OH_OW * OB;
+                const int64_t IH_IW = IH * IW;
+                const int64_t IC_IH_IW = IC * IH_IW;
+                const int64_t IB_IC_IH_IW = IC_IH_IW * IB;
+                const int64_t KH_KW = KH * KW;
+
+                int64_t PL = 0, PT = 0;
+
+                if (auto_pad != op::PadType::VALID)
+                {
+                    int64_t PW = (std::ceil(1.f * IW / SW) - 1) * SW + iwStep - IW;
+                    int64_t PH = (std::ceil(1.f * IH / SH) - 1) * SH + ihStep - IH;
+
+                    if ((PW > 0) && (PW < iwStep))
+                    {
+                        if (PW % 2 == 1)
+                        {
+                            if (auto_pad == op::PadType::SAME_LOWER)
+                            {
+                                PL = (PW + 1) / 2;
+                            }
+                            else if (auto_pad == op::PadType::SAME_UPPER)
+                            {
+                                PL = (PW - 1) / 2;
+                            }
+                        }
+                        else
+                        {
+                            PL = PW / 2;
+                        }
+                    }
+                    if ((PH > 0) && (PH < ihStep))
+                    {
+                        if (PH % 2 == 1)
+                        {
+                            if (auto_pad == op::PadType::SAME_LOWER)
+                            {
+                                PT = (PH + 1) / 2;
+                            }
+                            else if (auto_pad == op::PadType::SAME_UPPER)
+                            {
+                                PT = (PH - 1) / 2;
+                            }
+                        }
+                        else
+                        {
+                            PT = PH / 2;
+                        }
+                    }
+                }
+
+                for (int64_t ob = 0; ob < OB; ob++)
+                {
+                    const int64_t ib_ICIHIW = ob * IC_IH_IW;
+                    const int64_t ob_OCOHOW = ob * OC_OH_OW;
+                    for (int64_t oh = 0; oh < OH; oh++)
+                    {
+                        const int64_t ob_OCOHOW_ohOW = ob_OCOHOW + oh * OW;
+                        int64_t ih0 = oh * SH - PT;
+                        for (int64_t ow = 0; ow < OW; ow++)
+                        {
+                            const int64_t ob_OCOHOW_ohOW_ow = ob_OCOHOW_ohOW + ow;
+                            int64_t iw0 = ow * SW - PL;
+                            int64_t oc = 0;
+
+                            for (int64_t kh = 0; kh < KH; kh++)
+                            {
+                                int64_t ihKH = ih0 + kh * RH;
+                                int64_t ib_ICIHIW_ihKH_IW = ib_ICIHIW + ihKH * IW;
+                                for (int64_t kw = 0; kw < KW; kw++)
+                                {
+                                    for (int64_t ic = 0; ic < IC; ic++, oc++)
+                                    {
+                                        int64_t iwKW = iw0 + kw * RW;
+                                        int64_t dst_idx = ob_OCOHOW_ohOW_ow + oc * OH_OW;
+                                        if (dst_idx >= OB_OC_OH_OW)
+                                            throw ngraph_error(
+                                                "ExtractImagePatches. Destination index is out of "
+                                                "bounds.");
+                                        if (ihKH < 0 || ihKH >= IH || iwKW < 0 || iwKW >= IW)
+                                        {
+                                            out[dst_idx] = T(0);
+                                        }
+                                        else
+                                        {
+                                            int64_t src_idx = ib_ICIHIW_ihKH_IW + ic * IH_IW + iwKW;
+                                            if (src_idx >= IB_IC_IH_IW)
+                                                throw ngraph_error(
+                                                    "ExtractImagePatches. Source index is out of "
+                                                    "bounds.");
+                                            out[dst_idx] = input[src_idx];
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            } // extractImagePatches
+
+        } // reference
+    }     // runtime
+} // ngraph
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/floor.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/floor.hpp
new file mode 100644 (file)
index 0000000..f33d4b4
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void floor(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::floor(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/gather.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/gather.hpp
new file mode 100644 (file)
index 0000000..4ad4aa9
--- /dev/null
@@ -0,0 +1,175 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <numeric>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/runtime/reference/gather_nd.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            // Implement gather by calling gather_nd on sub-problems
+            // # prepare constant shapes for tensors used for sub problems
+            // indices'.shape  = indices.shape[-1] + [1]
+            // params'.shape = params.shape[axis:]
+            // out'.shape = params'.shape
+            // out'.shape[0] = indices.shape[-1]
+            // # call sub-problems
+            // foreach (params_index, out_index) in outer "axis" dimensions
+            //     # params_prime is shared by inner loop
+            //     params' = param[params_index] # rank(params') == rank(params) - axis
+            //     foreach indices_index in outer N-1 dimensions
+            //         indices' = indices[indices_index] # rank(indices') == 2
+            //         out_index = out_index + indices_index
+            //         out' = out[out_index] # rank(out') == rank(params')
+            //         gather_nd(params', indices'', out')
+            template <typename T, typename U>
+            void gather(const T* params,
+                        const U* indices,
+                        T* out,
+                        const Shape& params_shape,
+                        const Shape& indices_shape,
+                        const Shape& out_shape,
+                        size_t axis)
+            {
+                using namespace std;
+                // prepare shape of params_prime (remove first "axis" dimensions)
+                Shape params_prime_shape(params_shape);
+                params_prime_shape.erase(params_prime_shape.begin(),
+                                         params_prime_shape.begin() + axis);
+                // prepare shape of indices_prime
+                size_t indices_ndim = static_cast<size_t>(indices_shape.size());
+                Shape indices_prime_shape;
+                // prepare shape of out_prime (same as params_prime except for first dim)
+                Shape out_prime_shape(params_prime_shape);
+                if (indices_ndim > 0)
+                {
+                    out_prime_shape[0] = indices_shape[indices_ndim - 1];
+                    indices_prime_shape.emplace_back(indices_shape[indices_ndim - 1]);
+                }
+                else
+                {
+                    out_prime_shape[0] = 1;
+                }
+                indices_prime_shape.emplace_back(1);
+
+                // Create a CoordinateTransform for "out" that visits the outer "axis" dimensions
+                size_t out_ndim = static_cast<size_t>(out_shape.size());
+                Coordinate out_outer_start_corner(out_ndim, 0);
+                Coordinate out_outer_end_corner(out_shape);
+                for (size_t i = axis; i < out_ndim; i++)
+                {
+                    out_outer_end_corner[i] = 1;
+                }
+                Strides out_outer_strides(out_ndim, 1);
+                AxisVector out_outer_axis_order(out_ndim);
+                std::iota(out_outer_axis_order.begin(), out_outer_axis_order.end(), 0);
+                CoordinateTransform out_outer_transform(out_shape,
+                                                        out_outer_start_corner,
+                                                        out_outer_end_corner,
+                                                        out_outer_strides,
+                                                        out_outer_axis_order);
+
+                // Create a CoordinateTransform for "params" that visits the outer "axis" dimensions
+                size_t params_ndim = static_cast<size_t>(params_shape.size());
+                Coordinate params_outer_start_corner(params_ndim, 0);
+                Coordinate params_outer_end_corner(params_shape);
+                for (size_t i = axis; i < params_ndim; i++)
+                {
+                    params_outer_end_corner[i] = 1;
+                }
+                Strides params_outer_strides(params_ndim, 1);
+                AxisVector params_outer_axis_order(params_ndim);
+                std::iota(params_outer_axis_order.begin(), params_outer_axis_order.end(), 0);
+                CoordinateTransform params_outer_transform(params_shape,
+                                                           params_outer_start_corner,
+                                                           params_outer_end_corner,
+                                                           params_outer_strides,
+                                                           params_outer_axis_order);
+
+                // Create a CoordinateTransform for "indices" that visits only the first element
+                // along inner most axis
+                Coordinate indices_outer_start_corner(indices_ndim, 0);
+                Coordinate indices_outer_end_corner(indices_shape);
+                if (indices_ndim > 0)
+                {
+                    indices_outer_end_corner[indices_ndim - 1] = 1;
+                }
+                Strides indices_outer_strides(indices_ndim, 1);
+                AxisVector indices_outer_axis_order(indices_ndim);
+                std::iota(indices_outer_axis_order.begin(), indices_outer_axis_order.end(), 0);
+                CoordinateTransform indices_outer_transform(indices_shape,
+                                                            indices_outer_start_corner,
+                                                            indices_outer_end_corner,
+                                                            indices_outer_strides,
+                                                            indices_outer_axis_order);
+
+                // Create an inner CoordinateTransfrom for "out"
+                size_t out_inner_ndim = out_ndim - axis;
+                Shape out_inner_shape(out_shape);
+                out_inner_shape.erase(out_inner_shape.begin(), out_inner_shape.begin() + axis);
+                Coordinate out_inner_start_corner(out_inner_ndim, 0);
+                Coordinate out_inner_end_corner(out_inner_shape);
+                if (indices_ndim > 0)
+                {
+                    out_inner_end_corner[indices_ndim - 1] = 1;
+                }
+                for (size_t i = indices_ndim; i < out_inner_ndim; i++)
+                {
+                    out_inner_end_corner[i] = 1;
+                }
+                Strides out_inner_strides(out_inner_ndim, 1);
+                AxisVector out_inner_axis_order(out_inner_ndim);
+                std::iota(out_inner_axis_order.begin(), out_inner_axis_order.end(), 0);
+                CoordinateTransform out_inner_transform(out_inner_shape,
+                                                        out_inner_start_corner,
+                                                        out_inner_end_corner,
+                                                        out_inner_strides,
+                                                        out_inner_axis_order);
+
+                auto out_outer_coord_iter = out_outer_transform.begin();
+                for (const Coordinate& params_outer_coord : params_outer_transform)
+                {
+                    const T* params_prime =
+                        &params[params_outer_transform.index(params_outer_coord)];
+                    T* out_outer = &out[out_outer_transform.index(*out_outer_coord_iter)];
+
+                    auto out_inner_coord_iter = out_inner_transform.begin();
+                    for (const Coordinate& indices_outer_coord : indices_outer_transform)
+                    {
+                        const U* indices_prime =
+                            &indices[indices_outer_transform.index(indices_outer_coord)];
+                        T* out_prime = &out_outer[out_inner_transform.index(*out_inner_coord_iter)];
+                        gather_nd<T, U>(params_prime,
+                                        indices_prime,
+                                        out_prime,
+                                        params_prime_shape,
+                                        indices_prime_shape,
+                                        out_prime_shape);
+                        out_inner_coord_iter++;
+                    }
+                    out_outer_coord_iter++;
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/gather_nd.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/gather_nd.hpp
new file mode 100644 (file)
index 0000000..a596098
--- /dev/null
@@ -0,0 +1,108 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <numeric>
+
+#include "ngraph/coordinate_transform.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            // foreach leaf_vector_index in indices.shape[:-1]
+            //     vector = indices[leaf_vector_index]
+            //     out[leaf_vector_index:] = params[vector]
+            template <typename T, typename U>
+            void gather_nd(const T* params,
+                           const U* indices,
+                           T* out,
+                           const Shape& params_shape,
+                           const Shape& indices_shape,
+                           const Shape& out_shape)
+            {
+                using namespace std;
+                // Create a CoordinateTransform for "indices" that visits only the first element
+                // along inner most axis
+                size_t indices_ndim = static_cast<size_t>(indices_shape.size());
+                Coordinate indices_outer_start_corner(indices_ndim, 0);
+                Coordinate indices_outer_end_corner(indices_shape);
+                size_t slice_rank = indices_shape[indices_ndim - 1];
+                indices_outer_end_corner[indices_ndim - 1] = 1;
+                Strides indices_strides(indices_ndim, 1);
+                AxisVector indices_axis_order(indices_ndim);
+                std::iota(indices_axis_order.begin(), indices_axis_order.end(), 0);
+                CoordinateTransform indices_outer_transform(indices_shape,
+                                                            indices_outer_start_corner,
+                                                            indices_outer_end_corner,
+                                                            indices_strides,
+                                                            indices_axis_order);
+
+                // Create a matching CoordinateTransform for "out" that visits the same outer
+                // coordinates
+                size_t out_ndim = static_cast<size_t>(out_shape.size());
+                Coordinate out_start_corner(out_ndim, 0);
+                Coordinate out_end_corner(out_shape);
+                for (size_t i = indices_ndim - 1; i < out_ndim; i++)
+                {
+                    out_end_corner[i] = 1;
+                }
+                Strides out_strides(out_ndim, 1);
+                AxisVector out_axis_order(out_ndim);
+                std::iota(out_axis_order.begin(), out_axis_order.end(), 0);
+                CoordinateTransform out_transform(
+                    out_shape, out_start_corner, out_end_corner, out_strides, out_axis_order);
+                size_t params_ndim = static_cast<size_t>(params_shape.size());
+                Strides params_strides(params_ndim, 1);
+                AxisVector params_axis_order(params_ndim);
+                std::iota(params_axis_order.begin(), params_axis_order.end(), 0);
+
+                // Gather slices from "params" and copy to "out"
+                auto out_coord_iter = out_transform.begin();
+                for (const Coordinate& indices_coord : indices_outer_transform)
+                {
+                    Coordinate params_start_corner(params_ndim, 0);
+                    Coordinate params_end_corner(params_shape);
+                    auto indices_index = indices_outer_transform.index(indices_coord);
+                    for (size_t i = 0; i < slice_rank; i++)
+                    {
+                        U index = indices[indices_index];
+                        // take care of negative indices
+                        index = index >= 0 ? index : index + params_shape[i];
+                        params_start_corner[i] = index;
+                        params_end_corner[i] = index + 1;
+                        indices_index++;
+                    }
+                    CoordinateTransform params_transform(params_shape,
+                                                         params_start_corner,
+                                                         params_end_corner,
+                                                         params_strides,
+                                                         params_axis_order);
+                    auto out_index = out_transform.index(*out_coord_iter);
+                    for (const Coordinate& params_coord : params_transform)
+                    {
+                        out[out_index] = params[params_transform.index(params_coord)];
+                        out_index++;
+                    }
+                    out_coord_iter++;
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/greater.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/greater.hpp
new file mode 100644 (file)
index 0000000..1586a48
--- /dev/null
@@ -0,0 +1,58 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+#include "ngraph/op/util/attr_types.hpp"
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void greater(const T* arg0,
+                         const T* arg1,
+                         char* out,
+                         size_t count) // TODO: using char for bool, is this right?
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg0[i] > arg1[i];
+                }
+            }
+
+            template <typename T, typename U>
+            void greater(const T* arg0,
+                         const T* arg1,
+                         U* out,
+                         const Shape& arg0_shape,
+                         const Shape& arg1_shape,
+                         const op::AutoBroadcastSpec& broadcast_spec)
+            {
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
+                        return x > y;
+                    });
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/greater_eq.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/greater_eq.hpp
new file mode 100644 (file)
index 0000000..380177b
--- /dev/null
@@ -0,0 +1,58 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+#include "ngraph/op/util/attr_types.hpp"
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void greater_eq(const T* arg0,
+                            const T* arg1,
+                            char* out,
+                            size_t count) // TODO: using char for bool, is this right?
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg0[i] >= arg1[i];
+                }
+            }
+
+            template <typename T, typename U>
+            void greater_eq(const T* arg0,
+                            const T* arg1,
+                            U* out,
+                            const Shape& arg0_shape,
+                            const Shape& arg1_shape,
+                            const op::AutoBroadcastSpec& broadcast_spec)
+            {
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
+                        return x >= y;
+                    });
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/less.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/less.hpp
new file mode 100644 (file)
index 0000000..0f41890
--- /dev/null
@@ -0,0 +1,58 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+#include "ngraph/op/util/attr_types.hpp"
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void less(const T* arg0,
+                      const T* arg1,
+                      char* out,
+                      size_t count) // TODO: using char for bool, is this right?
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg0[i] < arg1[i];
+                }
+            }
+
+            template <typename T, typename U>
+            void less(const T* arg0,
+                      const T* arg1,
+                      U* out,
+                      const Shape& arg0_shape,
+                      const Shape& arg1_shape,
+                      const op::AutoBroadcastSpec& broadcast_spec)
+            {
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
+                        return x < y;
+                    });
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/less_eq.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/less_eq.hpp
new file mode 100644 (file)
index 0000000..a4fb0a3
--- /dev/null
@@ -0,0 +1,58 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+#include "ngraph/op/util/attr_types.hpp"
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void less_eq(const T* arg0,
+                         const T* arg1,
+                         char* out,
+                         size_t count) // TODO: using char for bool, is this right?
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg0[i] <= arg1[i];
+                }
+            }
+
+            template <typename T, typename U>
+            void less_eq(const T* arg0,
+                         const T* arg1,
+                         U* out,
+                         const Shape& arg0_shape,
+                         const Shape& arg1_shape,
+                         const op::AutoBroadcastSpec& broadcast_spec)
+            {
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
+                        return x <= y;
+                    });
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/log.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/log.hpp
new file mode 100644 (file)
index 0000000..10a0db2
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void log(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::log(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/logical_reduction.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/logical_reduction.hpp
new file mode 100644 (file)
index 0000000..2c06329
--- /dev/null
@@ -0,0 +1,66 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/runtime/reference/any.hpp"
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            static inline void reduce_logical_and(const char* arg,
+                                                  char* out,
+                                                  const Shape& input_shape,
+                                                  const AxisSet& reduction_axes,
+                                                  bool keep_dims)
+            {
+                CoordinateTransform output_transform(
+                    reduce(input_shape, reduction_axes, keep_dims));
+
+                for (const Coordinate& output_coord : output_transform)
+                {
+                    out[output_transform.index(output_coord)] = 1;
+                }
+
+                CoordinateTransform input_transform(input_shape);
+
+                for (const Coordinate& input_coord : input_transform)
+                {
+                    Coordinate output_coord = reduce(input_coord, reduction_axes, keep_dims);
+                    out[output_transform.index(output_coord)] =
+                        out[output_transform.index(output_coord)] &&
+                        arg[input_transform.index(input_coord)];
+                }
+            }
+
+            static inline void reduce_logical_or(const char* arg,
+                                                 char* out,
+                                                 const Shape& input_shape,
+                                                 const AxisSet& reduction_axes,
+                                                 bool keep_dims)
+            {
+                runtime::reference::any(arg, out, input_shape, reduction_axes, keep_dims);
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/lrn.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/lrn.hpp
new file mode 100644 (file)
index 0000000..2494c6a
--- /dev/null
@@ -0,0 +1,114 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <algorithm>
+#include <cmath>
+#include <numeric>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void sum_region_across_axes(const T* arg,
+                                        size_t current_axis_index,
+                                        const std::vector<size_t>& axes,
+                                        Coordinate& sum_coord,
+                                        T& square_sum,
+                                        const std::vector<size_t>& begin_area,
+                                        const std::vector<size_t>& end_area,
+                                        const CoordinateTransform& input_transform)
+            {
+                // all nested axes were visited
+                if (current_axis_index == axes.size())
+                {
+                    square_sum += arg[input_transform.index(sum_coord)] *
+                                  arg[input_transform.index(sum_coord)];
+                    return;
+                }
+                auto current_axis = axes[current_axis_index];
+                for (auto current_axis_coord = begin_area[current_axis];
+                     current_axis_coord < end_area[current_axis];
+                     ++current_axis_coord)
+                {
+                    sum_coord.at(current_axis) = current_axis_coord;
+                    sum_region_across_axes(arg,
+                                           current_axis_index + 1,
+                                           axes,
+                                           sum_coord,
+                                           square_sum,
+                                           begin_area,
+                                           end_area,
+                                           input_transform);
+                }
+            }
+
+            template <typename T>
+            void lrn(const T* arg,
+                     const AxisSet& axes,
+                     T* out,
+                     const Shape& arg_shape,
+                     double dalpha,
+                     double dbeta,
+                     double dbias,
+                     size_t size)
+            {
+                T alpha = static_cast<T>(dalpha);
+                T beta = static_cast<T>(dbeta);
+                T bias = static_cast<T>(dbias);
+
+                std::vector<size_t> begin_area(arg_shape.size());
+                std::vector<size_t> end_area(arg_shape.size());
+
+                CoordinateTransform input_transform(arg_shape);
+                for (const Coordinate& in_coord : input_transform)
+                {
+                    // area determined by in_coord local neighborhood
+                    for (const auto& axis_coord : axes)
+                    {
+                        begin_area[axis_coord] =
+                            std::max<int>(0, in_coord.at(axis_coord) - (size - 1) / 2);
+                        end_area[axis_coord] = std::min<int>(
+                            arg_shape.at(axis_coord), in_coord.at(axis_coord) + (size - 1) / 2 + 1);
+                    }
+
+                    T square_sum = 0;
+                    auto sum_coord = in_coord;
+                    auto axes_vec = std::vector<size_t>(axes.begin(), axes.end());
+                    sum_region_across_axes(arg,
+                                           0,
+                                           axes_vec,
+                                           sum_coord,
+                                           square_sum,
+                                           begin_area,
+                                           end_area,
+                                           input_transform);
+
+                    T x = arg[input_transform.index(in_coord)];
+                    out[input_transform.index(in_coord)] =
+                        x / (std::pow(bias + (alpha / size) * square_sum, beta));
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/matmul.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/matmul.hpp
new file mode 100644 (file)
index 0000000..17de94b
--- /dev/null
@@ -0,0 +1,274 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <numeric>
+#include <utility>
+#include <vector>
+
+#include "ngraph/axis_vector.hpp"
+#include "ngraph/builder/autobroadcast.hpp"
+#include "ngraph/runtime/opt_kernel/reshape.hpp"
+#include "ngraph/runtime/reference/broadcast.hpp"
+#include "ngraph/runtime/reference/dot.hpp"
+#include "ngraph/shape_util.hpp"
+
+using namespace std;
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            /// \brief Reference kernel for matmul computation.
+            ///
+            /// \tparam T Type of input and output tensors.
+            ///
+            /// \param arg0 Pointer to the buffer for left operand input tensor.
+            /// \param arg1 Pointer to the buffer for right operand input tensor.
+            /// \param out Pointer to the buffer for output tensor. This must be pre-allocated by
+            ///            the caller, and must be large enough to hold a tensor of the correct
+            ///            shape.
+            /// \param arg0_shape Shape of arg0.
+            /// \param arg1_shape Shape of arg1.
+            /// \param out_shape Shape of out.
+            /// \param transpose_arg0 Flag to indicate if transpose on arg0.
+            /// \param transpose_arg1 Flag to indicate if transpose on arg1.
+            template <typename T>
+            void matmul(const T* arg0,
+                        const T* arg1,
+                        T* out,
+                        const Shape& arg0_shape,
+                        const Shape& arg1_shape,
+                        const Shape& out_shape,
+                        bool transpose_arg0,
+                        bool transpose_arg1)
+            {
+                // Steps to compute matmul:
+                // 1) Check inputs and perform transpose on arg if applicable
+                // 2) If ranks of both args are 2D and below (no batch dim),
+                //    perform dot and return result; otherwise, continue next
+                // 3) Check if auto broadcast is needed on args or transposed args,
+                //    and perform broadcast if applicable
+                // 4) Perform dot on the args or updated args and return result
+
+                size_t arg0_rank = arg0_shape.size();
+                size_t arg1_rank = arg1_shape.size();
+                size_t out_rank = out_shape.size();
+
+                // vector vars to hold pontential intermediate transpose,
+                // broadcast result
+                vector<T> arg0_transpose_vec;
+                vector<T> arg1_transpose_vec;
+                vector<T> arg0_broadcast_vec;
+                vector<T> arg1_broadcast_vec;
+
+                // pointers to updated inputs
+                const T* arg0_update = arg0;
+                const T* arg1_update = arg1;
+
+                // vars for updated inputs shapes
+                Shape wip_arg0_shape = arg0_shape;
+                Shape wip_arg1_shape = arg1_shape;
+
+                auto get_transpose_order = [](const Shape& input_shape) {
+                    size_t rank = input_shape.size();
+                    NGRAPH_CHECK(rank > 1, "Invalid input for transpose");
+                    vector<size_t> axes_order(rank);
+                    iota(axes_order.begin(), axes_order.end(), 0);
+                    swap(axes_order[rank - 1], axes_order[rank - 2]);
+                    return AxisVector{begin(axes_order), end(axes_order)};
+                };
+
+                auto get_broadcast_axes = [](const Shape& marker_shape, const Shape& target_shape) {
+                    NGRAPH_CHECK(marker_shape.size() == target_shape.size(),
+                                 "Incompatible input shapes");
+                    AxisSet broadcast_axes;
+                    for (size_t i = 0; i < marker_shape.size(); i++)
+                    {
+                        if (marker_shape[i] == 1 && target_shape[i] != 1)
+                        {
+                            broadcast_axes.insert(i);
+                        }
+                    }
+                    return broadcast_axes;
+                };
+
+                // Perform transpose if requested
+                if (transpose_arg0 && arg0_rank > 1)
+                {
+                    arg0_transpose_vec.reserve(shape_size(arg0_shape));
+                    auto axis_vector = get_transpose_order(arg0_shape);
+                    swap(wip_arg0_shape[arg0_rank - 1], wip_arg0_shape[arg0_rank - 2]);
+                    opt_kernel::reshape(reinterpret_cast<const char*>(arg0),
+                                        reinterpret_cast<char*>(arg0_transpose_vec.data()),
+                                        arg0_shape,
+                                        axis_vector,
+                                        wip_arg0_shape,
+                                        sizeof(T));
+
+                    arg0_update = arg0_transpose_vec.data();
+                }
+
+                if (transpose_arg1 && arg1_rank > 1)
+                {
+                    arg1_transpose_vec.reserve(shape_size(arg1_shape));
+                    auto axis_vector = get_transpose_order(arg1_shape);
+                    swap(wip_arg1_shape[arg1_rank - 1], wip_arg1_shape[arg1_rank - 2]);
+                    opt_kernel::reshape(reinterpret_cast<const char*>(arg1),
+                                        reinterpret_cast<char*>(arg1_transpose_vec.data()),
+                                        arg1_shape,
+                                        axis_vector,
+                                        wip_arg1_shape,
+                                        sizeof(T));
+
+                    arg1_update = arg1_transpose_vec.data();
+                }
+
+                // Inputs are 2D and below, perform dot directly
+                if (arg0_rank <= 2 && arg1_rank <= 2)
+                {
+                    return dot(arg0_update,
+                               arg1_update,
+                               out,
+                               wip_arg0_shape,
+                               wip_arg1_shape,
+                               out_shape,
+                               1);
+                }
+
+                // Check and perform auto-broadcast if needed
+                // If one of the arg is 2D or below, no need to
+                // do broadcast on it, just use its value for
+                // every batch of dot compuatation later
+
+                if (arg0_rank > 2 && arg1_rank > 2)
+                {
+                    const auto& broadcast_shapes = builder::get_numpy_broadcast_shapes(
+                        {Shape{begin(wip_arg0_shape), next(end(wip_arg0_shape), -2)},
+                         Shape{begin(wip_arg1_shape), next(end(wip_arg1_shape), -2)}});
+
+                    Shape arg0_br_target_shape = broadcast_shapes.first;
+                    Shape arg1_br_target_shape = broadcast_shapes.first;
+                    Shape arg0_br_marker_shape = broadcast_shapes.second.at(0);
+                    Shape arg1_br_marker_shape = broadcast_shapes.second.at(1);
+
+                    arg0_br_target_shape.insert(
+                        end(arg0_br_target_shape),
+                        next(begin(wip_arg0_shape), wip_arg0_shape.size() - 2),
+                        end(wip_arg0_shape));
+                    arg1_br_target_shape.insert(
+                        end(arg1_br_target_shape),
+                        next(begin(wip_arg1_shape), wip_arg1_shape.size() - 2),
+                        end(wip_arg1_shape));
+
+                    arg0_br_marker_shape.insert(
+                        end(arg0_br_marker_shape),
+                        next(begin(wip_arg0_shape), wip_arg0_shape.size() - 2),
+                        end(wip_arg0_shape));
+                    arg1_br_marker_shape.insert(
+                        end(arg1_br_marker_shape),
+                        next(begin(wip_arg1_shape), wip_arg1_shape.size() - 2),
+                        end(wip_arg1_shape));
+
+                    if (arg0_br_target_shape != wip_arg0_shape)
+                    {
+                        auto broadcast_axes =
+                            get_broadcast_axes(arg0_br_marker_shape, arg0_br_target_shape);
+                        if (!broadcast_axes.empty())
+                        {
+                            arg0_broadcast_vec.reserve(shape_size(arg0_br_target_shape));
+                            broadcast(arg0_update,
+                                      arg0_broadcast_vec.data(),
+                                      wip_arg0_shape,
+                                      arg0_br_target_shape,
+                                      broadcast_axes);
+
+                            arg0_update = arg0_broadcast_vec.data();
+                            wip_arg0_shape = arg0_br_target_shape;
+                            arg0_rank = wip_arg0_shape.size();
+                        }
+                    }
+
+                    if (arg1_br_target_shape != wip_arg1_shape)
+                    {
+                        auto broadcast_axes =
+                            get_broadcast_axes(arg1_br_marker_shape, arg1_br_target_shape);
+                        if (!broadcast_axes.empty())
+                        {
+                            arg1_broadcast_vec.reserve(shape_size(arg1_br_target_shape));
+                            broadcast(arg1_update,
+                                      arg1_broadcast_vec.data(),
+                                      wip_arg1_shape,
+                                      arg1_br_target_shape,
+                                      broadcast_axes);
+
+                            arg1_update = arg1_broadcast_vec.data();
+                            wip_arg1_shape = arg1_br_target_shape;
+                            arg1_rank = wip_arg1_shape.size();
+                        }
+                    }
+                }
+
+                // Perform batched dot
+
+                size_t output_batch_size = 1;
+
+                // Calculate number of batches
+                if (out_rank < 3)
+                {
+                    // Output is {batch_size, dot_result}, i.e.,
+                    // arg 0 shape {2}, arg1 shape {3, 2, 1}, output shape {3, 1}
+                    output_batch_size = out_shape[0];
+                }
+                else
+                {
+                    for (size_t i = 0; i < (out_rank - 2); i++)
+                    {
+                        output_batch_size *= out_shape[i];
+                    }
+                }
+
+                Shape dot_arg0_shape = (arg0_rank > 2) ? Shape{wip_arg0_shape[arg0_rank - 2],
+                                                               wip_arg0_shape[arg0_rank - 1]}
+                                                       : wip_arg0_shape;
+                Shape dot_arg1_shape = (arg1_rank > 2) ? Shape{wip_arg1_shape[arg1_rank - 2],
+                                                               wip_arg1_shape[arg1_rank - 1]}
+                                                       : wip_arg1_shape;
+                Shape dot_output_shape =
+                    (out_rank > 2) ? Shape{out_shape[out_rank - 2], out_shape[out_rank - 1]}
+                                   : Shape{out_shape[out_rank - 1]};
+
+                const size_t arg0_offset = (arg0_rank > 2) ? shape_size(dot_arg0_shape) : 0;
+                const size_t arg1_offset = (arg1_rank > 2) ? shape_size(dot_arg1_shape) : 0;
+                const size_t output_offset = shape_size(dot_output_shape);
+                for (size_t i = 0; i < output_batch_size; i++)
+                {
+                    dot(arg0_update + i * arg0_offset,
+                        arg1_update + i * arg1_offset,
+                        out + i * output_offset,
+                        dot_arg0_shape,
+                        dot_arg1_shape,
+                        dot_output_shape,
+                        1);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/max.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/max.hpp
new file mode 100644 (file)
index 0000000..cd62a09
--- /dev/null
@@ -0,0 +1,66 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <limits>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void max(const T* arg,
+                     T* out,
+                     const Shape& in_shape,
+                     const AxisSet& reduction_axes,
+                     bool keep_dims)
+            {
+                T minval = std::numeric_limits<T>::has_infinity
+                               ? T(-std::numeric_limits<T>::infinity())
+                               : std::numeric_limits<T>::min();
+
+                auto out_shape = reduce(in_shape, reduction_axes, keep_dims);
+                CoordinateTransform output_transform(out_shape);
+
+                for (const Coordinate& output_coord : output_transform)
+                {
+                    out[output_transform.index(output_coord)] = minval;
+                }
+
+                CoordinateTransform input_transform(in_shape);
+
+                for (const Coordinate& input_coord : input_transform)
+                {
+                    Coordinate output_coord = reduce(input_coord, reduction_axes, keep_dims);
+
+                    T x = arg[input_transform.index(input_coord)];
+                    T max = out[output_transform.index(output_coord)];
+                    if (x > max)
+                    {
+                        out[output_transform.index(output_coord)] = x;
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/max_pool.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/max_pool.hpp
new file mode 100644 (file)
index 0000000..1f37535
--- /dev/null
@@ -0,0 +1,225 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <numeric>
+
+#include "ngraph/coordinate_transform.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void max_pool_backprop(const T* arg_forward,
+                                   const T* delta,
+                                   T* out,
+                                   const Shape& delta_shape,
+                                   const Shape& out_shape, // same as arg_forward_shape
+                                   const Shape& window_shape,
+                                   const Strides& window_movement_strides,
+                                   const Shape& padding_below,
+                                   const Shape& padding_above)
+            {
+                CoordinateTransform out_transform(out_shape);
+
+                for (const Coordinate& out_coord : out_transform)
+                {
+                    out[out_transform.index(out_coord)] = 0;
+                }
+
+                CoordinateTransform delta_transform(delta_shape);
+
+                for (const Coordinate& delta_coord : delta_transform)
+                {
+                    size_t img_index = delta_coord[0];
+                    size_t channel = delta_coord[1];
+
+                    size_t n_image_dimensions = out_shape.size() - 2;
+                    Coordinate source_window_transform_start(2 + n_image_dimensions);
+                    Coordinate source_window_transform_end(2 + n_image_dimensions);
+                    Strides source_window_transform_source_strides(2 + n_image_dimensions, 1);
+                    AxisVector source_window_transform_source_axis_order(2 + n_image_dimensions);
+                    CoordinateDiff source_window_transform_padding_below(2 + n_image_dimensions);
+                    CoordinateDiff source_window_transform_padding_above(2 + n_image_dimensions);
+
+                    source_window_transform_start[0] = img_index;
+                    source_window_transform_end[0] = img_index + 1;
+                    source_window_transform_start[1] = channel;
+                    source_window_transform_end[1] = channel + 1;
+                    source_window_transform_padding_below[0] = 0;
+                    source_window_transform_padding_below[1] = 0;
+                    source_window_transform_padding_above[0] = 0;
+                    source_window_transform_padding_above[1] = 0;
+
+                    for (size_t i = 2; i < n_image_dimensions + 2; i++)
+                    {
+                        size_t window_shape_this_dim = window_shape[i - 2];
+                        size_t movement_stride = window_movement_strides[i - 2];
+
+                        source_window_transform_start[i] = movement_stride * delta_coord[i];
+                        source_window_transform_end[i] =
+                            source_window_transform_start[i] + window_shape_this_dim;
+                        source_window_transform_padding_below[i] = padding_below[i - 2];
+                        source_window_transform_padding_above[i] = padding_above[i - 2];
+                    }
+                    std::iota(begin(source_window_transform_source_axis_order),
+                              end(source_window_transform_source_axis_order),
+                              0);
+
+                    CoordinateTransform source_window_transform(
+                        out_shape,
+                        source_window_transform_start,
+                        source_window_transform_end,
+                        source_window_transform_source_strides,
+                        source_window_transform_source_axis_order,
+                        source_window_transform_padding_below,
+                        source_window_transform_padding_above);
+
+                    Coordinate argmax_coord;
+                    bool argmax_coord_valid = false;
+                    T max_val = 0; // just initializing to keep compiler happy, this 0 is ignored
+
+                    for (const Coordinate& source_window_coord : source_window_transform)
+                    {
+                        if (source_window_transform.has_source_coordinate(source_window_coord))
+                        {
+                            T candidate =
+                                arg_forward[source_window_transform.index(source_window_coord)];
+
+                            if (!argmax_coord_valid || candidate > max_val)
+                            {
+                                max_val = candidate;
+                                argmax_coord = source_window_coord;
+                                argmax_coord_valid = true;
+                            }
+                        }
+                    }
+
+                    if (argmax_coord_valid)
+                    {
+                        out[source_window_transform.index(argmax_coord)] +=
+                            delta[delta_transform.index(delta_coord)];
+                    }
+                }
+            }
+
+            template <typename T>
+            void max_pool(const T* arg,
+                          T* out,
+                          const Shape& arg_shape,
+                          const Shape& out_shape,
+                          const Shape& window_shape,
+                          const Strides& window_movement_strides,
+                          const Shape& padding_below,
+                          const Shape& padding_above)
+            {
+                // At the outermost level we will walk over every output coordinate O.
+                CoordinateTransform output_transform(out_shape);
+
+                for (const Coordinate& out_coord : output_transform)
+                {
+                    // Our output coordinate O will have the form:
+                    //
+                    //   (N,chan,i_1,...,i_n)
+
+                    size_t batch_index = out_coord[0];
+                    size_t channel = out_coord[1];
+
+                    // For the input data we need to iterate the coordinate:
+                    //
+                    //   I:
+                    //
+                    // over the range (noninclusive on the right):
+                    //
+                    //   (N,chan,s_1*i_1,s_2*i_2,...,s_n*i_n) ->
+                    //
+                    //     (N+1,chan+1,s_1*i_1 + window_shape_1,...,s_n*i_n + window_shape_n)
+                    //
+                    // with unit stride.
+                    //
+                    // We iterate this over the *padded* data, so below we will need to check for
+                    // coordinates that fall in the padding area.
+
+                    size_t n_spatial_dimensions = arg_shape.size() - 2;
+
+                    Coordinate input_batch_transform_start(2 + n_spatial_dimensions);
+                    Coordinate input_batch_transform_end(2 + n_spatial_dimensions);
+                    Strides input_batch_transform_source_strides(2 + n_spatial_dimensions, 1);
+                    AxisVector input_batch_transform_source_axis_order(2 + n_spatial_dimensions);
+                    CoordinateDiff input_batch_transform_padding_below(2 + n_spatial_dimensions);
+                    CoordinateDiff input_batch_transform_padding_above(2 + n_spatial_dimensions);
+
+                    input_batch_transform_start[0] = batch_index;
+                    input_batch_transform_end[0] = batch_index + 1;
+                    input_batch_transform_start[1] = channel;
+                    input_batch_transform_end[1] = channel + 1;
+                    input_batch_transform_padding_below[0] = 0;
+                    input_batch_transform_padding_below[1] = 0;
+                    input_batch_transform_padding_above[0] = 0;
+                    input_batch_transform_padding_above[1] = 0;
+
+                    for (size_t i = 2; i < n_spatial_dimensions + 2; i++)
+                    {
+                        size_t window_shape_this_dim = window_shape[i - 2];
+                        size_t movement_stride = window_movement_strides[i - 2];
+
+                        input_batch_transform_start[i] = movement_stride * out_coord[i];
+                        input_batch_transform_end[i] =
+                            input_batch_transform_start[i] + window_shape_this_dim;
+                        input_batch_transform_padding_below[i] = padding_below[i - 2];
+                        input_batch_transform_padding_above[i] = padding_above[i - 2];
+                    }
+
+                    for (size_t i = 0; i < arg_shape.size(); i++)
+                    {
+                        input_batch_transform_source_axis_order[i] = i;
+                    }
+
+                    CoordinateTransform input_batch_transform(
+                        arg_shape,
+                        input_batch_transform_start,
+                        input_batch_transform_end,
+                        input_batch_transform_source_strides,
+                        input_batch_transform_source_axis_order,
+                        input_batch_transform_padding_below,
+                        input_batch_transform_padding_above);
+
+                    // As we go, we compute the maximum value:
+                    //
+                    //   output[O] = max(output[O],arg[I])
+
+                    T result = std::numeric_limits<T>::lowest();
+
+                    for (const Coordinate& input_batch_coord : input_batch_transform)
+                    {
+                        if (input_batch_transform.has_source_coordinate(input_batch_coord))
+                        {
+                            T x = arg[input_batch_transform.index(input_batch_coord)];
+                            result = x > result ? x : result;
+                        }
+                    }
+
+                    out[output_transform.index(out_coord)] = result;
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/maximum.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/maximum.hpp
new file mode 100644 (file)
index 0000000..8eef0d1
--- /dev/null
@@ -0,0 +1,55 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+#include "ngraph/op/util/attr_types.hpp"
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void maximum(const T* arg0, const T* arg1, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg0[i] > arg1[i] ? arg0[i] : arg1[i];
+                }
+            }
+
+            template <typename T>
+            void maximum(const T* arg0,
+                         const T* arg1,
+                         T* out,
+                         const Shape& arg0_shape,
+                         const Shape& arg1_shape,
+                         const op::AutoBroadcastSpec& broadcast_spec)
+            {
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
+                        return x > y ? x : y;
+                    });
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/mean.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/mean.hpp
new file mode 100644 (file)
index 0000000..28bc579
--- /dev/null
@@ -0,0 +1,93 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <map>
+#include <vector>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/runtime/reference/sum.hpp"
+#include "ngraph/shape_util.hpp"
+#include "ngraph/type/bfloat16.hpp"
+#include "ngraph/type/float16.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void mean(const T* arg,
+                      T* out,
+                      const Shape& in_shape,
+                      const AxisSet& reduction_axes,
+                      bool keep_dims)
+            {
+                auto out_shape = reduce(in_shape, reduction_axes, keep_dims);
+                CoordinateTransform output_transform(out_shape);
+                std::vector<T> cs(shape_size(out_shape));
+
+                for (const Coordinate& output_coord : output_transform)
+                {
+                    out[output_transform.index(output_coord)] = 0;
+                    cs[output_transform.index(output_coord)] = 0;
+                }
+
+                CoordinateTransform input_transform(in_shape);
+                std::map<size_t, int> index_to_count_map;
+
+                for (const Coordinate& input_coord : input_transform)
+                {
+                    Coordinate output_coord = reduce(input_coord, reduction_axes, keep_dims);
+
+                    T x = arg[input_transform.index(input_coord)];
+                    T& z = out[output_transform.index(output_coord)];
+                    auto index = output_transform.index(output_coord);
+                    if (index_to_count_map.find(index) == index_to_count_map.end())
+                    {
+                        index_to_count_map[index] = 1;
+                    }
+                    else
+                    {
+                        index_to_count_map[index]++;
+                    }
+
+                    if (is_finite(x) && is_finite(z))
+                    {
+                        T& c = cs[output_transform.index(output_coord)];
+                        T t = z + (x - c);
+                        c = (t - z) - (x - c);
+                        z = t;
+                    }
+                    else
+                    {
+                        z = z + x;
+                    }
+                }
+
+                for (const Coordinate& output_coord : output_transform)
+                {
+                    auto count = index_to_count_map[output_transform.index(output_coord)];
+                    out[output_transform.index(output_coord)] =
+                        out[output_transform.index(output_coord)] / count;
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/min.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/min.hpp
new file mode 100644 (file)
index 0000000..5a39533
--- /dev/null
@@ -0,0 +1,65 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <limits>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/shape_util.hpp"
+
+#ifdef _WIN32
+#undef min
+#endif
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void min(const T* arg, T* out, const Shape& in_shape, const AxisSet& reduction_axes)
+            {
+                T minval = std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity()
+                                                                : std::numeric_limits<T>::max();
+
+                auto out_shape = reduce(in_shape, reduction_axes, false);
+                CoordinateTransform output_transform(out_shape);
+
+                for (const Coordinate& output_coord : output_transform)
+                {
+                    out[output_transform.index(output_coord)] = minval;
+                }
+
+                CoordinateTransform input_transform(in_shape);
+
+                for (const Coordinate& input_coord : input_transform)
+                {
+                    Coordinate output_coord = reduce(input_coord, reduction_axes, false);
+
+                    T x = arg[input_transform.index(input_coord)];
+                    T min = out[output_transform.index(output_coord)];
+                    if (x < min)
+                    {
+                        out[output_transform.index(output_coord)] = x;
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/minimum.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/minimum.hpp
new file mode 100644 (file)
index 0000000..4a6f9d0
--- /dev/null
@@ -0,0 +1,55 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+#include "ngraph/op/util/attr_types.hpp"
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void minimum(const T* arg0, const T* arg1, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg0[i] < arg1[i] ? arg0[i] : arg1[i];
+                }
+            }
+
+            template <typename T>
+            void minimum(const T* arg0,
+                         const T* arg1,
+                         T* out,
+                         const Shape& arg0_shape,
+                         const Shape& arg1_shape,
+                         const op::AutoBroadcastSpec& broadcast_spec)
+            {
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
+                        return x < y ? x : y;
+                    });
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/mish.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/mish.hpp
new file mode 100644 (file)
index 0000000..3bc1202
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void mish(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg[i] * std::tanh(std::log((std::exp(arg[i]) + 1.0)));
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/multiply.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/multiply.hpp
new file mode 100644 (file)
index 0000000..78976d3
--- /dev/null
@@ -0,0 +1,55 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+#include "ngraph/op/util/attr_types.hpp"
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void multiply(const T* arg0, const T* arg1, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg0[i] * arg1[i];
+                }
+            }
+
+            template <typename T>
+            void multiply(const T* arg0,
+                          const T* arg1,
+                          T* out,
+                          const Shape& arg0_shape,
+                          const Shape& arg1_shape,
+                          const op::AutoBroadcastSpec& broadcast_spec)
+            {
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
+                        return x * y;
+                    });
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/negate.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/negate.hpp
new file mode 100644 (file)
index 0000000..bf9019f
--- /dev/null
@@ -0,0 +1,37 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void negate(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = -arg[i];
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/non_zero.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/non_zero.hpp
new file mode 100644 (file)
index 0000000..a5b0970
--- /dev/null
@@ -0,0 +1,146 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            /// \brief Return number of non-zero entries in the input argument.
+            ///
+            /// \param arg Input tensor
+            /// \param arg_shape Input tensor shape
+            /// Output number of non-zero entries in arg
+            template <typename T>
+            size_t non_zero_get_count(const T* arg, const Shape& arg_shape)
+            {
+                T zero = 0;
+                size_t arg_rank = arg_shape.size();
+                size_t arg_count = shape_size(arg_shape);
+                size_t non_zero_count = 0;
+
+                // Input arg is scalar
+                if (arg_rank == 0)
+                {
+                    if (*arg != zero)
+                    {
+                        non_zero_count = 1;
+                    }
+                }
+                else // Input is non scalar case
+                {
+                    for (size_t i = 0; i < arg_count; i++)
+                    {
+                        if (arg[i] != zero)
+                        {
+                            non_zero_count++;
+                        }
+                    }
+                }
+
+                return non_zero_count;
+            }
+
+            /// \brief Return indices of non-zero entries in input argument.
+            ///
+            /// \param arg Input tensor
+            /// \param arg_shape Input tensor shape
+            /// \param out Output containing indices of non-zero entries in arg
+            template <typename T, typename U>
+            void non_zero(const T* arg, U* out, const Shape& arg_shape)
+            {
+                T zero = 0;
+                size_t arg_rank = arg_shape.size();
+                size_t arg_count = shape_size(arg_shape);
+
+                size_t non_zero_count = non_zero_get_count(arg, arg_shape);
+
+                // Input arg only contains 0s
+                if (non_zero_count == 0)
+                {
+                    return;
+                }
+
+                // Input arg is non-zero scalar
+                if (arg_rank == 0)
+                {
+                    out[0] = static_cast<U>(0);
+                    return;
+                }
+
+                // Dimensional size for the arg_shape. This is used to map one-dimentional
+                // arg array indices to corresponding arg_rank-dimentional shape indices.
+                // i.e., arg_shape {2, 3, 2} => elem_per_axis {6, 2, 1}.
+                // Array index 4 in arg (arg[4]) correspond to 3-D index of [0][2][0]
+                std::vector<size_t> elem_per_axis;
+                elem_per_axis.reserve(arg_rank);
+
+                size_t temp = arg_count;
+                for (size_t i = 0; i < arg_rank; i++)
+                {
+                    temp = temp / arg_shape[i];
+                    elem_per_axis.push_back(temp);
+                }
+
+                // Column index in out to record a non-zero entry
+                size_t col_index = 0;
+
+                // Array index in out to write non-zero index value
+                size_t out_index = 0;
+
+                // Find non-zero entries in arg and write the indices info in out.
+                // For a non-zero entry, map its array index to corresponding indices
+                // in arg_shape, then, write each of the arg_shape index value to
+                // out array at the position that is determined by entry's dimension
+                // distance and number of non-zero entries prior to it.
+                // i,e., Given input with shape{2, 3, 2}, rank = 3
+                // input [[[0, 2], [0, 0], [3, 4]],
+                //        [[5, 0], [6, 0], [7, 8]]]
+                //
+                // output shape {3, 7}, rank = 2
+                // output [[0, 0, 0, 1, 1, 1, 1],
+                //         [0, 2, 2, 0, 1, 2, 2],
+                //         [1, 0, 1, 0, 0, 0, 1]]
+                //
+                // input[0][2][0] = 3 is arg[4]
+                // output for this entry out[1] = 0, out[8] = 2, out[15] = 0
+                for (size_t i = 0; i < arg_count; i++)
+                {
+                    if (arg[i] != zero)
+                    {
+                        temp = i;
+
+                        for (size_t j = 0; j < arg_rank; j++)
+                        {
+                            out_index = j * non_zero_count + col_index;
+                            out[out_index] = static_cast<U>(temp / elem_per_axis[j]);
+
+                            temp = temp % elem_per_axis[j];
+                        }
+
+                        col_index++;
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/not.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/not.hpp
new file mode 100644 (file)
index 0000000..d31e0ac
--- /dev/null
@@ -0,0 +1,37 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void logical_not(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = static_cast<T>(!(arg[i]));
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/not_equal.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/not_equal.hpp
new file mode 100644 (file)
index 0000000..1cc32dd
--- /dev/null
@@ -0,0 +1,67 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+
+#include <cstddef>
+
+#include "ngraph/op/util/attr_types.hpp"
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void not_equal(const T* arg0,
+                           const T* arg1,
+                           char* out,
+                           size_t count) // TODO: using char for bool, is this right?
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg0[i] != arg1[i];
+                }
+            }
+
+            template <typename T, typename U>
+            void not_equal(const T* arg0,
+                           const T* arg1,
+                           U* out,
+                           const Shape& arg0_shape,
+                           const Shape& arg1_shape,
+                           const op::AutoBroadcastSpec& broadcast_spec)
+            {
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
+                        return x != y;
+                    });
+            }
+        }
+    }
+}
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/one_hot.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/one_hot.hpp
new file mode 100644 (file)
index 0000000..99a9d41
--- /dev/null
@@ -0,0 +1,86 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename INDICES_TYPE, typename OUTPUT_TYPE>
+            void one_hot(const INDICES_TYPE* arg,
+                         OUTPUT_TYPE* out,
+                         const Shape& in_shape,
+                         const Shape& out_shape,
+                         size_t one_hot_axis,
+                         const OUTPUT_TYPE on_value,
+                         const OUTPUT_TYPE off_value)
+            {
+                // Step 1: Set off_value to the output.
+                CoordinateTransform output_transform(out_shape);
+
+                for (const Coordinate& output_coord : output_transform)
+                {
+                    out[output_transform.index(output_coord)] = off_value;
+                }
+
+                // Step 2: Write off_value at needed positions, throwing exceptions when invalid
+                // conditions are encountered.
+                CoordinateTransform input_transform(in_shape);
+
+                for (const Coordinate& input_coord : input_transform)
+                {
+                    INDICES_TYPE val = arg[input_transform.index(input_coord)];
+
+                    if (std::floor(val) < val || std::floor(val) > val)
+                    {
+                        continue;
+                    }
+
+                    size_t one_hot_pos = static_cast<size_t>(val);
+
+                    if (one_hot_pos >= out_shape[one_hot_axis])
+                    {
+                        continue;
+                    }
+
+                    Coordinate one_hot_coord = inject(input_coord, one_hot_axis, one_hot_pos);
+
+                    out[output_transform.index(one_hot_coord)] = on_value;
+                }
+            }
+
+            template <typename T>
+            void one_hot(const T* arg,
+                         T* out,
+                         const Shape& in_shape,
+                         const Shape& out_shape,
+                         size_t one_hot_axis)
+            {
+                const T on_value = 1;
+                const T off_value = 0;
+                one_hot<T, T>(arg, out, in_shape, out_shape, one_hot_axis, on_value, off_value);
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/or.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/or.hpp
new file mode 100644 (file)
index 0000000..6dcf9ed
--- /dev/null
@@ -0,0 +1,56 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+#include "ngraph/op/util/attr_types.hpp"
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void logical_or(const T* arg0, const T* arg1, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = static_cast<T>(arg0[i] || arg1[i]);
+                }
+            }
+
+            template <typename T>
+            void logical_or(const T* arg0,
+                            const T* arg1,
+                            T* out,
+                            const Shape& arg0_shape,
+                            const Shape& arg1_shape,
+                            const op::AutoBroadcastSpec& broadcast_spec)
+            {
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
+                        return static_cast<T>(x || y);
+                    });
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/pad.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/pad.hpp
new file mode 100644 (file)
index 0000000..f9ada12
--- /dev/null
@@ -0,0 +1,204 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/axis_vector.hpp"
+#include "ngraph/check.hpp"
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/op/pad.hpp" // for op::PadMode
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void pad(const T* arg0,
+                     const T* arg1,
+                     T* out,
+                     const Shape& arg0_shape,
+                     const Shape& out_shape,
+                     const CoordinateDiff& padding_below,
+                     const CoordinateDiff& padding_above,
+                     op::PadMode pad_mode)
+            {
+                Coordinate input_start(arg0_shape.size(), 0); // start at (0,0,...,0)
+                Coordinate input_end = out_shape; // end at (d'0,d'1,...,d'n), the outer corner of
+                                                  // the post-padding shape
+
+                Strides input_strides(arg0_shape.size(), 1);
+
+                AxisVector input_axis_order(arg0_shape.size());
+                for (size_t i = 0; i < arg0_shape.size(); i++)
+                {
+                    input_axis_order[i] = i;
+                }
+
+                CoordinateTransform input_transform(arg0_shape,
+                                                    input_start,
+                                                    input_end,
+                                                    input_strides,
+                                                    input_axis_order,
+                                                    padding_below,
+                                                    padding_above);
+                CoordinateTransform output_transform(out_shape);
+
+                CoordinateTransform::Iterator output_it = output_transform.begin();
+
+                NGRAPH_CHECK(shape_size(input_transform.get_target_shape()) ==
+                             shape_size(output_transform.get_target_shape()));
+
+                for (const Coordinate& in_coord : input_transform)
+                {
+                    const Coordinate& out_coord = *output_it;
+
+                    T v(0);
+
+                    switch (pad_mode)
+                    {
+                    case op::PadMode::CONSTANT:
+                        // If the coordinate is out of bounds, substitute *arg1.
+                        v = input_transform.has_source_coordinate(in_coord)
+                                ? arg0[input_transform.index(in_coord)]
+                                : *arg1;
+                        break;
+                    case op::PadMode::EDGE:
+                    {
+                        Coordinate c = in_coord; // have to copy because in_coord is const
+
+                        // Truncate each out-of-bound dimension.
+                        for (size_t i = 0; i < c.size(); i++)
+                        {
+                            if (static_cast<ptrdiff_t>(c[i]) < padding_below[i])
+                            {
+                                c[i] = padding_below[i];
+                            }
+
+                            if (static_cast<ptrdiff_t>(c[i]) >=
+                                (padding_below[i] + static_cast<ptrdiff_t>(arg0_shape[i])))
+                            {
+                                c[i] = static_cast<size_t>(
+                                    padding_below[i] + static_cast<ptrdiff_t>(arg0_shape[i]) - 1);
+                            }
+                        }
+                        v = arg0[input_transform.index(c)];
+                        break;
+                    }
+                    case op::PadMode::REFLECT:
+                    {
+                        // clang-format off
+                        // The algorithm here is a bit complicated because if the padding is
+                        // bigger than the tensor, we may reflect multiple times.
+                        //
+                        // Example:
+                        //
+                        // Input shape:     [2]
+                        // Padding:         6 below, 6 above
+                        // Output shape:    [14]
+                        //
+                        // Input:                       a b
+                        // Expected output: a b a b a b a b a b a b a b
+                        //
+                        // Computation for coordinate 13 of output:
+                        //
+                        //         . . . . . . a b . . . . .[.] -> (oob above by 6 spaces, so reflection is at top-6)
+                        //         .[.]. . . . a b . . . . . .  -> (oob below by 5 spaces, so reflection is at bottom+5)
+                        //         . . . . . . a b . . .[.]. .  -> (oob above by 4 spaces, so reflection is at top-4)
+                        //         . . .[.]. . a b . . . . . .  -> (oob below by 3 spaces, so reflection is at bottom+3)
+                        //         . . . . . . a b .[.]. . . .  -> (oob above by 2 spaces, so reflection is at top-2)
+                        //         . . . . .[.]a b . . . . . .  -> (oob below by 1 space,  so reflection is at bottom+1)
+                        //         . . . . . . a[b]. . . . . .  -> (no longer oob, so copy from here)
+                        //
+                        // Note that this algorithm works because REFLECT padding only makes sense
+                        // if each dim is >= 2.
+                        // clang-format on
+                        Coordinate c = in_coord; // have to copy because in_coord is const
+
+                        for (size_t i = 0; i < c.size(); i++)
+                        {
+                            ptrdiff_t new_dim = c[i];
+                            bool done_reflecting = false;
+
+                            while (!done_reflecting)
+                            {
+                                if (new_dim < padding_below[i])
+                                {
+                                    ptrdiff_t distance_oob = padding_below[i] - new_dim;
+                                    new_dim = padding_below[i] + distance_oob;
+                                }
+                                else if (new_dim >=
+                                         padding_below[i] + static_cast<ptrdiff_t>(arg0_shape[i]))
+                                {
+                                    ptrdiff_t distance_oob =
+                                        new_dim - padding_below[i] -
+                                        (static_cast<ptrdiff_t>(arg0_shape[i]) - 1);
+                                    new_dim = padding_below[i] +
+                                              static_cast<ptrdiff_t>(arg0_shape[i]) - distance_oob -
+                                              1;
+                                }
+                                else
+                                {
+                                    done_reflecting = true;
+                                }
+                            }
+
+                            c[i] = static_cast<size_t>(new_dim);
+                        }
+                        v = arg0[input_transform.index(c)];
+                        break;
+                    }
+                    case op::PadMode::SYMMETRIC:
+                    {
+                        Coordinate c = in_coord; // have to copy because in_coord is const
+                        for (size_t i = 0; i < c.size(); i++)
+                        {
+                            ptrdiff_t pos = padding_below[i] - (c[i] + 1);
+                            if (pos >= 0)
+                            {
+                                c[i] = static_cast<size_t>(pos + padding_below[i]);
+                            }
+                            else
+                            {
+                                pos = -(pos + 1);
+                                ptrdiff_t src_dim = static_cast<ptrdiff_t>(arg0_shape[i]);
+                                if (pos < src_dim)
+                                {
+                                    c[i] = static_cast<size_t>(pos + padding_below[i]);
+                                }
+                                else
+                                {
+                                    c[i] = static_cast<size_t>(padding_below[i] + src_dim +
+                                                               padding_above[i] - pos);
+                                }
+                            }
+                        }
+                        v = arg0[input_transform.index(c)];
+                        break;
+                    }
+                    }
+
+                    out[output_transform.index(out_coord)] = v;
+
+                    ++output_it;
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/power.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/power.hpp
new file mode 100644 (file)
index 0000000..52af243
--- /dev/null
@@ -0,0 +1,56 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+#include "ngraph/op/util/attr_types.hpp"
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void power(const T* arg0, const T* arg1, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::pow(arg0[i], arg1[i]);
+                }
+            }
+
+            template <typename T>
+            void power(const T* arg0,
+                       const T* arg1,
+                       T* out,
+                       const Shape& arg0_shape,
+                       const Shape& arg1_shape,
+                       const op::AutoBroadcastSpec& broadcast_spec)
+            {
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
+                        return std::pow(x, y);
+                    });
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/prelu.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/prelu.hpp
new file mode 100644 (file)
index 0000000..47e4b7f
--- /dev/null
@@ -0,0 +1,48 @@
+//*****************************************************************************
+// Copyright 2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+#include <op/util/attr_types.hpp>
+#include <shape.hpp>
+
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void prelu(const T* arg,
+                       const T* slope,
+                       T* out,
+                       const Shape& arg_shape,
+                       const Shape& slope_shape)
+            {
+                int cnt = 0;
+                for (size_t i = 0; i < shape_size(arg_shape); ++i)
+                {
+                    out[i] =
+                        arg[i] < T(0) ? T(arg[i] * slope[cnt++ % shape_size(slope_shape)]) : arg[i];
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/prior_box.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/prior_box.hpp
new file mode 100644 (file)
index 0000000..f9402f0
--- /dev/null
@@ -0,0 +1,296 @@
+//*****************************************************************************
+// Copyright 2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/axis_vector.hpp"
+#include "ngraph/check.hpp"
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/op/prior_box.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            static inline float clip_great(float x, float threshold)
+            {
+                return x < threshold ? x : threshold;
+            }
+
+            static inline float clip_less(float x, float threshold)
+            {
+                return x > threshold ? x : threshold;
+            }
+
+            template <typename T>
+            void prior_box(const T* data,
+                           const T* img,
+                           float* dst_data,
+                           const Shape& out_shape,
+                           const op::PriorBoxAttrs& attrs)
+            {
+                const int64_t W = data[1];
+                const int64_t H = data[0];
+                const int64_t IW = img[1];
+                const int64_t IH = img[0];
+
+                const int64_t OH = out_shape[1];
+                const int64_t OW = 1;
+
+                std::vector<float> aspect_ratios = {1.0f};
+                for (const auto& aspect_ratio : attrs.aspect_ratio)
+                {
+                    bool exist = false;
+                    for (const auto existed_value : aspect_ratios)
+                        exist |= std::fabs(aspect_ratio - existed_value) < 1e-6;
+
+                    if (!exist)
+                    {
+                        aspect_ratios.push_back(aspect_ratio);
+                        if (attrs.flip)
+                        {
+                            aspect_ratios.push_back(1.0f / aspect_ratio);
+                        }
+                    }
+                }
+
+                std::vector<float> variance = attrs.variance;
+                NGRAPH_CHECK(variance.size() == 1 || variance.size() == 4 || variance.empty());
+                if (variance.empty())
+                    variance.push_back(0.1f);
+
+                int64_t num_priors = op::PriorBox::number_of_priors(attrs);
+
+                float step = attrs.step;
+                auto min_size = attrs.min_size;
+                if (!attrs.scale_all_sizes)
+                {
+                    // mxnet-like PriorBox
+                    if (step == -1)
+                        step = 1.f * IH / H;
+                    else
+                        step *= IH;
+                    for (auto& size : min_size)
+                        size *= IH;
+                }
+
+                int64_t idx = 0;
+                float center_x, center_y, box_width, box_height, step_x, step_y;
+                float IWI = 1.0f / static_cast<float>(IW);
+                float IHI = 1.0f / static_cast<float>(IH);
+
+                if (step == 0)
+                {
+                    step_x = static_cast<float>(IW) / W;
+                    step_y = static_cast<float>(IH) / H;
+                }
+                else
+                {
+                    step_x = step;
+                    step_y = step;
+                }
+
+                auto calculate_data = [&dst_data, &IWI, &IHI, &idx](
+                    float center_x, float center_y, float box_width, float box_height, bool clip) {
+                    if (clip)
+                    {
+                        // order: xmin, ymin, xmax, ymax
+                        dst_data[idx++] = clip_less((center_x - box_width) * IWI, 0);
+                        dst_data[idx++] = clip_less((center_y - box_height) * IHI, 0);
+                        dst_data[idx++] = clip_great((center_x + box_width) * IWI, 1);
+                        dst_data[idx++] = clip_great((center_y + box_height) * IHI, 1);
+                    }
+                    else
+                    {
+                        dst_data[idx++] = (center_x - box_width) * IWI;
+                        dst_data[idx++] = (center_y - box_height) * IHI;
+                        dst_data[idx++] = (center_x + box_width) * IWI;
+                        dst_data[idx++] = (center_y + box_height) * IHI;
+                    }
+                };
+
+                for (int64_t h = 0; h < H; ++h)
+                {
+                    for (int64_t w = 0; w < W; ++w)
+                    {
+                        if (step == 0)
+                        {
+                            center_x = (w + 0.5f) * step_x;
+                            center_y = (h + 0.5f) * step_y;
+                        }
+                        else
+                        {
+                            center_x = (attrs.offset + w) * step;
+                            center_y = (attrs.offset + h) * step;
+                        }
+
+                        for (size_t s = 0; s < attrs.fixed_size.size(); ++s)
+                        {
+                            auto fixed_size_ = static_cast<size_t>(attrs.fixed_size[s]);
+                            box_width = box_height = fixed_size_ * 0.5f;
+
+                            if (!attrs.fixed_ratio.empty())
+                            {
+                                for (float ar : attrs.fixed_ratio)
+                                {
+                                    auto density_ = static_cast<int64_t>(attrs.density[s]);
+                                    auto shift =
+                                        static_cast<int64_t>(attrs.fixed_size[s] / density_);
+                                    ar = std::sqrt(ar);
+                                    float box_width_ratio = attrs.fixed_size[s] * 0.5f * ar;
+                                    float box_height_ratio = attrs.fixed_size[s] * 0.5f / ar;
+                                    for (size_t r = 0; r < density_; ++r)
+                                    {
+                                        for (size_t c = 0; c < density_; ++c)
+                                        {
+                                            float center_x_temp = center_x - fixed_size_ / 2 +
+                                                                  shift / 2.f + c * shift;
+                                            float center_y_temp = center_y - fixed_size_ / 2 +
+                                                                  shift / 2.f + r * shift;
+                                            calculate_data(center_x_temp,
+                                                           center_y_temp,
+                                                           box_width_ratio,
+                                                           box_height_ratio,
+                                                           true);
+                                        }
+                                    }
+                                }
+                            }
+                            else
+                            {
+                                if (!attrs.density.empty())
+                                {
+                                    auto density_ = static_cast<int64_t>(attrs.density[s]);
+                                    auto shift =
+                                        static_cast<int64_t>(attrs.fixed_size[s] / density_);
+                                    for (int64_t r = 0; r < density_; ++r)
+                                    {
+                                        for (int64_t c = 0; c < density_; ++c)
+                                        {
+                                            float center_x_temp = center_x - fixed_size_ / 2 +
+                                                                  shift / 2.f + c * shift;
+                                            float center_y_temp = center_y - fixed_size_ / 2 +
+                                                                  shift / 2.f + r * shift;
+                                            calculate_data(center_x_temp,
+                                                           center_y_temp,
+                                                           box_width,
+                                                           box_height,
+                                                           true);
+                                        }
+                                    }
+                                }
+                                //  Rest of priors
+                                for (float ar : aspect_ratios)
+                                {
+                                    if (fabs(ar - 1.) < 1e-6)
+                                    {
+                                        continue;
+                                    }
+
+                                    auto density_ = static_cast<int64_t>(attrs.density[s]);
+                                    auto shift =
+                                        static_cast<int64_t>(attrs.fixed_size[s] / density_);
+                                    ar = std::sqrt(ar);
+                                    float box_width_ratio = attrs.fixed_size[s] * 0.5f * ar;
+                                    float box_height_ratio = attrs.fixed_size[s] * 0.5f / ar;
+                                    for (int64_t r = 0; r < density_; ++r)
+                                    {
+                                        for (int64_t c = 0; c < density_; ++c)
+                                        {
+                                            float center_x_temp = center_x - fixed_size_ / 2 +
+                                                                  shift / 2.f + c * shift;
+                                            float center_y_temp = center_y - fixed_size_ / 2 +
+                                                                  shift / 2.f + r * shift;
+                                            calculate_data(center_x_temp,
+                                                           center_y_temp,
+                                                           box_width_ratio,
+                                                           box_height_ratio,
+                                                           true);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+
+                        for (size_t ms_idx = 0; ms_idx < min_size.size(); ms_idx++)
+                        {
+                            box_width = min_size[ms_idx] * 0.5f;
+                            box_height = min_size[ms_idx] * 0.5f;
+                            calculate_data(center_x, center_y, box_width, box_height, false);
+
+                            if (attrs.max_size.size() > ms_idx)
+                            {
+                                box_width = box_height =
+                                    std::sqrt(min_size[ms_idx] * attrs.max_size[ms_idx]) * 0.5f;
+                                calculate_data(center_x, center_y, box_width, box_height, false);
+                            }
+
+                            if (attrs.scale_all_sizes ||
+                                (!attrs.scale_all_sizes && (ms_idx == min_size.size() - 1)))
+                            {
+                                size_t s_idx = attrs.scale_all_sizes ? ms_idx : 0;
+                                for (float ar : aspect_ratios)
+                                {
+                                    if (std::fabs(ar - 1.0f) < 1e-6)
+                                    {
+                                        continue;
+                                    }
+
+                                    ar = std::sqrt(ar);
+                                    box_width = min_size[s_idx] * 0.5f * ar;
+                                    box_height = min_size[s_idx] * 0.5f / ar;
+                                    calculate_data(
+                                        center_x, center_y, box_width, box_height, false);
+                                }
+                            }
+                        }
+                    }
+                }
+
+                if (attrs.clip)
+                {
+                    for (uint64_t i = 0; i < H * W * num_priors * 4; ++i)
+                    {
+                        dst_data[i] = (std::min)((std::max)(dst_data[i], 0.0f), 1.0f);
+                    }
+                }
+
+                uint64_t channel_size = OH * OW;
+                if (variance.size() == 1)
+                {
+                    for (uint64_t i = 0; i < channel_size; ++i)
+                    {
+                        dst_data[i + channel_size] = variance[0];
+                    }
+                }
+                else
+                {
+                    for (uint64_t i = 0; i < H * W * num_priors; ++i)
+                    {
+                        for (size_t j = 0; j < 4; ++j)
+                        {
+                            dst_data[i * 4 + j + channel_size] = variance[j];
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/prior_box_clustered.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/prior_box_clustered.hpp
new file mode 100644 (file)
index 0000000..f6b76a6
--- /dev/null
@@ -0,0 +1,116 @@
+//*****************************************************************************
+// Copyright 2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/axis_vector.hpp"
+#include "ngraph/check.hpp"
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/op/prior_box_clustered.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void prior_box_clustered(const T* data,
+                                     const T* img,
+                                     float* dst_data,
+                                     const Shape& out_shape,
+                                     const op::PriorBoxClusteredAttrs& attrs)
+            {
+                size_t num_priors_ = attrs.widths.size();
+
+                auto variances = attrs.variances;
+                if (variances.empty())
+                    variances.push_back(0.1f);
+
+                // Execute
+                const int64_t layer_width = data[1];
+                const int64_t layer_height = data[0];
+
+                int64_t img_width = img[1];
+                int64_t img_height = img[0];
+
+                // TODO: Uncomment after PriorBoxClustered is aligned with the specification.
+
+                //                int img_width = img_w_ == 0 ? img[1] : img_w_;
+                //                int img_height = img_h_ == 0 ? img[0] : img_h_;
+
+                //                float step_w = attrs.step_widths == 0 ? step_ : attrs.step_widths;
+                //                float step_h = attrs.step_heights == 0 ? step_ :
+                //                attrs.step_heights;
+
+                float step_w = attrs.step_widths;
+                float step_h = attrs.step_heights;
+
+                if (step_w == 0 && step_h == 0)
+                {
+                    step_w = static_cast<float>(img_width) / layer_width;
+                    step_h = static_cast<float>(img_height) / layer_height;
+                }
+
+                size_t var_size = variances.size();
+                for (int64_t h = 0; h < layer_height; ++h)
+                {
+                    for (int64_t w = 0; w < layer_width; ++w)
+                    {
+                        float center_x = (w + attrs.offset) * step_w;
+                        float center_y = (h + attrs.offset) * step_h;
+
+                        for (size_t s = 0; s < num_priors_; ++s)
+                        {
+                            float box_width = attrs.widths[s];
+                            float box_height = attrs.heights[s];
+
+                            float xmin = (center_x - box_width / 2.0f) / img_width;
+                            float ymin = (center_y - box_height / 2.0f) / img_height;
+                            float xmax = (center_x + box_width / 2.0f) / img_width;
+                            float ymax = (center_y + box_height / 2.0f) / img_height;
+
+                            if (attrs.clip)
+                            {
+                                xmin = (std::min)((std::max)(xmin, 0.0f), 1.0f);
+                                ymin = (std::min)((std::max)(ymin, 0.0f), 1.0f);
+                                xmax = (std::min)((std::max)(xmax, 0.0f), 1.0f);
+                                ymax = (std::min)((std::max)(ymax, 0.0f), 1.0f);
+                            }
+
+                            auto get_idx = [&](uint64_t cnt) -> uint64_t {
+                                return h * layer_width * num_priors_ * cnt + w * num_priors_ * cnt +
+                                       s * cnt;
+                            };
+
+                            uint64_t idx = get_idx(4);
+                            dst_data[idx + 0] = xmin;
+                            dst_data[idx + 1] = ymin;
+                            dst_data[idx + 2] = xmax;
+                            dst_data[idx + 3] = ymax;
+
+                            idx = get_idx(var_size);
+                            for (size_t j = 0; j < var_size; j++)
+                                dst_data[idx + j + out_shape[1]] = variances[j];
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/product.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/product.hpp
new file mode 100644 (file)
index 0000000..057424f
--- /dev/null
@@ -0,0 +1,58 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void product(const T* arg,
+                         T* out,
+                         const Shape& in_shape,
+                         const AxisSet& reduction_axes,
+                         bool keep_dims)
+            {
+                auto out_shape = reduce(in_shape, reduction_axes, keep_dims);
+                CoordinateTransform output_transform(out_shape);
+
+                for (const Coordinate& output_coord : output_transform)
+                {
+                    out[output_transform.index(output_coord)] = 1;
+                }
+
+                CoordinateTransform input_transform(in_shape);
+
+                for (const Coordinate& input_coord : input_transform)
+                {
+                    Coordinate output_coord = reduce(input_coord, reduction_axes, keep_dims);
+
+                    size_t output_index = output_transform.index(output_coord);
+
+                    out[output_index] = out[output_index] * arg[input_transform.index(input_coord)];
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/quantize.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/quantize.hpp
new file mode 100644 (file)
index 0000000..99afe2e
--- /dev/null
@@ -0,0 +1,120 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/op/quantize.hpp"
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename REAL, typename QUANT>
+            void quantize(const REAL* input,
+                          const REAL* scale,
+                          const QUANT* zero_point,
+                          QUANT* output,
+                          const Shape& input_shape,
+                          const Shape& scale_zero_point_shape,
+                          const AxisSet& axes,
+                          op::Quantize::RoundMode round_mode)
+            {
+                CoordinateTransform input_transform(input_shape);
+                CoordinateTransform scale_zero_point_transform(scale_zero_point_shape);
+
+                for (const Coordinate& input_coord : input_transform)
+                {
+                    Coordinate scale_zero_point_coord = project(input_coord, axes);
+
+                    // apply scale
+                    REAL qvalue = input[input_transform.index(input_coord)] /
+                                  scale[scale_zero_point_transform.index(scale_zero_point_coord)];
+
+                    // round
+                    if (round_mode == op::Quantize::RoundMode::ROUND_NEAREST_TOWARD_INFINITY)
+                    {
+                        REAL abs_qvalue = std::fabs(qvalue);
+                        REAL abs_qvalue_toward_inf =
+                            std::floor(abs_qvalue + static_cast<REAL>(0.5));
+                        qvalue = (qvalue < static_cast<REAL>(0.0)) ? -abs_qvalue_toward_inf
+                                                                   : abs_qvalue_toward_inf;
+                    }
+                    else if (round_mode == op::Quantize::RoundMode::ROUND_NEAREST_TOWARD_ZERO)
+                    {
+                        auto abs_qvalue = std::fabs(qvalue);
+                        auto abs_qvalue_toward_zero =
+                            std::ceil(abs_qvalue - static_cast<REAL>(0.5));
+                        qvalue = (qvalue < static_cast<REAL>(0.0)) ? -abs_qvalue_toward_zero
+                                                                   : abs_qvalue_toward_zero;
+                    }
+                    else if (round_mode == op::Quantize::RoundMode::ROUND_NEAREST_UPWARD)
+                    {
+                        qvalue = std::floor(qvalue + static_cast<REAL>(0.5));
+                    }
+                    else if (round_mode == op::Quantize::RoundMode::ROUND_NEAREST_DOWNWARD)
+                    {
+                        qvalue = std::ceil(qvalue - static_cast<REAL>(0.5));
+                    }
+                    else if (round_mode == op::Quantize::RoundMode::ROUND_NEAREST_TOWARD_EVEN)
+                    {
+                        auto up_qvalue = std::floor(qvalue + static_cast<REAL>(0.5));
+                        auto dn_qvalue = std::ceil(qvalue - static_cast<REAL>(0.5));
+                        auto rem = std::fmod(up_qvalue, 2.0);
+                        qvalue = (rem == 0.0) ? up_qvalue : dn_qvalue;
+                    }
+                    else if (round_mode == op::Quantize::RoundMode::ROUND_TOWARD_INFINITY)
+                    {
+                        auto abs_qvalue = std::fabs(qvalue);
+                        auto abs_qvalue_toward_inf = std::ceil(abs_qvalue);
+                        qvalue = (qvalue < static_cast<REAL>(0.0)) ? -abs_qvalue_toward_inf
+                                                                   : abs_qvalue_toward_inf;
+                    }
+                    else if (round_mode == op::Quantize::RoundMode::ROUND_TOWARD_ZERO)
+                    {
+                        auto abs_qvalue = std::fabs(qvalue);
+                        auto abs_qvalue_toward_zero = std::floor(abs_qvalue);
+                        qvalue = (qvalue < static_cast<REAL>(0.0)) ? -abs_qvalue_toward_zero
+                                                                   : abs_qvalue_toward_zero;
+                    }
+                    else if (round_mode == op::Quantize::RoundMode::ROUND_UP)
+                    {
+                        qvalue = std::ceil(qvalue);
+                    }
+                    else if (round_mode == op::Quantize::RoundMode::ROUND_DOWN)
+                    {
+                        qvalue = std::floor(qvalue);
+                    }
+
+                    // apply zero_point
+                    qvalue += zero_point[scale_zero_point_transform.index(scale_zero_point_coord)];
+
+                    // clamp
+                    qvalue = std::max<REAL>(qvalue,
+                                            static_cast<REAL>(std::numeric_limits<QUANT>::min()));
+                    qvalue = std::min<REAL>(qvalue,
+                                            static_cast<REAL>(std::numeric_limits<QUANT>::max()));
+
+                    // cast
+                    output[input_transform.index(input_coord)] = static_cast<QUANT>(qvalue);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/range.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/range.hpp
new file mode 100644 (file)
index 0000000..4897522
--- /dev/null
@@ -0,0 +1,63 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <type_traits>
+
+#include "ngraph/axis_vector.hpp"
+#include "ngraph/check.hpp"
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/type/bfloat16.hpp"
+#include "ngraph/type/float16.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            // Return type is `void`, only enabled if `T` is a built-in FP
+            // type, or nGraph's `bfloat16` or `float16` type.
+            template <typename T>
+            typename std::enable_if<std::is_floating_point<T>::value ||
+                                    std::is_same<T, bfloat16>::value ||
+                                    std::is_same<T, float16>::value>::type
+                range(const T* start, const T* step, const Shape& out_shape, T* out)
+            {
+                for (size_t i = 0; i < shape_size(out_shape); i++)
+                {
+                    out[i] = *start + (static_cast<T>(i) * (*step));
+                }
+            }
+
+            // Return type is `void`, only enabled if `T` is `is_integral`.
+            template <typename T>
+            typename std::enable_if<std::is_integral<T>::value>::type
+                range(const T* start, const T* step, const Shape& out_shape, T* out)
+            {
+                T val = *start;
+
+                for (size_t i = 0; i < shape_size(out_shape); i++)
+                {
+                    out[i] = val;
+                    val += *step;
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/reduce_l1.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/reduce_l1.hpp
new file mode 100644 (file)
index 0000000..21bc8c5
--- /dev/null
@@ -0,0 +1,59 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void reduce_l1(const T* arg,
+                           T* out,
+                           const Shape& in_shape,
+                           const AxisSet& reduction_axes,
+                           bool keep_dims)
+            {
+                auto out_shape = reduce(in_shape, reduction_axes, keep_dims);
+                CoordinateTransform output_transform(out_shape);
+
+                for (const Coordinate& output_coord : output_transform)
+                {
+                    out[output_transform.index(output_coord)] = 0;
+                }
+
+                CoordinateTransform input_transform(in_shape);
+
+                for (const Coordinate& input_coord : input_transform)
+                {
+                    Coordinate output_coord = reduce(input_coord, reduction_axes, keep_dims);
+
+                    size_t output_index = output_transform.index(output_coord);
+
+                    out[output_index] =
+                        out[output_index] + abs(arg[input_transform.index(input_coord)]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/reduce_l2.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/reduce_l2.hpp
new file mode 100644 (file)
index 0000000..2623a04
--- /dev/null
@@ -0,0 +1,65 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void reduce_l2(const T* arg,
+                           T* out,
+                           const Shape& in_shape,
+                           const AxisSet& reduction_axes,
+                           bool keep_dims)
+            {
+                auto out_shape = reduce(in_shape, reduction_axes, keep_dims);
+                CoordinateTransform output_transform(out_shape);
+
+                for (const Coordinate& output_coord : output_transform)
+                {
+                    out[output_transform.index(output_coord)] = 0;
+                }
+
+                CoordinateTransform input_transform(in_shape);
+
+                for (const Coordinate& input_coord : input_transform)
+                {
+                    Coordinate output_coord = reduce(input_coord, reduction_axes, keep_dims);
+
+                    size_t output_index = output_transform.index(output_coord);
+
+                    out[output_index] = out[output_index] +
+                                        arg[input_transform.index(input_coord)] *
+                                            arg[input_transform.index(input_coord)];
+                }
+                for (const Coordinate& output_coord : output_transform)
+                {
+                    out[output_transform.index(output_coord)] =
+                        sqrt(out[output_transform.index(output_coord)]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/relu.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/relu.hpp
new file mode 100644 (file)
index 0000000..0fabf4b
--- /dev/null
@@ -0,0 +1,47 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void relu(const T* arg, T* out, size_t count)
+            {
+                T zero = 0;
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg[i] > zero ? arg[i] : zero;
+                }
+            }
+            template <typename T>
+            void relu_backprop(const T* arg, const T* delta_arg, T* out, size_t count)
+            {
+                T zero = 0;
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg[i] > zero ? delta_arg[i] : zero;
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/replace_slice.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/replace_slice.hpp
new file mode 100644 (file)
index 0000000..6cf444f
--- /dev/null
@@ -0,0 +1,70 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/check.hpp"
+#include "ngraph/coordinate_transform.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void replace_slice(const T* arg0, // replacement context
+                               const T* arg1, // replacement value
+                               T* out,
+                               const Shape& arg1_shape,
+                               const Coordinate& lower_bounds,
+                               const Coordinate& upper_bounds,
+                               const Strides& strides,
+                               const Shape& out_shape)
+            {
+                // Step 1: Copy the entire replacement context to the output.
+                CoordinateTransform copy_transform(out_shape);
+
+                for (Coordinate copy_coord : copy_transform)
+                {
+                    out[copy_transform.index(copy_coord)] = arg0[copy_transform.index(copy_coord)];
+                }
+
+                // Step 2: Overwrite the slice for replacement.
+                CoordinateTransform input_transform(arg1_shape);
+                CoordinateTransform output_transform(
+                    out_shape, lower_bounds, upper_bounds, strides);
+
+                NGRAPH_CHECK(shape_size(input_transform.get_target_shape()) ==
+                             shape_size(output_transform.get_target_shape()));
+
+                CoordinateTransform::Iterator output_it = output_transform.begin();
+
+                for (const Coordinate& input_coord : input_transform)
+                {
+                    const Coordinate& output_coord = *output_it;
+
+                    out[output_transform.index(output_coord)] =
+                        arg1[input_transform.index(input_coord)];
+
+                    ++output_it;
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/reshape.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/reshape.hpp
new file mode 100644 (file)
index 0000000..e4711d6
--- /dev/null
@@ -0,0 +1,40 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/axis_vector.hpp"
+#include "ngraph/check.hpp"
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/type/element_type.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            void reshape(const char* arg,
+                         char* out,
+                         const Shape& in_shape,
+                         const AxisVector& in_axis_order,
+                         const Shape& out_shape,
+                         size_t elem_size);
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/result.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/result.hpp
new file mode 100644 (file)
index 0000000..a6081bd
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <algorithm>
+#include <cmath>
+#include <numeric>
+#include <vector>
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void result(const T* arg, T* out, size_t count)
+            {
+                memcpy(out, arg, sizeof(T) * count);
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/reverse.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/reverse.hpp
new file mode 100644 (file)
index 0000000..9abca26
--- /dev/null
@@ -0,0 +1,37 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/coordinate_transform.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            void reverse(const char* arg,
+                         char* out,
+                         const Shape& arg_shape,
+                         const Shape& out_shape,
+                         const AxisSet& reversed_axes,
+                         size_t elem_size);
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/reverse_sequence.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/reverse_sequence.hpp
new file mode 100644 (file)
index 0000000..15f6398
--- /dev/null
@@ -0,0 +1,69 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <numeric>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T, typename U>
+            void reverse_sequence(const T* arg,
+                                  T* out,
+                                  const Shape& arg_shape,
+                                  size_t batch_axis,
+                                  size_t sequence_axis,
+                                  const U* sequence_lengths)
+            {
+                CoordinateTransform input_transform(arg_shape);
+                for (const Coordinate& in_coord : input_transform)
+                {
+                    size_t batch_index = in_coord[batch_axis];
+                    auto orig_seq_index = static_cast<size_t>(sequence_lengths[batch_index]);
+
+                    if (orig_seq_index > arg_shape.at(sequence_axis))
+                    {
+                        throw ngraph_error(
+                            "One of the elements of sequence lengths is greater than sequence axis "
+                            "dimension");
+                    }
+
+                    if (orig_seq_index == 0)
+                    {
+                        orig_seq_index = 1;
+                    }
+
+                    size_t sequence_index = in_coord[sequence_axis] < orig_seq_index
+                                                ? orig_seq_index - in_coord[sequence_axis] - 1
+                                                : in_coord[sequence_axis];
+
+                    // make a copy of in_coord and update sequence_index
+                    Coordinate out_coord = in_coord;
+                    out_coord[sequence_axis] = sequence_index;
+                    out[input_transform.index(out_coord)] = arg[input_transform.index(in_coord)];
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/round.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/round.hpp
new file mode 100644 (file)
index 0000000..50949ab
--- /dev/null
@@ -0,0 +1,52 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            T round_to_nearest_even(const T arg)
+            {
+                const auto floor_arg = std::floor(arg);
+                const auto diff = arg - floor_arg;
+                if (diff < 0.5f || (diff == 0.5f && static_cast<int>(floor_arg) % 2 == 0))
+                {
+                    return floor_arg;
+                }
+                else
+                {
+                    return floor_arg + 1.0f;
+                }
+            }
+
+            template <typename T>
+            void round(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; ++i)
+                {
+                    out[i] = round_to_nearest_even(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/scatter_elements_update.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/scatter_elements_update.hpp
new file mode 100644 (file)
index 0000000..c0f239d
--- /dev/null
@@ -0,0 +1,65 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstring>
+
+#include "ngraph/check.hpp"
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename DataType, typename IndicesType>
+            void scatter_elem_update(const DataType* input_data,
+                                     const IndicesType* indices,
+                                     const DataType* updates,
+                                     const int64_t& axis,
+                                     DataType* out_buf,
+                                     const Shape& data_shape,
+                                     const Shape& indices_shape)
+            {
+                // Copy inputs to out
+                std::memcpy(out_buf, input_data, sizeof(DataType) * shape_size(data_shape));
+
+                // 3D example
+                // output[indices[i][j][k]][j][k] = updates[i][j][k] if axis = 0,
+                // output[i][indices[i][j][k]][k] = updates[i][j][k] if axis = 1,
+                // output[i][j][indices[i][j][k]] = updates[i][j][k] if axis = 2
+
+                CoordinateTransform indices_transform{indices_shape};
+                CoordinateTransform data_transform{data_shape};
+
+                for (const Coordinate& indices_cord : indices_transform)
+                {
+                    const size_t indices_idx = indices_transform.index(indices_cord);
+                    Coordinate out_cord(indices_cord);
+                    out_cord.at(axis) = indices[indices_idx];
+                    NGRAPH_CHECK(data_transform.has_source_coordinate(out_cord),
+                                 "Provided index coordinates are out of input data bounds: ",
+                                 out_cord,
+                                 ".");
+                    out_buf[data_transform.index(out_cord)] = updates[indices_idx];
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/scatter_nd_update.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/scatter_nd_update.hpp
new file mode 100644 (file)
index 0000000..37d3b5a
--- /dev/null
@@ -0,0 +1,63 @@
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#pragma once
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/shape.hpp"
+
+using namespace ngraph;
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename dataType, typename indicesType>
+            void scatterNdUpdate(const dataType* inputData,
+                                 const indicesType* indices,
+                                 const dataType* updates,
+                                 dataType* outBuf,
+                                 const Shape& dataShape,
+                                 const Shape& indicesShape,
+                                 const Shape& updatesShape)
+            {
+                size_t numSlices = 1;
+                size_t sliceSize = 1;
+                for (size_t i = 0; i < indicesShape.size() - 1; i++)
+                {
+                    numSlices *= indicesShape[i];
+                }
+                for (size_t i = indicesShape.size() - 1; i < updatesShape.size(); i++)
+                {
+                    sliceSize *= updatesShape[i];
+                }
+
+                const size_t k = indicesShape.back();
+                std::memcpy(outBuf, inputData, sizeof(dataType) * shape_size(dataShape));
+                CoordinateTransform dataTransform{dataShape};
+
+                for (size_t i = 0; i < numSlices; i++)
+                {
+                    Coordinate coord;
+                    for (size_t j = 0; j < k; j++)
+                    {
+                        coord.push_back(indices[i * k + j]);
+                    }
+                    for (size_t j = k; j < dataShape.size(); j++)
+                    {
+                        coord.push_back(0);
+                    }
+
+                    const size_t startDataIdx = dataTransform.index(coord);
+                    for (size_t j = 0; j < sliceSize; j++)
+                    {
+                        outBuf[startDataIdx + j] = updates[i * sliceSize + j];
+                    }
+                }
+            }
+        } // namespace reference
+    }     // namespace runtime
+} // namespace ngraph
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/scatter_update.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/scatter_update.hpp
new file mode 100644 (file)
index 0000000..e3cae8c
--- /dev/null
@@ -0,0 +1,86 @@
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#pragma once
+
+#include <string>
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/shape.hpp"
+
+using namespace ngraph;
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename dataType, typename indicesType, typename axisType>
+            void scatterUpdate(const dataType* inputData,
+                               const indicesType* indices,
+                               const dataType* updates,
+                               const axisType* _axis,
+                               dataType* outBuf,
+                               const Shape& dataShape,
+                               const Shape& indicesShape,
+                               const Shape& updatesShape)
+            {
+                int rank = static_cast<int>(dataShape.size());
+                if (_axis[0] < -rank || _axis[0] > rank - 1)
+                {
+                    std::string error =
+                        std::string("ScatterUpdate layer has out of bounds axis value: ") +
+                        std::to_string(_axis[0]);
+                    throw ngraph_error(error);
+                }
+                size_t axis = _axis[0] < 0 ? _axis[0] + rank : _axis[0];
+                CoordinateTransform indicesTransform{indicesShape};
+
+                Shape dataShapeIter = dataShape;
+                dataShapeIter.erase(dataShapeIter.begin() + axis);
+                CoordinateTransform dataTransfIter{dataShapeIter};
+
+                CoordinateTransform updateTransform{updatesShape};
+                CoordinateTransform dataTransform{dataShape};
+
+                std::memcpy(outBuf, inputData, sizeof(dataType) * shape_size(dataShape));
+
+                for (const Coordinate& indicesCoordIt : indicesTransform)
+                {
+                    const size_t indicesIdx = indicesTransform.index(indicesCoordIt);
+
+                    if (indices[indicesIdx] < 0)
+                    {
+                        std::string error =
+                            std::string("ScatterUpdate layer has negative index value: ") +
+                            std::to_string(indices[indicesIdx]);
+                        throw ngraph_error(error);
+                    }
+                    const size_t idx = static_cast<size_t>(indices[indicesIdx]);
+                    if (dataShape[axis] <= idx)
+                    {
+                        std::string error =
+                            std::string("ScatterUpdate layer has out of bounds coordinate: ") +
+                            std::to_string(idx) + " on 'data' input on " + std::to_string(axis) +
+                            "th axis";
+                        throw ngraph_error(error);
+                    }
+
+                    for (const Coordinate& dataCoordIt : dataTransfIter)
+                    {
+                        Coordinate dataCoord = dataCoordIt;
+                        dataCoord.insert(dataCoord.begin() + axis, idx);
+                        const size_t startIndices = dataTransform.index(dataCoord);
+
+                        auto updCoord = dataCoordIt;
+                        updCoord.insert(
+                            updCoord.begin() + axis, indicesCoordIt.begin(), indicesCoordIt.end());
+                        const size_t startUpd = updateTransform.index(updCoord);
+                        outBuf[startIndices] = updates[startUpd];
+                    }
+                }
+            }
+        } // namespace reference
+    }     // namespace runtime
+} // namespace ngraph
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/select.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/select.hpp
new file mode 100644 (file)
index 0000000..3f6da66
--- /dev/null
@@ -0,0 +1,66 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+#include <iostream>
+
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void select(const char* arg0,
+                        const T* arg1,
+                        const T* arg2,
+                        T* out,
+                        size_t count) // TODO: using char for bool, is this right?
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg0[i] ? arg1[i] : arg2[i];
+                }
+            }
+
+            template <typename T>
+            void select(const char* arg0,
+                        const T* arg1,
+                        const T* arg2,
+                        T* out,
+                        const Shape& arg0_shape,
+                        const Shape& arg1_shape,
+                        const Shape& arg2_shape,
+                        const op::AutoBroadcastSpec& broadcast_spec)
+            {
+                autobroadcast_select(
+                    arg0,
+                    arg1,
+                    arg2,
+                    out,
+                    arg0_shape,
+                    arg1_shape,
+                    arg2_shape,
+                    broadcast_spec,
+                    [](char s, T x, T y) -> T { return static_cast<T>(s ? x : y); });
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/shape_of.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/shape_of.hpp
new file mode 100644 (file)
index 0000000..57621af
--- /dev/null
@@ -0,0 +1,37 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            inline void shape_of(const Shape& arg_shape, T* out)
+            {
+                for (size_t i = 0; i < arg_shape.size(); i++)
+                {
+                    out[i] = static_cast<T>(arg_shape[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/sigmoid.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/sigmoid.hpp
new file mode 100644 (file)
index 0000000..5c10b5f
--- /dev/null
@@ -0,0 +1,53 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void sigmoid(const T* arg, T* out, size_t count)
+            {
+                T exp_value;
+                for (size_t i = 0; i < count; i++)
+                {
+                    exp_value = std::exp(-arg[i]);
+                    out[i] = 1 / (1 + exp_value);
+                }
+            }
+
+            template <typename T>
+            void sigmoid_backprop(const T* arg, const T* delta_arg, T* out, size_t count)
+            {
+                T exp_value;
+                T func_x;
+                for (size_t i = 0; i < count; i++)
+                {
+                    exp_value = std::exp(-arg[i]);
+                    func_x = 1 / (1 + exp_value);
+                    out[i] = delta_arg[i] * func_x * (1 - func_x);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/sign.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/sign.hpp
new file mode 100644 (file)
index 0000000..72bcdd4
--- /dev/null
@@ -0,0 +1,37 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void sign(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = (arg[i] < T(0) ? T(-1) : (arg[i] > T(0) ? T(1) : T(0)));
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/sin.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/sin.hpp
new file mode 100644 (file)
index 0000000..d7935ff
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void sin(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::sin(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/sinh.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/sinh.hpp
new file mode 100644 (file)
index 0000000..1515aa6
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void sinh(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::sinh(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/slice.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/slice.hpp
new file mode 100644 (file)
index 0000000..f59ec7c
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/type/element_type.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            void slice(const char* arg,
+                       char* out,
+                       const Shape& arg_shape,
+                       const Coordinate& lower_bounds,
+                       const Coordinate& upper_bounds,
+                       const Strides& strides,
+                       const Shape& out_shape,
+                       size_t elem_size);
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/softmax.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/softmax.hpp
new file mode 100644 (file)
index 0000000..9c83a56
--- /dev/null
@@ -0,0 +1,61 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/runtime/reference/max.hpp"
+#include "ngraph/runtime/reference/sum.hpp"
+#include "ngraph/shape_util.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void softmax(const T* arg, T* out, const Shape& shape, const AxisSet& axes)
+            {
+                auto temp_shape = reduce(shape, axes, true);
+                auto temp_elements = shape_size(temp_shape);
+                auto temp_ptr = new T[temp_elements];
+
+                max(arg, temp_ptr, shape, axes, true);
+
+                CoordinateTransform transform(shape);
+                CoordinateTransform temp_transform(temp_shape);
+                for (const Coordinate& coord : transform)
+                {
+                    Coordinate temp_coord = reduce(coord, axes, true);
+                    out[transform.index(coord)] = std::exp(
+                        arg[transform.index(coord)] - temp_ptr[temp_transform.index(temp_coord)]);
+                }
+
+                sum(out, temp_ptr, shape, axes, true);
+
+                for (const Coordinate& coord : transform)
+                {
+                    Coordinate temp_coord = reduce(coord, axes, true);
+                    out[transform.index(coord)] /= temp_ptr[temp_transform.index(temp_coord)];
+                }
+
+                delete[] temp_ptr;
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/sqrt.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/sqrt.hpp
new file mode 100644 (file)
index 0000000..4661f65
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void sqrt(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::sqrt(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/strided_slice.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/strided_slice.hpp
new file mode 100644 (file)
index 0000000..3c606a7
--- /dev/null
@@ -0,0 +1,42 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/check.hpp"
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/runtime/host_tensor.hpp"
+#include "ngraph/runtime/opt_kernel/reshape.hpp"
+#include "ngraph/runtime/reference/reverse.hpp"
+#include "ngraph/runtime/reference/slice.hpp"
+#include "ngraph/slice_plan.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            void strided_slice(const char* arg,
+                               char* out,
+                               const Shape& arg_shape,
+                               const SlicePlan& sp,
+                               size_t elem_type);
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/subtract.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/subtract.hpp
new file mode 100644 (file)
index 0000000..bc3b63f
--- /dev/null
@@ -0,0 +1,55 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+#include "ngraph/op/util/attr_types.hpp"
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void subtract(const T* arg0, const T* arg1, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg0[i] - arg1[i];
+                }
+            }
+
+            template <typename T>
+            void subtract(const T* arg0,
+                          const T* arg1,
+                          T* out,
+                          const Shape& arg0_shape,
+                          const Shape& arg1_shape,
+                          const op::AutoBroadcastSpec& broadcast_spec)
+            {
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
+                        return x - y;
+                    });
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/sum.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/sum.hpp
new file mode 100644 (file)
index 0000000..a67cbac
--- /dev/null
@@ -0,0 +1,96 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/shape_util.hpp"
+#include "ngraph/type/bfloat16.hpp"
+#include "ngraph/type/float16.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            // Windows doesn't seem to like it if we directly use std::isfinite on integer types,
+            // so we will roll our own thing here.
+            template <typename T>
+            typename std::enable_if<std::is_floating_point<T>::value, bool>::type is_finite(T x)
+            {
+                return std::isfinite(x);
+            }
+
+            template <typename T>
+            typename std::enable_if<std::is_same<T, bfloat16>::value ||
+                                        std::is_same<T, float16>::value,
+                                    bool>::type
+                is_finite(T x)
+            {
+                return std::isfinite(static_cast<float>(x));
+            }
+
+            template <typename T>
+            typename std::enable_if<std::is_integral<T>::value, bool>::type is_finite(T /* x */)
+            {
+                return true;
+            }
+
+            template <typename T>
+            void sum(const T* arg,
+                     T* out,
+                     const Shape& in_shape,
+                     const AxisSet& reduction_axes,
+                     bool keep_dims)
+            {
+                auto out_shape = reduce(in_shape, reduction_axes, keep_dims);
+                CoordinateTransform output_transform(out_shape);
+                std::vector<T> cs(shape_size(out_shape));
+
+                for (const Coordinate& output_coord : output_transform)
+                {
+                    out[output_transform.index(output_coord)] = 0;
+                    cs[output_transform.index(output_coord)] = 0;
+                }
+
+                CoordinateTransform input_transform(in_shape);
+
+                for (const Coordinate& input_coord : input_transform)
+                {
+                    Coordinate output_coord = reduce(input_coord, reduction_axes, keep_dims);
+
+                    T x = arg[input_transform.index(input_coord)];
+                    T& z = out[output_transform.index(output_coord)];
+
+                    if (is_finite(x) && is_finite(z))
+                    {
+                        T& c = cs[output_transform.index(output_coord)];
+                        T t = z + (x - c);
+                        c = (t - z) - (x - c);
+                        z = t;
+                    }
+                    else
+                    {
+                        z = z + x;
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/swish.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/swish.hpp
new file mode 100644 (file)
index 0000000..14bb42e
--- /dev/null
@@ -0,0 +1,43 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void swish(const T* arg, const T* beta, T* out, size_t count)
+            {
+                T beta_value = static_cast<T>(1.0);
+                if (beta != nullptr)
+                {
+                    beta_value = beta[0];
+                }
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = arg[i] / (1.0 + std::exp(-arg[i] * beta_value));
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/tan.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/tan.hpp
new file mode 100644 (file)
index 0000000..49e1dbb
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void tan(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::tan(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/tanh.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/tanh.hpp
new file mode 100644 (file)
index 0000000..9c71c9c
--- /dev/null
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void tanh(const T* arg, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = std::tanh(arg[i]);
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/tile.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/tile.hpp
new file mode 100644 (file)
index 0000000..53d25ee
--- /dev/null
@@ -0,0 +1,37 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/type/element_type.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            void tile(const char* arg,
+                      char* out,
+                      const Shape& in_shape,
+                      const Shape& out_shape,
+                      size_t elem_size);
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/topk.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/topk.hpp
new file mode 100644 (file)
index 0000000..cb5c5bf
--- /dev/null
@@ -0,0 +1,175 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <algorithm>
+#include <cmath>
+#include <numeric>
+
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/op/topk.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            // Had to split out these two functions. They used to be lambda expressions but
+            // MSVC had difficulty compiling. This way is more explicit.
+            template <typename T, typename U>
+            inline bool compare_max(const std::tuple<T, U>& a, const std::tuple<T, U>& b)
+            {
+// this is intentional to be able to compare floats directly
+// without using relative or absolute tolerance
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+                if (std::get<0>(a) == std::get<0>(b))
+                {
+                    return std::get<1>(a) < std::get<1>(b);
+                }
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+                return a > b;
+            }
+
+            template <typename T, typename U>
+            inline bool compare_min(const std::tuple<T, U>& a, const std::tuple<T, U>& b)
+            {
+                return a < b;
+            }
+
+            template <typename T, typename U>
+            inline bool sort_indices_descending(const std::tuple<T, U>& a,
+                                                const std::tuple<T, U>& b)
+            {
+                return std::get<1>(a) < std::get<1>(b);
+            }
+
+            template <typename T, typename U>
+            inline bool sort_indices_ascending(const std::tuple<T, U>& a, const std::tuple<T, U>& b)
+            {
+                return std::get<1>(a) > std::get<1>(b);
+            }
+
+            template <typename T, typename U>
+            void topk(const T* arg,
+                      U* out_indices,
+                      T* out_values,
+                      const Shape& in_shape,
+                      const Shape& out_shape,
+                      size_t axis,
+                      size_t k,
+                      bool compute_max,
+                      op::TopK::SortType sort = op::TopK::SortType::NONE)
+            {
+                using namespace std;
+                // reorder source axis visit order and make "axis" inner most
+                size_t ndim = static_cast<size_t>(in_shape.size());
+                Coordinate start_corner(ndim, 0);
+                Coordinate end_corner(in_shape);
+                end_corner[axis] = 1;
+                Strides strides(ndim, 1);
+                AxisVector axis_order(ndim);
+                iota(axis_order.begin(), axis_order.end(), 0);
+                axis_order.erase(axis_order.begin() + axis);
+                axis_order.push_back(axis);
+                // Create CoordinateTransforms that visits only the first element along "axis"
+                CoordinateTransform input_transform(
+                    in_shape, start_corner, end_corner, strides, axis_order);
+                CoordinateTransform output_transform(
+                    out_shape, start_corner, end_corner, strides, axis_order);
+                // Create temp vector for sorting.
+                vector<tuple<T, U>> workspace(in_shape[axis]);
+                vector<size_t> in_strides = ngraph::row_major_strides(in_shape);
+                vector<size_t> out_strides = ngraph::row_major_strides(out_shape);
+                auto in_axis_stride = in_strides[axis];
+                auto out_axis_stride = out_strides[axis];
+                for (const Coordinate& coord : input_transform)
+                {
+                    auto arg_index = input_transform.index(coord);
+                    auto out_index = output_transform.index(coord);
+                    // Fill the temp vector
+                    U i = 0;
+                    for (tuple<T, U>& entry : workspace)
+                    {
+                        get<0>(entry) = arg[arg_index];
+                        get<1>(entry) = i;
+                        arg_index += in_axis_stride;
+                        i++;
+                    }
+                    // Sort the temp vector
+                    if (compute_max)
+                    {
+                        nth_element(workspace.begin(),
+                                    workspace.begin() + k,
+                                    workspace.end(),
+                                    compare_max<T, U>);
+                    }
+                    else
+                    {
+                        nth_element(workspace.begin(),
+                                    workspace.begin() + k,
+                                    workspace.end(),
+                                    compare_min<T, U>);
+                    }
+                    // Write temp vector to output
+                    if (compute_max)
+                    {
+                        switch (sort)
+                        {
+                        case op::TopK::SortType::NONE: break;
+                        case op::TopK::SortType::SORT_INDICES:
+                            std::sort(workspace.begin(),
+                                      workspace.begin() + k,
+                                      sort_indices_descending<T, U>);
+                            break;
+                        case op::TopK::SortType::SORT_VALUES:
+                            std::sort(workspace.begin(), workspace.begin() + k, compare_max<T, U>);
+                            break;
+                        }
+                    }
+                    else
+                    {
+                        switch (sort)
+                        {
+                        case op::TopK::SortType::NONE: break;
+                        case op::TopK::SortType::SORT_INDICES:
+                            std::sort(workspace.begin(),
+                                      workspace.begin() + k,
+                                      sort_indices_ascending<T, U>);
+                            break;
+                        case op::TopK::SortType::SORT_VALUES:
+                            std::sort(workspace.begin(), workspace.begin() + k, compare_min<T, U>);
+                            break;
+                        }
+                    }
+                    for (size_t j = 0; j < k; j++)
+                    {
+                        tuple<T, U> entry = workspace[j];
+                        out_values[out_index] = get<0>(entry);
+                        out_indices[out_index] = get<1>(entry);
+                        out_index += out_axis_stride;
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/xor.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/xor.hpp
new file mode 100644 (file)
index 0000000..87e7e1f
--- /dev/null
@@ -0,0 +1,55 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cstddef>
+
+#include "ngraph/op/util/attr_types.hpp"
+#include "ngraph/runtime/reference/autobroadcast_binop.hpp"
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            template <typename T>
+            void logical_xor(const T* arg0, const T* arg1, T* out, size_t count)
+            {
+                for (size_t i = 0; i < count; i++)
+                {
+                    out[i] = static_cast<T>((arg0[i] || arg1[i]) && !(arg0[i] && arg1[i]));
+                }
+            }
+
+            template <typename T>
+            void logical_xor(const T* arg0,
+                             const T* arg1,
+                             T* out,
+                             const Shape& arg0_shape,
+                             const Shape& arg1_shape,
+                             const op::AutoBroadcastSpec& broadcast_spec)
+            {
+                autobroadcast_binop(
+                    arg0, arg1, out, arg0_shape, arg1_shape, broadcast_spec, [](T x, T y) -> T {
+                        return static_cast<T>((x || y) && !(x && y));
+                    });
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/src/coordinate_transform.cpp b/ngraph/core/reference/src/coordinate_transform.cpp
new file mode 100644 (file)
index 0000000..da72e55
--- /dev/null
@@ -0,0 +1,539 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#include <algorithm>
+#include <cstdio>
+#include <iostream>
+#include <numeric>
+#include <sstream>
+#include <vector>
+
+#include "ngraph/axis_vector.hpp"
+#include "ngraph/coordinate_diff.hpp"
+#include "ngraph/coordinate_transform.hpp"
+#include "ngraph/except.hpp"
+#include "ngraph/shape.hpp"
+#include "ngraph/strides.hpp"
+#include "ngraph/util.hpp"
+
+using namespace ngraph;
+
+namespace
+{
+    Strides default_strides(size_t n_axes) { return Strides(n_axes, 1); }
+    CoordinateDiff default_padding(size_t n_axes) { return CoordinateDiff(n_axes, 0); }
+    AxisVector default_axis_order(size_t n_axes)
+    {
+        AxisVector result(n_axes);
+        std::iota(result.begin(), result.end(), 0);
+        return result;
+    }
+
+    Coordinate default_source_start_corner(size_t n_axes) { return Coordinate(n_axes, 0); }
+    Coordinate default_source_end_corner(const Shape& source_shape) { return source_shape; }
+}
+
+CoordinateTransformBasic::CoordinateTransformBasic(const Shape& source_shape)
+    : m_source_shape(source_shape)
+{
+}
+
+// Compute the index of a source-space coordinate in the buffer.
+size_t CoordinateTransformBasic::index(const Coordinate& c) const noexcept
+{
+    size_t index = 0;
+    size_t stride = 1;
+    size_t const padding = c.size() - m_source_shape.size();
+
+    for (size_t axis = m_source_shape.size(); axis-- > 0;)
+    {
+        if (m_source_shape[axis] > 1)
+        {
+            index += c[axis + padding] * stride;
+            stride *= m_source_shape[axis];
+        }
+    }
+
+    return index;
+}
+
+CoordinateIterator CoordinateTransformBasic::begin() const noexcept
+{
+    return CoordinateIterator(m_source_shape);
+}
+
+const CoordinateIterator& CoordinateTransformBasic::end() const noexcept
+{
+    return CoordinateIterator::end();
+}
+
+CoordinateTransform::CoordinateTransform(const Shape& source_shape,
+                                         const Coordinate& source_start_corner,
+                                         const Coordinate& source_end_corner,
+                                         const Strides& source_strides,
+                                         const AxisVector& source_axis_order,
+                                         const CoordinateDiff& target_padding_below,
+                                         const CoordinateDiff& target_padding_above,
+                                         const Strides& target_dilation_strides)
+    : CoordinateTransformBasic(source_shape)
+    , m_source_start_corner(source_start_corner)
+    , m_source_end_corner(source_end_corner)
+    , m_source_strides(source_strides)
+    , m_source_axis_order(source_axis_order)
+    , m_target_padding_below(target_padding_below)
+    , m_target_padding_above(target_padding_above)
+    , m_target_dilation_strides(target_dilation_strides)
+{
+    m_n_axes = source_shape.size();
+
+    if (m_n_axes != source_start_corner.size())
+    {
+        throw std::domain_error(
+            "Source start corner does not have the same number of axes as the source space shape");
+    }
+    if (m_n_axes != source_end_corner.size())
+    {
+        throw std::domain_error(
+            "Source end corner does not have the same number of axes as the source space shape");
+    }
+    if (m_n_axes != source_strides.size())
+    {
+        throw std::domain_error(
+            "Source strides do not have the same number of axes as the source space shape");
+    }
+    if (m_n_axes != source_axis_order.size())
+    {
+        // Note: this check is NOT redundant with the is_permutation check below, though you might
+        // think it is. If the lengths don't match then is_permutation won't catch that; it'll
+        // either stop short or walk off the end of source_axis_order.
+        throw std::domain_error(
+            "Source axis order does not have the same number of axes as the source space shape");
+    }
+    if (m_n_axes != target_padding_below.size())
+    {
+        throw std::domain_error(
+            "Padding-below shape does not have the same number of axes as the source space shape");
+    }
+    if (m_n_axes != target_padding_above.size())
+    {
+        throw std::domain_error(
+            "Padding-above shape does not have the same number of axes as the source space shape");
+    }
+    if (m_n_axes != target_dilation_strides.size())
+    {
+        throw std::domain_error(
+            "Target dilation strides do not have the same number of axes as the source shape");
+    }
+
+    AxisVector all_axes(m_n_axes);
+    for (size_t i = 0; i < all_axes.size(); i++)
+    {
+        all_axes[i] = i;
+    }
+
+    if (!std::is_permutation(all_axes.begin(), all_axes.end(), source_axis_order.begin()))
+    {
+        throw std::domain_error(
+            "Source axis order is not a permutation of {0,...,n-1} where n is the number of axes "
+            "in the source space shape");
+    }
+
+    for (size_t i = 0; i < m_n_axes; i++)
+    {
+        if (target_dilation_strides[i] == 0)
+        {
+            std::stringstream ss;
+
+            ss << "The target dilation stride is 0 at axis " << i;
+            throw std::domain_error(ss.str());
+        }
+    }
+
+    std::vector<std::ptrdiff_t> padded_upper_bounds;
+
+    for (size_t i = 0; i < m_n_axes; i++)
+    {
+        std::ptrdiff_t padded_upper_bound =
+            subtract_or_zero(source_shape[i], size_t(1)) * target_dilation_strides[i] + 1 +
+            target_padding_below[i] + target_padding_above[i];
+
+        if (padded_upper_bound < 0)
+        {
+            std::stringstream ss;
+
+            ss << "The end corner is out of bounds at axis " << i;
+            throw std::domain_error(ss.str());
+        }
+
+        padded_upper_bounds.push_back(padded_upper_bound);
+    }
+
+    for (size_t i = 0; i < m_n_axes; i++)
+    {
+        if (static_cast<int64_t>(source_start_corner[i]) >= padded_upper_bounds[i] &&
+            source_start_corner[i] != source_shape[i])
+        {
+            std::stringstream ss;
+
+            ss << "The start corner is out of bounds at axis " << i;
+            throw std::domain_error(ss.str());
+        }
+
+        if (static_cast<int64_t>(source_end_corner[i]) > padded_upper_bounds[i])
+        {
+            std::stringstream ss;
+
+            ss << "The end corner is out of bounds at axis " << i;
+            throw std::domain_error(ss.str());
+        }
+    }
+
+    for (size_t i = 0; i < m_n_axes; i++)
+    {
+        if (source_strides[i] == 0)
+        {
+            std::stringstream ss;
+
+            ss << "The source stride is 0 at axis " << i;
+            throw std::domain_error(ss.str());
+        }
+    }
+
+    for (size_t axis = 0; axis < m_n_axes; axis++)
+    {
+        m_target_shape.push_back(ceil_div(source_end_corner[source_axis_order[axis]] -
+                                              source_start_corner[source_axis_order[axis]],
+                                          source_strides[source_axis_order[axis]]));
+    }
+}
+
+CoordinateTransform::CoordinateTransform(const Shape& source_shape,
+                                         const Coordinate& source_start_corner,
+                                         const Coordinate& source_end_corner,
+                                         const Strides& source_strides,
+                                         const AxisVector& source_axis_order,
+                                         const CoordinateDiff& target_padding_below,
+                                         const CoordinateDiff& target_padding_above)
+    : CoordinateTransform(source_shape,
+                          source_start_corner,
+                          source_end_corner,
+                          source_strides,
+                          source_axis_order,
+                          target_padding_below,
+                          target_padding_above,
+                          default_strides(source_shape.size()))
+{
+}
+
+CoordinateTransform::CoordinateTransform(const Shape& source_shape,
+                                         const Coordinate& source_start_corner,
+                                         const Coordinate& source_end_corner,
+                                         const Strides& source_strides,
+                                         const AxisVector& source_axis_order)
+    : CoordinateTransform(source_shape,
+                          source_start_corner,
+                          source_end_corner,
+                          source_strides,
+                          source_axis_order,
+                          default_padding(source_shape.size()),
+                          default_padding(source_shape.size()),
+                          default_strides(source_shape.size()))
+{
+}
+
+CoordinateTransform::CoordinateTransform(const Shape& source_shape,
+                                         const Coordinate& source_start_corner,
+                                         const Coordinate& source_end_corner,
+                                         const Strides& source_strides)
+    : CoordinateTransform(source_shape,
+                          source_start_corner,
+                          source_end_corner,
+                          source_strides,
+                          default_axis_order(source_shape.size()),
+                          default_padding(source_shape.size()),
+                          default_padding(source_shape.size()),
+                          default_strides(source_shape.size()))
+{
+}
+
+CoordinateTransform::CoordinateTransform(const Shape& source_shape,
+                                         const Coordinate& source_start_corner,
+                                         const Coordinate& source_end_corner)
+    : CoordinateTransform(source_shape,
+                          source_start_corner,
+                          source_end_corner,
+                          default_strides(source_shape.size()),
+                          default_axis_order(source_shape.size()),
+                          default_padding(source_shape.size()),
+                          default_padding(source_shape.size()),
+                          default_strides(source_shape.size()))
+{
+}
+
+CoordinateTransform::CoordinateTransform(const Shape& source_shape)
+    : CoordinateTransform(source_shape,
+                          default_source_start_corner(source_shape.size()),
+                          default_source_end_corner(source_shape),
+                          default_strides(source_shape.size()),
+                          default_axis_order(source_shape.size()),
+                          default_padding(source_shape.size()),
+                          default_padding(source_shape.size()),
+                          default_strides(source_shape.size()))
+{
+}
+
+// Compute the index of a target-space coordinate in thebuffer.
+size_t CoordinateTransform::index(const Coordinate& c) const
+{
+    return CoordinateTransformBasic::index(to_source_coordinate(c));
+}
+
+// Convert a target-space coordinate to a source-space coordinate.
+Coordinate CoordinateTransform::to_source_coordinate(const Coordinate& c_target) const
+{
+    if (c_target.size() != m_n_axes)
+    {
+        throw std::domain_error(
+            "Target coordinate rank does not match the coordinate transform rank");
+    }
+
+    Coordinate c_source(c_target.size());
+
+    for (size_t target_axis = 0; target_axis < m_n_axes; target_axis++)
+    {
+        size_t source_axis = m_source_axis_order[target_axis];
+
+        size_t target_pos = c_target[target_axis];
+        size_t pos_destrided = target_pos * m_source_strides[source_axis];
+        size_t pos_deshifted = pos_destrided + m_source_start_corner[source_axis];
+        size_t pos_depadded = pos_deshifted - m_target_padding_below[target_axis];
+        size_t pos_dedilated = pos_depadded / m_target_dilation_strides[target_axis];
+        c_source[source_axis] = pos_dedilated;
+    }
+
+    return c_source;
+}
+
+// A point in the target space is considered not to have a source coordinate if it was inserted due
+// to padding or dilation, or if it is out of the bounds of the target space.
+bool CoordinateTransform::has_source_coordinate(const Coordinate& c_target) const
+{
+    if (c_target.size() != m_n_axes)
+    {
+        throw std::domain_error(
+            "Target coordinate rank does not match the coordinate transform rank");
+    }
+
+    for (size_t target_axis = 0; target_axis < m_n_axes; target_axis++)
+    {
+        // Is this coordinate out of bounds of the target space?
+        if (c_target[target_axis] >= m_target_shape[target_axis])
+        {
+            return false;
+        }
+
+        // The rest of this is a replay of the corresponding logic in `to_source_coordinate`, with
+        // bounds and divisibility checking.
+        std::ptrdiff_t source_axis = m_source_axis_order[target_axis];
+
+        std::ptrdiff_t target_pos = c_target[target_axis];
+        std::ptrdiff_t pos_destrided = target_pos * m_source_strides[source_axis];
+        std::ptrdiff_t pos_deshifted = pos_destrided + m_source_start_corner[source_axis];
+
+        // If we are in the below-padding or the above-padding.
+        if (pos_deshifted < m_target_padding_below[target_axis])
+        {
+            return false;
+        }
+        std::ptrdiff_t pos_depadded = pos_deshifted - m_target_padding_below[target_axis];
+
+        // If we are in the above-padding, we have no source coordinate.
+        if (m_source_shape[source_axis] == 0 ||
+            (pos_depadded >= ((static_cast<int64_t>(m_source_shape[source_axis]) - 1) *
+                              static_cast<int64_t>(m_target_dilation_strides[target_axis])) +
+                                 1))
+        {
+            return false;
+        }
+
+        // If we are in a dilation gap, we have no source coordinate.
+        if (pos_depadded % m_target_dilation_strides[target_axis] != 0)
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+const Shape& CoordinateTransform::get_source_shape() const noexcept
+{
+    return m_source_shape;
+}
+
+const Shape& CoordinateTransform::get_target_shape() const noexcept
+{
+    return m_target_shape;
+}
+
+const Coordinate& CoordinateTransform::get_source_start_corner() const noexcept
+{
+    return m_source_start_corner;
+}
+
+const Coordinate& CoordinateTransform::get_source_end_corner() const noexcept
+{
+    return m_source_end_corner;
+}
+
+const Strides& CoordinateTransform::get_source_strides() const noexcept
+{
+    return m_source_strides;
+}
+
+const AxisVector& CoordinateTransform::get_source_axis_order() const noexcept
+{
+    return m_source_axis_order;
+}
+
+const Strides& CoordinateTransform::get_target_dilation_strides() const noexcept
+{
+    return m_target_dilation_strides;
+}
+
+CoordinateIterator CoordinateTransform::begin() const noexcept
+{
+    return CoordinateIterator(m_target_shape);
+}
+
+const CoordinateIterator& CoordinateTransform::end() const noexcept
+{
+    return CoordinateIterator::end();
+}
+
+// The "is_end" parameter is true if we want the "end()" iterator.
+CoordinateIterator::CoordinateIterator(const Shape& target_shape, bool is_end)
+    : m_target_shape(target_shape)
+    , m_coordinate(target_shape.size(), 0)
+{
+    // The case where we have a zero-length axis is a bit special, in that
+    // the iterator always starts out of bounds.
+    bool const empty = std::find(target_shape.begin(), target_shape.end(), 0) != target_shape.end();
+
+    m_oob = is_end || empty;
+}
+
+void CoordinateIterator::operator++()
+{
+    advance(m_target_shape.size() - 1);
+}
+
+size_t CoordinateIterator::advance(size_t axis) noexcept
+{
+    m_oob |= m_target_shape.empty();
+
+    if (m_oob)
+        return m_target_shape.size();
+
+    bool carry_out = false;
+
+    // Increment the target coordinate.
+    do
+    {
+        m_coordinate[axis]++;
+
+        if (m_coordinate[axis] < m_target_shape[axis])
+        {
+            // No carry-out, so we are done.
+            return axis;
+        }
+        else
+        {
+            m_coordinate[axis] = 0;
+            carry_out = true;
+        }
+    } while (axis-- > 0);
+
+    // If we are still here there was carry-out from the most significant axis. We are now out of
+    // bounds.
+    m_oob = true;
+
+    return m_target_shape.size();
+}
+
+CoordinateIterator CoordinateIterator::operator++(int)
+{
+    CoordinateIterator temp = *this;
+    ++(*this);
+    return temp;
+}
+
+void CoordinateIterator::operator+=(size_t n)
+{
+    for (size_t i = 0; i < n; i++)
+    {
+        ++(*this);
+    }
+}
+
+const Coordinate& CoordinateIterator::operator*() const noexcept
+{
+    return m_coordinate;
+}
+
+bool CoordinateIterator::operator!=(const CoordinateIterator& it) const noexcept
+{
+    return !(*this == it);
+}
+
+bool CoordinateIterator::operator==(const CoordinateIterator& it) const noexcept
+{
+    if (it.m_oob)
+    {
+        // Out-of-bounds iterators are always equal; in other words, an iterator is always equal to
+        // end() even if the internally stored coordinates are different.
+
+        // If one iterator is out of bounds and the other is not, they are unequal even if their
+        // target coordinates happen to match.
+        return m_oob;
+    }
+    else if (m_oob)
+    {
+        return false;
+    }
+
+    if (m_target_shape != it.m_target_shape)
+    {
+        return false;
+    }
+
+    // Check axis-wise if the iterators are on the same target coordinate.
+    for (size_t axis = 0; axis < m_target_shape.size(); axis++)
+    {
+        if (m_coordinate[axis] != it.m_coordinate[axis])
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+const CoordinateIterator& CoordinateIterator::end()
+{
+    static const CoordinateIterator it(Shape(), true);
+    return it;
+}
diff --git a/ngraph/core/reference/src/runtime/opt_kernel/reshape.cpp b/ngraph/core/reference/src/runtime/opt_kernel/reshape.cpp
new file mode 100644 (file)
index 0000000..ba78493
--- /dev/null
@@ -0,0 +1,267 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#include <cmath>
+#include <stdio.h>
+
+#include "ngraph/check.hpp"
+#include "ngraph/runtime/opt_kernel/reshape.hpp"
+
+using namespace ngraph;
+
+namespace
+{
+    void reshape_in0(const char* in,
+                     char* out,
+                     const Shape& in_shape,
+                     const AxisVector& in_axis_order,
+                     const Shape& out_shape,
+                     size_t elem_size)
+    {
+        memcpy(out, in, elem_size);
+    }
+
+    void reshape_in1(const char* in,
+                     char* out,
+                     const Shape& in_shape,
+                     const AxisVector& in_axis_order,
+                     const Shape& out_shape,
+                     size_t elem_size)
+    {
+        size_t size[1];
+        size_t in_index[1];
+        size_t* map_index[1];
+        for (size_t i = 0; i < 1; i++)
+        {
+            size[i] = in_shape[in_axis_order[i]];
+            map_index[in_axis_order[i]] = &in_index[i];
+        }
+        for (in_index[0] = 0; in_index[0] < size[0]; ++in_index[0])
+        {
+            memcpy(out, in + *map_index[0] * elem_size, elem_size);
+            out += elem_size;
+        }
+    }
+
+    void reshape_in2(const char* in,
+                     char* out,
+                     const Shape& in_shape,
+                     const AxisVector& in_axis_order,
+                     const Shape& out_shape,
+                     size_t elem_size)
+    {
+        size_t size[2];
+        size_t in_index[2];
+        size_t* map_index[2];
+        for (size_t i = 0; i < 2; i++)
+        {
+            size[i] = in_shape[in_axis_order[i]];
+            map_index[in_axis_order[i]] = &in_index[i];
+        }
+        for (in_index[0] = 0; in_index[0] < size[0]; ++in_index[0])
+        {
+            for (in_index[1] = 0; in_index[1] < size[1]; ++in_index[1])
+            {
+                // clang-format off
+                memcpy(out,
+                       in + (*map_index[0] * in_shape[1] +
+                             *map_index[1]) * elem_size,
+                       elem_size);
+                out += elem_size;
+                // clang-format on
+            }
+        }
+    }
+
+    void reshape_in3(const char* in,
+                     char* out,
+                     const Shape& in_shape,
+                     const AxisVector& in_axis_order,
+                     const Shape& out_shape,
+                     size_t elem_size)
+    {
+        size_t size[3];
+        size_t in_index[3];
+        size_t* map_index[3];
+        for (size_t i = 0; i < 3; i++)
+        {
+            size[i] = in_shape[in_axis_order[i]];
+            map_index[in_axis_order[i]] = &in_index[i];
+        }
+        for (in_index[0] = 0; in_index[0] < size[0]; ++in_index[0])
+        {
+            for (in_index[1] = 0; in_index[1] < size[1]; ++in_index[1])
+            {
+                for (in_index[2] = 0; in_index[2] < size[2]; ++in_index[2])
+                {
+                    // clang-format off
+                    memcpy(out,
+                           in + (*map_index[0] * in_shape[1] * in_shape[2] +
+                                 *map_index[1] * in_shape[2] +
+                                 *map_index[2]) * elem_size,
+                           elem_size);
+                    out += elem_size;
+                    // clang-format on
+                }
+            }
+        }
+    }
+
+    void reshape_in4(const char* in,
+                     char* out,
+                     const Shape& in_shape,
+                     const AxisVector& in_axis_order,
+                     const Shape& out_shape,
+                     size_t elem_size)
+    {
+        size_t size[4];
+        size_t in_index[4];
+        size_t* map_index[4];
+        for (size_t i = 0; i < 4; i++)
+        {
+            size[i] = in_shape[in_axis_order[i]];
+            map_index[in_axis_order[i]] = &in_index[i];
+        }
+        for (in_index[0] = 0; in_index[0] < size[0]; ++in_index[0])
+        {
+            for (in_index[1] = 0; in_index[1] < size[1]; ++in_index[1])
+            {
+                for (in_index[2] = 0; in_index[2] < size[2]; ++in_index[2])
+                {
+                    for (in_index[3] = 0; in_index[3] < size[3]; ++in_index[3])
+                    {
+                        // clang-format off
+                        memcpy(out,
+                               in + (*map_index[0] * in_shape[1] * in_shape[2] * in_shape[3] +
+                                     *map_index[1] * in_shape[2] * in_shape[3] +
+                                     *map_index[2] * in_shape[3] +
+                                     *map_index[3]) * elem_size,
+                               elem_size);
+                        out += elem_size;
+                        // clang-format on
+                    }
+                }
+            }
+        }
+    }
+
+    void reshape_in5(const char* in,
+                     char* out,
+                     const Shape& in_shape,
+                     const AxisVector& in_axis_order,
+                     const Shape& out_shape,
+                     size_t elem_size)
+    {
+        size_t size[5];
+        size_t in_index[5];
+        size_t* map_index[5];
+        for (size_t i = 0; i < 5; i++)
+        {
+            size[i] = in_shape[in_axis_order[i]];
+            map_index[in_axis_order[i]] = &in_index[i];
+        }
+        for (in_index[0] = 0; in_index[0] < size[0]; ++in_index[0])
+        {
+            for (in_index[1] = 0; in_index[1] < size[1]; ++in_index[1])
+            {
+                for (in_index[2] = 0; in_index[2] < size[2]; ++in_index[2])
+                {
+                    for (in_index[3] = 0; in_index[3] < size[3]; ++in_index[3])
+                    {
+                        for (in_index[4] = 0; in_index[4] < size[4]; ++in_index[4])
+                        {
+                            // clang-format off
+                            memcpy(out,
+                                   in + (*map_index[0] * in_shape[1] * in_shape[2] * in_shape[3] * in_shape[4] +
+                                         *map_index[1] * in_shape[2] * in_shape[3] * in_shape[4] +
+                                         *map_index[2] * in_shape[3] * in_shape[4] +
+                                         *map_index[3] * in_shape[4] +
+                                         *map_index[4]) * elem_size,
+                                   elem_size);
+                            out += elem_size;
+                            // clang-format on
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    void reshape_in6(const char* in,
+                     char* out,
+                     const Shape& in_shape,
+                     const AxisVector& in_axis_order,
+                     const Shape& out_shape,
+                     size_t elem_size)
+    {
+        size_t size[6];
+        size_t in_index[6];
+        size_t* map_index[6];
+        for (size_t i = 0; i < 6; i++)
+        {
+            size[i] = in_shape[in_axis_order[i]];
+            map_index[in_axis_order[i]] = &in_index[i];
+        }
+        for (in_index[0] = 0; in_index[0] < size[0]; ++in_index[0])
+        {
+            for (in_index[1] = 0; in_index[1] < size[1]; ++in_index[1])
+            {
+                for (in_index[2] = 0; in_index[2] < size[2]; ++in_index[2])
+                {
+                    for (in_index[3] = 0; in_index[3] < size[3]; ++in_index[3])
+                    {
+                        for (in_index[4] = 0; in_index[4] < size[4]; ++in_index[4])
+                        {
+                            for (in_index[5] = 0; in_index[5] < size[5]; ++in_index[5])
+                            {
+                                // clang-format off
+                                memcpy(out,
+                                       in + (*map_index[0] * in_shape[1] * in_shape[2] * in_shape[3] * in_shape[4] * in_shape[5] +
+                                             *map_index[1] * in_shape[2] * in_shape[3] * in_shape[4] * in_shape[5] +
+                                             *map_index[2] * in_shape[3] * in_shape[4] * in_shape[5] +
+                                             *map_index[3] * in_shape[4] * in_shape[5] +
+                                             *map_index[4] * in_shape[5] +
+                                             *map_index[5]) * elem_size,
+                                       elem_size);
+                                out += elem_size;
+                                // clang-format on
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+void runtime::opt_kernel::reshape(const char* in,
+                                  char* out,
+                                  const Shape& in_shape,
+                                  const AxisVector& in_axis_order,
+                                  const Shape& out_shape,
+                                  size_t elem_size)
+{
+    switch (in_shape.size())
+    {
+    case 0: reshape_in0(in, out, in_shape, in_axis_order, out_shape, elem_size); break;
+    case 1: reshape_in1(in, out, in_shape, in_axis_order, out_shape, elem_size); break;
+    case 2: reshape_in2(in, out, in_shape, in_axis_order, out_shape, elem_size); break;
+    case 3: reshape_in3(in, out, in_shape, in_axis_order, out_shape, elem_size); break;
+    case 4: reshape_in4(in, out, in_shape, in_axis_order, out_shape, elem_size); break;
+    case 5: reshape_in5(in, out, in_shape, in_axis_order, out_shape, elem_size); break;
+    case 6: reshape_in6(in, out, in_shape, in_axis_order, out_shape, elem_size); break;
+    default: reference::reshape(in, out, in_shape, in_axis_order, out_shape, elem_size); break;
+    }
+}
diff --git a/ngraph/core/reference/src/runtime/reference/eval_helpers.cpp b/ngraph/core/reference/src/runtime/reference/eval_helpers.cpp
new file mode 100644 (file)
index 0000000..de3b322
--- /dev/null
@@ -0,0 +1,42 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#include <algorithm>
+
+#include "ngraph/check.hpp"
+#include "ngraph/runtime/reference/eval_helpers.hpp"
+
+namespace ngraph
+{
+    namespace eval
+    {
+        AxisSet extract_reduction_axes(const HostTensorPtr& axes, const char* op_name)
+        {
+            const auto axes_count = axes->get_element_count();
+            const auto axes_buffer = axes->get_data_ptr<int64_t>();
+
+            const bool negative_axis_received = std::any_of(
+                axes_buffer, axes_buffer + axes_count, [](const int64_t axis) { return axis < 0; });
+
+            NGRAPH_CHECK(!negative_axis_received,
+                         "Negative axis value received in the ",
+                         op_name,
+                         " evaluation. This case is not supported.");
+
+            return AxisSet(std::vector<AxisSet::value_type>(axes_buffer, axes_buffer + axes_count));
+        }
+    }
+}
diff --git a/ngraph/core/reference/src/runtime/reference/reshape.cpp b/ngraph/core/reference/src/runtime/reference/reshape.cpp
new file mode 100644 (file)
index 0000000..5872ee3
--- /dev/null
@@ -0,0 +1,57 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#include <cmath>
+#include <stdio.h>
+
+#include "ngraph/check.hpp"
+#include "ngraph/runtime/reference/reshape.hpp"
+
+using namespace ngraph;
+
+void runtime::reference::reshape(const char* arg,
+                                 char* out,
+                                 const Shape& in_shape,
+                                 const AxisVector& in_axis_order,
+                                 const Shape& out_shape,
+                                 size_t elem_size)
+{
+    // Unfortunately we don't yet have a constructor for CoordinateTransform that lets
+    // us pass only source_space_shape
+    // and source_axis_order so we have to construct the defaults here.
+    Shape in_start_corner(in_shape.size(), 0); // (0,...0)
+    Strides in_strides(in_shape.size(), 1);    // (1,...,1)
+
+    CoordinateTransform input_transform(
+        in_shape, in_start_corner, in_shape, in_strides, in_axis_order);
+    CoordinateTransform output_transform(out_shape);
+
+    NGRAPH_CHECK(shape_size(input_transform.get_target_shape()) ==
+                 shape_size(output_transform.get_target_shape()));
+
+    CoordinateTransform::Iterator output_it = output_transform.begin();
+
+    for (const Coordinate& input_coord : input_transform)
+    {
+        const Coordinate& output_coord = *output_it;
+
+        memcpy(out + output_transform.index(output_coord) * elem_size,
+               arg + input_transform.index(input_coord) * elem_size,
+               elem_size);
+
+        ++output_it;
+    }
+}
diff --git a/ngraph/core/reference/src/runtime/reference/reverse.cpp b/ngraph/core/reference/src/runtime/reference/reverse.cpp
new file mode 100644 (file)
index 0000000..b53f5c4
--- /dev/null
@@ -0,0 +1,53 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#include <cmath>
+#include <stdio.h>
+
+#include "ngraph/check.hpp"
+#include "ngraph/runtime/reference/reverse.hpp"
+
+using namespace ngraph;
+
+void runtime::reference::reverse(const char* arg,
+                                 char* out,
+                                 const Shape& arg_shape,
+                                 const Shape& out_shape,
+                                 const AxisSet& reversed_axes,
+                                 size_t elem_size)
+{
+    // In fact arg_shape == out_shape, but we'll use both for stylistic consistency with
+    // other kernels.
+    CoordinateTransform arg_transform(arg_shape);
+    CoordinateTransform output_transform(out_shape);
+
+    for (Coordinate out_coord : output_transform)
+    {
+        Coordinate arg_coord = out_coord;
+
+        for (size_t i = 0; i < arg_coord.size(); i++)
+        {
+            if (reversed_axes.count(i) != 0)
+            {
+                arg_coord[i] = arg_shape[i] - arg_coord[i] - 1;
+            }
+        }
+
+        memcpy(out + output_transform.index(out_coord) * elem_size,
+               arg + arg_transform.index(arg_coord) * elem_size,
+               elem_size);
+    }
+}
diff --git a/ngraph/core/reference/src/runtime/reference/slice.cpp b/ngraph/core/reference/src/runtime/reference/slice.cpp
new file mode 100644 (file)
index 0000000..415d55a
--- /dev/null
@@ -0,0 +1,59 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#include <cmath>
+#include <stdio.h>
+
+#include "ngraph/check.hpp"
+#include "ngraph/runtime/reference/slice.hpp"
+
+namespace ngraph
+{
+    namespace runtime
+    {
+        namespace reference
+        {
+            void slice(const char* arg,
+                       char* out,
+                       const Shape& arg_shape,
+                       const Coordinate& lower_bounds,
+                       const Coordinate& upper_bounds,
+                       const Strides& strides,
+                       const Shape& out_shape,
+                       size_t elem_size)
+            {
+                CoordinateTransform input_transform(arg_shape, lower_bounds, upper_bounds, strides);
+                CoordinateTransform output_transform(out_shape);
+
+                CoordinateTransform::Iterator output_it = output_transform.begin();
+
+                NGRAPH_CHECK(shape_size(input_transform.get_target_shape()) ==
+                             shape_size(output_transform.get_target_shape()));
+
+                for (const Coordinate& in_coord : input_transform)
+                {
+                    const Coordinate& out_coord = *output_it;
+
+                    memcpy(out + output_transform.index(out_coord) * elem_size,
+                           arg + input_transform.index(in_coord) * elem_size,
+                           elem_size);
+
+                    ++output_it;
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/core/reference/src/runtime/reference/strided_slice.cpp b/ngraph/core/reference/src/runtime/reference/strided_slice.cpp
new file mode 100644 (file)
index 0000000..033109f
--- /dev/null
@@ -0,0 +1,53 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#include <cmath>
+#include <stdio.h>
+
+#include "ngraph/check.hpp"
+#include "ngraph/runtime/aligned_buffer.hpp"
+#include "ngraph/runtime/reference/strided_slice.hpp"
+
+using namespace ngraph;
+
+void runtime::reference::strided_slice(
+    const char* arg, char* out, const Shape& arg_shape, const SlicePlan& sp, size_t elem_type)
+{
+    runtime::AlignedBuffer slice_out_buffer(shape_size(sp.reshape_in_shape) * elem_type);
+    slice(reinterpret_cast<const char*>(arg),
+          slice_out_buffer.get_ptr<char>(),
+          arg_shape,
+          Coordinate(sp.begins.begin(), sp.begins.end()),
+          Coordinate(sp.ends.begin(), sp.ends.end()),
+          Strides(sp.strides.begin(), sp.strides.end()),
+          sp.reshape_in_shape,
+          elem_type);
+
+    runtime::AlignedBuffer reshape_out_buffer(shape_size(sp.reshape_out_shape) * elem_type);
+    opt_kernel::reshape(slice_out_buffer.get_ptr<char>(),
+                        reshape_out_buffer.get_ptr<char>(),
+                        sp.reshape_in_shape,
+                        get_default_order(sp.reshape_in_shape.size()),
+                        sp.reshape_out_shape,
+                        elem_type);
+
+    reverse(reshape_out_buffer.get_ptr<char>(),
+            out,
+            sp.reshape_out_shape,
+            sp.reshape_out_shape,
+            sp.reverse_axes,
+            elem_type);
+}
diff --git a/ngraph/core/reference/src/runtime/reference/tile.cpp b/ngraph/core/reference/src/runtime/reference/tile.cpp
new file mode 100644 (file)
index 0000000..335a530
--- /dev/null
@@ -0,0 +1,47 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#include <cmath>
+#include <stdio.h>
+
+#include "ngraph/check.hpp"
+#include "ngraph/runtime/reference/tile.hpp"
+
+using namespace ngraph;
+
+void runtime::reference::tile(
+    const char* arg, char* out, const Shape& in_shape, const Shape& out_shape, size_t elem_size)
+{
+    Shape in_shape_expanded(in_shape);
+    in_shape_expanded.insert(in_shape_expanded.begin(), out_shape.size() - in_shape.size(), 1);
+    CoordinateTransform input_transform(in_shape_expanded);
+    CoordinateTransform output_transform(out_shape);
+
+    for (const Coordinate& output_coord : output_transform)
+    {
+        std::vector<size_t> coord;
+        for (auto i = 0; i < output_coord.size(); i++)
+        {
+            auto val = output_coord[i] % in_shape_expanded[i];
+            coord.push_back(val);
+        }
+        Coordinate input_coord(coord);
+
+        memcpy(out + output_transform.index(output_coord) * elem_size,
+               arg + input_transform.index(input_coord) * elem_size,
+               elem_size);
+    }
+}
diff --git a/ngraph/core/src/coordinate_transform.cpp b/ngraph/core/src/coordinate_transform.cpp
deleted file mode 100644 (file)
index da72e55..0000000
+++ /dev/null
@@ -1,539 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#include <algorithm>
-#include <cstdio>
-#include <iostream>
-#include <numeric>
-#include <sstream>
-#include <vector>
-
-#include "ngraph/axis_vector.hpp"
-#include "ngraph/coordinate_diff.hpp"
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/except.hpp"
-#include "ngraph/shape.hpp"
-#include "ngraph/strides.hpp"
-#include "ngraph/util.hpp"
-
-using namespace ngraph;
-
-namespace
-{
-    Strides default_strides(size_t n_axes) { return Strides(n_axes, 1); }
-    CoordinateDiff default_padding(size_t n_axes) { return CoordinateDiff(n_axes, 0); }
-    AxisVector default_axis_order(size_t n_axes)
-    {
-        AxisVector result(n_axes);
-        std::iota(result.begin(), result.end(), 0);
-        return result;
-    }
-
-    Coordinate default_source_start_corner(size_t n_axes) { return Coordinate(n_axes, 0); }
-    Coordinate default_source_end_corner(const Shape& source_shape) { return source_shape; }
-}
-
-CoordinateTransformBasic::CoordinateTransformBasic(const Shape& source_shape)
-    : m_source_shape(source_shape)
-{
-}
-
-// Compute the index of a source-space coordinate in the buffer.
-size_t CoordinateTransformBasic::index(const Coordinate& c) const noexcept
-{
-    size_t index = 0;
-    size_t stride = 1;
-    size_t const padding = c.size() - m_source_shape.size();
-
-    for (size_t axis = m_source_shape.size(); axis-- > 0;)
-    {
-        if (m_source_shape[axis] > 1)
-        {
-            index += c[axis + padding] * stride;
-            stride *= m_source_shape[axis];
-        }
-    }
-
-    return index;
-}
-
-CoordinateIterator CoordinateTransformBasic::begin() const noexcept
-{
-    return CoordinateIterator(m_source_shape);
-}
-
-const CoordinateIterator& CoordinateTransformBasic::end() const noexcept
-{
-    return CoordinateIterator::end();
-}
-
-CoordinateTransform::CoordinateTransform(const Shape& source_shape,
-                                         const Coordinate& source_start_corner,
-                                         const Coordinate& source_end_corner,
-                                         const Strides& source_strides,
-                                         const AxisVector& source_axis_order,
-                                         const CoordinateDiff& target_padding_below,
-                                         const CoordinateDiff& target_padding_above,
-                                         const Strides& target_dilation_strides)
-    : CoordinateTransformBasic(source_shape)
-    , m_source_start_corner(source_start_corner)
-    , m_source_end_corner(source_end_corner)
-    , m_source_strides(source_strides)
-    , m_source_axis_order(source_axis_order)
-    , m_target_padding_below(target_padding_below)
-    , m_target_padding_above(target_padding_above)
-    , m_target_dilation_strides(target_dilation_strides)
-{
-    m_n_axes = source_shape.size();
-
-    if (m_n_axes != source_start_corner.size())
-    {
-        throw std::domain_error(
-            "Source start corner does not have the same number of axes as the source space shape");
-    }
-    if (m_n_axes != source_end_corner.size())
-    {
-        throw std::domain_error(
-            "Source end corner does not have the same number of axes as the source space shape");
-    }
-    if (m_n_axes != source_strides.size())
-    {
-        throw std::domain_error(
-            "Source strides do not have the same number of axes as the source space shape");
-    }
-    if (m_n_axes != source_axis_order.size())
-    {
-        // Note: this check is NOT redundant with the is_permutation check below, though you might
-        // think it is. If the lengths don't match then is_permutation won't catch that; it'll
-        // either stop short or walk off the end of source_axis_order.
-        throw std::domain_error(
-            "Source axis order does not have the same number of axes as the source space shape");
-    }
-    if (m_n_axes != target_padding_below.size())
-    {
-        throw std::domain_error(
-            "Padding-below shape does not have the same number of axes as the source space shape");
-    }
-    if (m_n_axes != target_padding_above.size())
-    {
-        throw std::domain_error(
-            "Padding-above shape does not have the same number of axes as the source space shape");
-    }
-    if (m_n_axes != target_dilation_strides.size())
-    {
-        throw std::domain_error(
-            "Target dilation strides do not have the same number of axes as the source shape");
-    }
-
-    AxisVector all_axes(m_n_axes);
-    for (size_t i = 0; i < all_axes.size(); i++)
-    {
-        all_axes[i] = i;
-    }
-
-    if (!std::is_permutation(all_axes.begin(), all_axes.end(), source_axis_order.begin()))
-    {
-        throw std::domain_error(
-            "Source axis order is not a permutation of {0,...,n-1} where n is the number of axes "
-            "in the source space shape");
-    }
-
-    for (size_t i = 0; i < m_n_axes; i++)
-    {
-        if (target_dilation_strides[i] == 0)
-        {
-            std::stringstream ss;
-
-            ss << "The target dilation stride is 0 at axis " << i;
-            throw std::domain_error(ss.str());
-        }
-    }
-
-    std::vector<std::ptrdiff_t> padded_upper_bounds;
-
-    for (size_t i = 0; i < m_n_axes; i++)
-    {
-        std::ptrdiff_t padded_upper_bound =
-            subtract_or_zero(source_shape[i], size_t(1)) * target_dilation_strides[i] + 1 +
-            target_padding_below[i] + target_padding_above[i];
-
-        if (padded_upper_bound < 0)
-        {
-            std::stringstream ss;
-
-            ss << "The end corner is out of bounds at axis " << i;
-            throw std::domain_error(ss.str());
-        }
-
-        padded_upper_bounds.push_back(padded_upper_bound);
-    }
-
-    for (size_t i = 0; i < m_n_axes; i++)
-    {
-        if (static_cast<int64_t>(source_start_corner[i]) >= padded_upper_bounds[i] &&
-            source_start_corner[i] != source_shape[i])
-        {
-            std::stringstream ss;
-
-            ss << "The start corner is out of bounds at axis " << i;
-            throw std::domain_error(ss.str());
-        }
-
-        if (static_cast<int64_t>(source_end_corner[i]) > padded_upper_bounds[i])
-        {
-            std::stringstream ss;
-
-            ss << "The end corner is out of bounds at axis " << i;
-            throw std::domain_error(ss.str());
-        }
-    }
-
-    for (size_t i = 0; i < m_n_axes; i++)
-    {
-        if (source_strides[i] == 0)
-        {
-            std::stringstream ss;
-
-            ss << "The source stride is 0 at axis " << i;
-            throw std::domain_error(ss.str());
-        }
-    }
-
-    for (size_t axis = 0; axis < m_n_axes; axis++)
-    {
-        m_target_shape.push_back(ceil_div(source_end_corner[source_axis_order[axis]] -
-                                              source_start_corner[source_axis_order[axis]],
-                                          source_strides[source_axis_order[axis]]));
-    }
-}
-
-CoordinateTransform::CoordinateTransform(const Shape& source_shape,
-                                         const Coordinate& source_start_corner,
-                                         const Coordinate& source_end_corner,
-                                         const Strides& source_strides,
-                                         const AxisVector& source_axis_order,
-                                         const CoordinateDiff& target_padding_below,
-                                         const CoordinateDiff& target_padding_above)
-    : CoordinateTransform(source_shape,
-                          source_start_corner,
-                          source_end_corner,
-                          source_strides,
-                          source_axis_order,
-                          target_padding_below,
-                          target_padding_above,
-                          default_strides(source_shape.size()))
-{
-}
-
-CoordinateTransform::CoordinateTransform(const Shape& source_shape,
-                                         const Coordinate& source_start_corner,
-                                         const Coordinate& source_end_corner,
-                                         const Strides& source_strides,
-                                         const AxisVector& source_axis_order)
-    : CoordinateTransform(source_shape,
-                          source_start_corner,
-                          source_end_corner,
-                          source_strides,
-                          source_axis_order,
-                          default_padding(source_shape.size()),
-                          default_padding(source_shape.size()),
-                          default_strides(source_shape.size()))
-{
-}
-
-CoordinateTransform::CoordinateTransform(const Shape& source_shape,
-                                         const Coordinate& source_start_corner,
-                                         const Coordinate& source_end_corner,
-                                         const Strides& source_strides)
-    : CoordinateTransform(source_shape,
-                          source_start_corner,
-                          source_end_corner,
-                          source_strides,
-                          default_axis_order(source_shape.size()),
-                          default_padding(source_shape.size()),
-                          default_padding(source_shape.size()),
-                          default_strides(source_shape.size()))
-{
-}
-
-CoordinateTransform::CoordinateTransform(const Shape& source_shape,
-                                         const Coordinate& source_start_corner,
-                                         const Coordinate& source_end_corner)
-    : CoordinateTransform(source_shape,
-                          source_start_corner,
-                          source_end_corner,
-                          default_strides(source_shape.size()),
-                          default_axis_order(source_shape.size()),
-                          default_padding(source_shape.size()),
-                          default_padding(source_shape.size()),
-                          default_strides(source_shape.size()))
-{
-}
-
-CoordinateTransform::CoordinateTransform(const Shape& source_shape)
-    : CoordinateTransform(source_shape,
-                          default_source_start_corner(source_shape.size()),
-                          default_source_end_corner(source_shape),
-                          default_strides(source_shape.size()),
-                          default_axis_order(source_shape.size()),
-                          default_padding(source_shape.size()),
-                          default_padding(source_shape.size()),
-                          default_strides(source_shape.size()))
-{
-}
-
-// Compute the index of a target-space coordinate in thebuffer.
-size_t CoordinateTransform::index(const Coordinate& c) const
-{
-    return CoordinateTransformBasic::index(to_source_coordinate(c));
-}
-
-// Convert a target-space coordinate to a source-space coordinate.
-Coordinate CoordinateTransform::to_source_coordinate(const Coordinate& c_target) const
-{
-    if (c_target.size() != m_n_axes)
-    {
-        throw std::domain_error(
-            "Target coordinate rank does not match the coordinate transform rank");
-    }
-
-    Coordinate c_source(c_target.size());
-
-    for (size_t target_axis = 0; target_axis < m_n_axes; target_axis++)
-    {
-        size_t source_axis = m_source_axis_order[target_axis];
-
-        size_t target_pos = c_target[target_axis];
-        size_t pos_destrided = target_pos * m_source_strides[source_axis];
-        size_t pos_deshifted = pos_destrided + m_source_start_corner[source_axis];
-        size_t pos_depadded = pos_deshifted - m_target_padding_below[target_axis];
-        size_t pos_dedilated = pos_depadded / m_target_dilation_strides[target_axis];
-        c_source[source_axis] = pos_dedilated;
-    }
-
-    return c_source;
-}
-
-// A point in the target space is considered not to have a source coordinate if it was inserted due
-// to padding or dilation, or if it is out of the bounds of the target space.
-bool CoordinateTransform::has_source_coordinate(const Coordinate& c_target) const
-{
-    if (c_target.size() != m_n_axes)
-    {
-        throw std::domain_error(
-            "Target coordinate rank does not match the coordinate transform rank");
-    }
-
-    for (size_t target_axis = 0; target_axis < m_n_axes; target_axis++)
-    {
-        // Is this coordinate out of bounds of the target space?
-        if (c_target[target_axis] >= m_target_shape[target_axis])
-        {
-            return false;
-        }
-
-        // The rest of this is a replay of the corresponding logic in `to_source_coordinate`, with
-        // bounds and divisibility checking.
-        std::ptrdiff_t source_axis = m_source_axis_order[target_axis];
-
-        std::ptrdiff_t target_pos = c_target[target_axis];
-        std::ptrdiff_t pos_destrided = target_pos * m_source_strides[source_axis];
-        std::ptrdiff_t pos_deshifted = pos_destrided + m_source_start_corner[source_axis];
-
-        // If we are in the below-padding or the above-padding.
-        if (pos_deshifted < m_target_padding_below[target_axis])
-        {
-            return false;
-        }
-        std::ptrdiff_t pos_depadded = pos_deshifted - m_target_padding_below[target_axis];
-
-        // If we are in the above-padding, we have no source coordinate.
-        if (m_source_shape[source_axis] == 0 ||
-            (pos_depadded >= ((static_cast<int64_t>(m_source_shape[source_axis]) - 1) *
-                              static_cast<int64_t>(m_target_dilation_strides[target_axis])) +
-                                 1))
-        {
-            return false;
-        }
-
-        // If we are in a dilation gap, we have no source coordinate.
-        if (pos_depadded % m_target_dilation_strides[target_axis] != 0)
-        {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-const Shape& CoordinateTransform::get_source_shape() const noexcept
-{
-    return m_source_shape;
-}
-
-const Shape& CoordinateTransform::get_target_shape() const noexcept
-{
-    return m_target_shape;
-}
-
-const Coordinate& CoordinateTransform::get_source_start_corner() const noexcept
-{
-    return m_source_start_corner;
-}
-
-const Coordinate& CoordinateTransform::get_source_end_corner() const noexcept
-{
-    return m_source_end_corner;
-}
-
-const Strides& CoordinateTransform::get_source_strides() const noexcept
-{
-    return m_source_strides;
-}
-
-const AxisVector& CoordinateTransform::get_source_axis_order() const noexcept
-{
-    return m_source_axis_order;
-}
-
-const Strides& CoordinateTransform::get_target_dilation_strides() const noexcept
-{
-    return m_target_dilation_strides;
-}
-
-CoordinateIterator CoordinateTransform::begin() const noexcept
-{
-    return CoordinateIterator(m_target_shape);
-}
-
-const CoordinateIterator& CoordinateTransform::end() const noexcept
-{
-    return CoordinateIterator::end();
-}
-
-// The "is_end" parameter is true if we want the "end()" iterator.
-CoordinateIterator::CoordinateIterator(const Shape& target_shape, bool is_end)
-    : m_target_shape(target_shape)
-    , m_coordinate(target_shape.size(), 0)
-{
-    // The case where we have a zero-length axis is a bit special, in that
-    // the iterator always starts out of bounds.
-    bool const empty = std::find(target_shape.begin(), target_shape.end(), 0) != target_shape.end();
-
-    m_oob = is_end || empty;
-}
-
-void CoordinateIterator::operator++()
-{
-    advance(m_target_shape.size() - 1);
-}
-
-size_t CoordinateIterator::advance(size_t axis) noexcept
-{
-    m_oob |= m_target_shape.empty();
-
-    if (m_oob)
-        return m_target_shape.size();
-
-    bool carry_out = false;
-
-    // Increment the target coordinate.
-    do
-    {
-        m_coordinate[axis]++;
-
-        if (m_coordinate[axis] < m_target_shape[axis])
-        {
-            // No carry-out, so we are done.
-            return axis;
-        }
-        else
-        {
-            m_coordinate[axis] = 0;
-            carry_out = true;
-        }
-    } while (axis-- > 0);
-
-    // If we are still here there was carry-out from the most significant axis. We are now out of
-    // bounds.
-    m_oob = true;
-
-    return m_target_shape.size();
-}
-
-CoordinateIterator CoordinateIterator::operator++(int)
-{
-    CoordinateIterator temp = *this;
-    ++(*this);
-    return temp;
-}
-
-void CoordinateIterator::operator+=(size_t n)
-{
-    for (size_t i = 0; i < n; i++)
-    {
-        ++(*this);
-    }
-}
-
-const Coordinate& CoordinateIterator::operator*() const noexcept
-{
-    return m_coordinate;
-}
-
-bool CoordinateIterator::operator!=(const CoordinateIterator& it) const noexcept
-{
-    return !(*this == it);
-}
-
-bool CoordinateIterator::operator==(const CoordinateIterator& it) const noexcept
-{
-    if (it.m_oob)
-    {
-        // Out-of-bounds iterators are always equal; in other words, an iterator is always equal to
-        // end() even if the internally stored coordinates are different.
-
-        // If one iterator is out of bounds and the other is not, they are unequal even if their
-        // target coordinates happen to match.
-        return m_oob;
-    }
-    else if (m_oob)
-    {
-        return false;
-    }
-
-    if (m_target_shape != it.m_target_shape)
-    {
-        return false;
-    }
-
-    // Check axis-wise if the iterators are on the same target coordinate.
-    for (size_t axis = 0; axis < m_target_shape.size(); axis++)
-    {
-        if (m_coordinate[axis] != it.m_coordinate[axis])
-        {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-const CoordinateIterator& CoordinateIterator::end()
-{
-    static const CoordinateIterator it(Shape(), true);
-    return it;
-}
index 4b142c27fd7b4f998dc0efedb8734603c543df36..fc96d7c8edc0d8abb769d5ff2b0b38007d9c26b6 100644 (file)
@@ -15,7 +15,7 @@
 //*****************************************************************************
 
 #include "ngraph/op/prelu.hpp"
-#include <runtime/reference/prelu.hpp>
+#include <ngraph/runtime/reference/prelu.hpp>
 #include "ngraph/itt.hpp"
 
 #include "ngraph/builder/autobroadcast.hpp"
diff --git a/ngraph/core/src/runtime/opt_kernel/reshape.cpp b/ngraph/core/src/runtime/opt_kernel/reshape.cpp
deleted file mode 100644 (file)
index ba78493..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#include <cmath>
-#include <stdio.h>
-
-#include "ngraph/check.hpp"
-#include "ngraph/runtime/opt_kernel/reshape.hpp"
-
-using namespace ngraph;
-
-namespace
-{
-    void reshape_in0(const char* in,
-                     char* out,
-                     const Shape& in_shape,
-                     const AxisVector& in_axis_order,
-                     const Shape& out_shape,
-                     size_t elem_size)
-    {
-        memcpy(out, in, elem_size);
-    }
-
-    void reshape_in1(const char* in,
-                     char* out,
-                     const Shape& in_shape,
-                     const AxisVector& in_axis_order,
-                     const Shape& out_shape,
-                     size_t elem_size)
-    {
-        size_t size[1];
-        size_t in_index[1];
-        size_t* map_index[1];
-        for (size_t i = 0; i < 1; i++)
-        {
-            size[i] = in_shape[in_axis_order[i]];
-            map_index[in_axis_order[i]] = &in_index[i];
-        }
-        for (in_index[0] = 0; in_index[0] < size[0]; ++in_index[0])
-        {
-            memcpy(out, in + *map_index[0] * elem_size, elem_size);
-            out += elem_size;
-        }
-    }
-
-    void reshape_in2(const char* in,
-                     char* out,
-                     const Shape& in_shape,
-                     const AxisVector& in_axis_order,
-                     const Shape& out_shape,
-                     size_t elem_size)
-    {
-        size_t size[2];
-        size_t in_index[2];
-        size_t* map_index[2];
-        for (size_t i = 0; i < 2; i++)
-        {
-            size[i] = in_shape[in_axis_order[i]];
-            map_index[in_axis_order[i]] = &in_index[i];
-        }
-        for (in_index[0] = 0; in_index[0] < size[0]; ++in_index[0])
-        {
-            for (in_index[1] = 0; in_index[1] < size[1]; ++in_index[1])
-            {
-                // clang-format off
-                memcpy(out,
-                       in + (*map_index[0] * in_shape[1] +
-                             *map_index[1]) * elem_size,
-                       elem_size);
-                out += elem_size;
-                // clang-format on
-            }
-        }
-    }
-
-    void reshape_in3(const char* in,
-                     char* out,
-                     const Shape& in_shape,
-                     const AxisVector& in_axis_order,
-                     const Shape& out_shape,
-                     size_t elem_size)
-    {
-        size_t size[3];
-        size_t in_index[3];
-        size_t* map_index[3];
-        for (size_t i = 0; i < 3; i++)
-        {
-            size[i] = in_shape[in_axis_order[i]];
-            map_index[in_axis_order[i]] = &in_index[i];
-        }
-        for (in_index[0] = 0; in_index[0] < size[0]; ++in_index[0])
-        {
-            for (in_index[1] = 0; in_index[1] < size[1]; ++in_index[1])
-            {
-                for (in_index[2] = 0; in_index[2] < size[2]; ++in_index[2])
-                {
-                    // clang-format off
-                    memcpy(out,
-                           in + (*map_index[0] * in_shape[1] * in_shape[2] +
-                                 *map_index[1] * in_shape[2] +
-                                 *map_index[2]) * elem_size,
-                           elem_size);
-                    out += elem_size;
-                    // clang-format on
-                }
-            }
-        }
-    }
-
-    void reshape_in4(const char* in,
-                     char* out,
-                     const Shape& in_shape,
-                     const AxisVector& in_axis_order,
-                     const Shape& out_shape,
-                     size_t elem_size)
-    {
-        size_t size[4];
-        size_t in_index[4];
-        size_t* map_index[4];
-        for (size_t i = 0; i < 4; i++)
-        {
-            size[i] = in_shape[in_axis_order[i]];
-            map_index[in_axis_order[i]] = &in_index[i];
-        }
-        for (in_index[0] = 0; in_index[0] < size[0]; ++in_index[0])
-        {
-            for (in_index[1] = 0; in_index[1] < size[1]; ++in_index[1])
-            {
-                for (in_index[2] = 0; in_index[2] < size[2]; ++in_index[2])
-                {
-                    for (in_index[3] = 0; in_index[3] < size[3]; ++in_index[3])
-                    {
-                        // clang-format off
-                        memcpy(out,
-                               in + (*map_index[0] * in_shape[1] * in_shape[2] * in_shape[3] +
-                                     *map_index[1] * in_shape[2] * in_shape[3] +
-                                     *map_index[2] * in_shape[3] +
-                                     *map_index[3]) * elem_size,
-                               elem_size);
-                        out += elem_size;
-                        // clang-format on
-                    }
-                }
-            }
-        }
-    }
-
-    void reshape_in5(const char* in,
-                     char* out,
-                     const Shape& in_shape,
-                     const AxisVector& in_axis_order,
-                     const Shape& out_shape,
-                     size_t elem_size)
-    {
-        size_t size[5];
-        size_t in_index[5];
-        size_t* map_index[5];
-        for (size_t i = 0; i < 5; i++)
-        {
-            size[i] = in_shape[in_axis_order[i]];
-            map_index[in_axis_order[i]] = &in_index[i];
-        }
-        for (in_index[0] = 0; in_index[0] < size[0]; ++in_index[0])
-        {
-            for (in_index[1] = 0; in_index[1] < size[1]; ++in_index[1])
-            {
-                for (in_index[2] = 0; in_index[2] < size[2]; ++in_index[2])
-                {
-                    for (in_index[3] = 0; in_index[3] < size[3]; ++in_index[3])
-                    {
-                        for (in_index[4] = 0; in_index[4] < size[4]; ++in_index[4])
-                        {
-                            // clang-format off
-                            memcpy(out,
-                                   in + (*map_index[0] * in_shape[1] * in_shape[2] * in_shape[3] * in_shape[4] +
-                                         *map_index[1] * in_shape[2] * in_shape[3] * in_shape[4] +
-                                         *map_index[2] * in_shape[3] * in_shape[4] +
-                                         *map_index[3] * in_shape[4] +
-                                         *map_index[4]) * elem_size,
-                                   elem_size);
-                            out += elem_size;
-                            // clang-format on
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    void reshape_in6(const char* in,
-                     char* out,
-                     const Shape& in_shape,
-                     const AxisVector& in_axis_order,
-                     const Shape& out_shape,
-                     size_t elem_size)
-    {
-        size_t size[6];
-        size_t in_index[6];
-        size_t* map_index[6];
-        for (size_t i = 0; i < 6; i++)
-        {
-            size[i] = in_shape[in_axis_order[i]];
-            map_index[in_axis_order[i]] = &in_index[i];
-        }
-        for (in_index[0] = 0; in_index[0] < size[0]; ++in_index[0])
-        {
-            for (in_index[1] = 0; in_index[1] < size[1]; ++in_index[1])
-            {
-                for (in_index[2] = 0; in_index[2] < size[2]; ++in_index[2])
-                {
-                    for (in_index[3] = 0; in_index[3] < size[3]; ++in_index[3])
-                    {
-                        for (in_index[4] = 0; in_index[4] < size[4]; ++in_index[4])
-                        {
-                            for (in_index[5] = 0; in_index[5] < size[5]; ++in_index[5])
-                            {
-                                // clang-format off
-                                memcpy(out,
-                                       in + (*map_index[0] * in_shape[1] * in_shape[2] * in_shape[3] * in_shape[4] * in_shape[5] +
-                                             *map_index[1] * in_shape[2] * in_shape[3] * in_shape[4] * in_shape[5] +
-                                             *map_index[2] * in_shape[3] * in_shape[4] * in_shape[5] +
-                                             *map_index[3] * in_shape[4] * in_shape[5] +
-                                             *map_index[4] * in_shape[5] +
-                                             *map_index[5]) * elem_size,
-                                       elem_size);
-                                out += elem_size;
-                                // clang-format on
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-void runtime::opt_kernel::reshape(const char* in,
-                                  char* out,
-                                  const Shape& in_shape,
-                                  const AxisVector& in_axis_order,
-                                  const Shape& out_shape,
-                                  size_t elem_size)
-{
-    switch (in_shape.size())
-    {
-    case 0: reshape_in0(in, out, in_shape, in_axis_order, out_shape, elem_size); break;
-    case 1: reshape_in1(in, out, in_shape, in_axis_order, out_shape, elem_size); break;
-    case 2: reshape_in2(in, out, in_shape, in_axis_order, out_shape, elem_size); break;
-    case 3: reshape_in3(in, out, in_shape, in_axis_order, out_shape, elem_size); break;
-    case 4: reshape_in4(in, out, in_shape, in_axis_order, out_shape, elem_size); break;
-    case 5: reshape_in5(in, out, in_shape, in_axis_order, out_shape, elem_size); break;
-    case 6: reshape_in6(in, out, in_shape, in_axis_order, out_shape, elem_size); break;
-    default: reference::reshape(in, out, in_shape, in_axis_order, out_shape, elem_size); break;
-    }
-}
diff --git a/ngraph/core/src/runtime/reference/eval_helpers.cpp b/ngraph/core/src/runtime/reference/eval_helpers.cpp
deleted file mode 100644 (file)
index de3b322..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#include <algorithm>
-
-#include "ngraph/check.hpp"
-#include "ngraph/runtime/reference/eval_helpers.hpp"
-
-namespace ngraph
-{
-    namespace eval
-    {
-        AxisSet extract_reduction_axes(const HostTensorPtr& axes, const char* op_name)
-        {
-            const auto axes_count = axes->get_element_count();
-            const auto axes_buffer = axes->get_data_ptr<int64_t>();
-
-            const bool negative_axis_received = std::any_of(
-                axes_buffer, axes_buffer + axes_count, [](const int64_t axis) { return axis < 0; });
-
-            NGRAPH_CHECK(!negative_axis_received,
-                         "Negative axis value received in the ",
-                         op_name,
-                         " evaluation. This case is not supported.");
-
-            return AxisSet(std::vector<AxisSet::value_type>(axes_buffer, axes_buffer + axes_count));
-        }
-    }
-}
diff --git a/ngraph/core/src/runtime/reference/reshape.cpp b/ngraph/core/src/runtime/reference/reshape.cpp
deleted file mode 100644 (file)
index 5872ee3..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#include <cmath>
-#include <stdio.h>
-
-#include "ngraph/check.hpp"
-#include "ngraph/runtime/reference/reshape.hpp"
-
-using namespace ngraph;
-
-void runtime::reference::reshape(const char* arg,
-                                 char* out,
-                                 const Shape& in_shape,
-                                 const AxisVector& in_axis_order,
-                                 const Shape& out_shape,
-                                 size_t elem_size)
-{
-    // Unfortunately we don't yet have a constructor for CoordinateTransform that lets
-    // us pass only source_space_shape
-    // and source_axis_order so we have to construct the defaults here.
-    Shape in_start_corner(in_shape.size(), 0); // (0,...0)
-    Strides in_strides(in_shape.size(), 1);    // (1,...,1)
-
-    CoordinateTransform input_transform(
-        in_shape, in_start_corner, in_shape, in_strides, in_axis_order);
-    CoordinateTransform output_transform(out_shape);
-
-    NGRAPH_CHECK(shape_size(input_transform.get_target_shape()) ==
-                 shape_size(output_transform.get_target_shape()));
-
-    CoordinateTransform::Iterator output_it = output_transform.begin();
-
-    for (const Coordinate& input_coord : input_transform)
-    {
-        const Coordinate& output_coord = *output_it;
-
-        memcpy(out + output_transform.index(output_coord) * elem_size,
-               arg + input_transform.index(input_coord) * elem_size,
-               elem_size);
-
-        ++output_it;
-    }
-}
diff --git a/ngraph/core/src/runtime/reference/reverse.cpp b/ngraph/core/src/runtime/reference/reverse.cpp
deleted file mode 100644 (file)
index b53f5c4..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#include <cmath>
-#include <stdio.h>
-
-#include "ngraph/check.hpp"
-#include "ngraph/runtime/reference/reverse.hpp"
-
-using namespace ngraph;
-
-void runtime::reference::reverse(const char* arg,
-                                 char* out,
-                                 const Shape& arg_shape,
-                                 const Shape& out_shape,
-                                 const AxisSet& reversed_axes,
-                                 size_t elem_size)
-{
-    // In fact arg_shape == out_shape, but we'll use both for stylistic consistency with
-    // other kernels.
-    CoordinateTransform arg_transform(arg_shape);
-    CoordinateTransform output_transform(out_shape);
-
-    for (Coordinate out_coord : output_transform)
-    {
-        Coordinate arg_coord = out_coord;
-
-        for (size_t i = 0; i < arg_coord.size(); i++)
-        {
-            if (reversed_axes.count(i) != 0)
-            {
-                arg_coord[i] = arg_shape[i] - arg_coord[i] - 1;
-            }
-        }
-
-        memcpy(out + output_transform.index(out_coord) * elem_size,
-               arg + arg_transform.index(arg_coord) * elem_size,
-               elem_size);
-    }
-}
diff --git a/ngraph/core/src/runtime/reference/slice.cpp b/ngraph/core/src/runtime/reference/slice.cpp
deleted file mode 100644 (file)
index 415d55a..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#include <cmath>
-#include <stdio.h>
-
-#include "ngraph/check.hpp"
-#include "ngraph/runtime/reference/slice.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            void slice(const char* arg,
-                       char* out,
-                       const Shape& arg_shape,
-                       const Coordinate& lower_bounds,
-                       const Coordinate& upper_bounds,
-                       const Strides& strides,
-                       const Shape& out_shape,
-                       size_t elem_size)
-            {
-                CoordinateTransform input_transform(arg_shape, lower_bounds, upper_bounds, strides);
-                CoordinateTransform output_transform(out_shape);
-
-                CoordinateTransform::Iterator output_it = output_transform.begin();
-
-                NGRAPH_CHECK(shape_size(input_transform.get_target_shape()) ==
-                             shape_size(output_transform.get_target_shape()));
-
-                for (const Coordinate& in_coord : input_transform)
-                {
-                    const Coordinate& out_coord = *output_it;
-
-                    memcpy(out + output_transform.index(out_coord) * elem_size,
-                           arg + input_transform.index(in_coord) * elem_size,
-                           elem_size);
-
-                    ++output_it;
-                }
-            }
-        }
-    }
-}
diff --git a/ngraph/core/src/runtime/reference/strided_slice.cpp b/ngraph/core/src/runtime/reference/strided_slice.cpp
deleted file mode 100644 (file)
index 033109f..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#include <cmath>
-#include <stdio.h>
-
-#include "ngraph/check.hpp"
-#include "ngraph/runtime/aligned_buffer.hpp"
-#include "ngraph/runtime/reference/strided_slice.hpp"
-
-using namespace ngraph;
-
-void runtime::reference::strided_slice(
-    const char* arg, char* out, const Shape& arg_shape, const SlicePlan& sp, size_t elem_type)
-{
-    runtime::AlignedBuffer slice_out_buffer(shape_size(sp.reshape_in_shape) * elem_type);
-    slice(reinterpret_cast<const char*>(arg),
-          slice_out_buffer.get_ptr<char>(),
-          arg_shape,
-          Coordinate(sp.begins.begin(), sp.begins.end()),
-          Coordinate(sp.ends.begin(), sp.ends.end()),
-          Strides(sp.strides.begin(), sp.strides.end()),
-          sp.reshape_in_shape,
-          elem_type);
-
-    runtime::AlignedBuffer reshape_out_buffer(shape_size(sp.reshape_out_shape) * elem_type);
-    opt_kernel::reshape(slice_out_buffer.get_ptr<char>(),
-                        reshape_out_buffer.get_ptr<char>(),
-                        sp.reshape_in_shape,
-                        get_default_order(sp.reshape_in_shape.size()),
-                        sp.reshape_out_shape,
-                        elem_type);
-
-    reverse(reshape_out_buffer.get_ptr<char>(),
-            out,
-            sp.reshape_out_shape,
-            sp.reshape_out_shape,
-            sp.reverse_axes,
-            elem_type);
-}
diff --git a/ngraph/core/src/runtime/reference/tile.cpp b/ngraph/core/src/runtime/reference/tile.cpp
deleted file mode 100644 (file)
index 335a530..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-//*****************************************************************************
-// Copyright 2017-2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//*****************************************************************************
-
-#include <cmath>
-#include <stdio.h>
-
-#include "ngraph/check.hpp"
-#include "ngraph/runtime/reference/tile.hpp"
-
-using namespace ngraph;
-
-void runtime::reference::tile(
-    const char* arg, char* out, const Shape& in_shape, const Shape& out_shape, size_t elem_size)
-{
-    Shape in_shape_expanded(in_shape);
-    in_shape_expanded.insert(in_shape_expanded.begin(), out_shape.size() - in_shape.size(), 1);
-    CoordinateTransform input_transform(in_shape_expanded);
-    CoordinateTransform output_transform(out_shape);
-
-    for (const Coordinate& output_coord : output_transform)
-    {
-        std::vector<size_t> coord;
-        for (auto i = 0; i < output_coord.size(); i++)
-        {
-            auto val = output_coord[i] % in_shape_expanded[i];
-            coord.push_back(val);
-        }
-        Coordinate input_coord(coord);
-
-        memcpy(out + output_transform.index(output_coord) * elem_size,
-               arg + input_transform.index(input_coord) * elem_size,
-               elem_size);
-    }
-}
index 78af9d9a3193c054123e0c79627bdc9e9b82a458..9a472b761d177fbee63b19430f73ad666164063b 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "gtest/gtest.h"
 
+#include <ngraph/coordinate_transform.hpp>
 #include "ngraph/ngraph.hpp"
 #include "util/ndarray.hpp"
 #include "util/test_tools.hpp"
index 152f297520eddad462325e7f57f2cd5cfb38b591..c43922411e1cc2cb1fdf5886ed73c7ba4ef16f5b 100644 (file)
@@ -57,7 +57,8 @@ target_compile_definitions(ngraph_backend
         SHARED_LIB_PREFIX="${CMAKE_SHARED_LIBRARY_PREFIX}"
         SHARED_LIB_SUFFIX="${IE_BUILD_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX}"
 )
-target_link_libraries(ngraph_backend PUBLIC ngraph)
+target_link_libraries(ngraph_backend PUBLIC ngraph 
+                                            ngraph::reference)
 if (NOT WIN32)
     target_link_libraries(ngraph_backend PRIVATE dl)
 endif()
index dd331046ada213933b1917bd76e52aad990e1443..3bf678319ff6b33159abc9fbf49bfd654406198a 100644 (file)
 #include "ngraph/runtime/reference/convolution.hpp"
 #include "ngraph/runtime/reference/cos.hpp"
 #include "ngraph/runtime/reference/cosh.hpp"
+#include "ngraph/runtime/reference/ctc_loss.hpp"
 #include "ngraph/runtime/reference/cum_sum.hpp"
 #include "ngraph/runtime/reference/dequantize.hpp"
+#include "ngraph/runtime/reference/detection_output.hpp"
 #include "ngraph/runtime/reference/dot.hpp"
 #include "ngraph/runtime/reference/elu.hpp"
 #include "ngraph/runtime/reference/embedding_bag_offsets_sum.hpp"
@@ -76,6 +78,8 @@
 #include "ngraph/runtime/reference/reverse.hpp"
 #include "ngraph/runtime/reference/reverse_sequence.hpp"
 #include "ngraph/runtime/reference/round.hpp"
+#include "ngraph/runtime/reference/scatter_nd_update.hpp"
+#include "ngraph/runtime/reference/scatter_update.hpp"
 #include "ngraph/runtime/reference/select.hpp"
 #include "ngraph/runtime/reference/sigmoid.hpp"
 #include "ngraph/runtime/reference/sign.hpp"
 #include "op/convolution.hpp"
 #include "op/group_conv.hpp"
 
-#include "reference/ctc_loss.hpp"
-#include "reference/detection_output.hpp"
-#include "reference/scatter_nd_update.hpp"
-#include "reference/scatter_update.hpp"
-
 namespace ngraph
 {
     namespace runtime
diff --git a/ngraph/test/runtime/interpreter/reference/ctc_loss.hpp b/ngraph/test/runtime/interpreter/reference/ctc_loss.hpp
deleted file mode 100644 (file)
index 895f7f4..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright (C) 2020 Intel Corporation
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#pragma once
-
-#include <math.h>
-#include "ngraph/shape_util.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename T, typename U>
-            void CTCLoss(const T* logits,
-                         const Shape& logitsShape,
-                         const U* logitsLength,
-                         const U* labels,
-                         const U* labelsLength,
-                         const U* blankIndexP,
-                         const bool preprocessCollapseRepeated,
-                         const bool ctcMergeRepeated,
-                         const bool unique,
-                         T* output)
-            {
-                const size_t batchNum = logitsShape[0];
-                const size_t maxTime = logitsShape[1];
-                const size_t classesNum = logitsShape[2];
-                U blankIndex = classesNum - 1;
-                if (blankIndexP != nullptr)
-                {
-                    blankIndex = blankIndexP[0];
-                }
-
-                std::vector<U> targetD(maxTime);
-                std::vector<U> pathS(maxTime);
-
-                const size_t TC = maxTime * classesNum;
-
-                for (size_t b = 0; b < batchNum; b++)
-                {
-                    U actualLogitLen = logitsLength[b];
-                    U actualTargetLen = labelsLength[b];
-                    if (actualLogitLen >= maxTime || actualTargetLen >= maxTime ||
-                        actualTargetLen > actualLogitLen)
-                    {
-                        throw ngraph_error(
-                            std::string("Logit or label length cannot be more than max sequence"
-                                        "length. Also a label length cannot be greater than a"
-                                        "logit length.\nMaxSeqLen: ") +
-                            std::to_string(maxTime) + "; Logit len: " +
-                            std::to_string(actualLogitLen) + "; Label len: " +
-                            std::to_string(actualTargetLen));
-                    }
-
-                    const U* target = &labels[b * maxTime];
-                    // Decoding target:
-                    // merge repeated characters if preprocess_collapse_repeated == True,
-                    // find unique elemnts if unique == True
-                    size_t decodedTargetLen = 0lu;
-                    if (unique)
-                    {
-                        std::unordered_set<U> uniqVals;
-                        for (size_t t = 0lu; t < actualTargetLen; t++)
-                        {
-                            if (uniqVals.find(target[t]) != uniqVals.end())
-                            {
-                                continue;
-                            }
-                            uniqVals.insert(target[t]);
-                            targetD[decodedTargetLen++] = target[t];
-                        }
-                    }
-                    else if (preprocessCollapseRepeated)
-                    {
-                        U prevValue = target[0];
-                        targetD[decodedTargetLen++] = target[0];
-                        for (size_t t = 1lu; t < actualTargetLen; t++)
-                        {
-                            if (target[t] == prevValue)
-                            {
-                                continue;
-                            }
-                            targetD[decodedTargetLen++] = target[t];
-                            prevValue = target[t];
-                        }
-                    }
-                    else
-                    {
-                        std::copy(target, target + actualTargetLen, targetD.data());
-                        decodedTargetLen = actualTargetLen;
-                    }
-
-                    const size_t BTC = b * TC;
-
-                    std::vector<T> kExp(actualLogitLen, 0);
-                    for (size_t t = 0; t < actualLogitLen; t++)
-                    {
-                        size_t btcT = BTC + classesNum * t;
-                        for (size_t c = 0; c < classesNum; c++)
-                        {
-                            kExp[t] += std::exp(logits[btcT + c]);
-                        }
-                    }
-
-                    T res = -std::numeric_limits<T>::infinity();
-
-                    // Looking for aligned paths
-                    std::function<void(size_t targetIdx, size_t start, size_t end)> findPaths = [&](
-                        size_t targetIdx, size_t start, size_t end) {
-                        if (end > actualLogitLen)
-                        {
-                            T prod = 0;
-                            for (size_t t = 0; t < actualLogitLen; t++)
-                            {
-                                prod += std::log(std::exp(logits[BTC + classesNum * t + pathS[t]]) /
-                                                 kExp[t]);
-                            }
-                            if (res == -std::numeric_limits<T>::infinity())
-                                res = prod;
-                            else if (prod != -std::numeric_limits<T>::infinity())
-                                res = res + std::log1pf(std::exp(prod - res));
-
-                            return;
-                        }
-
-                        size_t nextIdx = targetIdx + 1;
-                        int64_t st64 = start;
-                        if (!ctcMergeRepeated)
-                        {
-                            for (size_t pos = start; pos < end; pos++)
-                            {
-                                for (size_t bl = start; bl < pos; bl++)
-                                {
-                                    pathS[bl] = blankIndex;
-                                }
-                                pathS[pos] = targetD[targetIdx];
-                                findPaths(nextIdx, pos + 1, end + 1);
-                            }
-                        }
-                        else
-                        {
-                            for (size_t pos = start; pos < end; pos++)
-                            {
-                                for (size_t bl = start; bl < pos; bl++)
-                                {
-                                    pathS[bl] = blankIndex;
-                                }
-                                for (int64_t bl = pos; bl >= st64; bl--)
-                                {
-                                    pathS[bl] = targetD[targetIdx];
-                                    if (end == actualLogitLen)
-                                    {
-                                        for (int64_t ble = pos + 1; ble < actualLogitLen; ble++)
-                                        {
-                                            pathS[ble] = blankIndex;
-                                        }
-                                    }
-                                    size_t next_start = pos + 1;
-                                    if (targetIdx < decodedTargetLen - 1 &&
-                                        targetD[targetIdx] == targetD[targetIdx + 1])
-                                    {
-                                        pathS[next_start++] = blankIndex;
-                                    }
-                                    findPaths(nextIdx, next_start, end + 1);
-                                }
-                            }
-                        }
-                    }; // findPaths
-
-                    findPaths(0lu, 0lu, actualLogitLen - decodedTargetLen + 1lu);
-
-                    output[b] = -res;
-
-                } // for (size_t b = 0; b < batchNum; b++)
-            }     // CTCLoss
-        }         // reference
-    }             // runtime
-} // ngraph
diff --git a/ngraph/test/runtime/interpreter/reference/detection_output.hpp b/ngraph/test/runtime/interpreter/reference/detection_output.hpp
deleted file mode 100644 (file)
index 8379d79..0000000
+++ /dev/null
@@ -1,669 +0,0 @@
-// Copyright (C) 2020 Intel Corporation
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#pragma once
-
-#include <cstddef>
-#include <map>
-#include <string>
-#include <vector>
-
-#include "ngraph/shape.hpp"
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            enum
-            {
-                idxLocation,
-                idxConfidence,
-                idxPriors,
-                idxArmConfidence,
-                idxArmLocation,
-                numInputs
-            };
-
-            template <typename dataType>
-            class referenceDetectionOutput
-            {
-            private:
-                struct NormalizedBBox
-                {
-                    dataType xmin = 0;
-                    dataType ymin = 0;
-                    dataType xmax = 0;
-                    dataType ymax = 0;
-                    dataType size = 0;
-                };
-                using LabelBBox = std::map<int, std::vector<NormalizedBBox>>;
-
-                ngraph::op::DetectionOutputAttrs attrs;
-                size_t numImages;
-                size_t priorSize;
-                size_t numPriors;
-                size_t numLocClasses;
-                size_t offset;
-
-                void GetLocPredictions(const dataType* locData, std::vector<LabelBBox>& locations)
-                {
-                    locations.resize(numImages);
-                    for (size_t i = 0; i < numImages; ++i)
-                    {
-                        LabelBBox& labelBbox = locations[i];
-                        for (size_t p = 0; p < numPriors; ++p)
-                        {
-                            size_t startIdx = p * numLocClasses * 4;
-                            for (size_t c = 0; c < numLocClasses; ++c)
-                            {
-                                int label = attrs.share_location ? -1 : c;
-                                if (labelBbox.find(label) == labelBbox.end())
-                                {
-                                    labelBbox[label].resize(numPriors);
-                                }
-                                labelBbox[label][p].xmin = locData[startIdx + c * 4];
-                                labelBbox[label][p].ymin = locData[startIdx + c * 4 + 1];
-                                labelBbox[label][p].xmax = locData[startIdx + c * 4 + 2];
-                                labelBbox[label][p].ymax = locData[startIdx + c * 4 + 3];
-                            }
-                        }
-                        locData += numPriors * numLocClasses * 4;
-                    }
-                }
-
-                void GetConfidenceScores(
-                    const dataType* confData,
-                    std::vector<std::map<int, std::vector<dataType>>>& confPreds)
-                {
-                    confPreds.resize(numImages);
-                    for (int i = 0; i < numImages; ++i)
-                    {
-                        std::map<int, std::vector<dataType>>& labelScores = confPreds[i];
-                        for (int p = 0; p < numPriors; ++p)
-                        {
-                            int startIdx = p * attrs.num_classes;
-                            for (int c = 0; c < attrs.num_classes; ++c)
-                            {
-                                labelScores[c].push_back(confData[startIdx + c]);
-                            }
-                        }
-                        confData += numPriors * attrs.num_classes;
-                    }
-                }
-
-                void OSGetConfidenceScores(
-                    const dataType* confData,
-                    const dataType* armConfData,
-                    std::vector<std::map<int, std::vector<dataType>>>& confPreds)
-                {
-                    confPreds.resize(numImages);
-                    for (int i = 0; i < numImages; ++i)
-                    {
-                        std::map<int, std::vector<dataType>>& labelScores = confPreds[i];
-                        for (int p = 0; p < numPriors; ++p)
-                        {
-                            int startIdx = p * attrs.num_classes;
-                            if (armConfData[p * 2 + 1] < attrs.objectness_score)
-                            {
-                                for (int c = 0; c < attrs.num_classes; ++c)
-                                {
-                                    c == attrs.background_label_id ? labelScores[c].push_back(1)
-                                                                   : labelScores[c].push_back(0);
-                                }
-                            }
-                            else
-                            {
-                                for (int c = 0; c < attrs.num_classes; ++c)
-                                {
-                                    labelScores[c].push_back(confData[startIdx + c]);
-                                }
-                            }
-                        }
-                        confData += numPriors * attrs.num_classes;
-                        armConfData += numPriors * 2;
-                    }
-                }
-
-                dataType BBoxSize(const NormalizedBBox& bbox)
-                {
-                    if (bbox.xmax < bbox.xmin || bbox.ymax < bbox.ymin)
-                    {
-                        return 0;
-                    }
-                    else
-                    {
-                        dataType width = bbox.xmax - bbox.xmin;
-                        dataType height = bbox.ymax - bbox.ymin;
-                        return width * height;
-                    }
-                }
-
-                void GetPriorBBoxes(const dataType* priorData,
-                                    std::vector<std::vector<NormalizedBBox>>& priorBboxes,
-                                    std::vector<std::vector<std::vector<dataType>>>& priorVariances)
-                {
-                    priorBboxes.resize(numImages);
-                    priorVariances.resize(numImages);
-                    for (int n = 0; n < numImages; n++)
-                    {
-                        priorData += attrs.variance_encoded_in_target
-                                         ? n * numPriors * priorSize
-                                         : 2 * n * numPriors * priorSize;
-                        std::vector<NormalizedBBox>& currPrBbox = priorBboxes[n];
-                        std::vector<std::vector<dataType>>& currPrVar = priorVariances[n];
-                        for (int i = 0; i < numPriors; ++i)
-                        {
-                            int start_idx = i * priorSize;
-                            NormalizedBBox bbox;
-                            bbox.xmin = priorData[start_idx + 0 + offset];
-                            bbox.ymin = priorData[start_idx + 1 + offset];
-                            bbox.xmax = priorData[start_idx + 2 + offset];
-                            bbox.ymax = priorData[start_idx + 3 + offset];
-                            dataType bbox_size = BBoxSize(bbox);
-                            bbox.size = bbox_size;
-                            currPrBbox.push_back(bbox);
-                        }
-                        if (!attrs.variance_encoded_in_target)
-                        {
-                            const dataType* priorVar = priorData + numPriors * priorSize;
-                            for (int i = 0; i < numPriors; ++i)
-                            {
-                                int start_idx = i * 4;
-                                std::vector<dataType> var;
-                                for (int j = 0; j < 4; ++j)
-                                {
-                                    var.push_back(priorVar[start_idx + j]);
-                                }
-                                currPrVar.push_back(var);
-                            }
-                        }
-                    }
-                }
-
-                void DecodeBBox(const NormalizedBBox& priorBboxes,
-                                const std::vector<dataType>& priorVariances,
-                                const NormalizedBBox& bbox,
-                                NormalizedBBox& decodeBbox)
-                {
-                    dataType priorXmin = priorBboxes.xmin;
-                    dataType priorYmin = priorBboxes.ymin;
-                    dataType priorXmax = priorBboxes.xmax;
-                    dataType priorYmax = priorBboxes.ymax;
-
-                    if (!attrs.normalized)
-                    {
-                        priorXmin /= attrs.input_width;
-                        priorYmin /= attrs.input_height;
-                        priorXmax /= attrs.input_width;
-                        priorYmax /= attrs.input_height;
-                    }
-                    if (attrs.code_type == "caffe.PriorBoxParameter.CORNER")
-                    {
-                        if (attrs.variance_encoded_in_target)
-                        {
-                            decodeBbox.xmin = priorXmin + bbox.xmin;
-                            decodeBbox.ymin = priorYmin + bbox.ymin;
-                            decodeBbox.xmax = priorXmax + bbox.xmax;
-                            decodeBbox.ymax = priorYmax + bbox.ymax;
-                        }
-                        else
-                        {
-                            decodeBbox.xmin = priorXmin + priorVariances[0] * bbox.xmin;
-                            decodeBbox.ymin = priorYmin + priorVariances[1] * bbox.ymin;
-                            decodeBbox.xmax = priorXmax + priorVariances[2] * bbox.xmax;
-                            decodeBbox.ymax = priorYmax + priorVariances[3] * bbox.ymax;
-                        }
-                    }
-                    else if (attrs.code_type == "caffe.PriorBoxParameter.CENTER_SIZE")
-                    {
-                        dataType priorWidth = priorXmax - priorXmin;
-                        dataType priorHeight = priorYmax - priorYmin;
-                        dataType priorCenterX = (priorXmin + priorXmax) / 2;
-                        dataType priorCenterY = (priorYmin + priorYmax) / 2;
-                        dataType decodeBboxCenterX, decodeBboxCenterY;
-                        dataType decodeBboxWidth, decodeBboxHeight;
-                        if (attrs.variance_encoded_in_target)
-                        {
-                            decodeBboxCenterX = bbox.xmin * priorWidth + priorCenterX;
-                            decodeBboxCenterY = bbox.ymin * priorHeight + priorCenterY;
-                            decodeBboxWidth = std::exp(bbox.xmax) * priorWidth;
-                            decodeBboxHeight = std::exp(bbox.ymax) * priorHeight;
-                        }
-                        else
-                        {
-                            decodeBboxCenterX =
-                                priorVariances[0] * bbox.xmin * priorWidth + priorCenterX;
-                            decodeBboxCenterY =
-                                priorVariances[1] * bbox.ymin * priorHeight + priorCenterY;
-                            decodeBboxWidth = std::exp(priorVariances[2] * bbox.xmax) * priorWidth;
-                            decodeBboxHeight =
-                                std::exp(priorVariances[3] * bbox.ymax) * priorHeight;
-                        }
-                        decodeBbox.xmin = decodeBboxCenterX - decodeBboxWidth / 2;
-                        decodeBbox.ymin = decodeBboxCenterY - decodeBboxHeight / 2;
-                        decodeBbox.xmax = decodeBboxCenterX + decodeBboxWidth / 2;
-                        decodeBbox.ymax = decodeBboxCenterY + decodeBboxHeight / 2;
-                    }
-                    if (attrs.clip_before_nms)
-                    {
-                        decodeBbox.xmin =
-                            std::max<dataType>(0, std::min<dataType>(1, decodeBbox.xmin));
-                        decodeBbox.ymin =
-                            std::max<dataType>(0, std::min<dataType>(1, decodeBbox.ymin));
-                        decodeBbox.xmax =
-                            std::max<dataType>(0, std::min<dataType>(1, decodeBbox.xmax));
-                        decodeBbox.ymax =
-                            std::max<dataType>(0, std::min<dataType>(1, decodeBbox.ymax));
-                    }
-                    dataType bboxSize = BBoxSize(decodeBbox);
-                    decodeBbox.size = bboxSize;
-                }
-
-                void DecodeBBoxes(const std::vector<NormalizedBBox>& priorBboxes,
-                                  const std::vector<std::vector<dataType>>& priorVariances,
-                                  const std::vector<NormalizedBBox>& labelLocPreds,
-                                  std::vector<NormalizedBBox>& decodeBboxes)
-                {
-                    int numBboxes = priorBboxes.size();
-                    for (int i = 0; i < numBboxes; ++i)
-                    {
-                        NormalizedBBox decodeBbox;
-                        DecodeBBox(priorBboxes[i], priorVariances[i], labelLocPreds[i], decodeBbox);
-                        decodeBboxes.push_back(decodeBbox);
-                    }
-                }
-
-                void DecodeBBoxesAll(
-                    const std::vector<LabelBBox>& locPreds,
-                    const std::vector<std::vector<NormalizedBBox>>& priorBboxes,
-                    const std::vector<std::vector<std::vector<dataType>>>& priorVariances,
-                    std::vector<LabelBBox>& decodeBboxes)
-                {
-                    decodeBboxes.resize(numImages);
-                    for (int i = 0; i < numImages; ++i)
-                    {
-                        LabelBBox& decodeBboxesImage = decodeBboxes[i];
-                        const std::vector<NormalizedBBox>& currPrBbox = priorBboxes[i];
-                        const std::vector<std::vector<dataType>>& currPrVar = priorVariances[i];
-                        for (int c = 0; c < numLocClasses; ++c)
-                        {
-                            int label = attrs.share_location ? -1 : c;
-                            if (label == attrs.background_label_id)
-                            {
-                                continue;
-                            }
-                            const std::vector<NormalizedBBox>& labelLocPreds =
-                                locPreds[i].find(label)->second;
-                            DecodeBBoxes(
-                                currPrBbox, currPrVar, labelLocPreds, decodeBboxesImage[label]);
-                        }
-                    }
-                }
-
-                void CasRegDecodeBBoxesAll(
-                    const std::vector<LabelBBox>& locPreds,
-                    const std::vector<std::vector<NormalizedBBox>>& priorBboxes,
-                    const std::vector<std::vector<std::vector<dataType>>>& priorVariances,
-                    std::vector<LabelBBox>& decodeBboxes,
-                    const std::vector<LabelBBox>& armLocPreds)
-                {
-                    decodeBboxes.resize(numImages);
-                    for (int i = 0; i < numImages; ++i)
-                    {
-                        LabelBBox& decodeBboxesImage = decodeBboxes[i];
-                        const std::vector<NormalizedBBox>& currPrBbox = priorBboxes[i];
-                        const std::vector<std::vector<dataType>>& currPrVar = priorVariances[i];
-                        for (int c = 0; c < numLocClasses; ++c)
-                        {
-                            int label = attrs.share_location ? -1 : c;
-                            if (label == attrs.background_label_id)
-                            {
-                                continue;
-                            }
-                            const std::vector<NormalizedBBox>& labelArmLocPreds =
-                                armLocPreds[i].find(label)->second;
-                            std::vector<NormalizedBBox> decodePriorBboxes;
-                            DecodeBBoxes(
-                                currPrBbox, currPrVar, labelArmLocPreds, decodePriorBboxes);
-                            const std::vector<NormalizedBBox>& labelLocPreds =
-                                locPreds[i].find(label)->second;
-                            DecodeBBoxes(decodePriorBboxes,
-                                         currPrVar,
-                                         labelLocPreds,
-                                         decodeBboxesImage[label]);
-                        }
-                    }
-                }
-
-                template <typename T>
-                static bool SortScorePairDescend(const std::pair<dataType, T>& pair1,
-                                                 const std::pair<dataType, T>& pair2)
-                {
-                    return pair1.first > pair2.first;
-                }
-
-                void GetMaxScoreIndex(const std::vector<dataType>& scores,
-                                      const dataType threshold,
-                                      const int topK,
-                                      std::vector<std::pair<dataType, int>>& scoreIndexVec)
-                {
-                    for (int i = 0; i < scores.size(); ++i)
-                    {
-                        if (scores[i] > threshold)
-                        {
-                            scoreIndexVec.push_back(std::make_pair(scores[i], i));
-                        }
-                    }
-
-                    std::stable_sort(
-                        scoreIndexVec.begin(), scoreIndexVec.end(), SortScorePairDescend<int>);
-                    if (topK > -1 && topK < scoreIndexVec.size())
-                    {
-                        scoreIndexVec.resize(topK);
-                    }
-                }
-
-                void IntersectBBox(const NormalizedBBox& bbox1,
-                                   const NormalizedBBox& bbox2,
-                                   NormalizedBBox& intersectBbox)
-                {
-                    if (bbox2.xmin > bbox1.xmax || bbox2.xmax < bbox1.xmin ||
-                        bbox2.ymin > bbox1.ymax || bbox2.ymax < bbox1.ymin)
-                    {
-                        intersectBbox.xmin = 0;
-                        intersectBbox.ymin = 0;
-                        intersectBbox.xmax = 0;
-                        intersectBbox.ymax = 0;
-                    }
-                    else
-                    {
-                        intersectBbox.xmin = std::max<dataType>(bbox1.xmin, bbox2.xmin);
-                        intersectBbox.ymin = std::max<dataType>(bbox1.ymin, bbox2.ymin);
-                        intersectBbox.xmax = std::min<dataType>(bbox1.xmax, bbox2.xmax);
-                        intersectBbox.ymax = std::min<dataType>(bbox1.ymax, bbox2.ymax);
-                    }
-                }
-
-                dataType JaccardOverlap(const NormalizedBBox& bbox1, const NormalizedBBox& bbox2)
-                {
-                    NormalizedBBox intersectBbox;
-                    IntersectBBox(bbox1, bbox2, intersectBbox);
-                    dataType intersectWidth, intersectHeight;
-                    intersectWidth = intersectBbox.xmax - intersectBbox.xmin;
-                    intersectHeight = intersectBbox.ymax - intersectBbox.ymin;
-                    if (intersectWidth > 0 && intersectHeight > 0)
-                    {
-                        dataType intersect_size = intersectWidth * intersectHeight;
-                        dataType bbox1_size = BBoxSize(bbox1);
-                        dataType bbox2_size = BBoxSize(bbox2);
-
-                        return intersect_size / (bbox1_size + bbox2_size - intersect_size);
-                    }
-                    else
-                    {
-                        return 0.0f;
-                    }
-                }
-
-                void caffeNMS(const std::vector<NormalizedBBox>& bboxes,
-                              const std::vector<dataType>& scores,
-                              std::vector<int>& indices)
-                {
-                    std::vector<std::pair<dataType, int>> scoreIndexVec;
-                    GetMaxScoreIndex(
-                        scores, attrs.confidence_threshold, attrs.top_k, scoreIndexVec);
-                    while (scoreIndexVec.size() != 0)
-                    {
-                        const int idx = scoreIndexVec.front().second;
-                        bool keep = true;
-                        for (int k = 0; k < indices.size(); ++k)
-                        {
-                            const int kept_idx = indices[k];
-                            dataType overlap = JaccardOverlap(bboxes[idx], bboxes[kept_idx]);
-                            if (overlap > attrs.nms_threshold)
-                            {
-                                keep = false;
-                                break;
-                            }
-                        }
-                        if (keep)
-                        {
-                            indices.push_back(idx);
-                        }
-                        scoreIndexVec.erase(scoreIndexVec.begin());
-                    }
-                }
-
-                void mxNetNms(const LabelBBox& decodeBboxesImage,
-                              const std::map<int, std::vector<dataType>>& confScores,
-                              std::map<int, std::vector<int>>& indices)
-                {
-                    std::vector<std::pair<dataType, std::pair<int, int>>> scoreIndexPairs;
-                    for (int p = 0; p < numPriors; p++)
-                    {
-                        dataType conf = -1;
-                        int id = 0;
-                        for (int c = 1; c < attrs.num_classes; c++)
-                        {
-                            dataType temp = confScores.at(c)[p];
-                            if (temp > conf)
-                            {
-                                conf = temp;
-                                id = c;
-                            }
-                        }
-                        if (id > 0 && conf >= attrs.confidence_threshold)
-                        {
-                            scoreIndexPairs.push_back(std::make_pair(conf, std::make_pair(id, p)));
-                        }
-                    }
-                    std::sort(scoreIndexPairs.begin(),
-                              scoreIndexPairs.end(),
-                              SortScorePairDescend<std::pair<int, int>>);
-
-                    if (attrs.top_k != -1)
-                        if (scoreIndexPairs.size() > attrs.top_k)
-                            scoreIndexPairs.resize(attrs.top_k);
-
-                    while (scoreIndexPairs.size() != 0)
-                    {
-                        const int cls = scoreIndexPairs.front().second.first;
-                        const int prior = scoreIndexPairs.front().second.second;
-                        std::vector<int>& currInd = indices[cls];
-                        bool keep = true;
-                        for (int i = 0; i < currInd.size(); i++)
-                        {
-                            const int keptIdx = currInd[i];
-                            auto currBbox = attrs.share_location ? decodeBboxesImage.at(-1)
-                                                                 : decodeBboxesImage.at(cls);
-                            dataType overlap = JaccardOverlap(currBbox[prior], currBbox[keptIdx]);
-                            if (overlap > attrs.nms_threshold)
-                            {
-                                keep = false;
-                                break;
-                            }
-                        }
-                        if (keep)
-                        {
-                            currInd.push_back(prior);
-                        }
-                        scoreIndexPairs.erase(scoreIndexPairs.begin());
-                    }
-                }
-
-            public:
-                referenceDetectionOutput(const ngraph::op::DetectionOutputAttrs& _attrs,
-                                         const ngraph::Shape& locShape,
-                                         const ngraph::Shape& priorsShape)
-                    : attrs(_attrs)
-                {
-                    numImages = locShape[0];
-                    priorSize = _attrs.normalized ? 4 : 5;
-                    offset = _attrs.normalized ? 0 : 1;
-                    numPriors = priorsShape[2] / priorSize;
-                    numLocClasses =
-                        _attrs.share_location ? 1 : static_cast<size_t>(_attrs.num_classes);
-                }
-
-                void run(const dataType* _location,
-                         const dataType* _confidence,
-                         const dataType* _priors,
-                         const dataType* _armConfidence,
-                         const dataType* _armLocation,
-                         dataType* result)
-                {
-                    bool withAddBoxPred = _armConfidence != nullptr && _armLocation != nullptr;
-                    std::vector<LabelBBox> armLocPreds;
-                    if (withAddBoxPred)
-                    {
-                        GetLocPredictions(_armLocation, armLocPreds);
-                    }
-                    std::vector<LabelBBox> locPreds;
-                    GetLocPredictions(_location, locPreds);
-                    std::vector<std::map<int, std::vector<dataType>>> confPreds;
-                    if (withAddBoxPred)
-                    {
-                        OSGetConfidenceScores(_confidence, _armConfidence, confPreds);
-                    }
-                    else
-                    {
-                        GetConfidenceScores(_confidence, confPreds);
-                    }
-                    std::vector<std::vector<NormalizedBBox>> priorBboxes;
-                    std::vector<std::vector<std::vector<dataType>>> priorVariances;
-                    GetPriorBBoxes(_priors, priorBboxes, priorVariances);
-                    std::vector<LabelBBox> decodeBboxes;
-                    if (withAddBoxPred)
-                    {
-                        CasRegDecodeBBoxesAll(
-                            locPreds, priorBboxes, priorVariances, decodeBboxes, armLocPreds);
-                    }
-                    else
-                    {
-                        DecodeBBoxesAll(locPreds, priorBboxes, priorVariances, decodeBboxes);
-                    }
-
-                    int numKept = 0;
-                    std::vector<std::map<int, std::vector<int>>> allIndices;
-                    for (int i = 0; i < numImages; ++i)
-                    {
-                        const LabelBBox& decodeBboxesImage = decodeBboxes[i];
-                        const std::map<int, std::vector<dataType>>& confScores = confPreds[i];
-                        std::map<int, std::vector<int>> indices;
-                        int numDet = 0;
-                        if (!attrs.decrease_label_id)
-                        {
-                            // Caffe style
-                            for (int c = 0; c < attrs.num_classes; ++c)
-                            {
-                                if (c == attrs.background_label_id)
-                                {
-                                    continue;
-                                }
-                                const std::vector<dataType>& scores = confScores.find(c)->second;
-                                int label = attrs.share_location ? -1 : c;
-                                const std::vector<NormalizedBBox>& bboxes =
-                                    decodeBboxesImage.find(label)->second;
-                                caffeNMS(bboxes, scores, indices[c]);
-                                numDet += indices[c].size();
-                            }
-                        }
-                        else
-                        {
-                            // MXNet style
-                            mxNetNms(decodeBboxesImage, confScores, indices);
-                            for (auto it = indices.begin(); it != indices.end(); it++)
-                                numDet += it->second.size();
-                        }
-                        if (attrs.keep_top_k[0] > -1 && numDet > attrs.keep_top_k[0])
-                        {
-                            std::vector<std::pair<dataType, std::pair<int, int>>> scoreIndexPairs;
-                            for (auto it = indices.begin(); it != indices.end(); ++it)
-                            {
-                                int label = it->first;
-                                const std::vector<int>& labelIndices = it->second;
-                                const std::vector<dataType>& scores =
-                                    confScores.find(label)->second;
-                                for (int j = 0; j < labelIndices.size(); ++j)
-                                {
-                                    int idx = labelIndices[j];
-                                    scoreIndexPairs.push_back(
-                                        std::make_pair(scores[idx], std::make_pair(label, idx)));
-                                }
-                            }
-                            std::sort(scoreIndexPairs.begin(),
-                                      scoreIndexPairs.end(),
-                                      SortScorePairDescend<std::pair<int, int>>);
-                            scoreIndexPairs.resize(attrs.keep_top_k[0]);
-                            std::map<int, std::vector<int>> newIndices;
-                            for (int j = 0; j < scoreIndexPairs.size(); ++j)
-                            {
-                                int label = scoreIndexPairs[j].second.first;
-                                int idx = scoreIndexPairs[j].second.second;
-                                newIndices[label].push_back(idx);
-                            }
-                            allIndices.push_back(newIndices);
-                            numKept += attrs.top_k;
-                        }
-                        else
-                        {
-                            allIndices.push_back(indices);
-                            numKept += numDet;
-                        }
-                    }
-
-                    int count = 0;
-                    for (int i = 0; i < numImages; ++i)
-                    {
-                        const std::map<int, std::vector<dataType>>& confScores = confPreds[i];
-                        const LabelBBox& decodeBboxesImage = decodeBboxes[i];
-                        for (auto it = allIndices[i].begin(); it != allIndices[i].end(); ++it)
-                        {
-                            int label = it->first;
-                            const std::vector<dataType>& scores = confScores.find(label)->second;
-                            int loc_label = attrs.share_location ? -1 : label;
-                            const std::vector<NormalizedBBox>& bboxes =
-                                decodeBboxesImage.find(loc_label)->second;
-                            std::vector<int>& indices = it->second;
-                            for (int j = 0; j < indices.size(); ++j)
-                            {
-                                int idx = indices[j];
-                                result[count * 7 + 0] = i;
-                                result[count * 7 + 1] =
-                                    attrs.decrease_label_id ? (label - 1) : label;
-                                result[count * 7 + 2] = scores[idx];
-                                const NormalizedBBox& bbox = bboxes[idx];
-
-                                dataType xmin = bbox.xmin;
-                                dataType ymin = bbox.ymin;
-                                dataType xmax = bbox.xmax;
-                                dataType ymax = bbox.ymax;
-
-                                if (attrs.clip_after_nms)
-                                {
-                                    xmin = std::max<dataType>(0, std::min<dataType>(1, xmin));
-                                    ymin = std::max<dataType>(0, std::min<dataType>(1, ymin));
-                                    xmax = std::max<dataType>(0, std::min<dataType>(1, xmax));
-                                    ymax = std::max<dataType>(0, std::min<dataType>(1, ymax));
-                                }
-
-                                result[count * 7 + 3] = xmin;
-                                result[count * 7 + 4] = ymin;
-                                result[count * 7 + 5] = xmax;
-                                result[count * 7 + 6] = ymax;
-                                ++count;
-                            }
-                        }
-                    }
-                    if (count < numImages * attrs.keep_top_k[0])
-                    {
-                        result[count * 7 + 0] = -1;
-                    }
-                }
-            };
-        } // namespace reference
-    }     // namespace runtime
-} // namespace ngraph
diff --git a/ngraph/test/runtime/interpreter/reference/scatter_nd_update.hpp b/ngraph/test/runtime/interpreter/reference/scatter_nd_update.hpp
deleted file mode 100644 (file)
index 37d3b5a..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (C) 2020 Intel Corporation
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#pragma once
-
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/shape.hpp"
-
-using namespace ngraph;
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename dataType, typename indicesType>
-            void scatterNdUpdate(const dataType* inputData,
-                                 const indicesType* indices,
-                                 const dataType* updates,
-                                 dataType* outBuf,
-                                 const Shape& dataShape,
-                                 const Shape& indicesShape,
-                                 const Shape& updatesShape)
-            {
-                size_t numSlices = 1;
-                size_t sliceSize = 1;
-                for (size_t i = 0; i < indicesShape.size() - 1; i++)
-                {
-                    numSlices *= indicesShape[i];
-                }
-                for (size_t i = indicesShape.size() - 1; i < updatesShape.size(); i++)
-                {
-                    sliceSize *= updatesShape[i];
-                }
-
-                const size_t k = indicesShape.back();
-                std::memcpy(outBuf, inputData, sizeof(dataType) * shape_size(dataShape));
-                CoordinateTransform dataTransform{dataShape};
-
-                for (size_t i = 0; i < numSlices; i++)
-                {
-                    Coordinate coord;
-                    for (size_t j = 0; j < k; j++)
-                    {
-                        coord.push_back(indices[i * k + j]);
-                    }
-                    for (size_t j = k; j < dataShape.size(); j++)
-                    {
-                        coord.push_back(0);
-                    }
-
-                    const size_t startDataIdx = dataTransform.index(coord);
-                    for (size_t j = 0; j < sliceSize; j++)
-                    {
-                        outBuf[startDataIdx + j] = updates[i * sliceSize + j];
-                    }
-                }
-            }
-        } // namespace reference
-    }     // namespace runtime
-} // namespace ngraph
diff --git a/ngraph/test/runtime/interpreter/reference/scatter_update.hpp b/ngraph/test/runtime/interpreter/reference/scatter_update.hpp
deleted file mode 100644 (file)
index e3cae8c..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (C) 2020 Intel Corporation
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#pragma once
-
-#include <string>
-#include "ngraph/coordinate_transform.hpp"
-#include "ngraph/shape.hpp"
-
-using namespace ngraph;
-
-namespace ngraph
-{
-    namespace runtime
-    {
-        namespace reference
-        {
-            template <typename dataType, typename indicesType, typename axisType>
-            void scatterUpdate(const dataType* inputData,
-                               const indicesType* indices,
-                               const dataType* updates,
-                               const axisType* _axis,
-                               dataType* outBuf,
-                               const Shape& dataShape,
-                               const Shape& indicesShape,
-                               const Shape& updatesShape)
-            {
-                int rank = static_cast<int>(dataShape.size());
-                if (_axis[0] < -rank || _axis[0] > rank - 1)
-                {
-                    std::string error =
-                        std::string("ScatterUpdate layer has out of bounds axis value: ") +
-                        std::to_string(_axis[0]);
-                    throw ngraph_error(error);
-                }
-                size_t axis = _axis[0] < 0 ? _axis[0] + rank : _axis[0];
-                CoordinateTransform indicesTransform{indicesShape};
-
-                Shape dataShapeIter = dataShape;
-                dataShapeIter.erase(dataShapeIter.begin() + axis);
-                CoordinateTransform dataTransfIter{dataShapeIter};
-
-                CoordinateTransform updateTransform{updatesShape};
-                CoordinateTransform dataTransform{dataShape};
-
-                std::memcpy(outBuf, inputData, sizeof(dataType) * shape_size(dataShape));
-
-                for (const Coordinate& indicesCoordIt : indicesTransform)
-                {
-                    const size_t indicesIdx = indicesTransform.index(indicesCoordIt);
-
-                    if (indices[indicesIdx] < 0)
-                    {
-                        std::string error =
-                            std::string("ScatterUpdate layer has negative index value: ") +
-                            std::to_string(indices[indicesIdx]);
-                        throw ngraph_error(error);
-                    }
-                    const size_t idx = static_cast<size_t>(indices[indicesIdx]);
-                    if (dataShape[axis] <= idx)
-                    {
-                        std::string error =
-                            std::string("ScatterUpdate layer has out of bounds coordinate: ") +
-                            std::to_string(idx) + " on 'data' input on " + std::to_string(axis) +
-                            "th axis";
-                        throw ngraph_error(error);
-                    }
-
-                    for (const Coordinate& dataCoordIt : dataTransfIter)
-                    {
-                        Coordinate dataCoord = dataCoordIt;
-                        dataCoord.insert(dataCoord.begin() + axis, idx);
-                        const size_t startIndices = dataTransform.index(dataCoord);
-
-                        auto updCoord = dataCoordIt;
-                        updCoord.insert(
-                            updCoord.begin() + axis, indicesCoordIt.begin(), indicesCoordIt.end());
-                        const size_t startUpd = updateTransform.index(updCoord);
-                        outBuf[startIndices] = updates[startUpd];
-                    }
-                }
-            }
-        } // namespace reference
-    }     // namespace runtime
-} // namespace ngraph
index 2568364530097f0b6497e0da7e07b446d2c7278d..cf32e5880bf6b39865a07c746186a7b4ac41120b 100644 (file)
 
 cmake_minimum_required(VERSION 3.10)
 
-file(REMOVE "${CMAKE_BINARY_DIR}/openvino_targets_developer.cmake")
-
-unset(OpenVINODeveloperPackageTargets CACHE)
-
-function(openvino_developer_export_targets)
-    set(OpenVINODeveloperPackageTargets "${OpenVINODeveloperPackageTargets};${ARGV}")
-
-    # to allow exporting of aliased targets with the original names
-    foreach(target_name ${OpenVINODeveloperPackageTargets})
-        if(TARGET "${target_name}")
-            get_target_property(original_name ${target_name} ALIASED_TARGET)
-            if(TARGET "${original_name}")
-                message(STATUS "The name ${target_name} is an ALIAS for ${original_name}. "
-                        "It will be exported to the InferenceEngineDeveloperPackage with the original name.")
-                list(REMOVE_ITEM OpenVINODeveloperPackageTargets ${target_name})
-                list(APPEND OpenVINODeveloperPackageTargets ${original_name})
-            endif()
-        endif()
-    endforeach()
-
-    list(REMOVE_DUPLICATES OpenVINODeveloperPackageTargets)
-    set(OpenVINODeveloperPackageTargets "${OpenVINODeveloperPackageTargets}" CACHE INTERNAL
-        "Paths to extra Inference Engine plugins" FORCE)
-endfunction()
-
 add_subdirectory(itt)
 
 openvino_developer_export_targets(openvino::itt)