diff --git a/.circleci/config.yml b/.circleci/config.yml index 2b6a32f7a..7266cf4ad 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -408,6 +408,27 @@ jobs: path: tests.unit.plugins.controls - store_artifacts: path: tests.unit.plugins.controls + tests.unit.plugins.dist_keras_support: + <<: *docker_config + working_directory: /phylanx/build + steps: + - <<: *attach_phylanx_tree + - <<: *avoid_cmake_rerun + - <<: *justify_building_all + - run: + name: Justify build + command: ninja -n -d explain tests.unit.plugins.dist_keras_support + - run: + name: Build DistKerasSupport primitive plugin unit tests + command: cmake --build . -- -j1 tests.unit.plugins.dist_keras_support + - run: + name: Run DistKerasSupport primitive plugin unit tests + command: ctest -T test --no-compress-output --output-on-failure -R tests.unit.plugins.dist_keras_support + - <<: *convert_xml + - store_test_results: + path: tests.unit.plugins.dist_keras_support + - store_artifacts: + path: tests.unit.plugins.dist_keras_support tests.unit.plugins.dist_matrixops: <<: *docker_config working_directory: /phylanx/build @@ -678,6 +699,9 @@ workflows: - tests.unit.plugins.controls: requires: - build + - tests.unit.plugins.dist_keras_support: + requires: + - build - tests.unit.plugins.dist_matrixops: requires: - build @@ -715,6 +739,7 @@ workflows: - tests.unit.plugins.arithmetics - tests.unit.plugins.booleans - tests.unit.plugins.controls + - tests.unit.plugins.dist_keras_support - tests.unit.plugins.dist_matrixops - tests.unit.plugins.fileio_solvers - tests.unit.plugins.keras_support diff --git a/CMakeLists.txt b/CMakeLists.txt index ad712b2c6..2649fd622 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,12 @@ endif() phylanx_info("CMake version: " ${CMAKE_VERSION}) phylanx_info("Phylanx version: " ${PHYLANX_VERSION}) +# ############################################################################## +# C++ feature tests +# ############################################################################## +include(Phylanx_PerformCxxFeatureTests) +phylanx_perform_cxx_feature_tests() + ################################################################################ # Locate HPX as we need to ensure to use at least the same C++ dialect as HPX uses phylanx_setup_hpx() diff --git a/cmake/Phylanx_AddConfigTests.cmake b/cmake/Phylanx_AddConfigTests.cmake new file mode 100644 index 000000000..e13ccb61f --- /dev/null +++ b/cmake/Phylanx_AddConfigTests.cmake @@ -0,0 +1,246 @@ +# Copyright (c) 2011 Bryce Lelbach +# Copyright (c) 2014 Thomas Heller +# Copyright (c) 2020 Hartmut Kaiser +# +# SPDX-License-Identifier: BSL-1.0 +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +set(PHYLANX_ADDCONFIGTEST_LOADED TRUE) + +include(CheckLibraryExists) + +function(add_phylanx_config_test variable) + set(options FILE EXECUTE) + set(one_value_args SOURCE ROOT CMAKECXXFEATURE) + set(multi_value_args + INCLUDE_DIRECTORIES + LINK_DIRECTORIES + COMPILE_DEFINITIONS + LIBRARIES + ARGS + DEFINITIONS + REQUIRED + ) + cmake_parse_arguments( + ${variable} "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN} + ) + + set(_run_msg) + # Check CMake feature tests if the user didn't override the value of this + # variable: + if(NOT DEFINED ${variable}) + if(${variable}_CMAKECXXFEATURE) + # We don't have to run our own feature test if there is a corresponding + # cmake feature test and cmake reports the feature is supported on this + # platform. + list(FIND CMAKE_CXX_COMPILE_FEATURES ${${variable}_CMAKECXXFEATURE} __pos) + if(NOT ${__pos} EQUAL -1) + set(${variable} + TRUE + CACHE INTERNAL "" + ) + set(_run_msg "Success (cmake feature test)") + endif() + endif() + endif() + + if(NOT DEFINED ${variable}) + file(MAKE_DIRECTORY + "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/config_tests" + ) + + string(TOLOWER "${variable}" variable_lc) + if(${variable}_FILE) + if(${variable}_ROOT) + set(test_source "${${variable}_ROOT}/share/phylanx/${${variable}_SOURCE}") + else() + set(test_source "${PROJECT_SOURCE_DIR}/${${variable}_SOURCE}") + endif() + else() + set(test_source + "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/config_tests/${variable_lc}.cpp" + ) + file(WRITE "${test_source}" "${${variable}_SOURCE}\n") + endif() + set(test_binary + ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/config_tests/${variable_lc} + ) + + get_directory_property(CONFIG_TEST_INCLUDE_DIRS INCLUDE_DIRECTORIES) + get_directory_property(CONFIG_TEST_LINK_DIRS LINK_DIRECTORIES) + set(COMPILE_DEFINITIONS_TMP) + set(CONFIG_TEST_COMPILE_DEFINITIONS) + get_directory_property(COMPILE_DEFINITIONS_TMP COMPILE_DEFINITIONS) + foreach(def IN LISTS COMPILE_DEFINITIONS_TMP + ${variable}_COMPILE_DEFINITIONS + ) + set(CONFIG_TEST_COMPILE_DEFINITIONS + "${CONFIG_TEST_COMPILE_DEFINITIONS} -D${def}" + ) + endforeach() + get_property( + PHYLANX_TARGET_COMPILE_OPTIONS_PUBLIC_VAR GLOBAL + PROPERTY phylanx_TARGET_COMPILE_OPTIONS_PUBLIC + ) + get_property( + PHYLANX_TARGET_COMPILE_OPTIONS_PRIVATE_VAR GLOBAL + PROPERTY phylanx_TARGET_COMPILE_OPTIONS_PRIVATE + ) + set(PHYLANX_TARGET_COMPILE_OPTIONS_VAR + ${PHYLANX_TARGET_COMPILE_OPTIONS_PUBLIC_VAR} + ${PHYLANX_TARGET_COMPILE_OPTIONS_PRIVATE_VAR} + ) + foreach(_flag ${PHYLANX_TARGET_COMPILE_OPTIONS_VAR}) + if(NOT "${_flag}" MATCHES "^\\$.*") + set(CONFIG_TEST_COMPILE_DEFINITIONS + "${CONFIG_TEST_COMPILE_DEFINITIONS} ${_flag}" + ) + endif() + endforeach() + + set(CONFIG_TEST_INCLUDE_DIRS ${CONFIG_TEST_INCLUDE_DIRS} + ${${variable}_INCLUDE_DIRECTORIES} + ) + set(CONFIG_TEST_LINK_DIRS ${CONFIG_TEST_LINK_DIRS} + ${${variable}_LINK_DIRECTORIES} + ) + + if(${variable}_EXECUTE) + if(NOT CMAKE_CROSSCOMPILING) + # cmake-format: off + try_run( + ${variable}_RUN_RESULT ${variable}_COMPILE_RESULT + ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/config_tests + ${test_source} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${CONFIG_TEST_INCLUDE_DIRS}" + "-DLINK_DIRECTORIES=${CONFIG_TEST_LINK_DIRS}" + "-DLINK_LIBRARIES=${CONFIG_TEST_LINK_LIBRARIES}" + "-DCOMPILE_DEFINITIONS=${CONFIG_TEST_COMPILE_DEFINITIONS}" + CXX_STANDARD ${phylanx_CXX_STANDARD} + CXX_STANDARD_REQUIRED ON + CXX_EXTENSIONS FALSE + RUN_OUTPUT_VARIABLE ${variable}_OUTPUT + ARGS ${${variable}_ARGS} + ) + # cmake-format: on + if(${variable}_COMPILE_RESULT AND NOT ${variable}_RUN_RESULT) + set(${variable}_RESULT TRUE) + else() + set(${variable}_RESULT FALSE) + endif() + else() + set(${variable}_RESULT FALSE) + endif() + else() + # cmake-format: off + try_compile( + ${variable}_RESULT + ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/config_tests + ${test_source} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${CONFIG_TEST_INCLUDE_DIRS}" + "-DLINK_DIRECTORIES=${CONFIG_TEST_LINK_DIRS}" + "-DLINK_LIBRARIES=${CONFIG_TEST_LINK_LIBRARIES}" + "-DCOMPILE_DEFINITIONS=${CONFIG_TEST_COMPILE_DEFINITIONS}" + OUTPUT_VARIABLE ${variable}_OUTPUT + CXX_STANDARD ${phylanx_CXX_STANDARD} + CXX_STANDARD_REQUIRED ON + CXX_EXTENSIONS FALSE + COPY_FILE ${test_binary} + ) + # cmake-format: on + phylanx_debug("Compile test: ${variable}") + phylanx_debug("Compilation output: ${${variable}_OUTPUT}") + endif() + + set(_run_msg "Success") + else() + set(${variable}_RESULT ${${variable}}) + if(NOT _run_msg) + set(_run_msg "pre-set to ${${variable}}") + endif() + endif() + + string(TOUPPER "${variable}" variable_uc) + set(_msg "Performing Test ${variable_uc}") + + if(${variable}_RESULT) + set(_msg "${_msg} - ${_run_msg}") + else() + set(_msg "${_msg} - Failed") + endif() + + set(${variable} + ${${variable}_RESULT} + CACHE INTERNAL "" + ) + phylanx_info(${_msg}) + + if(${variable}_RESULT) + foreach(definition ${${variable}_DEFINITIONS}) + phylanx_add_config_define(${definition}) + endforeach() + elseif(${variable}_REQUIRED) + phylanx_warn("Test failed, detailed output:\n\n${${variable}_OUTPUT}") + phylanx_error(${${variable}_REQUIRED}) + endif() +endfunction() + +# Makes it possible to provide a feature test that is able to test the compiler +# to build parts of phylanx directly when the given definition is defined. +function(add_phylanx_in_framework_config_test variable) + # Generate the config only if the test wasn't executed yet + if(NOT DEFINED ${variable}) + # Location to generate the config headers to + set(${variable}_GENERATED_DIR + "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/config_tests/header-${variable}" + ) + generate_config_defines_header(${${variable}_GENERATED_DIR}) + endif() + + set(options) + set(one_value_args) + set(multi_value_args DEFINITIONS INCLUDE_DIRECTORIES COMPILE_DEFINITIONS) + cmake_parse_arguments( + ${variable} "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN} + ) + + # We call the generic feature test method while modifying some existing parsed + # arguments in order to alter the INCLUDE_DIRECTORIES and the + # COMPILE_DEFINITIONS. It's important here not to link the config test against + # an executable because otherwise this will result in unresolved references to + # the phylanx library, that wasn't built as of now. + add_phylanx_config_test( + ${variable} ${${variable}_UNPARSED_ARGUMENTS} + DEFINITIONS ${${variable}_DEFINITIONS} + COMPILE_DEFINITIONS + ${${variable}_COMPILE_DEFINITIONS} + # We add the definitions we test to the existing compile definitions. + ${${variable}_DEFINITIONS} + # Add PHYLANX_NO_VERSION_CHECK to make header only parts of phylanx available + # without requiring to link against the phylanx sources. We can remove this + # workaround as soon as CMake 3.6 is the minimal required version and + # supports: CMAKE_TRY_COMPILE_TARGET_TYPE = STATIC_LIBRARY when using + # try_compile to not to throw errors on unresolved symbols. + PHYLANX_NO_VERSION_CHECK + INCLUDE_DIRECTORIES + ${${variable}_INCLUDE_DIRECTORIES} + # We add the generated headers to the include dirs + ${${variable}_GENERATED_DIR} + ) + + if(DEFINED ${variable}_GENERATED_DIR) + # Cleanup the generated header + file(REMOVE_RECURSE "${${variable}_GENERATED_DIR}") + endif() +endfunction() + +# ############################################################################## +function(phylanx_check_for_cxx17_shared_ptr_array) + add_phylanx_config_test( + PHYLANX_WITH_CXX17_SHARED_PTR_ARRAY + SOURCE cmake/tests/cxx17_shared_ptr_array.cpp FILE ${ARGN} + ) +endfunction() diff --git a/cmake/Phylanx_PerformCxxFeatureTests.cmake b/cmake/Phylanx_PerformCxxFeatureTests.cmake new file mode 100644 index 000000000..cb9ec9652 --- /dev/null +++ b/cmake/Phylanx_PerformCxxFeatureTests.cmake @@ -0,0 +1,16 @@ +# Copyright (c) 2020 Hartmut Kaiser +# +# SPDX-License-Identifier: BSL-1.0 +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +include(Phylanx_AddConfigTests) + +# ############################################################################## +# C++ feature tests +# ############################################################################## +function(phylanx_perform_cxx_feature_tests) + phylanx_check_for_cxx17_shared_ptr_array( + DEFINITIONS PHYLANX_HAVE_CXX17_SHARED_PTR_ARRAY + ) +endfunction() diff --git a/cmake/templates/setup.py.in b/cmake/templates/setup.py.in index 5290f4df8..71365557c 100644 --- a/cmake/templates/setup.py.in +++ b/cmake/templates/setup.py.in @@ -55,6 +55,8 @@ class CopyBuildExt(build_ext): print("copying {} -> {}".format(source_path, extdir)) shutil.copyfile(source_path, os.path.join(extdir, filename)) +with open(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))+'/README.md') as f: + README = f.read() setup_args = { 'name': 'phylanx', @@ -63,7 +65,8 @@ setup_args = { 'author_email': 'phylanx@stellar-group.org', 'url': 'phylanx.stellar-group.org', 'description': 'A Python wrapper for the Phylanx execution engine', - 'long_description': '', + 'long_description': README, + 'long_description_content_type':'text/markdown', 'packages': ['phylanx', 'phylanx.ast', 'phylanx.execution_tree', 'phylanx.core', 'phylanx.util', 'phylanx.plugins'], 'package_dir': {'': '@PYTHON_PACKAGE_BASE_DIR@'}, @@ -72,6 +75,7 @@ setup_args = { '@PYTHON_PACKAGE_BASE_DIR@', '@PYTHON_BINARY_BASE_DIR@') ], + 'install_requires': ['numpy'], 'cmdclass': { 'build_ext': CopyBuildExt }, diff --git a/cmake/tests/cxx17_shared_ptr_array.cpp b/cmake/tests/cxx17_shared_ptr_array.cpp new file mode 100644 index 000000000..525ea97e9 --- /dev/null +++ b/cmake/tests/cxx17_shared_ptr_array.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2020 Hartmut Kaiser +// +// SPDX-License-Identifier: BSL-1.0 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +int main() +{ + std::shared_ptr p (new int[10]); + + return 0; +} diff --git a/examples/algorithms/kmeans/kmeans_fix_points.cpp b/examples/algorithms/kmeans/kmeans_fix_points.cpp index 8fe64ee49..d21e0aaf0 100644 --- a/examples/algorithms/kmeans/kmeans_fix_points.cpp +++ b/examples/algorithms/kmeans/kmeans_fix_points.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2018 Parsa Amini -// Copyright (c) 2018-2010 Hartmut Kaiser +// Copyright (c) 2018-2020 Hartmut Kaiser // Copyright (c) 2020 Bita Hasheminezhad // // Distributed under the Boost Software License, Version 1.0.0. (See accompanying diff --git a/examples/algorithms/kmeans/kmeans_fix_points_3d.cpp b/examples/algorithms/kmeans/kmeans_fix_points_3d.cpp index 1874b541f..8c461765c 100644 --- a/examples/algorithms/kmeans/kmeans_fix_points_3d.cpp +++ b/examples/algorithms/kmeans/kmeans_fix_points_3d.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2018 Parsa Amini -// Copyright (c) 2018-2010 Hartmut Kaiser +// Copyright (c) 2018-2020 Hartmut Kaiser // Copyright (c) 2020 Bita Hasheminezhad // // Distributed under the Boost Software License, Version 1.0.0. (See accompanying diff --git a/examples/interpreter/physl.cpp b/examples/interpreter/physl.cpp index f8bd1ab9d..71d343fa6 100644 --- a/examples/interpreter/physl.cpp +++ b/examples/interpreter/physl.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include diff --git a/phylanx/execution_tree/annotation.hpp b/phylanx/execution_tree/annotation.hpp index fd9b74c8e..355e5a4bf 100644 --- a/phylanx/execution_tree/annotation.hpp +++ b/phylanx/execution_tree/annotation.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Hartmut Kaiser +// Copyright (c) 2019-2020 Hartmut Kaiser // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -142,6 +142,7 @@ namespace phylanx { namespace execution_tree { explicit annotation_wrapper(primitive_argument_type const& op); annotation_wrapper(primitive_argument_type const& op1, primitive_argument_type const& op2); + explicit annotation_wrapper(primitive_arguments_type const& ops); primitive_argument_type propagate(primitive_argument_type&& val, std::string const& name, std::string const& codename); diff --git a/phylanx/execution_tree/compiler/actors.hpp b/phylanx/execution_tree/compiler/actors.hpp index eb627a825..5c7deb6f4 100644 --- a/phylanx/execution_tree/compiler/actors.hpp +++ b/phylanx/execution_tree/compiler/actors.hpp @@ -15,6 +15,10 @@ #include #include +#if !defined(PHYLANX_HAVE_CXX17_SHARED_PTR_ARRAY) +#include +#endif + #include #include #include @@ -357,12 +361,21 @@ namespace phylanx { namespace execution_tree { namespace compiler name_ = std::move(name); } +#if !defined(PHYLANX_HAVE_CXX17_SHARED_PTR_ARRAY) + void set_named_args(boost::shared_array named_args, + std::size_t num_named_args) + { + num_named_args_ = num_named_args; + named_args_ = std::move(named_args); + } +#else void set_named_args(std::shared_ptr named_args, std::size_t num_named_args) { num_named_args_ = num_named_args; named_args_ = std::move(named_args); } +#endif //////////////////////////////////////////////////////////////////////// topology get_expression_topology() const @@ -407,7 +420,11 @@ namespace phylanx { namespace execution_tree { namespace compiler primitive_argument_type arg_; std::string name_; std::size_t num_named_args_; +#if !defined(PHYLANX_HAVE_CXX17_SHARED_PTR_ARRAY) + boost::shared_array named_args_; +#else std::shared_ptr named_args_; +#endif private: friend class hpx::serialization::access; diff --git a/phylanx/execution_tree/localities_annotation.hpp b/phylanx/execution_tree/localities_annotation.hpp index 044f8b956..725a7d222 100644 --- a/phylanx/execution_tree/localities_annotation.hpp +++ b/phylanx/execution_tree/localities_annotation.hpp @@ -64,6 +64,8 @@ namespace phylanx { namespace execution_tree // annotation as_annotation( // std::string const& name, std::string const& codename) const; + bool is_page_tiled( + std::string const& name, std::string const& codename) const; bool is_row_tiled( std::string const& name, std::string const& codename) const; bool is_column_tiled( diff --git a/phylanx/execution_tree/primitives.hpp b/phylanx/execution_tree/primitives.hpp index a85efe49c..2d1101f60 100644 --- a/phylanx/execution_tree/primitives.hpp +++ b/phylanx/execution_tree/primitives.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2019 Hartmut Kaiser +// Copyright (c) 2017-2020 Hartmut Kaiser // 2018 R. Tohid // // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/phylanx/execution_tree/primitives/timer.hpp b/phylanx/execution_tree/primitives/timer.hpp new file mode 100644 index 000000000..585273d03 --- /dev/null +++ b/phylanx/execution_tree/primitives/timer.hpp @@ -0,0 +1,46 @@ +// Copyright (c) 2020 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(PHYLANX_PRIMITIVES_TIMER_JUL_17_2020_0439PM) +#define PHYLANX_PRIMITIVES_TIMER_JUL_17_2020_0439PM + +#include +#include +#include + +#include + +#include +#include +#include + +namespace phylanx { namespace execution_tree { namespace primitives { + + class timer + : public primitive_component_base + , public std::enable_shared_from_this + { + protected: + hpx::future eval( + primitive_arguments_type const& operands, + primitive_arguments_type const& args, + eval_context ctx) const override; + + public: + static match_pattern_type const match_data; + + timer() = default; + + timer(primitive_arguments_type&& operands, std::string const& name, + std::string const& codename); + }; + + PHYLANX_EXPORT primitive create_timer(hpx::id_type const& locality, + primitive_arguments_type&& operands, std::string const& name = "", + std::string const& codename = ""); + +}}} // namespace phylanx::execution_tree::primitives + +#endif diff --git a/phylanx/include/plugins.hpp b/phylanx/include/plugins.hpp index 66b62fd00..9b6da0ec2 100644 --- a/phylanx/include/plugins.hpp +++ b/phylanx/include/plugins.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/phylanx/plugins/arithmetics/arithmetics.hpp b/phylanx/plugins/arithmetics/arithmetics.hpp index 22499ae28..948547e29 100644 --- a/phylanx/plugins/arithmetics/arithmetics.hpp +++ b/phylanx/plugins/arithmetics/arithmetics.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/phylanx/plugins/arithmetics/mod_operation.hpp b/phylanx/plugins/arithmetics/mod_operation.hpp new file mode 100644 index 000000000..42fff458a --- /dev/null +++ b/phylanx/plugins/arithmetics/mod_operation.hpp @@ -0,0 +1,60 @@ +// Copyright (c) 2017-2018 Hartmut Kaiser +// Copyright (c) 2018 Shahrzad Shirzad +// Copyright (c) 2018 Parsa Amini +// Copyright (c) 2020 Steven R. Brandt +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(PHYLANX_PRIMITIVES_MOD_OPERATION_JUN_18_2020_1202PM) +#define PHYLANX_PRIMITIVES_MOD_OPERATION_JUN_18_2020_1202PM + +#include + +#include + +#include +#include +#include + +namespace phylanx { namespace execution_tree { namespace primitives +{ + /////////////////////////////////////////////////////////////////////////// + namespace detail + { + struct mod_op; + } + + /////////////////////////////////////////////////////////////////////////// + class mod_operation + : public primitive_component_base + , public std::enable_shared_from_this + { + using base_type = primitive_component_base; + + protected: + hpx::future eval( + primitive_arguments_type const& operands, + primitive_arguments_type const& args, eval_context ctx) const; + + public: + static match_pattern_type const match_data; + + mod_operation() = default; + + mod_operation( + primitive_arguments_type && operands, + std::string const& name, std::string const& codename); + }; + + /////////////////////////////////////////////////////////////////////////// + inline primitive create_mod_operation(hpx::id_type const& locality, + primitive_arguments_type&& operands, + std::string const& name = "", std::string const& codename = "") + { + return create_primitive_component( + locality, "__mod", std::move(operands), name, codename); + } +}}} + +#endif diff --git a/phylanx/plugins/arithmetics/numeric_impl.hpp b/phylanx/plugins/arithmetics/numeric_impl.hpp index d9c366cad..dc43e2968 100644 --- a/phylanx/plugins/arithmetics/numeric_impl.hpp +++ b/phylanx/plugins/arithmetics/numeric_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2018 Hartmut Kaiser +// Copyright (c) 2017-2020 Hartmut Kaiser // Copyright (c) 2018 Shahrzad Shirzad // Copyright (c) 2018 Parsa Amini // @@ -540,7 +540,10 @@ namespace phylanx { namespace execution_tree { namespace primitives [this_ = std::move(this_)](primitive_arguments_type&& ops) -> primitive_argument_type { - return this_->handle_numeric_operands(std::move(ops)); + annotation_wrapper wrap(ops); + return wrap.propagate( + this_->handle_numeric_operands(std::move(ops)), + this_->name_, this_->codename_); }), detail::map_operands( operands, functional::value_operand{}, args, diff --git a/phylanx/plugins/booleans/comparison_impl.hpp b/phylanx/plugins/booleans/comparison_impl.hpp index fa00c8f82..cd3f8e015 100644 --- a/phylanx/plugins/booleans/comparison_impl.hpp +++ b/phylanx/plugins/booleans/comparison_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2019 Hartmut Kaiser +// Copyright (c) 2017-2020 Hartmut Kaiser // Copyright (c) 2018 Shahrzad Shirzad // Copyright (c) 2018 Tianyi Zhang // @@ -9,6 +9,7 @@ #define PHYLANX_PRIMITIVES_COMPARISON_IMPL_SEP_02_2018_0443PM #include +#include #include #include #include @@ -626,16 +627,23 @@ namespace phylanx { namespace execution_tree { namespace primitives bool propagate_type = (operands.size() == 3 && phylanx::execution_tree::extract_scalar_boolean_value(operands[2])); - return hpx::dataflow(hpx::launch::sync, hpx::util::unwrapping( + return hpx::dataflow(hpx::launch::sync, [this_ = std::move(this_), propagate_type]( - primitive_argument_type&& op1, - primitive_argument_type&& op2) + hpx::future&& lhs, + hpx::future&& rhs) -> primitive_argument_type { + auto&& op1 = lhs.get(); + auto&& op2 = rhs.get(); + + annotation_wrapper wrap(op1, op2); + return primitive_argument_type( - util::visit(visit_comparison{*this_, propagate_type}, - std::move(op1.variant()), std::move(op2.variant()))); - }), + wrap.propagate(util::visit( + visit_comparison{*this_, propagate_type}, + std::move(op1.variant()), std::move(op2.variant())), + this_->name_, this_->codename_)); + }, value_operand(operands[0], args, name_, codename_, ctx), value_operand(operands[1], args, name_, codename_, ctx)); } diff --git a/phylanx/plugins/booleans/logical_operation_impl.hpp b/phylanx/plugins/booleans/logical_operation_impl.hpp index 9fd3c6ab9..7a462fd88 100644 --- a/phylanx/plugins/booleans/logical_operation_impl.hpp +++ b/phylanx/plugins/booleans/logical_operation_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2019 Hartmut Kaiser +// Copyright (c) 2017-2020 Hartmut Kaiser // Copyright (c) 2018 Shahrzad Shirzad // Copyright (c) 2018 Tiany Zhang // @@ -9,6 +9,7 @@ #define PHYLANX_PRIMITIVES_LOGICAL_OPERATION_IMPL_SEP_02_2018_0703PM #include +#include #include #include #include @@ -499,15 +500,22 @@ namespace phylanx { namespace execution_tree { namespace primitives } auto this_ = this->shared_from_this(); - return hpx::dataflow(hpx::launch::sync, hpx::util::unwrapping( - [this_ = std::move(this_)](primitive_argument_type&& op1, - primitive_argument_type&& op2) + return hpx::dataflow(hpx::launch::sync, + [this_ = std::move(this_)]( + hpx::future&& lhs, + hpx::future&& rhs) -> primitive_argument_type { + auto&& op1 = lhs.get(); + auto&& op2 = rhs.get(); + + annotation_wrapper wrap(op1, op2); + return primitive_argument_type( - util::visit(visit_logical{*this_}, - std::move(op1.variant()), std::move(op2.variant()))); - }), + wrap.propagate(util::visit(visit_logical{*this_}, + std::move(op1.variant()), std::move(op2.variant())), + this_->name_, this_->codename_)); + }, value_operand(operands[0], args, name_, codename_, ctx), value_operand(operands[1], args, name_, codename_, ctx)); } diff --git a/phylanx/plugins/common/conv1d_all_paddings.hpp b/phylanx/plugins/common/conv1d_all_paddings.hpp new file mode 100644 index 000000000..a1e4bccea --- /dev/null +++ b/phylanx/plugins/common/conv1d_all_paddings.hpp @@ -0,0 +1,64 @@ +// Copyright (c) 2019-2020 Bita Hasheminezhad +// Copyright (c) 2019-2020 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(PHYLANX_COMMON_CONV1D_OPERATION) +#define PHYLANX_COMMON_CONV1D_OPERATION + +#include +#include +#include +#include + +#include +#include + +namespace phylanx { namespace common { + + PHYLANX_COMMON_EXPORT execution_tree::primitive_argument_type conv1d_valid( + ir::node_data&& arg, ir::node_data&& kernel); + PHYLANX_COMMON_EXPORT execution_tree::primitive_argument_type conv1d_valid( + ir::node_data&& arg, ir::node_data&& kernel, + std::int64_t strides); + PHYLANX_COMMON_EXPORT execution_tree::primitive_argument_type + conv1d_valid_dilation(ir::node_data&& arg, + ir::node_data&& kernel, std::int64_t dilation_rate); + + PHYLANX_COMMON_EXPORT execution_tree::primitive_argument_type conv1d_same( + ir::node_data&& arg, ir::node_data&& kernel); + PHYLANX_COMMON_EXPORT execution_tree::primitive_argument_type conv1d_same( + ir::node_data&& arg, ir::node_data&& kernel, + std::int64_t strides); + PHYLANX_COMMON_EXPORT execution_tree::primitive_argument_type + conv1d_same_dilation(ir::node_data&& arg, + ir::node_data&& kernel, std::int64_t dilation_rate); + + PHYLANX_COMMON_EXPORT execution_tree::primitive_argument_type conv1d_causal( + ir::node_data&& arg, ir::node_data&& kernel); + PHYLANX_COMMON_EXPORT execution_tree::primitive_argument_type conv1d_causal( + ir::node_data&& arg, ir::node_data&& kernel, + std::int64_t strides); + PHYLANX_COMMON_EXPORT execution_tree::primitive_argument_type + conv1d_causal_dilation(ir::node_data&& arg, + ir::node_data&& kernel, std::int64_t dilation_rate); + + PHYLANX_COMMON_EXPORT execution_tree::primitive_argument_type + conv1d_all_paddings(ir::node_data&& arg, + ir::node_data&& kernel, std::string&& padding, + std::string const& name, std::string const& codename); + PHYLANX_COMMON_EXPORT execution_tree::primitive_argument_type + conv1d_all_paddings(ir::node_data&& arg, + ir::node_data&& kernel, std::string&& padding, + std::int64_t strides, std::string const& name, + std::string const& codename); + PHYLANX_COMMON_EXPORT execution_tree::primitive_argument_type + conv1d_all_paddings_dilation(ir::node_data&& arg, + ir::node_data&& kernel, std::string&& padding, + std::int64_t dilation_rate, std::string const& name, + std::string const& codename); + +}} // namespace phylanx::common + +#endif diff --git a/phylanx/plugins/dist_keras_support/dist_conv1d.hpp b/phylanx/plugins/dist_keras_support/dist_conv1d.hpp new file mode 100644 index 000000000..50c77c1e2 --- /dev/null +++ b/phylanx/plugins/dist_keras_support/dist_conv1d.hpp @@ -0,0 +1,66 @@ +// Copyright (c) 2020 Bita Hasheminezhad +// Copyright (c) 2020 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(PHYLANX_DIST_MATRIXOPS_CONV1D_OPERATION) +#define PHYLANX_DIST_MATRIXOPS_CONV1D_OPERATION + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +namespace phylanx { namespace dist_keras_support { namespace primitives { + + class dist_conv1d + : public execution_tree::primitives::primitive_component_base + , public std::enable_shared_from_this + { + protected: + hpx::future eval( + execution_tree::primitive_arguments_type const& operands, + execution_tree::primitive_arguments_type const& args, + execution_tree::eval_context ctx) const override; + + public: + static execution_tree::match_pattern_type const match_data; + + dist_conv1d() = default; + + dist_conv1d(execution_tree::primitive_arguments_type&& operands, + std::string const& name, std::string const& codename); + + private: + execution_tree::primitive_argument_type conv1d_all_paddings( + ir::node_data&& arg, ir::node_data&& kernel, + execution_tree::localities_information&& arg_locs, + execution_tree::localities_information&& kernel_locs, + std::string&& padding, std::string&& given_name) const; + execution_tree::primitive_argument_type conv1d_all_paddings( + execution_tree::primitive_argument_type&& arg, + execution_tree::primitive_argument_type&& kernel, + std::string&& padding, std::string&& given_name) const; + }; + + inline execution_tree::primitive create_dist_conv1d( + hpx::id_type const& locality, + execution_tree::primitive_arguments_type&& operands, + std::string const& name = "", std::string const& codename = "") + { + return execution_tree::create_primitive_component( + locality, "conv1d_d", std::move(operands), name, codename); + } +}}} + +#endif diff --git a/phylanx/plugins/dist_keras_support/dist_keras_support.hpp b/phylanx/plugins/dist_keras_support/dist_keras_support.hpp new file mode 100644 index 000000000..f8dbe8186 --- /dev/null +++ b/phylanx/plugins/dist_keras_support/dist_keras_support.hpp @@ -0,0 +1,11 @@ +// Copyright (c) 2020 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(PHYLANX_PLUGINS_DIST_KERAS_SUPPORT_JUN_25_2020) +#define PHYLANX_PLUGINS_DIST_KERAS_SUPPORT_JUN_25_2020 + +#include + +#endif diff --git a/phylanx/plugins/dist_matrixops/dist_argminmax_impl.hpp b/phylanx/plugins/dist_matrixops/dist_argminmax_impl.hpp index 16f61d5df..74aeb8e70 100644 --- a/phylanx/plugins/dist_matrixops/dist_argminmax_impl.hpp +++ b/phylanx/plugins/dist_matrixops/dist_argminmax_impl.hpp @@ -530,7 +530,6 @@ namespace phylanx { namespace dist_matrixops { namespace primitives { primitive_argument_type local_result = common::argminmax2d( std::move(args), name_, codename_, &local_value); - // correct index to be global auto indices_node_data = extract_integer_value_strict( std::move(local_result), name_, codename_); diff --git a/phylanx/plugins/keras_support/conv1d_operation.hpp b/phylanx/plugins/keras_support/conv1d_operation.hpp index 62b8f453e..2becae774 100644 --- a/phylanx/plugins/keras_support/conv1d_operation.hpp +++ b/phylanx/plugins/keras_support/conv1d_operation.hpp @@ -10,11 +10,10 @@ #include #include #include +#include -#include #include -#include #include #include #include @@ -46,40 +45,6 @@ namespace phylanx { namespace execution_tree { namespace primitives { conv1d_operation(primitive_arguments_type&& operands, std::string const& name, std::string const& codename); - - private: - primitive_argument_type conv1d_valid(ir::node_data&& arg, - ir::node_data&& kernel) const; - primitive_argument_type conv1d_valid(ir::node_data&& arg, - ir::node_data&& kernel, std::int64_t strides) const; - primitive_argument_type conv1d_valid_dilation( - ir::node_data&& arg, ir::node_data&& kernel, - std::int64_t dilation_rate) const; - - primitive_argument_type conv1d_same(ir::node_data&& arg, - ir::node_data&& kernel) const; - primitive_argument_type conv1d_same(ir::node_data&& arg, - ir::node_data&& kernel, std::int64_t strides) const; - primitive_argument_type conv1d_same_dilation( - ir::node_data&& arg, ir::node_data&& kernel, - std::int64_t dilation_rate) const; - - primitive_argument_type conv1d_causal(ir::node_data&& arg, - ir::node_data&& kernel) const; - primitive_argument_type conv1d_causal(ir::node_data&& arg, - ir::node_data&& kernel, std::int64_t strides) const; - primitive_argument_type conv1d_causal_dilation( - ir::node_data&& arg, ir::node_data&& kernel, - std::int64_t dilation_rate) const; - - primitive_argument_type conv1d_any_pad(ir::node_data&& arg, - ir::node_data&& kernel, std::string&& padding) const; - primitive_argument_type conv1d_any_pad(ir::node_data&& arg, - ir::node_data&& kernel, std::string&& padding, - std::int64_t strides) const; - primitive_argument_type conv1d_any_pad_dilation( - ir::node_data&& arg, ir::node_data&& kernel, - std::string&& padding, std::int64_t dilation_rate) const; }; inline primitive create_conv1d_operation(hpx::id_type const& locality, diff --git a/phylanx/plugins/keras_support/conv_indices_helper.hpp b/phylanx/plugins/keras_support/conv_indices_helper.hpp index dc19ed051..1f7be7c11 100644 --- a/phylanx/plugins/keras_support/conv_indices_helper.hpp +++ b/phylanx/plugins/keras_support/conv_indices_helper.hpp @@ -119,5 +119,37 @@ namespace conv_indices blaze::ceil(static_cast(kernel_size) / dilation_rate); return sizes{image_begin, kernel_begin, corrected_kernel_size}; } + + /////////////////////////////////////////////////////////////////////////// + inline sizes get_subsizes_causal( + std::int64_t kernel_size, std::int64_t relative_position) + { + if (relative_position < 0) + { + return sizes{ + 0, -relative_position, kernel_size + relative_position}; + } + + return sizes{relative_position, 0, kernel_size}; + } + + inline sizes get_subsizes_causal_dilated(std::int64_t kernel_size, + std::int64_t relative_position, std::int64_t dilation_rate) + { + if (relative_position < 0) + { + std::int64_t remainder = relative_position % dilation_rate; + remainder = remainder >= 0 ? remainder : dilation_rate + remainder; + std::int64_t corrected_kernel_size = kernel_size + + blaze::floor( + static_cast(relative_position) / dilation_rate); + + std::int64_t kernel_beg_ = blaze::ceil( + static_cast(-relative_position) / dilation_rate); + return sizes{remainder, kernel_beg_, corrected_kernel_size}; + } + + return sizes{relative_position, 0, kernel_size}; + } } #endif diff --git a/phylanx/util/distributed_matrix.hpp b/phylanx/util/distributed_matrix.hpp index affd21574..49a39e4b5 100644 --- a/phylanx/util/distributed_matrix.hpp +++ b/phylanx/util/distributed_matrix.hpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/phylanx/util/distributed_object.hpp b/phylanx/util/distributed_object.hpp index 84335c5ee..bba0bf5e7 100644 --- a/phylanx/util/distributed_object.hpp +++ b/phylanx/util/distributed_object.hpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/phylanx/util/distributed_tensor.hpp b/phylanx/util/distributed_tensor.hpp index 4e5c69100..929df9631 100644 --- a/phylanx/util/distributed_tensor.hpp +++ b/phylanx/util/distributed_tensor.hpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/phylanx/util/distributed_vector.hpp b/phylanx/util/distributed_vector.hpp index 1edcac77a..7e316f9ba 100644 --- a/phylanx/util/distributed_vector.hpp +++ b/phylanx/util/distributed_vector.hpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index d1d29ac47..a1603d1fa 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -81,7 +81,7 @@ if (PYTHON_EXECUTABLE) # for the install step it does not matter which setup.py we use install(CODE - "execute_process(COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY}_${__install_config}.py install --user)") + "execute_process(COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY}_${__install_config}.py bdist_wheel)") endif() diff --git a/python/phylanx/ast/physl.py b/python/phylanx/ast/physl.py index b23ecbff7..9555a0338 100644 --- a/python/phylanx/ast/physl.py +++ b/python/phylanx/ast/physl.py @@ -1148,6 +1148,11 @@ def _LtE(self, node): return '__le' + def _Mod(self, node): + """Leaf node, returning raw string of the `mod` operation.""" + + return '__mod' + def _Module(self, node): """Root node of the Python AST.""" module = list(self._apply_rule(m) for m in node.body) diff --git a/python/src/bindings/binding_helpers.cpp b/python/src/bindings/binding_helpers.cpp index a1152dd0d..3b234c9c5 100644 --- a/python/src/bindings/binding_helpers.cpp +++ b/python/src/bindings/binding_helpers.cpp @@ -7,7 +7,7 @@ #include -#include +#include #include #include diff --git a/python/src/bindings/util.cpp b/python/src/bindings/util.cpp index b9cbb5bd6..137cf4259 100644 --- a/python/src/bindings/util.cpp +++ b/python/src/bindings/util.cpp @@ -14,7 +14,7 @@ #include -#include +#include #include #include diff --git a/src/execution_tree/annotation.cpp b/src/execution_tree/annotation.cpp index c2fc2e504..925d699c9 100644 --- a/src/execution_tree/annotation.cpp +++ b/src/execution_tree/annotation.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Hartmut Kaiser +// Copyright (c) 2019-2020 Hartmut Kaiser // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -438,6 +438,18 @@ namespace phylanx { namespace execution_tree { } } + annotation_wrapper::annotation_wrapper(primitive_arguments_type const& ops) + { + for (auto const& op : ops) + { + if (op.has_annotation()) + { + ann_ = op.annotation(); + break; + } + } + } + primitive_argument_type annotation_wrapper::propagate( primitive_argument_type&& val, std::string const& name, std::string const& codename) diff --git a/src/execution_tree/compiler/compiler.cpp b/src/execution_tree/compiler/compiler.cpp index 66c7be51c..a50dc253e 100644 --- a/src/execution_tree/compiler/compiler.cpp +++ b/src/execution_tree/compiler/compiler.cpp @@ -660,7 +660,11 @@ namespace phylanx { namespace execution_tree { namespace compiler { function compile_body(std::vector const& args, ast::expression const& body, hpx::id_type const& locality) const { +#if !defined(PHYLANX_HAVE_CXX17_SHARED_PTR_ARRAY) + boost::shared_array named_args; +#else std::shared_ptr named_args; +#endif std::size_t base_arg_num = env_.base_arg_num(); bool has_default_value = false; diff --git a/src/execution_tree/localities_annotation.cpp b/src/execution_tree/localities_annotation.cpp index b3ac3be22..73e762305 100644 --- a/src/execution_tree/localities_annotation.cpp +++ b/src/execution_tree/localities_annotation.cpp @@ -528,6 +528,39 @@ namespace phylanx { namespace execution_tree // annotation_.as_annotation()); // } + bool localities_information::is_page_tiled( + std::string const& name, std::string const& codename) const + { + for (std::size_t i = 0; i != tiles_.size(); ++i) + { + switch (tiles_[i].dimension()) + { + case 0: + continue; + + case 3: + return detail::dim_tiled<1>(tiles_, rows(name, codename)) && + detail::dim_tiled<2>(tiles_, columns(name, codename)); + + case 1: HPX_FALLTHROUGH; + case 2: HPX_FALLTHROUGH; + case 4: HPX_FALLTHROUGH; + default: + break; + } + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "localities_information::is_page_tiled", + util::generate_error_message( + "unexpected dimensionality for calling is_page_tiled()", + name, codename)); + } + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "localities_information::is_page_tiled", + util::generate_error_message( + "cannot call is_page_tiled() when all tiles are empty", name, + codename)); + } + bool localities_information::is_row_tiled( std::string const& name, std::string const& codename) const { @@ -541,8 +574,11 @@ namespace phylanx { namespace execution_tree case 2: return detail::dim_tiled<1>(tiles_, columns(name, codename)); + case 3: + return detail::dim_tiled<0>(tiles_, pages(name, codename)) && + detail::dim_tiled<2>(tiles_, columns(name, codename)); + case 1: HPX_FALLTHROUGH; - case 3: HPX_FALLTHROUGH; case 4: HPX_FALLTHROUGH; default: break; @@ -573,8 +609,11 @@ namespace phylanx { namespace execution_tree case 2: return detail::dim_tiled<0>(tiles_, rows(name, codename)); + case 3: + return detail::dim_tiled<0>(tiles_, pages(name, codename)) && + detail::dim_tiled<1>(tiles_, rows(name, codename)); + case 1: HPX_FALLTHROUGH; - case 3: HPX_FALLTHROUGH; case 4: HPX_FALLTHROUGH; default: break; diff --git a/src/execution_tree/patterns.cpp b/src/execution_tree/patterns.cpp index 4824cf7f7..1441b5ff6 100644 --- a/src/execution_tree/patterns.cpp +++ b/src/execution_tree/patterns.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2019 Hartmut Kaiser +// Copyright (c) 2017-2020 Hartmut Kaiser // // Distributed under the Boost Software License}, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -129,14 +129,16 @@ namespace phylanx { namespace execution_tree pattern_list get_all_known_patterns() { - pattern_list patterns = {// debugging support - PHYLANX_MATCH_DATA(find_all_localities), + pattern_list patterns = { + // debugging support + PHYLANX_MATCH_DATA(assert_condition), PHYLANX_MATCH_DATA(console_output), PHYLANX_MATCH_DATA(debug_output), PHYLANX_MATCH_DATA(enable_tracing), + PHYLANX_MATCH_DATA(find_all_localities), PHYLANX_MATCH_DATA(format_string), PHYLANX_MATCH_DATA(string_output), - PHYLANX_MATCH_DATA(assert_condition), + PHYLANX_MATCH_DATA(timer), // special purpose primitives PHYLANX_MATCH_DATA_VERBATIM( diff --git a/src/execution_tree/primitives/assert_condition.cpp b/src/execution_tree/primitives/assert_condition.cpp index 27880e567..740a13b19 100644 --- a/src/execution_tree/primitives/assert_condition.cpp +++ b/src/execution_tree/primitives/assert_condition.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/execution_tree/primitives/console_output.cpp b/src/execution_tree/primitives/console_output.cpp index 136160b5e..705beff9d 100644 --- a/src/execution_tree/primitives/console_output.cpp +++ b/src/execution_tree/primitives/console_output.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/execution_tree/primitives/debug_output.cpp b/src/execution_tree/primitives/debug_output.cpp index e711d5047..db7014668 100644 --- a/src/execution_tree/primitives/debug_output.cpp +++ b/src/execution_tree/primitives/debug_output.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/execution_tree/primitives/find_all_localities.cpp b/src/execution_tree/primitives/find_all_localities.cpp index 7aa0c2e1a..29b6e401c 100644 --- a/src/execution_tree/primitives/find_all_localities.cpp +++ b/src/execution_tree/primitives/find_all_localities.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/execution_tree/primitives/format_string.cpp b/src/execution_tree/primitives/format_string.cpp index 6884664b4..ebd7c8743 100644 --- a/src/execution_tree/primitives/format_string.cpp +++ b/src/execution_tree/primitives/format_string.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/execution_tree/primitives/function.cpp b/src/execution_tree/primitives/function.cpp index a93486a8d..cb62848c5 100644 --- a/src/execution_tree/primitives/function.cpp +++ b/src/execution_tree/primitives/function.cpp @@ -78,6 +78,13 @@ namespace phylanx { namespace execution_tree { namespace primitives primitive const* p = util::get_if(&operands_[0]); if (p != nullptr) { + // we represent function calls with empty argument lists as + // a function call with a single nil argument to be able to + // distinguish func() from invoke(func) + if (args.size() == 1 && args[0].is_implicit_nil()) + { + return p->eval(primitive_arguments_type{}, std::move(ctx)); + } return p->eval(args, std::move(ctx)); } return hpx::make_ready_future( diff --git a/src/execution_tree/primitives/phyname.cpp b/src/execution_tree/primitives/phyname.cpp index 6f942f5f6..e6defb462 100644 --- a/src/execution_tree/primitives/phyname.cpp +++ b/src/execution_tree/primitives/phyname.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/execution_tree/primitives/phytype.cpp b/src/execution_tree/primitives/phytype.cpp index 8435bc03b..344fcc73c 100644 --- a/src/execution_tree/primitives/phytype.cpp +++ b/src/execution_tree/primitives/phytype.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/execution_tree/primitives/timer.cpp b/src/execution_tree/primitives/timer.cpp new file mode 100644 index 000000000..9ae2ec62c --- /dev/null +++ b/src/execution_tree/primitives/timer.cpp @@ -0,0 +1,128 @@ +// Copyright (c) 2020 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +namespace phylanx { namespace execution_tree { namespace primitives { + + /////////////////////////////////////////////////////////////////////////// + primitive create_timer(hpx::id_type const& locality, + primitive_arguments_type&& operands, std::string const& name, + std::string const& codename) + { + static std::string type("timer"); + return create_primitive_component( + locality, type, std::move(operands), name, codename); + } + + match_pattern_type const timer::match_data = { + + hpx::util::make_tuple("timer", + std::vector{"timer(_1, _2)"}, &create_timer, + &create_primitive, + R"(arg, done + This primitive allows to measure the execution time of the embedded + expression 'arg' and reports it to the supplied reporting function + 'done'. + + Args: + + arg (expression) : the operation to measure the execution time for + done (function) : a function that will be called with the measured time + + Returns: + + whatever the evaluation of 'arg' returns)" + )}; + + /////////////////////////////////////////////////////////////////////////// + timer::timer(primitive_arguments_type&& operands, std::string const& name, + std::string const& codename) + : primitive_component_base(std::move(operands), name, codename) + { + } + + hpx::future timer::eval( + primitive_arguments_type const& operands, + primitive_arguments_type const& args, eval_context ctx) const + { + if (operands.size() != 2) + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "timer::eval", + generate_error_message( + "the timer primitive requires exactly two operands")); + } + + if (!valid(operands[0]) || !valid(operands[1])) + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "timer::eval", + generate_error_message( + "the timer primitive requires that the " + "arguments given by the operands array are valid")); + } + + auto this_ = this->shared_from_this(); + return hpx::dataflow(hpx::launch::sync, + [this_ = std::move(this_), ctx, func = operands[0], args]( + hpx::future&& l) mutable + -> primitive_argument_type + { + hpx::util::high_resolution_timer t; + + // execute body + primitive const* p = util::get_if(&func); + if (p == nullptr) + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "timer::eval", + this_->generate_error_message( + "the first argument to timer must be an " + "invocable object")); + } + + primitive_argument_type result = p->eval(hpx::launch::sync, + primitive_argument_type{}, ctx); + + double elapsed = t.elapsed(); + + // report timings + auto&& arg = l.get(); + + primitive const* r = util::get_if(&arg); + if (p == nullptr) + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "timer::eval", + this_->generate_error_message( + "the second argument to timer must be an " + "invocable object")); + } + + r->eval(hpx::launch::sync, primitive_argument_type{elapsed}, + std::move(ctx)); + + // return overall result + return result; + }, + value_operand(operands[1], args, name_, codename_, + add_mode(ctx, eval_dont_evaluate_lambdas))); + } +}}} // namespace phylanx::execution_tree::primitives diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index 5cab47390..2ccc7da02 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2018-2019 Hartmut Kaiser +# Copyright (c) 2018-2020 Hartmut Kaiser # # Distributed under the Boost Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,6 +9,7 @@ set(subdirs booleans common controls + dist_keras_support dist_matrixops fileio keras_support diff --git a/src/plugins/algorithms/als.cpp b/src/plugins/algorithms/als.cpp index 90142e745..b0fb698da 100644 --- a/src/plugins/algorithms/als.cpp +++ b/src/plugins/algorithms/als.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/plugins/algorithms/kmeans.cpp b/src/plugins/algorithms/kmeans.cpp index 3615d28e5..881fe9d70 100644 --- a/src/plugins/algorithms/kmeans.cpp +++ b/src/plugins/algorithms/kmeans.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/plugins/algorithms/lra.cpp b/src/plugins/algorithms/lra.cpp index 362f11a68..fc843c0e8 100644 --- a/src/plugins/algorithms/lra.cpp +++ b/src/plugins/algorithms/lra.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/plugins/arithmetics/arithmetics.cpp b/src/plugins/arithmetics/arithmetics.cpp index d0ed1c69b..63cf55f2a 100644 --- a/src/plugins/arithmetics/arithmetics.cpp +++ b/src/plugins/arithmetics/arithmetics.cpp @@ -23,6 +23,8 @@ PHYLANX_REGISTER_PLUGIN_FACTORY(maximum_plugin, phylanx::execution_tree::primitives::maximum::match_data); PHYLANX_REGISTER_PLUGIN_FACTORY(minimum_plugin, phylanx::execution_tree::primitives::minimum::match_data); +PHYLANX_REGISTER_PLUGIN_FACTORY(mod_operation_plugin, + phylanx::execution_tree::primitives::mod_operation::match_data); PHYLANX_REGISTER_PLUGIN_FACTORY(mul_operation_plugin, phylanx::execution_tree::primitives::mul_operation::match_data); PHYLANX_REGISTER_PLUGIN_FACTORY(sub_operation_plugin, diff --git a/src/plugins/arithmetics/mod_operation.cpp b/src/plugins/arithmetics/mod_operation.cpp new file mode 100644 index 000000000..6c9699f1a --- /dev/null +++ b/src/plugins/arithmetics/mod_operation.cpp @@ -0,0 +1,152 @@ +// Copyright (c) 2017-2018 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +namespace phylanx { namespace execution_tree { namespace primitives +{ + ////////////////////////////////////////////////////////////////////////// + match_pattern_type const mod_operation::match_data = + { + match_pattern_type{"__mod", + std::vector{"_1 % _2", "__mod(_1, _2)"}, + &create_mod_operation, &create_primitive, R"( + x0, x1 + Args: + + x0 (int): A dividend.\n" + x1 (int): A divisor.\n" + + Returns: + + The remainder of the division.)", + true + } + }; + + ////////////////////////////////////////////////////////////////////////// + mod_operation::mod_operation( + primitive_arguments_type && operands, + std::string const& name, std::string const& codename) + : base_type(std::move(operands), name, codename) + {} + + /////////////////////////////////////////////////////////////////////////// + hpx::future mod_operation::eval( + primitive_arguments_type const& operands, + primitive_arguments_type const& args, + eval_context ctx) const + { + if (operands.size() != 2) + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, "mod_operation::eval", + generate_error_message("the mod_operation primitive requires " + "exactly two operands")); + } + + bool arguments_valid = true; + for (std::size_t i = 0; i != operands.size(); ++i) + { + if (!valid(operands[i])) + { + arguments_valid = false; + } + } + + if (!arguments_valid) + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, "mod_operation::eval", + generate_error_message( + "the mod_operation primitive requires that the arguments " + "given by the operands array are valid")); + } + auto this_ = this->shared_from_this(); + + return hpx::dataflow(hpx::launch::sync, + hpx::util::unwrapping([this_ = std::move(this_)]( + primitive_arguments_type&& args) + -> primitive_argument_type + { + typedef phylanx::ir::node_data itype; + + itype left_ = extract_integer_value( + std::move(args[0]), this_->name_, this_->codename_); + itype right_ = extract_integer_value( + std::move(args[1]), this_->name_, this_->codename_); + + std::size_t left_dims = left_.num_dimensions(); + std::size_t right_dims = right_.num_dimensions(); + + if(right_dims == 0) { + if(left_dims == 1) { + assign_vector lvec{left_}; + auto r = right_.scalar(); + lvec = blaze::map(left_.vector(), [r](std::int64_t v){ + return v % r; + }); + primitive_argument_type p(std::move(left_)); + return p; + } + if(left_dims == 2) { + assign_matrix lmat{left_}; + auto r = right_.scalar(); + lmat = blaze::map(left_.matrix(), [r](std::int64_t v){ + return v % r; + }); + primitive_argument_type p(std::move(left_)); + return p; + } + } + if(left_dims == 0) { + if(right_dims == 1) { + assign_vector rvec{right_}; + auto l = left_.scalar(); + rvec = blaze::map(right_.vector(), [l](std::int64_t v){ + return l % v; + }); + primitive_argument_type p(std::move(right_)); + return p; + } + if(right_dims == 2) { + assign_matrix rmat{right_}; + auto l = left_.scalar(); + rmat = blaze::map(right_.matrix(), [l](std::int64_t v){ + return l % v; + }); + primitive_argument_type p(std::move(right_)); + return p; + } + } + if(left_dims == 1 && right_dims == 1) { + assign_vector lvec{left_}; + assign_vector rvec{right_}; + rvec = blaze::map(left_.vector(), right_.vector(), + [](std::int64_t l,std::int64_t r){ + return l % r; + }); + primitive_argument_type p(std::move(left_)); + return p; + } + return primitive_argument_type{ + left_.scalar() % right_.scalar()}; + }), + detail::map_operands( + operands, functional::value_operand{}, args, + name_, codename_, std::move(ctx))); + } +}}} diff --git a/src/plugins/booleans/nonzero_where.cpp b/src/plugins/booleans/nonzero_where.cpp index b07c6a54c..eeaaa343f 100644 --- a/src/plugins/booleans/nonzero_where.cpp +++ b/src/plugins/booleans/nonzero_where.cpp @@ -1,9 +1,10 @@ -// Copyright (c) 2017-2018 Hartmut Kaiser +// Copyright (c) 2017-2020 Hartmut Kaiser // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include +#include #include #include #include @@ -542,25 +543,41 @@ namespace phylanx { namespace execution_tree { namespace primitives auto this_ = this->shared_from_this(); if (nonzero_ || (where_ && operands.size() == 1)) { - return hpx::dataflow(hpx::launch::sync, hpx::util::unwrapping( - [this_ = std::move(this_)](primitive_argument_type&& op) + return hpx::dataflow(hpx::launch::sync, + [this_ = std::move(this_)]( + hpx::future&& op1) -> primitive_argument_type { - return util::visit(visit_nonzero{*this_}, - std::move(op.variant())); - }), + auto&& op = op1.get(); + + annotation_wrapper wrap(op); + + return wrap.propagate(util::visit(visit_nonzero{*this_}, + std::move(op.variant())), + this_->name_, this_->codename_); + }, value_operand(operands[0], args, name_, codename_)); } - return hpx::dataflow(hpx::launch::sync, hpx::util::unwrapping( - [this_ = std::move(this_)](primitive_argument_type&& cond, - primitive_argument_type&& lhs, primitive_argument_type&& rhs) + return hpx::dataflow(hpx::launch::sync, + [this_ = std::move(this_)]( + hpx::future&& cond, + hpx::future&& lhs, + hpx::future&& rhs) -> primitive_argument_type { - return util::visit( - visit_where{*this_, std::move(lhs), std::move(rhs)}, - std::move(cond.variant())); - }), + auto&& c = cond.get(); + auto&& op1 = lhs.get(); + auto&& op2 = rhs.get(); + + annotation_wrapper wrap(op1, op2); + + return wrap.propagate( + util::visit( + visit_where{*this_, std::move(op1), std::move(op2)}, + std::move(c.variant())), + this_->name_, this_->codename_); + }, value_operand(operands[0], args, name_, codename_), value_operand(operands[1], args, name_, codename_), value_operand(operands[2], args, name_, codename_)); diff --git a/src/plugins/common/conv1d_all_paddings.cpp b/src/plugins/common/conv1d_all_paddings.cpp new file mode 100644 index 000000000..8f648854c --- /dev/null +++ b/src/plugins/common/conv1d_all_paddings.cpp @@ -0,0 +1,482 @@ +// Copyright (c) 2019-2020 Bita Hasheminezhad +// Copyright (c) 2019-2020 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +namespace phylanx { namespace common { + + /////////////////////////////////////////////////////////////////////////// + execution_tree::primitive_argument_type conv1d_valid( + ir::node_data&& arg, ir::node_data&& kernel) + { + auto a = arg.tensor(); + auto k = kernel.tensor(); + std::size_t batch = a.pages(); + std::size_t filter_length = k.pages(); + std::size_t in_channels = a.columns(); + std::size_t out_channels = k.columns(); + std::size_t result_length = a.rows() - filter_length + 1; + + blaze::DynamicTensor result(batch, result_length, out_channels); + + for (std::size_t c = 0; c != out_channels; ++c) + { + auto kslice = blaze::columnslice(k, c); + for (std::size_t i = 0; i != result_length; ++i) + { + auto schur_product = blaze::subtensor(a, 0, i, 0, batch, + filter_length, in_channels) % + kslice; + for (std::size_t p = 0; p != batch; ++p) + { + auto pslice = blaze::pageslice(schur_product, p); + result(p, i, c) = blaze::sum(pslice); + } + } + } + return execution_tree::primitive_argument_type{std::move(result)}; + } + + execution_tree::primitive_argument_type conv1d_valid( + ir::node_data&& arg, ir::node_data&& kernel, + std::int64_t strides) + { + auto a = arg.tensor(); + auto k = kernel.tensor(); + std::size_t batch = a.pages(); + std::size_t filter_length = k.pages(); + std::size_t in_channels = a.columns(); + std::size_t out_channels = k.columns(); + std::size_t result_length = blaze::ceil( + static_cast(a.rows() - filter_length + 1) / strides); + + blaze::DynamicTensor result(batch, result_length, out_channels); + + for (std::size_t c = 0; c != out_channels; ++c) + { + auto kslice = blaze::columnslice(k, c); + for (std::size_t i = 0; i != result_length; ++i) + { + auto schur_product = blaze::subtensor(a, 0, i * strides, 0, + batch, filter_length, in_channels) % + kslice; + for (std::size_t p = 0; p != batch; ++p) + { + auto pslice = blaze::pageslice(schur_product, p); + result(p, i, c) = blaze::sum(pslice); + } + } + } + return execution_tree::primitive_argument_type{std::move(result)}; + } + + execution_tree::primitive_argument_type conv1d_valid_dilation( + ir::node_data&& arg, ir::node_data&& kernel, + std::int64_t dilation_rate) + { + auto a = arg.tensor(); + auto k = kernel.tensor(); + auto filter_length = static_cast(k.pages()); + auto data_length = static_cast(a.rows()); + std::size_t batch = a.pages(); + std::size_t in_channels = a.columns(); + std::size_t out_channels = k.columns(); + + std::int64_t result_length = + data_length - dilation_rate * (filter_length - 1); + + if(result_length <= 0) + HPX_THROW_EXCEPTION(hpx::bad_parameter, "conv1d_valid_dilation", + util::generate_error_message( + "this dilation_rate causes non-positive " + "result_length where padding is valid")); + + blaze::DynamicTensor result(batch, result_length, out_channels); + + for (std::size_t c = 0; c != out_channels; ++c) + { + auto kslice = blaze::columnslice(k, c); + for (std::size_t i = 0; i != result_length; ++i) + { + auto schur_product = + blaze::dilatedsubtensor(a, 0, i, 0, batch, filter_length, + in_channels, 1, dilation_rate, 1) % + kslice; + for (std::size_t p = 0; p != batch; ++p) + { + auto pslice = blaze::pageslice(schur_product, p); + result(p, i, c) = blaze::sum(pslice); + } + } + } + return execution_tree::primitive_argument_type{std::move(result)}; + } + + /////////////////////////////////////////////////////////////////////////// + execution_tree::primitive_argument_type conv1d_same( + ir::node_data&& arg, ir::node_data&& kernel) + { + auto a = arg.tensor(); + auto k = kernel.tensor(); + auto filter_length = static_cast(k.pages()); + auto data_length = static_cast(a.rows()); + std::size_t batch = a.pages(); + std::size_t in_channels = a.columns(); + std::size_t out_channels = k.columns(); + + std::int64_t pad_top = (filter_length - 1) / 2; + + blaze::DynamicTensor result(batch, data_length, out_channels); + + for (std::size_t c = 0; c != out_channels; ++c) + { + auto kslice = blaze::columnslice(k, c); + for (std::size_t i = 0; i != data_length; ++i) + { + auto sub = conv_indices::get_subsizes( + data_length, filter_length, i - pad_top); + auto schur_product = blaze::subtensor(a, 0, sub.image_beg_, 0, + batch, sub.size_, in_channels) % + blaze::submatrix( + kslice, sub.kernel_beg_, 0, sub.size_, in_channels); + for (std::size_t p = 0; p != batch; ++p) + { + auto pslice = blaze::pageslice(schur_product, p); + result(p, i, c) = blaze::sum(pslice); + } + } + } + return execution_tree::primitive_argument_type{std::move(result)}; + } + + execution_tree::primitive_argument_type conv1d_same( + ir::node_data&& arg, ir::node_data&& kernel, + std::int64_t strides) + { + auto a = arg.tensor(); + auto k = kernel.tensor(); + auto filter_length = static_cast(k.pages()); + auto data_length = static_cast(a.rows()); + std::size_t batch = a.pages(); + std::size_t in_channels = a.columns(); + std::size_t out_channels = k.columns(); + std::int64_t pad_width; + + if (data_length % strides == 0) + { + pad_width = filter_length > strides ? filter_length - strides : + static_cast(0); + } + else + { + pad_width = filter_length > (data_length % strides) ? + filter_length - (data_length % strides) : + static_cast(0); + } + + std::size_t result_length = blaze::ceil( + static_cast(data_length + pad_width - filter_length + 1) / + strides); + + blaze::DynamicTensor result(batch, result_length, out_channels); + std::size_t pad_top = pad_width / 2; + + for (std::size_t c = 0; c != out_channels; ++c) + { + auto kslice = blaze::columnslice(k, c); + for (std::size_t i = 0; i != result_length; ++i) + { + auto sub = conv_indices::get_subsizes( + data_length, filter_length, i * strides - pad_top); + auto schur_product = blaze::subtensor(a, 0, sub.image_beg_, 0, + batch, sub.size_, in_channels) % + blaze::submatrix( + kslice, sub.kernel_beg_, 0, sub.size_, in_channels); + for (std::size_t p = 0; p != batch; ++p) + { + auto pslice = blaze::pageslice(schur_product, p); + result(p, i, c) = blaze::sum(pslice); + } + } + } + return execution_tree::primitive_argument_type{std::move(result)}; + } + + execution_tree::primitive_argument_type conv1d_same_dilation( + ir::node_data&& arg, ir::node_data&& kernel, + std::int64_t dilation_rate) + { + auto a = arg.tensor(); + auto k = kernel.tensor(); + auto filter_length = static_cast(k.pages()); + auto data_length = static_cast(a.rows()); + std::size_t batch = a.pages(); + std::size_t in_channels = a.columns(); + std::size_t out_channels = k.columns(); + std::int64_t pad_top = (dilation_rate * (filter_length - 1)) / 2; + + blaze::DynamicTensor result( + batch, data_length, out_channels, 0.); + + for (std::size_t c = 0; c != out_channels; ++c) + { + auto kslice = blaze::columnslice(k, c); + for (std::size_t i = 0; i != data_length; ++i) + { + auto sub = conv_indices::get_subsizes_dilated( + data_length, filter_length, i - pad_top, dilation_rate); + + if (sub.size_ == 0) + continue; + + auto schur_product = + blaze::dilatedsubtensor(a, 0, sub.image_beg_, 0, batch, + sub.size_, in_channels, 1, dilation_rate, 1) % + blaze::submatrix( + kslice, sub.kernel_beg_, 0, sub.size_, in_channels); + for (std::size_t p = 0; p != batch; ++p) + { + auto pslice = blaze::pageslice(schur_product, p); + result(p, i, c) = blaze::sum(pslice); + } + } + } + return execution_tree::primitive_argument_type{std::move(result)}; + } + + /////////////////////////////////////////////////////////////////////////// + execution_tree::primitive_argument_type conv1d_causal( + ir::node_data&& arg, ir::node_data&& kernel) + { + auto a = arg.tensor(); + auto k = kernel.tensor(); + auto filter_length = static_cast(k.pages()); + auto data_length = static_cast(a.rows()); + std::size_t batch = a.pages(); + std::size_t in_channels = a.columns(); + std::size_t out_channels = k.columns(); + std::int64_t pad_top = filter_length - 1; // no pad_bottom + + blaze::DynamicTensor result(batch, data_length, out_channels); + + for (std::size_t c = 0; c != out_channels; ++c) + { + auto kslice = blaze::columnslice(k, c); + for (std::size_t i = 0; i != data_length; ++i) + { + auto sub = conv_indices::get_subsizes_causal( + filter_length, i - pad_top); + auto schur_product = blaze::subtensor(a, 0, sub.image_beg_, 0, + batch, sub.size_, in_channels) % + blaze::submatrix( + kslice, sub.kernel_beg_, 0, sub.size_, in_channels); + for (std::size_t p = 0; p != batch; ++p) + { + auto pslice = blaze::pageslice(schur_product, p); + result(p, i, c) = blaze::sum(pslice); + } + } + } + return execution_tree::primitive_argument_type{std::move(result)}; + } + + execution_tree::primitive_argument_type conv1d_causal( + ir::node_data&& arg, ir::node_data&& kernel, + std::int64_t strides) + { + auto a = arg.tensor(); + auto k = kernel.tensor(); + auto filter_length = static_cast(k.pages()); + auto data_length = static_cast(a.rows()); + std::size_t batch = a.pages(); + std::size_t in_channels = a.columns(); + std::size_t out_channels = k.columns(); + std::int64_t pad_top = filter_length - 1; // no pad_bottom + + std::size_t result_length = + blaze::ceil(static_cast(data_length) / strides); + + blaze::DynamicTensor result(batch, result_length, out_channels); + + for (std::size_t c = 0; c != out_channels; ++c) + { + auto kslice = blaze::columnslice(k, c); + for (std::size_t i = 0; i != result_length; ++i) + { + auto sub = conv_indices::get_subsizes_causal( + filter_length, i * strides - pad_top); + auto schur_product = blaze::subtensor(a, 0, sub.image_beg_, 0, + batch, sub.size_, in_channels) % + blaze::submatrix( + kslice, sub.kernel_beg_, 0, sub.size_, in_channels); + for (std::size_t p = 0; p != batch; ++p) + { + auto pslice = blaze::pageslice(schur_product, p); + result(p, i, c) = blaze::sum(pslice); + } + } + } + return execution_tree::primitive_argument_type{std::move(result)}; + } + + execution_tree::primitive_argument_type conv1d_causal_dilation( + ir::node_data&& arg, ir::node_data&& kernel, + std::int64_t dilation_rate) + { + auto a = arg.tensor(); + auto k = kernel.tensor(); + auto filter_length = static_cast(k.pages()); + auto data_length = static_cast(a.rows()); + std::size_t batch = a.pages(); + std::size_t in_channels = a.columns(); + std::size_t out_channels = k.columns(); + std::int64_t pad_top = + dilation_rate * (filter_length - 1); // no pad_bottom + + blaze::DynamicTensor result(batch, data_length, out_channels); + + for (std::size_t c = 0; c != out_channels; ++c) + { + auto kslice = blaze::columnslice(k, c); + for (std::size_t i = 0; i != data_length; ++i) + { + auto sub = conv_indices::get_subsizes_causal_dilated( + filter_length, i - pad_top, dilation_rate); + + if (sub.size_ == 0) + continue; + + auto schur_product = + blaze::dilatedsubtensor(a, 0, sub.image_beg_, 0, batch, + sub.size_, in_channels, 1, dilation_rate, 1) % + blaze::submatrix( + kslice, sub.kernel_beg_, 0, sub.size_, in_channels); + for (std::size_t p = 0; p != batch; ++p) + { + auto pslice = blaze::pageslice(schur_product, p); + result(p, i, c) = blaze::sum(pslice); + } + } + } + return execution_tree::primitive_argument_type{std::move(result)}; + } + + ///////////////////////////////////////////////////////////////////////////// + execution_tree::primitive_argument_type conv1d_all_paddings( + ir::node_data&& arg, ir::node_data&& kernel, + std::string&& padding, std::string const& name, + std::string const& codename) + { + if (execution_tree::extract_numeric_value_dimensions( + arg, name, codename)[2] != + execution_tree::extract_numeric_value_dimensions( + kernel, name, codename)[1]) + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "conv1d_all_paddings::conv1d_all_paddings", + util::generate_error_message( + "input depth must be evenly divisible by filter depth. " + "Number of input channels is not the same", + name, codename)); + } + + if (padding == "valid") + { + return conv1d_valid(std::move(arg), std::move(kernel)); + } + if (padding == "same") + { + return conv1d_same(std::move(arg), std::move(kernel)); + } + + // padding == causal + return conv1d_causal(std::move(arg), std::move(kernel)); + } + + execution_tree::primitive_argument_type conv1d_all_paddings( + ir::node_data&& arg, ir::node_data&& kernel, + std::string&& padding, std::int64_t strides, std::string const& name, + std::string const& codename) + { + if (execution_tree::extract_numeric_value_dimensions( + arg, name, codename)[2] != + execution_tree::extract_numeric_value_dimensions( + kernel, name, codename)[1]) + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "conv1d_all_paddings::conv1d_all_paddings", + util::generate_error_message( + "input depth must be evenly divisible by filter depth. " + "Number of input channels is not the same", + name, codename)); + } + + if (padding == "valid") + { + return conv1d_valid(std::move(arg), std::move(kernel), strides); + } + if (padding == "same") + { + return conv1d_same(std::move(arg), std::move(kernel), strides); + } + + // padding == causal + return conv1d_causal(std::move(arg), std::move(kernel), strides); + } + + execution_tree::primitive_argument_type conv1d_all_paddings_dilation( + ir::node_data&& arg, ir::node_data&& kernel, + std::string&& padding, std::int64_t dilation_rate, + std::string const& name, std::string const& codename) + { + if (execution_tree::extract_numeric_value_dimensions( + arg, name, codename)[2] != + execution_tree::extract_numeric_value_dimensions( + kernel, name, codename)[1]) + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "conv1d_all_paddings::conv1d_all_paddings", + util::generate_error_message( + "input depth must be evenly divisible by filter depth. " + "Number of input channels is not the same", + name, codename)); + } + + if (padding == "valid") + { + return conv1d_valid_dilation( + std::move(arg), std::move(kernel), dilation_rate); + } + if (padding == "same") + { + return conv1d_same_dilation( + std::move(arg), std::move(kernel), dilation_rate); + } + + // padding == causal + return conv1d_causal_dilation( + std::move(arg), std::move(kernel), dilation_rate); + } +}} diff --git a/src/plugins/controls/fmap_operation.cpp b/src/plugins/controls/fmap_operation.cpp index 1c4665342..085768d96 100644 --- a/src/plugins/controls/fmap_operation.cpp +++ b/src/plugins/controls/fmap_operation.cpp @@ -648,7 +648,7 @@ namespace phylanx { namespace execution_tree { namespace primitives } // the first argument must be an invokable - if (util::get_if(&operands_[0]) == nullptr) + if (util::get_if(&operands[0]) == nullptr) { HPX_THROW_EXCEPTION(hpx::bad_parameter, "fmap_operation::eval", diff --git a/src/plugins/dist_keras_support/CMakeLists.txt b/src/plugins/dist_keras_support/CMakeLists.txt new file mode 100644 index 000000000..27125eceb --- /dev/null +++ b/src/plugins/dist_keras_support/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (c) 2017-2020 Hartmut Kaiser +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +add_phylanx_primitive_plugin(dist_keras_support + SOURCE_ROOT "${PROJECT_SOURCE_DIR}/src/plugins/dist_keras_support" + HEADER_ROOT "${PROJECT_SOURCE_DIR}/phylanx/plugins/dist_keras_support" + AUTOGLOB + PLUGIN + FOLDER "Core/Plugins" + COMPONENT_DEPENDENCIES phylanx + DEPENDENCIES common) + +add_phylanx_pseudo_target(primitives.dist_keras_support_dir.dist_keras_support_plugin) +add_phylanx_pseudo_dependencies(primitives.dist_keras_support_dir + primitives.dist_keras_support_dir.dist_keras_support_plugin) +add_phylanx_pseudo_dependencies( + primitives.dist_keras_support_dir.dist_keras_support_plugin + dist_keras_support_primitive) diff --git a/src/plugins/dist_keras_support/dist_conv1d.cpp b/src/plugins/dist_keras_support/dist_conv1d.cpp new file mode 100644 index 000000000..c8785eb97 --- /dev/null +++ b/src/plugins/dist_keras_support/dist_conv1d.cpp @@ -0,0 +1,483 @@ +// Copyright (c) 2020 Bita Hasheminezhad +// Copyright (c) 2020 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +namespace phylanx { namespace dist_keras_support { namespace primitives +{ + /////////////////////////////////////////////////////////////////////////// + execution_tree::match_pattern_type const dist_conv1d::match_data = + { + hpx::util::make_tuple("conv1d_d", + std::vector{R"( + conv1d_d(_1, _2_kernel, + __arg(_3_padding, "valid"), + __arg(_4_strides, 1), + __arg(_5_dilation_rate, 1), + __arg(_6_name, "")) + )"}, + &create_dist_conv1d, &execution_tree::create_primitive, + R"(x, kernel, padding, strides, dilation_rate, name + Args: + x (array) : a 3d array consiting of batch, in_length and + in_channels dimensions. + kernel (array) : a 3d array consisting of filter_length, + in_channels and out_channels dimension. Note that the + in_channels should be the same in kernel and original array. + padding (optional, string) : padding mode, `valid` by default. It + can be either `valid`, `same` or `causal`. `vaild` means no + padding. `same` results the output with the same shape as + original array in case of unit strides. `causal` zero pads the + array in a way that no output element depend on the input + elements of its future. + strides (optional, integer) : the step to apply convolution over + array. It sets to 1 by default. + dilation_rate (optional, integer) : indicates the dilation rate, + the rate to sample the array in each step of convolution, 1 + by default. + name (optional, string): the result name. If not given it will be + the same as the next generation of the original distributed + array. + Returns: + 1D convolution (or 1D mathematical cross-correlation))") + }; + + /////////////////////////////////////////////////////////////////////////// + dist_conv1d::dist_conv1d( + execution_tree::primitive_arguments_type&& operands, + std::string const& name, std::string const& codename) + : primitive_component_base(std::move(operands), name, codename) + {} + + /////////////////////////////////////////////////////////////////////////// + namespace detail + { + execution_tree::primitive_argument_type conv1d_pad_top_bottom( + ir::node_data&& arg, ir::node_data&& kernel, + std::size_t pad, bool mode, std::string const& name, + std::string const& codename) + { + if (execution_tree::extract_numeric_value_dimensions( + arg, name, codename)[2] != + execution_tree::extract_numeric_value_dimensions( + kernel, name, codename)[1]) + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "conv1d_all_paddings::conv1d_pad_top_bottom", + util::generate_error_message( + "input depth must be evenly divisible by filter depth. " + "Number of input channels is not the same", + name, codename)); + } + + auto a = arg.tensor(); + auto k = kernel.tensor(); + auto filter_length = static_cast(k.pages()); + auto data_length = static_cast(a.rows()); + std::size_t batch = a.pages(); + std::size_t in_channels = a.columns(); + std::size_t out_channels = k.columns(); + std::size_t result_length = pad + data_length - filter_length + 1; + + blaze::DynamicTensor result( + batch, result_length, out_channels); + + if (mode) // top padding + { + for (std::size_t c = 0; c != out_channels; ++c) + { + auto kslice = blaze::columnslice(k, c); + for (std::size_t i = 0; i != result_length; ++i) + { + auto sub = conv_indices::get_subsizes_causal( + filter_length, i - pad); + auto schur_product = + blaze::subtensor(a, 0, sub.image_beg_, 0, batch, + sub.size_, in_channels) % + blaze::submatrix(kslice, sub.kernel_beg_, 0, + sub.size_, in_channels); + for (std::size_t p = 0; p != batch; ++p) + { + auto pslice = blaze::pageslice(schur_product, p); + result(p, i, c) = blaze::sum(pslice); + } + } + } + } + else // bottom padding + { + for (std::size_t c = 0; c != out_channels; ++c) + { + auto kslice = blaze::columnslice(k, c); + for (std::size_t i = 0; i != result_length; ++i) + { + auto sub = conv_indices::get_subsizes( + data_length, filter_length, i); + auto schur_product = + blaze::subtensor(a, 0, sub.image_beg_, 0, batch, + sub.size_, in_channels) % + blaze::submatrix(kslice, sub.kernel_beg_, 0, + sub.size_, in_channels); + for (std::size_t p = 0; p != batch; ++p) + { + auto pslice = blaze::pageslice(schur_product, p); + result(p, i, c) = blaze::sum(pslice); + } + } + } + } + + return execution_tree::primitive_argument_type{std::move(result)}; + } + } // namespace detail + + /////////////////////////////////////////////////////////////////////////// + execution_tree::primitive_argument_type dist_conv1d::conv1d_all_paddings( + ir::node_data&& arg, ir::node_data&& kernel, + execution_tree::localities_information&& arg_locs, + execution_tree::localities_information&& kernel_locs, + std::string&& padding, std::string&& given_name) const + { + using namespace execution_tree; + std::uint32_t const loc_id = arg_locs.locality_.locality_id_; + std::uint32_t const numtiles = arg_locs.locality_.num_localities_; + std::uint32_t const numtiles_k = kernel_locs.locality_.num_localities_; + + // tiling start and stop of the result tensor + std::int64_t res_page_start, res_page_stop, res_row_start, res_row_stop, + res_col_start, res_col_stop; + primitive_argument_type local_result; + + if (numtiles > 1 && numtiles_k == 1) + { + std::size_t filter_length = kernel.tensor().pages(); + + // parallelization mode is data, spatial or a combination of both + std::string base_name = + given_name.empty() ? arg_locs.annotation_.name_ : given_name; + + // updating the generation of localities annotation ; + annotation_information ann_info( + std::move(base_name), ++arg_locs.annotation_.generation_); + + auto locality_ann = arg_locs.locality_.as_annotation(); + + res_col_start = 0; + res_col_stop = kernel_locs.columns(name_, codename_); + + tiling_information_3d tile_info( + arg_locs.tiles_[loc_id], name_, codename_); + res_page_start = tile_info.spans_[0].start_; + res_page_stop = tile_info.spans_[0].stop_; + std::int64_t arg_row_start = tile_info.spans_[1].start_; + std::int64_t arg_row_stop = tile_info.spans_[1].stop_; + + if (padding == "valid" || arg_locs.is_page_tiled(name_, codename_)) + { + res_row_start = arg_row_start; + local_result = common::conv1d_all_paddings( + ir::node_data(std::move(arg)), std::move(kernel), + std::move(padding), name_, codename_); + + // getting res_row_stop considering the padding + res_row_stop = padding == "valid" ? + arg_row_stop - filter_length + 1 : + arg_row_stop; + } + else + { + // spatial parallelization where padding is same or causal + std ::size_t pad_top; + if (padding == "same") + { + pad_top = (filter_length - 1) / 2; + } + else // causal + { + pad_top = filter_length - 1; + } + if (arg_row_start == 0) + { + // one-sided pad from top + // same or causal padding + local_result = detail::conv1d_pad_top_bottom( + ir::node_data(std::move(arg)), + std::move(kernel), pad_top, true, name_, codename_); + res_row_start = 0; + res_row_stop = pad_top + arg_row_stop - filter_length + 1; + } + else + { + res_row_start = pad_top + arg_row_start; + if (padding != "causal" && + arg_row_stop == arg_locs.rows(name_, codename_)) + { + // one-sided pad from bottom only in same padding + local_result = detail::conv1d_pad_top_bottom( + ir::node_data(std::move(arg)), + std::move(kernel), filter_length - 1 - pad_top, + false, name_, codename_); + res_row_stop = res_row_start + arg_row_stop - + arg_row_start - pad_top; + } + else + { + // no padding (valid) + // middle parts of the array for the same padding + // non-top part of the array for the causal padding + local_result = common::conv1d_all_paddings( + ir::node_data(std::move(arg)), + std::move(kernel), "valid", name_, codename_); + res_row_stop = res_row_start + arg_row_stop - + arg_row_start - filter_length + 1; + } + } + } + + tiling_information_3d res_tile_info = tiling_information_3d( + tiling_span(res_page_start, res_page_stop), + tiling_span(res_row_start, res_row_stop), + tiling_span(res_col_start, res_col_stop)); + auto attached_annotation = + std::make_shared(localities_annotation(locality_ann, + res_tile_info.as_annotation(name_, codename_), ann_info, + name_, codename_)); + + // construct new tiling annotation + local_result.set_annotation(attached_annotation); + return local_result; + } + + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "dist_conv1d::conv1d_all_paddings", + generate_error_message("at this point only data and spatial " + "parallelizans are supported")); + } + + execution_tree::primitive_argument_type dist_conv1d::conv1d_all_paddings( + execution_tree::primitive_argument_type&& arg, + execution_tree::primitive_argument_type&& kernel, + std::string&& padding, std::string&& given_name) const + { + using namespace execution_tree; + if (arg.has_annotation() || kernel.has_annotation()) + { + localities_information arg_locs = + extract_localities_information(arg, name_, codename_); + localities_information kernel_locs = + extract_localities_information(kernel, name_, codename_); + return conv1d_all_paddings( + extract_numeric_value(std::move(arg), name_, codename_), + extract_numeric_value(std::move(kernel), name_, codename_), + std::move(arg_locs), std::move(kernel_locs), std::move(padding), + std::move(given_name)); + } + + return common::conv1d_all_paddings( + extract_numeric_value(std::move(arg), name_, codename_), + extract_numeric_value(std::move(kernel), name_, codename_), + std::move(padding), name_, codename_); + } + + /////////////////////////////////////////////////////////////////////////// + hpx::future dist_conv1d::eval( + execution_tree::primitive_arguments_type const& operands, + execution_tree::primitive_arguments_type const& args, + execution_tree::eval_context ctx) const + { + if (operands.size() < 2 || operands.size() > 6) + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "dist_conv1d::eval", + generate_error_message("the dist_conv1d primitive requires " + "between 2 and 6 operands")); + } + + for (auto const& i : operands) + { + if (!valid(i)) + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, "dist_conv1d::eval", + generate_error_message( + "the conv1d_d primitive requires that the arguments " + "given by the operands array are valid")); + } + } + + auto this_ = this->shared_from_this(); + return hpx::dataflow(hpx::launch::sync, + hpx::util::unwrapping([this_ = std::move(this_)]( + execution_tree::primitive_arguments_type&& args) + -> execution_tree::primitive_argument_type + { + using namespace execution_tree; + + std::size_t ndim = extract_numeric_value_dimension( + args[0], this_->name_, this_->codename_); + + if (ndim != + extract_numeric_value_dimension( + args[1], this_->name_, this_->codename_) || + ndim != 3) + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "dist_conv1d::eval", + this_->generate_error_message( + "conv1d_d operation requires for x and kernel to be " + "tensors")); + } + + std::string padding = "valid"; + if (valid(args[2])) + { + padding = extract_string_value_strict( + args[2], this_->name_, this_->codename_); + + if (padding != "valid" && padding != "same" && + padding != "causal") + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "dist_conv1d::eval", + this_->generate_error_message( + "invalid padding. Padding can be either " + "`valid`, `same`, or `causal`")); + } + } + + + if (padding == "valid") + { + if (extract_numeric_value_dimensions( + args[0], this_->name_, this_->codename_)[1] < + extract_numeric_value_dimensions( + args[1], this_->name_, this_->codename_)[0]) + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "dist_conv1d::eval", + this_->generate_error_message( + "the kernel size cannot be greater than the " + "array size in the valid padding mode")); + } + } + + std::int64_t strides = 1; + if (valid(args[3])) + { + if (is_list_operand_strict(args[3])) + { + ir::range s = extract_list_value( + args[3], this_->name_, this_->codename_); + if (s.size() == 1) + { + strides = + extract_scalar_positive_integer_value_strict( + *s.begin()); + } + else + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "dist_conv1d::eval", + this_->generate_error_message( + "conv1d_d requires the strides to " + "be of rank 1")); + } + } + else + { + strides = extract_scalar_positive_integer_value_strict( + args[3], this_->name_, this_->codename_); + } + } + + std::int64_t dilation_rate = 1; + if (valid(args[4])) + { + if (is_list_operand_strict(args[4])) + { + ir::range d = extract_list_value( + args[4], this_->name_, this_->codename_); + if (d.size() == 1) + { + dilation_rate = + extract_scalar_positive_integer_value_strict( + *d.begin()); + } + else + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "dist_conv1d::eval", + this_->generate_error_message( + "conv1d_d requires the dilation_rate to be " + "of rank 1")); + } + } + else + { + dilation_rate = + extract_scalar_positive_integer_value_strict( + args[4], this_->name_, this_->codename_); + } + } + + if (strides != 1 && dilation_rate != 1) + { + HPX_THROW_EXCEPTION(hpx::bad_parameter, + "dist_conv1d::eval", + this_->generate_error_message( + "strides > 1 not supported in conjunction with " + "dilation_rate > 1")); + } + + std::string given_name = ""; + if (valid(args[5])) + { + given_name = extract_string_value(std::move(args[5]), + this_->name_, this_->codename_); + } + + if (strides == 1 && dilation_rate == 1) + { + return this_->conv1d_all_paddings(std::move(args[0]), + std::move(args[1]), std::move(padding), + std::move(given_name)); + } + + HPX_THROW_EXCEPTION(hpx::bad_parameter, "dist_conv1d::eval", + this_->generate_error_message( + "strides > 1 or dilation_rate > 1 are not currently " + "supported")); + }), + execution_tree::primitives::detail::map_operands(operands, + execution_tree::functional::value_operand{}, args, name_, + codename_, std::move(ctx))); + } +}}} diff --git a/src/plugins/dist_keras_support/dist_keras_support.cpp b/src/plugins/dist_keras_support/dist_keras_support.cpp new file mode 100644 index 000000000..422cd1490 --- /dev/null +++ b/src/plugins/dist_keras_support/dist_keras_support.cpp @@ -0,0 +1,15 @@ +// Copyright (c) 2020 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include + +#include + +PHYLANX_REGISTER_PLUGIN_MODULE(); + +PHYLANX_REGISTER_PLUGIN_FACTORY(dist_conv1d_plugin, + phylanx::dist_keras_support::primitives::dist_conv1d::match_data); diff --git a/src/plugins/keras_support/CMakeLists.txt b/src/plugins/keras_support/CMakeLists.txt index 889b052e8..ae1a5c2ee 100644 --- a/src/plugins/keras_support/CMakeLists.txt +++ b/src/plugins/keras_support/CMakeLists.txt @@ -9,7 +9,8 @@ add_phylanx_primitive_plugin(keras_support AUTOGLOB PLUGIN FOLDER "Core/Plugins" - COMPONENT_DEPENDENCIES phylanx) + COMPONENT_DEPENDENCIES phylanx + DEPENDENCIES common) add_phylanx_pseudo_target(primitives.keras_support_dir.keras_support_plugin) add_phylanx_pseudo_dependencies(primitives.keras_support_dir diff --git a/src/plugins/keras_support/conv1d_operation.cpp b/src/plugins/keras_support/conv1d_operation.cpp index c92d7ee94..24dc16c2b 100644 --- a/src/plugins/keras_support/conv1d_operation.cpp +++ b/src/plugins/keras_support/conv1d_operation.cpp @@ -7,10 +7,10 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -23,9 +23,6 @@ #include #include -#include -#include - /////////////////////////////////////////////////////////////////////////////// namespace phylanx { namespace execution_tree { namespace primitives { @@ -71,455 +68,6 @@ namespace phylanx { namespace execution_tree { namespace primitives : primitive_component_base(std::move(operands), name, codename) {} - /////////////////////////////////////////////////////////////////////////// - primitive_argument_type conv1d_operation::conv1d_valid( - ir::node_data&& arg, ir::node_data&& kernel) const - { - auto a = arg.tensor(); - auto k = kernel.tensor(); - std::size_t batch = a.pages(); - std::size_t filter_length = k.pages(); - std::size_t in_channels = a.columns(); - std::size_t out_channels = k.columns(); - std::size_t result_length = a.rows() - filter_length + 1; - - blaze::DynamicTensor result(batch, result_length, out_channels); - - for (std::size_t c = 0; c != out_channels; ++c) - { - auto kslice = blaze::columnslice(k, c); - for (std::size_t i = 0; i != result_length; ++i) - { - auto schur_product = blaze::subtensor(a, 0, i, 0, batch, - filter_length, in_channels) % - kslice; - for (std::size_t p = 0; p != batch; ++p) - { - auto pslice = blaze::pageslice(schur_product, p); - result(p, i, c) = blaze::sum(pslice); - } - } - } - return primitive_argument_type{std::move(result)}; - } - - primitive_argument_type conv1d_operation::conv1d_valid( - ir::node_data&& arg, ir::node_data&& kernel, - std::int64_t strides) const - { - auto a = arg.tensor(); - auto k = kernel.tensor(); - std::size_t batch = a.pages(); - std::size_t filter_length = k.pages(); - std::size_t in_channels = a.columns(); - std::size_t out_channels = k.columns(); - std::size_t result_length = blaze::ceil( - static_cast(a.rows() - filter_length + 1) / strides); - - blaze::DynamicTensor result(batch, result_length, out_channels); - - for (std::size_t c = 0; c != out_channels; ++c) - { - auto kslice = blaze::columnslice(k, c); - for (std::size_t i = 0; i != result_length; ++i) - { - auto schur_product = blaze::subtensor(a, 0, i * strides, 0, - batch, filter_length, in_channels) % - kslice; - for (std::size_t p = 0; p != batch; ++p) - { - auto pslice = blaze::pageslice(schur_product, p); - result(p, i, c) = blaze::sum(pslice); - } - } - } - return primitive_argument_type{std::move(result)}; - } - - primitive_argument_type conv1d_operation::conv1d_valid_dilation( - ir::node_data&& arg, ir::node_data&& kernel, - std::int64_t dilation_rate) const - { - auto a = arg.tensor(); - auto k = kernel.tensor(); - auto filter_length = static_cast(k.pages()); - auto data_length = static_cast(a.rows()); - std::size_t batch = a.pages(); - std::size_t in_channels = a.columns(); - std::size_t out_channels = k.columns(); - - std::int64_t result_length = - data_length - dilation_rate * (filter_length - 1); - - if(result_length <= 0) - HPX_THROW_EXCEPTION(hpx::bad_parameter, - "conv1d_operation::eval", - generate_error_message("this dilation_rate causes non-positive " - "result_length where padding is valid")); - - blaze::DynamicTensor result(batch, result_length, out_channels); - - for (std::size_t c = 0; c != out_channels; ++c) - { - auto kslice = blaze::columnslice(k, c); - for (std::size_t i = 0; i != result_length; ++i) - { - auto schur_product = - blaze::dilatedsubtensor(a, 0, i, 0, batch, filter_length, - in_channels, 1, dilation_rate, 1) % - kslice; - for (std::size_t p = 0; p != batch; ++p) - { - auto pslice = blaze::pageslice(schur_product, p); - result(p, i, c) = blaze::sum(pslice); - } - } - } - return primitive_argument_type{std::move(result)}; - } - - /////////////////////////////////////////////////////////////////////////// - primitive_argument_type conv1d_operation::conv1d_same( - ir::node_data&& arg, ir::node_data&& kernel) const - { - auto a = arg.tensor(); - auto k = kernel.tensor(); - auto filter_length = static_cast(k.pages()); - auto data_length = static_cast(a.rows()); - std::size_t batch = a.pages(); - std::size_t in_channels = a.columns(); - std::size_t out_channels = k.columns(); - - std::int64_t pad_left = (filter_length - 1) / 2; - - blaze::DynamicTensor result(batch, data_length, out_channels); - - for (std::size_t c = 0; c != out_channels; ++c) - { - auto kslice = blaze::columnslice(k, c); - for (std::size_t i = 0; i != data_length; ++i) - { - auto sub = conv_indices::get_subsizes( - data_length, filter_length, i - pad_left); - auto schur_product = blaze::subtensor(a, 0, sub.image_beg_, 0, - batch, sub.size_, in_channels) % - blaze::submatrix( - kslice, sub.kernel_beg_, 0, sub.size_, in_channels); - for (std::size_t p = 0; p != batch; ++p) - { - auto pslice = blaze::pageslice(schur_product, p); - result(p, i, c) = blaze::sum(pslice); - } - } - } - return primitive_argument_type{std::move(result)}; - } - - primitive_argument_type conv1d_operation::conv1d_same( - ir::node_data&& arg, ir::node_data&& kernel, - std::int64_t strides) const - { - auto a = arg.tensor(); - auto k = kernel.tensor(); - auto filter_length = static_cast(k.pages()); - auto data_length = static_cast(a.rows()); - std::size_t batch = a.pages(); - std::size_t in_channels = a.columns(); - std::size_t out_channels = k.columns(); - std::int64_t pad_width; - - if (data_length % strides == 0) - { - pad_width = filter_length > strides ? filter_length - strides : - static_cast(0); - } - else - { - pad_width = filter_length > (data_length % strides) ? - filter_length - (data_length % strides) : - static_cast(0); - } - - std::size_t result_length = blaze::ceil( - static_cast(data_length + pad_width - filter_length + 1) / - strides); - - blaze::DynamicTensor result(batch, result_length, out_channels); - std::size_t pad_left = pad_width / 2; - - for (std::size_t c = 0; c != out_channels; ++c) - { - auto kslice = blaze::columnslice(k, c); - for (std::size_t i = 0; i != result_length; ++i) - { - auto sub = conv_indices::get_subsizes( - data_length, filter_length, i * strides - pad_left); - auto schur_product = blaze::subtensor(a, 0, sub.image_beg_, 0, - batch, sub.size_, in_channels) % - blaze::submatrix( - kslice, sub.kernel_beg_, 0, sub.size_, in_channels); - for (std::size_t p = 0; p != batch; ++p) - { - auto pslice = blaze::pageslice(schur_product, p); - result(p, i, c) = blaze::sum(pslice); - } - } - } - return primitive_argument_type{std::move(result)}; - } - - primitive_argument_type conv1d_operation::conv1d_same_dilation( - ir::node_data&& arg, ir::node_data&& kernel, - std::int64_t dilation_rate) const - { - auto a = arg.tensor(); - auto k = kernel.tensor(); - auto filter_length = static_cast(k.pages()); - auto data_length = static_cast(a.rows()); - std::size_t batch = a.pages(); - std::size_t in_channels = a.columns(); - std::size_t out_channels = k.columns(); - std::int64_t pad_left = (dilation_rate * (filter_length - 1) ) / 2; - - blaze::DynamicTensor result(batch, data_length, out_channels, 0.); - - for (std::size_t c = 0; c != out_channels; ++c) - { - auto kslice = blaze::columnslice(k, c); - for (std::size_t i = 0; i != data_length; ++i) - { - auto sub = conv_indices::get_subsizes_dilated( - data_length, filter_length, i - pad_left, dilation_rate); - - if (sub.size_ == 0) - continue; - - auto schur_product = - blaze::dilatedsubtensor(a, 0, sub.image_beg_, 0, batch, - sub.size_, in_channels, 1, dilation_rate, 1) % - blaze::submatrix( - kslice, sub.kernel_beg_, 0, sub.size_, in_channels); - for (std::size_t p = 0; p != batch; ++p) - { - auto pslice = blaze::pageslice(schur_product, p); - result(p, i, c) = blaze::sum(pslice); - } - } - } - return primitive_argument_type{std::move(result)}; - } - - /////////////////////////////////////////////////////////////////////////// - namespace detail - { - using sizes = conv_indices::sizes; - inline sizes get_subsizes_causal(std::int64_t image_size, - std::int64_t kernel_size, std::int64_t relative_position) - { - if (relative_position < 0) - { - return sizes{ - 0, -relative_position, kernel_size + relative_position}; - } - - return sizes{relative_position, 0, kernel_size}; - } - - inline sizes get_subsizes_causal_dilated(std::int64_t image_size, - std::int64_t kernel_size, std::int64_t relative_position, - std::int64_t dilation_rate) - { - if (relative_position < 0) - { - std::int64_t remainder = relative_position % dilation_rate; - remainder = - remainder >= 0 ? remainder : dilation_rate + remainder; - std::int64_t corrected_kernel_size = kernel_size + - blaze::floor( - static_cast(relative_position) / dilation_rate); - - std::int64_t kernel_beg_ = blaze::ceil( - static_cast(-relative_position) / dilation_rate); - return sizes{remainder, kernel_beg_, corrected_kernel_size}; - } - - return sizes{relative_position, 0, kernel_size}; - } - } - - ///////////////////////////////////////////////////////////////////////////// - primitive_argument_type conv1d_operation::conv1d_causal( - ir::node_data&& arg, - ir::node_data&& kernel) const - { - auto a = arg.tensor(); - auto k = kernel.tensor(); - auto filter_length = static_cast(k.pages()); - auto data_length = static_cast(a.rows()); - std::size_t batch = a.pages(); - std::size_t in_channels = a.columns(); - std::size_t out_channels = k.columns(); - std::int64_t pad_left = filter_length - 1; // no pad_right - - blaze::DynamicTensor result(batch, data_length, out_channels); - - for (std::size_t c = 0; c != out_channels; ++c) - { - auto kslice = blaze::columnslice(k, c); - for (std::size_t i = 0; i != data_length; ++i) - { - auto sub = detail::get_subsizes_causal( - data_length, filter_length, i - pad_left); - auto schur_product = blaze::subtensor(a, 0, sub.image_beg_, 0, - batch, sub.size_, in_channels) % - blaze::submatrix( - kslice, sub.kernel_beg_, 0, sub.size_, in_channels); - for (std::size_t p = 0; p != batch; ++p) - { - auto pslice = blaze::pageslice(schur_product, p); - result(p, i, c) = blaze::sum(pslice); - } - } - } - return primitive_argument_type{std::move(result)}; - } - - primitive_argument_type conv1d_operation::conv1d_causal( - ir::node_data&& arg, ir::node_data&& kernel, - std::int64_t strides) const - { - auto a = arg.tensor(); - auto k = kernel.tensor(); - auto filter_length = static_cast(k.pages()); - auto data_length = static_cast(a.rows()); - std::size_t batch = a.pages(); - std::size_t in_channels = a.columns(); - std::size_t out_channels = k.columns(); - std::int64_t pad_left = filter_length - 1; // no pad_right - - std::size_t result_length = - blaze::ceil(static_cast(data_length) / strides); - - blaze::DynamicTensor result(batch, result_length, out_channels); - - for (std::size_t c = 0; c != out_channels; ++c) - { - auto kslice = blaze::columnslice(k, c); - for (std::size_t i = 0; i != result_length; ++i) - { - auto sub = detail::get_subsizes_causal( - data_length, filter_length, i * strides - pad_left); - auto schur_product = blaze::subtensor(a, 0, sub.image_beg_, 0, - batch, sub.size_, in_channels) % - blaze::submatrix( - kslice, sub.kernel_beg_, 0, sub.size_, in_channels); - for (std::size_t p = 0; p != batch; ++p) - { - auto pslice = blaze::pageslice(schur_product, p); - result(p, i, c) = blaze::sum(pslice); - } - } - } - return primitive_argument_type{std::move(result)}; - } - - primitive_argument_type conv1d_operation::conv1d_causal_dilation( - ir::node_data&& arg, ir::node_data&& kernel, - std::int64_t dilation_rate) const - { - auto a = arg.tensor(); - auto k = kernel.tensor(); - auto filter_length = static_cast(k.pages()); - auto data_length = static_cast(a.rows()); - std::size_t batch = a.pages(); - std::size_t in_channels = a.columns(); - std::size_t out_channels = k.columns(); - std::int64_t pad_left = - dilation_rate * (filter_length - 1); // no pad_right - - blaze::DynamicTensor result(batch, data_length, out_channels); - - for (std::size_t c = 0; c != out_channels; ++c) - { - auto kslice = blaze::columnslice(k, c); - for (std::size_t i = 0; i != data_length; ++i) - { - auto sub = detail::get_subsizes_causal_dilated( - data_length, filter_length, i - pad_left, dilation_rate); - - if (sub.size_ == 0) - continue; - - auto schur_product = - blaze::dilatedsubtensor(a, 0, sub.image_beg_, 0, batch, - sub.size_, in_channels, 1, dilation_rate, 1) % - blaze::submatrix( - kslice, sub.kernel_beg_, 0, sub.size_, in_channels); - for (std::size_t p = 0; p != batch; ++p) - { - auto pslice = blaze::pageslice(schur_product, p); - result(p, i, c) = blaze::sum(pslice); - } - } - } - return primitive_argument_type{std::move(result)}; - } - - /////////////////////////////////////////////////////////////////////////// - primitive_argument_type conv1d_operation::conv1d_any_pad( - ir::node_data&& arg, ir::node_data&& kernel, - std::string&& padding) const - { - if (padding == "valid") - { - return conv1d_valid(std::move(arg), std::move(kernel)); - } - if (padding == "same") - { - return conv1d_same(std::move(arg), std::move(kernel)); - } - - // padding == causal - return conv1d_causal(std::move(arg), std::move(kernel)); - } - - primitive_argument_type conv1d_operation::conv1d_any_pad( - ir::node_data&& arg, ir::node_data&& kernel, - std::string&& padding, std::int64_t strides) const - { - if (padding == "valid") - { - return conv1d_valid(std::move(arg), std::move(kernel), strides); - } - if (padding == "same") - { - return conv1d_same(std::move(arg), std::move(kernel), strides); - } - - // padding == causal - return conv1d_causal(std::move(arg), std::move(kernel), strides); - } - - primitive_argument_type conv1d_operation::conv1d_any_pad_dilation( - ir::node_data&& arg, ir::node_data&& kernel, - std::string&& padding, std::int64_t dilation_rate) const - { - if (padding == "valid") - { - return conv1d_valid_dilation( - std::move(arg), std::move(kernel), dilation_rate); - } - if (padding == "same") - { - return conv1d_same_dilation( - std::move(arg), std::move(kernel), dilation_rate); - } - - // padding == causal - return conv1d_causal_dilation( - std::move(arg), std::move(kernel), dilation_rate); - } - /////////////////////////////////////////////////////////////////////////// hpx::future conv1d_operation::eval( primitive_arguments_type const& operands, @@ -668,30 +216,32 @@ namespace phylanx { namespace execution_tree { namespace primitives if (strides == 1 && dilation_rate == 1) { - return this_->conv1d_any_pad( + return common::conv1d_all_paddings( extract_numeric_value( std::move(args[0]), this_->name_, this_->codename_), extract_numeric_value( std::move(args[1]), this_->name_, this_->codename_), - std::move(padding)); + std::move(padding), this_->name_, this_->codename_); } if (dilation_rate == 1) // strides > 1 { - return this_->conv1d_any_pad( + return common::conv1d_all_paddings( extract_numeric_value( std::move(args[0]), this_->name_, this_->codename_), extract_numeric_value( std::move(args[1]), this_->name_, this_->codename_), - std::move(padding), strides); + std::move(padding), strides, this_->name_, + this_->codename_); } // strides == 1 and dilation_rate > 1 - return this_->conv1d_any_pad_dilation( + return common::conv1d_all_paddings_dilation( extract_numeric_value( std::move(args[0]), this_->name_, this_->codename_), extract_numeric_value( std::move(args[1]), this_->name_, this_->codename_), - std::move(padding), dilation_rate); + std::move(padding), dilation_rate, this_->name_, + this_->codename_); }), detail::map_operands(operands, functional::value_operand{}, args, name_, codename_, std::move(ctx))); diff --git a/src/plugins/matrixops/argsort.cpp b/src/plugins/matrixops/argsort.cpp index be745a167..b84f48d35 100644 --- a/src/plugins/matrixops/argsort.cpp +++ b/src/plugins/matrixops/argsort.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include diff --git a/tests/regressions/execution_tree/1213_timer_problem.cpp b/tests/regressions/execution_tree/1213_timer_problem.cpp new file mode 100644 index 000000000..a3bb65df7 --- /dev/null +++ b/tests/regressions/execution_tree/1213_timer_problem.cpp @@ -0,0 +1,57 @@ +// Copyright (c) 2020 Bita Hasheminezhad +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +char const* const conv1d_code = R"(block( + define(conv, + block( + define(array, + random_d(list(8, 10, 2))), + define(kernel, + random(list(4, 2, 100))), + timer( + conv1d_d(array, kernel), + lambda(time, cout("locality", find_here(), ":", time)) + ) + ) + ), + conv +))"; + +//////////////////////////////////////////////////////////////////////////////// +int hpx_main(int argc, char* argv[]) +{ + using namespace phylanx::execution_tree; + + // compile the given code + compiler::function_list snippets; + auto const& compiled_code = compile("conv", conv1d_code, snippets); + auto conv = compiled_code.run(); + + + conv(); + + return hpx::finalize(); +} + +int main(int argc, char* argv[]) +{ + std::vector cfg = { "hpx.run_hpx_main!=1" }; + + return hpx::init(argc, argv, cfg); +} diff --git a/tests/regressions/execution_tree/543_compile_twice.cpp b/tests/regressions/execution_tree/543_compile_twice.cpp index 59c79e831..6cc08caa3 100644 --- a/tests/regressions/execution_tree/543_compile_twice.cpp +++ b/tests/regressions/execution_tree/543_compile_twice.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/regressions/execution_tree/817_cout_nil.cpp b/tests/regressions/execution_tree/817_cout_nil.cpp index 666a59cad..85b36a2db 100644 --- a/tests/regressions/execution_tree/817_cout_nil.cpp +++ b/tests/regressions/execution_tree/817_cout_nil.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/regressions/execution_tree/CMakeLists.txt b/tests/regressions/execution_tree/CMakeLists.txt index 6c43c6770..ff74b8e98 100644 --- a/tests/regressions/execution_tree/CMakeLists.txt +++ b/tests/regressions/execution_tree/CMakeLists.txt @@ -11,6 +11,7 @@ set(tests 817_cout_nil 817_lambda_nil 1198_inaccessible_variable + 1213_timer_problem allow_empty_blocks_278 assign_variable_twice_491 assign_wrong_variable_245 @@ -45,6 +46,7 @@ set(out_of_scope_variable_232_FLAGS DEPENDENCIES HPX::iostreams_component) set(external_functions_337_FLAGS DEPENDENCIES HPX::iostreams_component) set(random_d_1139_PARAMETERS LOCALITIES 2) +set(1213_timer_problem_PARAMETERS LOCALITIES 2) foreach(test ${tests}) set(sources ${test}.cpp) diff --git a/tests/regressions/execution_tree/allow_return_nil_432.cpp b/tests/regressions/execution_tree/allow_return_nil_432.cpp index 8e23a3a1c..7f4a8b2bc 100644 --- a/tests/regressions/execution_tree/allow_return_nil_432.cpp +++ b/tests/regressions/execution_tree/allow_return_nil_432.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include diff --git a/tests/regressions/execution_tree/assign_variable_twice_491.cpp b/tests/regressions/execution_tree/assign_variable_twice_491.cpp index cfa49838e..7f7a85604 100644 --- a/tests/regressions/execution_tree/assign_variable_twice_491.cpp +++ b/tests/regressions/execution_tree/assign_variable_twice_491.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/regressions/execution_tree/assign_wrong_variable_245.cpp b/tests/regressions/execution_tree/assign_wrong_variable_245.cpp index af03da4a4..4c34b5e03 100644 --- a/tests/regressions/execution_tree/assign_wrong_variable_245.cpp +++ b/tests/regressions/execution_tree/assign_wrong_variable_245.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/regressions/execution_tree/cout_noargs_prints_nothing_159.cpp b/tests/regressions/execution_tree/cout_noargs_prints_nothing_159.cpp index 9181c4e42..a8df7c10d 100644 --- a/tests/regressions/execution_tree/cout_noargs_prints_nothing_159.cpp +++ b/tests/regressions/execution_tree/cout_noargs_prints_nothing_159.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/regressions/execution_tree/cout_prints_twice_155.cpp b/tests/regressions/execution_tree/cout_prints_twice_155.cpp index 6c786bf32..8934925db 100644 --- a/tests/regressions/execution_tree/cout_prints_twice_155.cpp +++ b/tests/regressions/execution_tree/cout_prints_twice_155.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/regressions/execution_tree/define_loses_values_177.cpp b/tests/regressions/execution_tree/define_loses_values_177.cpp index 4e6a30e79..b0ad46945 100644 --- a/tests/regressions/execution_tree/define_loses_values_177.cpp +++ b/tests/regressions/execution_tree/define_loses_values_177.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/regressions/execution_tree/empty_hstack_509.cpp b/tests/regressions/execution_tree/empty_hstack_509.cpp index 4e3258a25..accfb622f 100644 --- a/tests/regressions/execution_tree/empty_hstack_509.cpp +++ b/tests/regressions/execution_tree/empty_hstack_509.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/regressions/execution_tree/external_functions_337.cpp b/tests/regressions/execution_tree/external_functions_337.cpp index 651cba073..252dc7d15 100644 --- a/tests/regressions/execution_tree/external_functions_337.cpp +++ b/tests/regressions/execution_tree/external_functions_337.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/regressions/execution_tree/list_iter_space_429.cpp b/tests/regressions/execution_tree/list_iter_space_429.cpp index 75c2446e2..5350966e1 100644 --- a/tests/regressions/execution_tree/list_iter_space_429.cpp +++ b/tests/regressions/execution_tree/list_iter_space_429.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/regressions/execution_tree/list_of_variables_244.cpp b/tests/regressions/execution_tree/list_of_variables_244.cpp index 104ef7dab..cae46c265 100644 --- a/tests/regressions/execution_tree/list_of_variables_244.cpp +++ b/tests/regressions/execution_tree/list_of_variables_244.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/regressions/execution_tree/out_of_scope_variable_232.cpp b/tests/regressions/execution_tree/out_of_scope_variable_232.cpp index a839c70af..d117e7901 100644 --- a/tests/regressions/execution_tree/out_of_scope_variable_232.cpp +++ b/tests/regressions/execution_tree/out_of_scope_variable_232.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/regressions/execution_tree/replace_names_374.cpp b/tests/regressions/execution_tree/replace_names_374.cpp index 607811936..7421cf241 100644 --- a/tests/regressions/execution_tree/replace_names_374.cpp +++ b/tests/regressions/execution_tree/replace_names_374.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include diff --git a/tests/regressions/execution_tree/vector_of_variables_244.cpp b/tests/regressions/execution_tree/vector_of_variables_244.cpp index 886ead0e8..946fac75d 100644 --- a/tests/regressions/execution_tree/vector_of_variables_244.cpp +++ b/tests/regressions/execution_tree/vector_of_variables_244.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/distributed/remote_add.cpp b/tests/unit/distributed/remote_add.cpp index 3517ebaa5..a5c386a15 100644 --- a/tests/unit/distributed/remote_add.cpp +++ b/tests/unit/distributed/remote_add.cpp @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/distributed/remote_run.cpp b/tests/unit/distributed/remote_run.cpp index 20fb65506..67ed0ce35 100644 --- a/tests/unit/distributed/remote_run.cpp +++ b/tests/unit/distributed/remote_run.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/execution_tree/annotation_2_loc.cpp b/tests/unit/execution_tree/annotation_2_loc.cpp index f3089d4d9..53d3d7099 100644 --- a/tests/unit/execution_tree/annotation_2_loc.cpp +++ b/tests/unit/execution_tree/annotation_2_loc.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/execution_tree/primitives/CMakeLists.txt b/tests/unit/execution_tree/primitives/CMakeLists.txt index 9acf41a32..6c0ea6da3 100644 --- a/tests/unit/execution_tree/primitives/CMakeLists.txt +++ b/tests/unit/execution_tree/primitives/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2018 Hartmut Kaiser +# Copyright (c) 2017-2020 Hartmut Kaiser # # Distributed under the Boost Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -15,6 +15,7 @@ set(tests invoke_operation literal_value store_operation + timer ) foreach(test ${tests}) diff --git a/tests/unit/execution_tree/primitives/timer.cpp b/tests/unit/execution_tree/primitives/timer.cpp new file mode 100644 index 000000000..12f7742f9 --- /dev/null +++ b/tests/unit/execution_tree/primitives/timer.cpp @@ -0,0 +1,53 @@ +// Copyright (c) 2020 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +#include + +#include +#include +#include + +#include +#include + +void test_timer_operation(char const* expr, double expected) +{ + phylanx::execution_tree::compiler::function_list snippets; + auto const& code = phylanx::execution_tree::compile(expr, snippets); + auto f = code.run(); + + HPX_TEST_EQ(expected, + phylanx::execution_tree::extract_numeric_value( + f() + )[0]); +} + +int hpx_main(int argc, char* argv[]) +{ + test_timer_operation(R"( + timer( + block( + define(x, 3.14), + x + ), + lambda(x, debug("time: ", x, " [s]")) + ) + )", 3.14); + + return hpx::finalize(); +} + +int main(int argc, char* argv[]) +{ + HPX_TEST_EQ(hpx::init(argc, argv), 0); + + std::stringstream const& strm = hpx::get_consolestream(); + std::string result = strm.str(); + HPX_TEST(result.find("time: ") == 0); + HPX_TEST(result.find(" [s]") == result.size() - 5); + + return hpx::util::report_errors(); +} diff --git a/tests/unit/plugins/CMakeLists.txt b/tests/unit/plugins/CMakeLists.txt index bc2c06120..615689ed4 100644 --- a/tests/unit/plugins/CMakeLists.txt +++ b/tests/unit/plugins/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2018 Hartmut Kaiser +# Copyright (c) 2018-2020 Hartmut Kaiser # # Distributed under the Boost Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,6 +7,7 @@ set(subdirs arithmetics booleans controls + dist_keras_support dist_matrixops fileio keras_support diff --git a/tests/unit/plugins/dist_keras_support/CMakeLists.txt b/tests/unit/plugins/dist_keras_support/CMakeLists.txt new file mode 100644 index 000000000..3e7f470a0 --- /dev/null +++ b/tests/unit/plugins/dist_keras_support/CMakeLists.txt @@ -0,0 +1,38 @@ +# Copyright (c) 2020 Hartmut Kaiser +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +set(tests + dist_conv1d_2_loc + dist_conv1d_3_loc + dist_conv1d_4_loc + ) + +set(dist_conv1d_2_loc_PARAMETERS LOCALITIES 2) +set(dist_conv1d_3_loc_PARAMETERS LOCALITIES 3) +set(dist_conv1d_4_loc_PARAMETERS LOCALITIES 4) + + +foreach(test ${tests}) + set(sources ${test}.cpp) + + source_group("Source Files" FILES ${sources}) + + # add executable + add_phylanx_executable(${test}_test + SOURCES ${sources} + ${${test}_FLAGS} + EXCLUDE_FROM_ALL + FOLDER "Tests/Unit/Plugins/DistKerasSupport") + + add_phylanx_unit_test("plugins.dist_keras_support" ${test} ${${test}_PARAMETERS}) + + add_phylanx_pseudo_target(tests.unit.plugins.dist_keras_support.${test}) + add_phylanx_pseudo_dependencies(tests.unit.plugins.dist_keras_support + tests.unit.plugins.dist_keras_support.${test}) + add_phylanx_pseudo_dependencies(tests.unit.plugins.dist_keras_support.${test} + ${test}_test_exe) + +endforeach() + diff --git a/tests/unit/plugins/dist_keras_support/dist_conv1d_2_loc.cpp b/tests/unit/plugins/dist_keras_support/dist_conv1d_2_loc.cpp new file mode 100644 index 000000000..28a973a5c --- /dev/null +++ b/tests/unit/plugins/dist_keras_support/dist_conv1d_2_loc.cpp @@ -0,0 +1,356 @@ +// Copyright (c) 2020 Bita Hasheminezhad +// Copyright (c) 2020 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +#include + +#include +#include +#include +#include + +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +phylanx::execution_tree::primitive_argument_type compile_and_run( + std::string const& name, std::string const& codestr) +{ + phylanx::execution_tree::compiler::function_list snippets; + phylanx::execution_tree::compiler::environment env = + phylanx::execution_tree::compiler::default_environment(); + + auto const& code = + phylanx::execution_tree::compile(name, codestr, snippets, env); + return code.run().arg_; +} + +void test_conv1d_d_d_operation(std::string const& name, std::string const& code, + std::string const& expected_str) +{ + phylanx::execution_tree::primitive_argument_type result = + compile_and_run(name, code); + phylanx::execution_tree::primitive_argument_type comparison = + compile_and_run(name, expected_str); + + HPX_TEST_EQ(hpx::cout, result, comparison); +} + +/////////////////////////////////////////////////////////////////////////////// +// data parallelizaion with valid padding. The array is tiled on its pages and +// the filter is local +char const* const conv1d_d_code1 = R"( + conv1d_d( + constant_d(1, list(8, 6, 3), nil, nil, "const1", "page"), + constant(-1, list(4, 3, 5)), + "valid", + 1, + 1, + "conv_result" + ))"; +char const* const res_code1 = R"( + constant_d(-12, list(8, 3, 5), nil, nil, "conv_result/1", "page") +)"; + +// data parallelizaion with same padding. The array is tiled on its pages and +// the filter is local +char const* const conv1d_d_code2 = R"( + conv1d_d( + constant_d(1, list(4, 6, 2), nil, nil, "data_par", "page"), + constant(-1, list(4, 2, 3)), + "same" + ))"; + +// data parallelizaion with causal padding. The array is tiled on its pages and +// the filter is local +char const* const conv1d_d_code3 = R"( + conv1d_d( + constant_d(1, list(2, 6, 2), nil, nil, "data_par_causal", "page"), + constant(2, list(4, 2, 3)), + "causal" + ))"; + +void test_conv1d_d_0() +{ + test_conv1d_d_d_operation("test_conv1d_d__0", conv1d_d_code1, res_code1); +} + +void test_conv1d_d_1() +{ + if (hpx::get_locality_id() == 0) + { + test_conv1d_d_d_operation( + "test_conv1d_d__1", conv1d_d_code2, R"( + annotate_d([[[-6., -6., -6.], + [-8., -8., -8.], + [-8., -8., -8.], + [-8., -8., -8.], + [-6., -6., -6.], + [-4., -4., -4.]], + + [[-6., -6., -6.], + [-8., -8., -8.], + [-8., -8., -8.], + [-8., -8., -8.], + [-6., -6., -6.], + [-4., -4., -4.]]], + "data_par/1", list("tile", list("pages", 0, 2), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } + else + { + test_conv1d_d_d_operation( + "test_conv1d_d__1", conv1d_d_code2, R"( + annotate_d([[[-6., -6., -6.], + [-8., -8., -8.], + [-8., -8., -8.], + [-8., -8., -8.], + [-6., -6., -6.], + [-4., -4., -4.]], + + [[-6., -6., -6.], + [-8., -8., -8.], + [-8., -8., -8.], + [-8., -8., -8.], + [-6., -6., -6.], + [-4., -4., -4.]]], + "data_par/1", list("tile", list("pages", 2, 4), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } +} + +void test_conv1d_d_2() +{ + if (hpx::get_locality_id() == 0) + { + test_conv1d_d_d_operation( + "test_conv1d_d__2", conv1d_d_code3, R"( + annotate_d([[[ 4., 4., 4.], + [ 8., 8., 8.], + [12., 12., 12.], + [16., 16., 16.], + [16., 16., 16.], + [16., 16., 16.]]], + "data_par_causal/1", list("tile", list("pages", 0, 1), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } + else + { + test_conv1d_d_d_operation( + "test_conv1d_d__2", conv1d_d_code3, R"( + annotate_d([[[ 4., 4., 4.], + [ 8., 8., 8.], + [12., 12., 12.], + [16., 16., 16.], + [16., 16., 16.], + [16., 16., 16.]]], + "data_par_causal/1", list("tile", list("pages", 1, 2), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// spatial parallelization with valid padding, local kernel. The array is tiled +// on its rows and it has overlaps of fileter_length - 1 +void test_conv1d_d_3() +{ + if (hpx::get_locality_id() == 0) + { + test_conv1d_d_d_operation( + "test_conv1d_d__3", R"( + conv1d_d( + annotate_d( + [[[1,2],[3, 4],[5, 6]], + [[7,8],[9,10],[11,12]]], "arg_3", + list("tile", list("pages", 0, 2), list("rows", 0, 3), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 1, 1, 2, 1], [-1, 1, 1, 1]]], + "valid" + ) + )" , R"( + annotate_d([[[ 1., 12., 5., 5.], + [ 5., 24., 3., 5.]], + [[13., 48., -1., 5.], + [17., 60., -3., 5.]]], + "arg_3/1", list("tile", list("pages", 0, 2), + list("rows", 0, 2), list("columns", 0, 4)) + ) + )"); + } + else + { + test_conv1d_d_d_operation( + "test_conv1d_d__3", R"( + conv1d_d( + annotate_d( + [[[3,4], [5, 6], [7,8]], + [[9,10],[11,12],[1,2]]], "arg_3", + list("tile", list("pages", 0, 2), list("rows", 1, 4), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 1, 1, 2, 1], [-1, 1, 1, 1]]], + "valid" + ) + )" , R"( + annotate_d([[[ 5., 24., 3., 5.], + [ 9., 36., 1., 5.]], + [[ 17., 60., -3., 5.], + [ 21., 48., -41., -19.]]], + "arg_3/1", list("tile", list("pages", 0, 2), + list("rows", 1, 3), list("columns", 0, 4)) + ) + )"); + } +} + +// spatial parallelization with same padding, local kernel. The array is tiled +// on its rows and it has overlaps of fileter_length - 1 +void test_conv1d_d_4() +{ + if (hpx::get_locality_id() == 0) + { + test_conv1d_d_d_operation( + "test_conv1d_d__4", R"( + conv1d_d( + annotate_d( + [[[1,2],[3, 4],[5, 6]], + [[7,8],[9,10],[11,12]]], "arg_4", + list("tile", list("pages", 0, 2), list("rows", 0, 3), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 1, 1, 2, 1], [-1, 1, 1, 1]]], + "same" + ) + )" , R"( + annotate_d([[[ 1., 12., 5., 5.], + [ 5., 24., 3., 5.]], + [[ 13., 48., -1., 5.], + [ 17., 60., -3., 5.]]], + "arg_4/1", list("tile", list("pages", 0, 2), + list("rows", 0, 2), list("columns", 0, 4)) + ) + )"); + } + else + { + test_conv1d_d_d_operation( + "test_conv1d_d__4", R"( + conv1d_d( + annotate_d( + [[[3,4], [5, 6], [7,8]], + [[9,10],[11,12],[1,2]]], "arg_4", + list("tile", list("pages", 0, 2), list("rows", 1, 4), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 1, 1, 2, 1], [-1, 1, 1, 1]]], + "same" + ) + )" , R"( + annotate_d([[[ 5., 24., 3., 5.], + [ 9., 36., 1., 5.], + [ 14., 29., -29., -14.]], + [[ 17., 60., -3., 5.], + [ 21., 48., -41., -19.], + [ 2., 5., -5., -2.]]], + "arg_4/1", list("tile", list("pages", 0, 2), + list("rows", 1, 4), list("columns", 0, 4)) + ) + )"); + } +} + +// spatial parallelization with causal padding, local kernel. The array is tiled +// on its rows and it has overlaps of fileter_length - 1 +void test_conv1d_d_5() +{ + if (hpx::get_locality_id() == 0) + { + test_conv1d_d_d_operation( + "test_conv1d_d__5", R"( + conv1d_d( + annotate_d( + [[[1,2],[3, 4],[5, 6]], + [[7,8],[9,10],[11,12]]], "arg_5", + list("tile", list("pages", 0, 2), list("rows", 0, 3), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 1, 1, 2, 1], [-1, 1, 1, 1]]], + "causal" + ) + )" , R"( + annotate_d([[[-1., 3., 4., 3.], + [ 1., 12., 5., 5.], + [ 5., 24., 3., 5.]], + [[-1., 15., 22., 15.], + [13., 48., -1., 5.], + [17., 60., -3., 5.]]], + "arg_5/1", list("tile", list("pages", 0, 2), + list("rows", 0, 3), list("columns", 0, 4)) + ) + )"); + } + else + { + test_conv1d_d_d_operation( + "test_conv1d_d__5", R"( + conv1d_d( + annotate_d( + [[[3,4], [5, 6], [7,8]], + [[9,10],[11,12],[1,2]]], "arg_5", + list("tile", list("pages", 0, 2), list("rows", 1, 4), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 1, 1, 2, 1], [-1, 1, 1, 1]]], + "causal" + ) + )" , R"( + annotate_d([[[ 5., 24., 3., 5.], + [ 9., 36., 1., 5.]], + [[ 17., 60., -3., 5.], + [ 21., 48., -41., -19.]]], + "arg_5/1", list("tile", list("pages", 0, 2), + list("rows", 2, 4), list("columns", 0, 4)) + ) + )"); + } +} +/////////////////////////////////////////////////////////////////////////////// +int hpx_main(int argc, char* argv[]) +{ + test_conv1d_d_0(); + test_conv1d_d_1(); + test_conv1d_d_2(); + + test_conv1d_d_3(); + test_conv1d_d_4(); + test_conv1d_d_5(); + + hpx::finalize(); + return hpx::util::report_errors(); +} + +int main(int argc, char* argv[]) +{ + std::vector cfg = {"hpx.run_hpx_main!=1"}; + + return hpx::init(argc, argv, cfg); +} diff --git a/tests/unit/plugins/dist_keras_support/dist_conv1d_3_loc.cpp b/tests/unit/plugins/dist_keras_support/dist_conv1d_3_loc.cpp new file mode 100644 index 000000000..7c247c7e3 --- /dev/null +++ b/tests/unit/plugins/dist_keras_support/dist_conv1d_3_loc.cpp @@ -0,0 +1,458 @@ +// Copyright (c) 2020 Bita Hasheminezhad +// Copyright (c) 2020 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +#include + +#include +#include +#include +#include + +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +phylanx::execution_tree::primitive_argument_type compile_and_run( + std::string const& name, std::string const& codestr) +{ + phylanx::execution_tree::compiler::function_list snippets; + phylanx::execution_tree::compiler::environment env = + phylanx::execution_tree::compiler::default_environment(); + + auto const& code = + phylanx::execution_tree::compile(name, codestr, snippets, env); + return code.run().arg_; +} + +void test_conv1d_d_d_operation(std::string const& name, std::string const& code, + std::string const& expected_str) +{ + phylanx::execution_tree::primitive_argument_type result = + compile_and_run(name, code); + phylanx::execution_tree::primitive_argument_type comparison = + compile_and_run(name, expected_str); + + HPX_TEST_EQ(hpx::cout, result, comparison); +} + +/////////////////////////////////////////////////////////////////////////////// +// data parallelizaion with valid padding. The array is tiled on its pages and +// the filter is local +char const* const conv1d_d_code1 = R"( + conv1d_d( + constant_d(1, list(8, 6, 3), nil, nil, "const1", "page"), + constant(-1, list(4, 3, 5)), + "valid" + ))"; +char const* const res_code1 = R"( + constant_d(-12, list(8, 3, 5), nil, nil, "const1/1", "page") +)"; + +// data parallelizaion with same padding. The array is tiled on its pages and +// the filter is local +char const* const conv1d_d_code2 = R"( + conv1d_d( + constant_d(1, list(4, 6, 2), nil, nil, "data_par", "page"), + constant(-1, list(4, 2, 3)), + "same" + ))"; + +// data parallelizaion with causal padding. The array is tiled on its pages and +// the filter is local +char const* const conv1d_d_code3 = R"( + conv1d_d( + constant_d(1, list(3, 6, 2), nil, nil, "data_par_causal", "page"), + constant(2, list(4, 2, 3)), + "causal" + ))"; + +void test_conv1d_d_0() +{ + test_conv1d_d_d_operation("test_conv1d_d__0", conv1d_d_code1, res_code1); +} + +void test_conv1d_d_1() +{ + if (hpx::get_locality_id() == 0) + { + test_conv1d_d_d_operation( + "test_conv1d_d__1", conv1d_d_code2, R"( + annotate_d([[[-6., -6., -6.], + [-8., -8., -8.], + [-8., -8., -8.], + [-8., -8., -8.], + [-6., -6., -6.], + [-4., -4., -4.]], + + [[-6., -6., -6.], + [-8., -8., -8.], + [-8., -8., -8.], + [-8., -8., -8.], + [-6., -6., -6.], + [-4., -4., -4.]]], + "data_par/1", list("tile", list("pages", 0, 2), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } + else if (hpx::get_locality_id() == 1) + { + test_conv1d_d_d_operation( + "test_conv1d_d__1", conv1d_d_code2, R"( + annotate_d([[[-6., -6., -6.], + [-8., -8., -8.], + [-8., -8., -8.], + [-8., -8., -8.], + [-6., -6., -6.], + [-4., -4., -4.]]], + "data_par/1", list("tile", list("pages", 2, 3), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } + else + { + test_conv1d_d_d_operation( + "test_conv1d_d__1", conv1d_d_code2, R"( + annotate_d([[[-6., -6., -6.], + [-8., -8., -8.], + [-8., -8., -8.], + [-8., -8., -8.], + [-6., -6., -6.], + [-4., -4., -4.]]], + "data_par/1", list("tile", list("pages", 3, 4), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } +} + +void test_conv1d_d_2() +{ + if (hpx::get_locality_id() == 0) + { + test_conv1d_d_d_operation( + "test_conv1d_d__2", conv1d_d_code3, R"( + annotate_d([[[ 4., 4., 4.], + [ 8., 8., 8.], + [12., 12., 12.], + [16., 16., 16.], + [16., 16., 16.], + [16., 16., 16.]]], + "data_par_causal/1", list("tile", list("pages", 0, 1), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } + else if (hpx::get_locality_id() == 1) + { + test_conv1d_d_d_operation( + "test_conv1d_d__2", conv1d_d_code3, R"( + annotate_d([[[ 4., 4., 4.], + [ 8., 8., 8.], + [12., 12., 12.], + [16., 16., 16.], + [16., 16., 16.], + [16., 16., 16.]]], + "data_par_causal/1", list("tile", list("pages", 1, 2), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } + else + { + test_conv1d_d_d_operation( + "test_conv1d_d__2", conv1d_d_code3, R"( + annotate_d([[[ 4., 4., 4.], + [ 8., 8., 8.], + [12., 12., 12.], + [16., 16., 16.], + [16., 16., 16.], + [16., 16., 16.]]], + "data_par_causal/1", list("tile", list("pages", 2, 3), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// spatial parallelization with valid padding, local kernel. The array is tiled +// on its rows and it has overlaps of fileter_length - 1 +void test_conv1d_d_3() +{ + if (hpx::get_locality_id() == 0) + { + test_conv1d_d_d_operation( + "test_conv1d_d__3", R"( + conv1d_d( + annotate_d( + [[[1, 2], [3, 4], [5, 6]], + [[-1,-2],[-3,-4],[-5,-6]]], "arg_3loc_0", + list("tile", list("pages", 0, 2), list("rows", 0, 3), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 1, 1, 2, 1], [-1, 1, 1, 1]]], + "valid" + ) + )" , R"( + annotate_d([[[ 1., 12., 5., 5.], + [ 5., 24., 3., 5.]], + [[-1.,-12., -5., -5.], + [-5.,-24., -3., -5.]]], + "arg_3loc_0/1", list("tile", list("pages", 0, 2), + list("rows", 0, 2), list("columns", 0, 4)) + ) + )"); + } + else if (hpx::get_locality_id() == 1) + { + test_conv1d_d_d_operation( + "test_conv1d_d__3", R"( + conv1d_d( + annotate_d( + [[[3, 4], [5, 6], [7, 8], [9,10]], + [[-3,-4],[-5,-6],[-7,-8],[-9,-10]]], "arg_3loc_0", + list("tile", list("pages", 0, 2), list("rows", 1, 5), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 1, 1, 2, 1], [-1, 1, 1, 1]]], + "valid" + ) + )" , R"( + annotate_d([[[ 5., 24., 3., 5.], + [ 9., 36., 1., 5.], + [ 13., 48., -1., 5.]], + [[ -5., -24., -3., -5.], + [ -9., -36., -1., -5.], + [-13., -48., 1., -5.]]], + "arg_3loc_0/1", list("tile", list("pages", 0, 2), + list("rows", 1, 4), list("columns", 0, 4)) + ) + )"); + } + else + { + test_conv1d_d_d_operation( + "test_conv1d_d__3", R"( + conv1d_d( + annotate_d( + [[[7, 8],[9, 10], [11, 12]], + [[-7,-8],[-9,-10],[-11,-12]]], "arg_3loc_0", + list("tile", list("pages", 0, 2), list("rows", 3, 6), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 1, 1, 2, 1], [-1, 1, 1, 1]]], + "valid" + ) + )" , R"( + annotate_d([[[ 13., 48., -1., 5.], + [ 17., 60., -3., 5.]], + [[-13., -48., 1., -5.], + [-17., -60., 3., -5.]]], + "arg_3loc_0/1", list("tile", list("pages", 0, 2), + list("rows", 3, 5), list("columns", 0, 4)) + ) + )"); + } +} + +// spatial parallelization with same padding, local kernel. The array is tiled +// on its rows and it has overlaps of fileter_length - 1 +void test_conv1d_d_4() +{ + if (hpx::get_locality_id() == 0) + { + test_conv1d_d_d_operation( + "test_conv1d_d__4", R"( + conv1d_d( + annotate_d( + [[[1, 2], [3, 4], [5, 6]], + [[-1,-2],[-3,-4],[-5,-6]]], "arg_3loc_4", + list("tile", list("pages", 0, 2), list("rows", 0, 3), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 3, 1, 2,-1], [ 0, 1, 0,-1]]], + "same" + ) + )" , R"( + annotate_d([[[ 11., 12., 1., -9.], + [ 21., 24., -3., -17.]], + [[-11., -12., -1., 9.], + [-21., -24., 3., 17.]]], + "arg_3loc_4/1", list("tile", list("pages", 0, 2), + list("rows", 0, 2), list("columns", 0, 4)) + ) + )"); + } + else if (hpx::get_locality_id() == 1) + { + test_conv1d_d_d_operation( + "test_conv1d_d__4", R"( + conv1d_d( + annotate_d( + [[[3, 4], [5, 6], [7, 8], [9,10]], + [[-3,-4],[-5,-6],[-7,-8],[-9,-10]]], "arg_3loc_4", + list("tile", list("pages", 0, 2), list("rows", 1, 5), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 3, 1, 2,-1], [ 0, 1, 0,-1]]], + "same" + ) + )" , R"( + annotate_d([[[ 21., 24., -3., -17.], + [ 31., 36., -7., -25.], + [ 41., 48., -11., -33.]], + [[-21., -24., 3., 17.], + [-31., -36., 7., 25.], + [-41., -48., 11., 33.]]], + "arg_3loc_4/1", list("tile", list("pages", 0, 2), + list("rows", 1, 4), list("columns", 0, 4)) + ) + )"); + } + else + { + test_conv1d_d_d_operation( + "test_conv1d_d__4", R"( + conv1d_d( + annotate_d( + [[[7, 8],[9, 10], [11, 12]], + [[-7,-8],[-9,-10],[-11,-12]]], "arg_3loc_4", + list("tile", list("pages", 0, 2), list("rows", 3, 6), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 3, 1, 2,-1], [ 0, 1, 0,-1]]], + "same" + ) + )" , R"( + annotate_d([[[ 41., 48., -11., -33.], + [ 51., 60., -15., -41.], + [ 22., 45., -45., -22.]], + [[-41., -48., 11., 33.], + [-51., -60., 15., 41.], + [-22., -45., 45., 22.]]], + "arg_3loc_4/1", list("tile", list("pages", 0, 2), + list("rows", 3, 6), list("columns", 0, 4)) + ) + )"); + } +} + +// spatial parallelization with causal padding, local kernel. The array is tiled +// on its rows and it has overlaps of fileter_length - 1 +void test_conv1d_d_5() +{ + if (hpx::get_locality_id() == 0) + { + test_conv1d_d_d_operation( + "test_conv1d_d__5", R"( + conv1d_d( + annotate_d( + [[[1, 2], [3, 4], [5, 6]], + [[-1,-2],[-3,-4],[-5,-6]]], "arg_3loc_5", + list("tile", list("pages", 0, 2), list("rows", 0, 3), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 3, 1, 2,-1], [ 0, 1, 0,-1]]], + "causal" + ) + )" , R"( + annotate_d([[[ 3., 3., 2., -3.], + [ 11., 12., 1., -9.], + [ 21., 24., -3., -17.]], + [[ -3., -3., -2., 3.], + [-11., -12., -1., 9.], + [-21., -24., 3., 17.]]], + "arg_3loc_5/1", list("tile", list("pages", 0, 2), + list("rows", 0, 3), list("columns", 0, 4)) + ) + )"); + } + else if (hpx::get_locality_id() == 1) + { + test_conv1d_d_d_operation( + "test_conv1d_d__5", R"( + conv1d_d( + annotate_d( + [[[3, 4], [5, 6], [7, 8], [9,10]], + [[-3,-4],[-5,-6],[-7,-8],[-9,-10]]], "arg_3loc_5", + list("tile", list("pages", 0, 2), list("rows", 1, 5), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 3, 1, 2,-1], [ 0, 1, 0,-1]]], + "causal" + ) + )" , R"( + annotate_d([[[ 21., 24., -3., -17.], + [ 31., 36., -7., -25.], + [ 41., 48., -11., -33.]], + [[-21., -24., 3., 17.], + [-31., -36., 7., 25.], + [-41., -48., 11., 33.]]], + "arg_3loc_5/1", list("tile", list("pages", 0, 2), + list("rows", 2, 5), list("columns", 0, 4)) + ) + )"); + } + else + { + test_conv1d_d_d_operation( + "test_conv1d_d__5", R"( + conv1d_d( + annotate_d( + [[[7, 8],[9, 10], [11, 12]], + [[-7,-8],[-9,-10],[-11,-12]]], "arg_3loc_5", + list("tile", list("pages", 0, 2), list("rows", 3, 6), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 3, 1, 2,-1], [ 0, 1, 0,-1]]], + "causal" + ) + )" , R"( + annotate_d([[[ 41., 48., -11., -33.], + [ 51., 60., -15., -41.]], + [[-41., -48., 11., 33.], + [-51., -60., 15., 41.]]], + "arg_3loc_5/1", list("tile", list("pages", 0, 2), + list("rows", 4, 6), list("columns", 0, 4)) + ) + )"); + } +} + +/////////////////////////////////////////////////////////////////////////////// +int hpx_main(int argc, char* argv[]) +{ + test_conv1d_d_0(); + test_conv1d_d_1(); + test_conv1d_d_2(); + + test_conv1d_d_3(); + test_conv1d_d_4(); + test_conv1d_d_5(); + + hpx::finalize(); + return hpx::util::report_errors(); +} + +int main(int argc, char* argv[]) +{ + std::vector cfg = {"hpx.run_hpx_main!=1"}; + + return hpx::init(argc, argv, cfg); +} diff --git a/tests/unit/plugins/dist_keras_support/dist_conv1d_4_loc.cpp b/tests/unit/plugins/dist_keras_support/dist_conv1d_4_loc.cpp new file mode 100644 index 000000000..4ebbeff3a --- /dev/null +++ b/tests/unit/plugins/dist_keras_support/dist_conv1d_4_loc.cpp @@ -0,0 +1,429 @@ +// Copyright (c) 2020 Bita Hasheminezhad +// Copyright (c) 2020 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +#include + +#include +#include +#include +#include + +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +phylanx::execution_tree::primitive_argument_type compile_and_run( + std::string const& name, std::string const& codestr) +{ + phylanx::execution_tree::compiler::function_list snippets; + phylanx::execution_tree::compiler::environment env = + phylanx::execution_tree::compiler::default_environment(); + + auto const& code = + phylanx::execution_tree::compile(name, codestr, snippets, env); + return code.run().arg_; +} + +void test_conv1d_d_d_operation(std::string const& name, std::string const& code, + std::string const& expected_str) +{ + phylanx::execution_tree::primitive_argument_type result = + compile_and_run(name, code); + phylanx::execution_tree::primitive_argument_type comparison = + compile_and_run(name, expected_str); + + HPX_TEST_EQ(hpx::cout, result, comparison); +} + +/////////////////////////////////////////////////////////////////////////////// +// data parallelizaion with valid padding. The array is tiled on its pages and +// the filter is local +char const* const conv1d_d_code1 = R"( + conv1d_d( + constant_d(1, list(8, 6, 3), nil, nil, "const1", "page"), + constant(-1, list(4, 3, 5)), + "valid" + ))"; +char const* const res_code1 = R"( + constant_d(-12, list(8, 3, 5), nil, nil, "const1/1", "page") +)"; + +// data parallelizaion with same padding. The array is tiled on its pages and +// the filter is local +char const* const conv1d_d_code2 = R"( + conv1d_d( + constant_d(1, list(4, 6, 2), nil, nil, "data_par", "page"), + constant(-1, list(4, 2, 3)), + "same" + ))"; + +// data parallelizaion with causal padding. The array is tiled on its pages and +// the filter is local +char const* const conv1d_d_code3 = R"( + conv1d_d( + constant_d(1, list(4, 6, 2), nil, nil, "data_par_causal", "page"), + constant(2, list(4, 2, 3)), + "causal" + ))"; + +void test_conv1d_d_0() +{ + test_conv1d_d_d_operation("test_conv1d_d__0", conv1d_d_code1, res_code1); +} + +void test_conv1d_d_1() +{ + if (hpx::get_locality_id() == 0) + { + test_conv1d_d_d_operation( + "test_conv1d_d__1", conv1d_d_code2, R"( + annotate_d([[[-6., -6., -6.], + [-8., -8., -8.], + [-8., -8., -8.], + [-8., -8., -8.], + [-6., -6., -6.], + [-4., -4., -4.]]], + "data_par/1", list("tile", list("pages", 0, 1), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } + else if (hpx::get_locality_id() == 1) + { + test_conv1d_d_d_operation( + "test_conv1d_d__1", conv1d_d_code2, R"( + annotate_d([[[-6., -6., -6.], + [-8., -8., -8.], + [-8., -8., -8.], + [-8., -8., -8.], + [-6., -6., -6.], + [-4., -4., -4.]]], + "data_par/1", list("tile", list("pages", 1, 2), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } + else if (hpx::get_locality_id() == 2) + { + test_conv1d_d_d_operation( + "test_conv1d_d__1", conv1d_d_code2, R"( + annotate_d([[[-6., -6., -6.], + [-8., -8., -8.], + [-8., -8., -8.], + [-8., -8., -8.], + [-6., -6., -6.], + [-4., -4., -4.]]], + "data_par/1", list("tile", list("pages", 2, 3), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } + else + { + test_conv1d_d_d_operation( + "test_conv1d_d__1", conv1d_d_code2, R"( + annotate_d([[[-6., -6., -6.], + [-8., -8., -8.], + [-8., -8., -8.], + [-8., -8., -8.], + [-6., -6., -6.], + [-4., -4., -4.]]], + "data_par/1", list("tile", list("pages", 3, 4), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } +} + +void test_conv1d_d_2() +{ + if (hpx::get_locality_id() == 0) + { + test_conv1d_d_d_operation( + "test_conv1d_d__2", conv1d_d_code3, R"( + annotate_d([[[ 4., 4., 4.], + [ 8., 8., 8.], + [12., 12., 12.], + [16., 16., 16.], + [16., 16., 16.], + [16., 16., 16.]]], + "data_par_causal/1", list("tile", list("pages", 0, 1), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } + else if (hpx::get_locality_id() == 1) + { + test_conv1d_d_d_operation( + "test_conv1d_d__2", conv1d_d_code3, R"( + annotate_d([[[ 4., 4., 4.], + [ 8., 8., 8.], + [12., 12., 12.], + [16., 16., 16.], + [16., 16., 16.], + [16., 16., 16.]]], + "data_par_causal/1", list("tile", list("pages", 1, 2), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } + else if (hpx::get_locality_id() == 2) + { + test_conv1d_d_d_operation( + "test_conv1d_d__2", conv1d_d_code3, R"( + annotate_d([[[ 4., 4., 4.], + [ 8., 8., 8.], + [12., 12., 12.], + [16., 16., 16.], + [16., 16., 16.], + [16., 16., 16.]]], + "data_par_causal/1", list("tile", list("pages", 2, 3), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } + else + { + test_conv1d_d_d_operation( + "test_conv1d_d__2", conv1d_d_code3, R"( + annotate_d([[[ 4., 4., 4.], + [ 8., 8., 8.], + [12., 12., 12.], + [16., 16., 16.], + [16., 16., 16.], + [16., 16., 16.]]], + "data_par_causal/1", list("tile", list("pages", 3, 4), + list("rows", 0, 6), list("columns", 0, 3)) + ) + )"); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// spatial parallelization with valid padding, local kernel. The array is tiled +// on its rows and it has overlaps of fileter_length - 1 +void test_conv1d_d_3() +{ + if (hpx::get_locality_id() == 0) + { + test_conv1d_d_d_operation( + "test_conv1d_d__3", R"( + conv1d_d( + annotate_d( + [[[1, 2]], [[-1,-2]]], "arg_4loc_0", + list("tile", list("pages", 0, 2), list("rows", 0, 1), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]]], + "valid" + ) + )" , R"( + annotate_d([[[ 2., 5., -5., -2.]], + [[ -2., -5., 5., 2.]]], + "arg_4loc_0/1", list("tile", list("pages", 0, 2), + list("rows", 0, 1), list("columns", 0, 4)) + ) + )"); + } + else if (hpx::get_locality_id() == 1) + { + test_conv1d_d_d_operation( + "test_conv1d_d__3", R"( + conv1d_d( + annotate_d( + [[[3, 4]], [[-3,-4]]], "arg_4loc_0", + list("tile", list("pages", 0, 2), list("rows", 1, 2), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]]], + "valid" + ) + )" , R"( + annotate_d([[[ 6., 13., -13., -6.]], + [[ -6., -13., 13., 6.]]], + "arg_4loc_0/1", list("tile", list("pages", 0, 2), + list("rows", 1, 2), list("columns", 0, 4)) + ) + )"); + } + else if (hpx::get_locality_id() == 2) + { + test_conv1d_d_d_operation( + "test_conv1d_d__3", R"( + conv1d_d( + annotate_d( + [[[5, 6]], [[-5,-6]]], "arg_4loc_0", + list("tile", list("pages", 0, 2), list("rows", 2, 3), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]]], + "valid" + ) + )" , R"( + annotate_d([[[ 10., 21., -21., -10.]], + [[ -10., -21., 21., 10.]]], + "arg_4loc_0/1", list("tile", list("pages", 0, 2), + list("rows", 2, 3), list("columns", 0, 4)) + ) + )"); + } + else + { + test_conv1d_d_d_operation( + "test_conv1d_d__3", R"( + conv1d_d( + annotate_d( + [[[7, 8]], [[-7,-8]]], "arg_4loc_0", + list("tile", list("pages", 0, 2), list("rows", 3, 4), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]]], + "valid" + ) + )" , R"( + annotate_d([[[ 14., 29., -29., -14.]], + [[-14., -29., 29., 14.]]], + "arg_4loc_0/1", list("tile", list("pages", 0, 2), + list("rows", 3, 4), list("columns", 0, 4)) + ) + )"); + } +} + +// spatial parallelization with same padding, local kernel. The array is tiled +// on its rows and it has overlaps of fileter_length - 1 +void test_conv1d_d_4() +{ + if (hpx::get_locality_id() == 0) + { + test_conv1d_d_d_operation( + "test_conv1d_d__4", R"( + conv1d_d( + annotate_d( + [[[ 1, 2],[ 3, 4],[ 5, 6]], + [[-1,-2],[-3,-4],[-5,-6]]], "arg_4loc_4", + list("tile", list("pages", 0, 2), list("rows", 0, 3), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 0, 1, 0, 0], [ 2,-1, 0, 1]]], + "same" + ) + )" , R"( + annotate_d([[[ 10., 4., -5., 2.], + [ 18., 12., -13., 0.]], + [[-10., -4., 5., -2.], + [-18., -12., 13., 0.]]], + "arg_4loc_4/1", list("tile", list("pages", 0, 2), + list("rows", 0, 2), list("columns", 0, 4)) + ) + )"); + } + else if (hpx::get_locality_id() == 1) + { + test_conv1d_d_d_operation( + "test_conv1d_d__4", R"( + conv1d_d( + annotate_d( + [[[ 3, 4],[ 5, 6],[ 7, 8],[ 11, 12]], + [[-3,-4],[-5,-6],[-7,-8],[-11,-12]]], "arg_4loc_4", + list("tile", list("pages", 0, 2), list("rows", 1, 5), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 0, 1, 0, 0], [ 2,-1, 0, 1]]], + "same" + ) + )" , R"( + annotate_d([[[ 18., 12., -13., 0.], + [ 26., 20., -21., -2.], + [ 38., 28., -29., -2.]], + [[-18., -12., 13., 0.], + [-26., -20., 21., 2.], + [-38., -28., 29., 2.]]], + "arg_4loc_4/1", list("tile", list("pages", 0, 2), + list("rows", 1, 4), list("columns", 0, 4)) + ) + )"); + } + else if (hpx::get_locality_id() == 2) + { + test_conv1d_d_d_operation( + "test_conv1d_d__4", R"( + conv1d_d( + annotate_d( + [[[7, 8],[ 11, 12],[ 13, 14],[ 15, 16]], + [[-7,-8],[-11,-12],[-13,-14],[-15,-16]]], "arg_4loc_4", + list("tile", list("pages", 0, 2), list("rows", 3, 7), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 0, 1, 0, 0], [ 2,-1, 0, 1]]], + "same" + ) + )" , R"( + annotate_d([[[ 38., 28., -29., -2.], + [ 50., 44., -45., -8.], + [ 58., 52., -53., -10.]], + [[-38., -28., 29., 2.], + [-50., -44., 45., 8.], + [-58., -52., 53., 10.]]], + "arg_4loc_4/1", list("tile", list("pages", 0, 2), + list("rows", 3, 6), list("columns", 0, 4)) + ) + )"); + } + else + { + test_conv1d_d_d_operation( + "test_conv1d_d__4", R"( + conv1d_d( + annotate_d( + [[[ 13, 14],[ 15, 16],[ 17, 18]], + [[-13,-14],[-15,-16],[-17,-18]]], "arg_4loc_4", + list("tile", list("pages", 0, 2), list("rows", 5, 8), + list("columns", 0, 2)) + ), + [[[ 2, 3,-3,-2], [ 0, 1,-1, 0]], + [[ 0, 1, 0, 0], [ 2,-1, 0, 1]]], + "same" + ) + )" , R"( + annotate_d([[[ 58., 52., -53., -10.], + [ 66., 60., -61., -12.], + [ 34., 69., -69., -34.]], + [[-58., -52., 53., 10.], + [-66., -60., 61., 12.], + [-34., -69., 69., 34.]]], + "arg_4loc_4/1", list("tile", list("pages", 0, 2), + list("rows", 5, 8), list("columns", 0, 4)) + ) + )"); + } +} + +/////////////////////////////////////////////////////////////////////////////// +int hpx_main(int argc, char* argv[]) +{ + test_conv1d_d_0(); + test_conv1d_d_1(); + test_conv1d_d_2(); + + test_conv1d_d_3(); + test_conv1d_d_4(); + + hpx::finalize(); + return hpx::util::report_errors(); +} + +int main(int argc, char* argv[]) +{ + std::vector cfg = {"hpx.run_hpx_main!=1"}; + + return hpx::init(argc, argv, cfg); +} diff --git a/tests/unit/plugins/dist_matrixops/all_gather_2_loc.cpp b/tests/unit/plugins/dist_matrixops/all_gather_2_loc.cpp index 1f62569ef..1c0bd8a66 100644 --- a/tests/unit/plugins/dist_matrixops/all_gather_2_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/all_gather_2_loc.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/all_gather_4_loc.cpp b/tests/unit/plugins/dist_matrixops/all_gather_4_loc.cpp index 316423740..8832d39fd 100644 --- a/tests/unit/plugins/dist_matrixops/all_gather_4_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/all_gather_4_loc.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_argmax_3_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_argmax_3_loc.cpp index 108bd4341..a32e1ebce 100644 --- a/tests/unit/plugins/dist_matrixops/dist_argmax_3_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_argmax_3_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_argmin_2_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_argmin_2_loc.cpp index b5bb92183..6cb7e3cbb 100644 --- a/tests/unit/plugins/dist_matrixops/dist_argmin_2_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_argmin_2_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_cannon_product_4_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_cannon_product_4_loc.cpp index 5993c6b58..96b345ed7 100644 --- a/tests/unit/plugins/dist_matrixops/dist_cannon_product_4_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_cannon_product_4_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_cannon_product_9_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_cannon_product_9_loc.cpp index 2a432d9ab..d898d3d1c 100644 --- a/tests/unit/plugins/dist_matrixops/dist_cannon_product_9_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_cannon_product_9_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_constant_2_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_constant_2_loc.cpp index 6c6670849..4ef5fa0ef 100644 --- a/tests/unit/plugins/dist_matrixops/dist_constant_2_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_constant_2_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_constant_3_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_constant_3_loc.cpp index 94adecacd..48d8a67ae 100644 --- a/tests/unit/plugins/dist_matrixops/dist_constant_3_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_constant_3_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_constant_4_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_constant_4_loc.cpp index de25c452c..99dcc1df4 100644 --- a/tests/unit/plugins/dist_matrixops/dist_constant_4_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_constant_4_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_constant_6_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_constant_6_loc.cpp index 50a29f848..902a9eca8 100644 --- a/tests/unit/plugins/dist_matrixops/dist_constant_6_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_constant_6_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_diag_2_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_diag_2_loc.cpp index 6e441485c..7d9fb76df 100644 --- a/tests/unit/plugins/dist_matrixops/dist_diag_2_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_diag_2_loc.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_diag_4_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_diag_4_loc.cpp index 5777de08e..aa97003cd 100644 --- a/tests/unit/plugins/dist_matrixops/dist_diag_4_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_diag_4_loc.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_diag_6_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_diag_6_loc.cpp index 1c1ff8d7a..f9cdfdee9 100644 --- a/tests/unit/plugins/dist_matrixops/dist_diag_6_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_diag_6_loc.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_dot_operation_2_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_dot_operation_2_loc.cpp index dde76a194..cf8dfb34b 100644 --- a/tests/unit/plugins/dist_matrixops/dist_dot_operation_2_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_dot_operation_2_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_inverse_2_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_inverse_2_loc.cpp index ac5e68f93..3b0cb4e44 100644 --- a/tests/unit/plugins/dist_matrixops/dist_inverse_2_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_inverse_2_loc.cpp @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_inverse_3_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_inverse_3_loc.cpp index d2338cd9e..d63adc1e8 100644 --- a/tests/unit/plugins/dist_matrixops/dist_inverse_3_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_inverse_3_loc.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_random_2_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_random_2_loc.cpp index df5ff20e5..ffb11ceee 100644 --- a/tests/unit/plugins/dist_matrixops/dist_random_2_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_random_2_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_random_4_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_random_4_loc.cpp index 7ee368df8..8cc9728a7 100644 --- a/tests/unit/plugins/dist_matrixops/dist_random_4_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_random_4_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_random_5_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_random_5_loc.cpp index 165c92168..e7009df3e 100644 --- a/tests/unit/plugins/dist_matrixops/dist_random_5_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_random_5_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_slice_2_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_slice_2_loc.cpp index 04f367493..ff6aea3fc 100644 --- a/tests/unit/plugins/dist_matrixops/dist_slice_2_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_slice_2_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/dist_slice_3_loc.cpp b/tests/unit/plugins/dist_matrixops/dist_slice_3_loc.cpp index c31543fae..ec78c6e87 100644 --- a/tests/unit/plugins/dist_matrixops/dist_slice_3_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/dist_slice_3_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/retile_2_loc.cpp b/tests/unit/plugins/dist_matrixops/retile_2_loc.cpp index c8d68feea..7748b32a1 100644 --- a/tests/unit/plugins/dist_matrixops/retile_2_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/retile_2_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/retile_3_loc.cpp b/tests/unit/plugins/dist_matrixops/retile_3_loc.cpp index 1db7adbbc..509c4f1ac 100644 --- a/tests/unit/plugins/dist_matrixops/retile_3_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/retile_3_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/dist_matrixops/retile_6_loc.cpp b/tests/unit/plugins/dist_matrixops/retile_6_loc.cpp index 3af9cb1e0..27e90731b 100644 --- a/tests/unit/plugins/dist_matrixops/retile_6_loc.cpp +++ b/tests/unit/plugins/dist_matrixops/retile_6_loc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/plugins/matrixops/gauss_inverse.cpp b/tests/unit/plugins/matrixops/gauss_inverse.cpp index 9577acb01..81ec02cd4 100644 --- a/tests/unit/plugins/matrixops/gauss_inverse.cpp +++ b/tests/unit/plugins/matrixops/gauss_inverse.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/unit/python/execution_tree/CMakeLists.txt b/tests/unit/python/execution_tree/CMakeLists.txt index 30b8fc50b..88f9d5b93 100644 --- a/tests/unit/python/execution_tree/CMakeLists.txt +++ b/tests/unit/python/execution_tree/CMakeLists.txt @@ -16,6 +16,7 @@ set(tests make_array map_numpy map_numpy_constants + modulus_test multi_init multi_return parallel diff --git a/tests/unit/python/execution_tree/modulus_test.py b/tests/unit/python/execution_tree/modulus_test.py new file mode 100644 index 000000000..ce405c4d3 --- /dev/null +++ b/tests/unit/python/execution_tree/modulus_test.py @@ -0,0 +1,26 @@ +# Copyright (c) 2020 Steven R. Brandt +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +from phylanx import Phylanx +import numpy as np + + +def mod_test(): + v = np.array([5, 8, 3, 7]) + v %= 2 + q = np.array([5, 8, 3, 7]) + q = 2 % q + return [v, q] + + +mod_test2 = Phylanx(mod_test) +r1 = mod_test() +r2 = mod_test2() +for i in range(len(r1)): + if not np.all(r1[i] == r2[i]): + print("Differences found:", i) + print(r1[i]) + print(r2[i]) + assert False