Skip to content

Commit

Permalink
[§] introduces snippets generator (openvinotoolkit#4349)
Browse files Browse the repository at this point in the history
  • Loading branch information
Marina Kolpakova authored Mar 10, 2021
1 parent efcf24e commit 6e490c2
Show file tree
Hide file tree
Showing 64 changed files with 3,657 additions and 7 deletions.
4 changes: 3 additions & 1 deletion inference-engine/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@ add_subdirectory(low_precision_transformations)

add_subdirectory(offline_transformations)

add_subdirectory(snippets)

# add a custom target to build all Inference Engine Core libraries

add_custom_target(ie_libraries ALL
DEPENDS inference_engine_transformations inference_engine_legacy
inference_engine inference_engine_preproc
inference_engine_ir_v7_reader inference_engine_ir_reader
inference_engine_lp_transformations)
inference_engine_lp_transformations inference_engine_snippets)

if(NGRAPH_ONNX_IMPORT_ENABLE)
add_dependencies(ie_libraries inference_engine_onnx_reader)
Expand Down
4 changes: 3 additions & 1 deletion inference-engine/src/inference_engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,9 @@ if(WIN32)
set_target_properties(${TARGET_NAME}_s PROPERTIES COMPILE_PDB_NAME ${TARGET_NAME}_s)
endif()

target_link_libraries(${TARGET_NAME}_s PRIVATE openvino::itt ${CMAKE_DL_LIBS} ${NGRAPH_LIBRARIES}
target_link_libraries(${TARGET_NAME}_s PRIVATE openvino::itt openvino::conditional_compilation
${CMAKE_DL_LIBS} ${NGRAPH_LIBRARIES}
inference_engine_snippets
inference_engine_transformations pugixml)

target_compile_definitions(${TARGET_NAME}_s PUBLIC USE_STATIC_IE)
Expand Down
5 changes: 3 additions & 2 deletions inference-engine/src/legacy_api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ target_include_directories(${TARGET_NAME}_obj PRIVATE
${PUBLIC_HEADERS_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/src
${IE_MAIN_SOURCE_DIR}/src/inference_engine # For CNNNetworkNGraphImpl
$<TARGET_PROPERTY:inference_engine_snippets,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:inference_engine_transformations,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:inference_engine_plugin_api,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:ngraph::ngraph,INTERFACE_INCLUDE_DIRECTORIES>
Expand All @@ -53,7 +54,7 @@ add_cpplint_target(${TARGET_NAME}_obj_cpplint FOR_TARGETS ${TARGET_NAME}_obj)

# Create shared library

add_library(${TARGET_NAME} SHARED
add_library(${TARGET_NAME} SHARED
${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
$<TARGET_OBJECTS:${TARGET_NAME}_obj>)

Expand All @@ -62,7 +63,7 @@ ie_add_vs_version_file(NAME ${TARGET_NAME}

set_ie_threading_interface_for(${TARGET_NAME})

target_link_libraries(${TARGET_NAME} PUBLIC inference_engine
target_link_libraries(${TARGET_NAME} PUBLIC inference_engine inference_engine_snippets
PRIVATE pugixml openvino::itt
${NGRAPH_LIBRARIES} inference_engine_transformations)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "legacy/ngraph_ops/rnn_sequence_ie.hpp"
#include "legacy/ngraph_ops/lstm_sequence_ie.hpp"
#include "legacy/ngraph_ops/gru_sequence_ie.hpp"
#include "snippets/op/subgraph.hpp"
#include "exec_graph_info.hpp"

#include "caseless.hpp"
Expand Down Expand Up @@ -1978,6 +1979,15 @@ void convertFunctionToICNNNetwork(const std::shared_ptr<const ::ngraph::Function
cnnLayer->params[ExecGraphInfoSerialization::ORIGINAL_NAMES] = originalNames;
}

if (auto subgraph = ::ngraph::as_type_ptr<ngraph::snippets::op::Subgraph>(layer)) {
std::string names = "";
for (const auto& op : subgraph->get_body()->get_ordered_ops()) {
names += ", " + op->get_friendly_name();
}

cnnLayer->params["originalLayersNames"] += names;
}

std::string primitivesPriority = ::ngraph::getPrimitivesPriority(layer);
if (!primitivesPriority.empty()) {
cnnLayer->params["PrimitivesPriority"] = primitivesPriority;
Expand Down
56 changes: 56 additions & 0 deletions inference-engine/src/snippets/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright (C) 2021 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#

set (TARGET_NAME "inference_engine_snippets")

set(PUBLIC_HEADERS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include")

file(GLOB_RECURSE LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
file(GLOB_RECURSE PUBLIC_HEADERS ${PUBLIC_HEADERS_DIR}/snippets/*.hpp)

# Create named folders for the sources within the .vcproj
# Empty name lists them directly under the .vcproj

source_group("src" FILES ${LIBRARY_SRC})
source_group("include" FILES ${PUBLIC_HEADERS})

# Create shared library

add_library(${TARGET_NAME} SHARED
${LIBRARY_SRC}
${PUBLIC_HEADERS})

ie_faster_build(${TARGET_NAME}
UNITY
)

ie_add_vs_version_file(NAME ${TARGET_NAME}
FILEDESCRIPTION "Inference Engine Snippets transformations library")

target_compile_definitions(${TARGET_NAME} PRIVATE inference_engine_transformations_EXPORTS)

target_link_libraries(${TARGET_NAME} PUBLIC inference_engine_transformations ${NGRAPH_LIBRARIES}
PRIVATE ${NGRAPH_REF_LIBRARIES} openvino::conditional_compilation)

target_include_directories(${TARGET_NAME} PUBLIC ${PUBLIC_HEADERS_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)

add_cpplint_target(${TARGET_NAME}_cpplint FOR_TARGETS ${TARGET_NAME})

ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME})

# LTO

set_target_properties(${TARGET_NAME} PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE ${ENABLE_LTO})

# developer package

ie_developer_export_targets(${TARGET_NAME})

# install

install(TARGETS ${TARGET_NAME}
RUNTIME DESTINATION ${IE_CPACK_RUNTIME_PATH} COMPONENT core
ARCHIVE DESTINATION ${IE_CPACK_ARCHIVE_PATH} COMPONENT core
LIBRARY DESTINATION ${IE_CPACK_LIBRARY_PATH} COMPONENT core)
123 changes: 123 additions & 0 deletions inference-engine/src/snippets/include/snippets/generator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

/**
* @brief A file contains public interface for target indepenent code generator.
* @file generator.hpp
*/
#pragma once

#include <transformations_visibility.hpp>
#include "snippets_isa.hpp"

namespace ngraph {
namespace snippets {

using code = const uint8_t *;
using RegInfo = std::pair<std::vector<size_t>, std::vector<size_t>>;

TRANSFORMATIONS_API auto getRegisters(std::shared_ptr<ngraph::Node>& n) -> ngraph::snippets::RegInfo;

/**
* @interface Emitter
* @brief Base class for all target specific code emitters used by generator.
* @ingroup snippets
*/
class TRANSFORMATIONS_API Emitter {
public:
/**
* @brief Default constructor
*/
Emitter(const std::shared_ptr<ngraph::Node>& n) {
}

/**
* @brief called by generator to generate code to produce target code for a specific operation
* @param in vector of vector argument registers
* @param out vector of vector resulting registers
* @param pool optional vector of free vector registers which might be used inside method
* @param gpr vector of free generam puproce registers which might be used inside method
* @return void
*/
virtual void emit_code(const std::vector<size_t>& in,
const std::vector<size_t>& out,
const std::vector<size_t>& pool = {},
const std::vector<size_t>& gpr = {}) const = 0;

/**
* @brief called by generator to generate data section, if needed for a specific operation
* @return void
*/
virtual void emit_data() const {
}
};

/**
* @interface TargetMachine
* @brief Base class Target machine representation. Target derives from this class to provide generator information about supported emittors
* @ingroup snippets
*/
class TRANSFORMATIONS_API TargetMachine {
public:
/**
* @brief called by generator to all the emittors available for a target machine
* @return a map by node's type info with callbacks to create an instance of emmitter for corresponding operation type
*/
virtual auto getJitters() -> std::map<const ngraph::DiscreteTypeInfo, std::function<std::shared_ptr<Emitter>(std::shared_ptr<ngraph::Node>)>>{
return {};
}
};

/**
* @interface Schedule
* @brief Return scheduling information and pointer to generated kernel code
* @ingroup snippets
*/
class TRANSFORMATIONS_API Schedule {
public:
/**
* @brief Default constructor
*/
Schedule() : work_size({}), is_flat(false), ptr(nullptr) {}
/**
* @brief Default to create schedule out of specific parameters
* @param ws work size for kernel execution
* @param f can this kernel be linearided to 1D range
* @param p pointer to generated code
*/
Schedule(const Shape& ws, bool f, code p) : work_size(ws), is_flat(f), ptr(p) {}

Shape work_size {};
bool is_flat {false};
code ptr {nullptr};
};

/**
* @interface Generator
* @brief Target independent code generator interface
* @ingroup snippets
*/
class TRANSFORMATIONS_API Generator {
public:
/**
* @brief Default constructor
*/
Generator() = default;
/**
* @brief Default destructor
*/
virtual ~Generator() = default;
/**
* @brief virtual method any specific implementation should implement
* @param f runction in canonical for for table-based code generation
* @return pointer to generated code
*/
virtual code generate(std::shared_ptr<Function>& f) const = 0;

protected:
mutable std::map<const ngraph::DiscreteTypeInfo, std::function<std::shared_ptr<Emitter>(std::shared_ptr<ngraph::Node>)>> jitters;
};

} // namespace snippets
} // namespace ngraph
36 changes: 36 additions & 0 deletions inference-engine/src/snippets/include/snippets/op/blockedload.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once

#include <transformations_visibility.hpp>

#include <ngraph/op/op.hpp>
#include "load.hpp"

namespace ngraph {
namespace snippets {
namespace op {

/**
* @interface BlockedLoad
* @brief Generated by Canonicalization step for blocked data (NCHW<X>c) to be loaded
* @ingroup snippets
*/
class TRANSFORMATIONS_API BlockedLoad : public Load {
public:
NGRAPH_RTTI_DECLARATION;

BlockedLoad(const Output<Node>& x);
BlockedLoad() = default;

std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& new_args) const override {
check_new_args_count(this, new_args);
return std::make_shared<BlockedLoad>(new_args.at(0));
}
};

} // namespace op
} // namespace snippets
} // namespace ngraph
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once

#include <transformations_visibility.hpp>

#include <ngraph/op/op.hpp>
#include <ngraph/op/parameter.hpp>

namespace ngraph {
namespace snippets {
namespace op {

/**
* @interface BlockedParameter
* @brief Represents blocked input (NCHW<X>c) for a subgraph
* @ingroup snippets
*/
class TRANSFORMATIONS_API BlockedParameter : public ngraph::op::Parameter {
public:
NGRAPH_RTTI_DECLARATION;

BlockedParameter() = default;
BlockedParameter(const ngraph::element::Type& element_type, const PartialShape& pshape)
: Parameter(element_type, pshape) {
}

std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& new_args) const override {
check_new_args_count(this, new_args);
return std::make_shared<BlockedParameter>(m_element_type, m_partial_shape);
}
};

} // namespace op
} // namespace snippets
} // namespace ngraph
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once

#include <transformations_visibility.hpp>
#include <snippets/op/broadcastmove.hpp>

#include "ngraph/op/op.hpp"

namespace ngraph {
namespace snippets {
namespace op {

/**
* @interface BroadcastLoad
* @brief Is generated for broadcasting by least varying dimension for non-blocked cases and the second varying dimension for blocked
* @ingroup snippets
*/
class TRANSFORMATIONS_API BroadcastLoad : public BroadcastMove {
public:
NGRAPH_RTTI_DECLARATION;

BroadcastLoad(const Output<Node>& x, Shape output_shape);
BroadcastLoad() = default;

bool visit_attributes(AttributeVisitor& visitor) override;

std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& new_args) const override;

void validate_and_infer_types() override;

void set_broadcast_info(const Shape& bct) {
broadcast_info = bct;
}

bool is_broadcast(size_t idx) {
return broadcast_info[idx] == 1;
}

private:
Shape broadcast_info;
};

} // namespace op
} // namespace snippets
} // namespace ngraph
Loading

0 comments on commit 6e490c2

Please sign in to comment.