Skip to content

Commit

Permalink
Merge branch 'master' into akup/remove-contrains-from-ttols
Browse files Browse the repository at this point in the history
  • Loading branch information
akuporos authored Jan 17, 2025
2 parents 1cfadc4 + 7da364d commit 174a18e
Show file tree
Hide file tree
Showing 513 changed files with 4,488 additions and 3,393 deletions.
2 changes: 1 addition & 1 deletion .github/dockerfiles/docker_tag
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pr-28380
pr-28040
10 changes: 7 additions & 3 deletions .github/dockerfiles/ov_build/ubuntu_22_04_x64_cc/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ RUN apt-get update && \
# For Java API
default-jdk \
# Compiler \
clang \
clang-15 \
# Static analyzer
clang-tidy-15 \
# clang-tidy uses clang-format as a dependency
clang-format-15 \
&& \
rm -rf /var/lib/apt/lists/*

Expand All @@ -47,8 +51,8 @@ RUN chmod +x /install_build_dependencies.sh && \
rm -rf /var/lib/apt/lists/*

# Set clang as a default compiler
RUN update-alternatives --install /usr/bin/cc cc /usr/bin/clang 100 && \
update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100
RUN update-alternatives --install /usr/bin/cc cc /usr/bin/clang-15 100 && \
update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-15 100

# Install sscache
ARG SCCACHE_VERSION="v0.7.5"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build_doc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
lfs: 'true'

- name: Install apt-get dependencies
uses: awalsh128/cache-apt-pkgs-action@a6c3917cc929dd0345bfb2d3feaf9101823370ad # v1.4.2
uses: awalsh128/cache-apt-pkgs-action@5902b33ae29014e6ca012c5d8025d4346556bd40 # v1.4.3
with:
packages: graphviz texlive liblua5.2-0 libclang1-9 libclang-cpp9
version: 3.0
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/linux_conditional_compilation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,17 @@ jobs:
# Build
#

- name: CMake configure - CC COLLECT
- name: CMake configure - CC COLLECT with clang-tidy
# clang-tidy static analysis check is enabled as part of collection
# to avoid an additional separate build execution
run: |
cmake \
-G "${{ env.CMAKE_GENERATOR }}" \
-DCMAKE_CXX_STANDARD=20 \
-DBUILD_SHARED_LIBS=OFF \
-DENABLE_TESTS=ON \
-DENABLE_CPPLINT=OFF \
-DENABLE_CLANG_TIDY=ON \
-DENABLE_NCC_STYLE=OFF \
-DCMAKE_COMPILE_WARNING_AS_ERROR=ON \
-DENABLE_PROFILING_ITT=ON \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ include(python_requirements)

include(cpplint/cpplint)
include(clang_format/clang_format)
include(clang_tidy/clang_tidy)
include(ncc_naming_style/ncc_naming_style)

# Restore state
Expand Down
25 changes: 25 additions & 0 deletions cmake/developer_package/clang_tidy/clang_tidy.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright (C) 2018-2024 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#

if(ENABLE_CLANG_TIDY)
set(CLANG_TIDY_REQUIRED_VERSION 15 CACHE STRING "clang-tidy version to use")
set(CLANG_TIDY_FILENAME clang-tidy-${CLANG_TIDY_REQUIRED_VERSION} clang-tidy)
find_host_program(CLANG_TIDY NAMES ${CLANG_TIDY_FILENAME} PATHS ENV PATH)
if(CLANG_TIDY)
execute_process(COMMAND ${CLANG_TIDY} ${CMAKE_CURRENT_SOURCE_DIR} ARGS --version OUTPUT_VARIABLE CLANG_VERSION)
if(NOT CLANG_VERSION)
message(WARNING "Supported clang-tidy version is ${CLANG_TIDY_REQUIRED_VERSION}!")
set(ENABLE_CLANG_TIDY OFF)
else()
string(REGEX REPLACE "[^0-9]+([0-9]+)\\..*" "\\1" CLANG_TIDY_MAJOR_VERSION ${CLANG_VERSION})
if(NOT CLANG_TIDY_MAJOR_VERSION EQUAL CLANG_TIDY_REQUIRED_VERSION)
message(WARNING "Supported clang-tidy version is ${CLANG_TIDY_REQUIRED_VERSION}! Provided version ${CLANG_TIDY_MAJOR_VERSION}")
set(ENABLE_CLANG_TIDY OFF)
endif()
endif()
else()
message(WARNING "Supported clang-tidy-${CLANG_TIDY_REQUIRED_VERSION} is not found!")
set(ENABLE_CLANG_TIDY OFF)
endif()
endif()
2 changes: 2 additions & 0 deletions cmake/developer_package/features.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ ov_dependent_option (ENABLE_CPPLINT_REPORT "Build cpplint report instead of fail

ov_option (ENABLE_CLANG_FORMAT "Enable clang-format checks during the build" ${STYLE_CHECKS_DEFAULT})

ov_option (ENABLE_CLANG_TIDY "Enable clang-tidy checks during the build" ${STYLE_CHECKS_DEFAULT})

ov_option (ENABLE_NCC_STYLE "Enable ncc style check" ${STYLE_CHECKS_DEFAULT})

ov_option (ENABLE_UNSAFE_LOCATIONS "skip check for MD5 for dependency" OFF)
Expand Down
9 changes: 8 additions & 1 deletion cmake/developer_package/plugins/plugins.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ endif()
# [SKIP_INSTALL]
# [SKIP_REGISTRATION] Skip creation of <device>.xml
# [ADD_CLANG_FORMAT]
# [ADD_CLANG_TIDY]
# )
#
function(ov_add_plugin)
set(options SKIP_INSTALL PSEUDO_DEVICE ADD_CLANG_FORMAT AS_EXTENSION SKIP_REGISTRATION)
set(options SKIP_INSTALL PSEUDO_DEVICE ADD_CLANG_FORMAT ADD_CLANG_TIDY AS_EXTENSION SKIP_REGISTRATION)
set(oneValueArgs NAME DEVICE_NAME VERSION_DEFINES_FOR PSEUDO_PLUGIN_FOR)
set(multiValueArgs DEFAULT_CONFIG SOURCES OBJECT_LIBRARIES CPPLINT_FILTERS)
cmake_parse_arguments(OV_PLUGIN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
Expand Down Expand Up @@ -105,6 +106,12 @@ function(ov_add_plugin)
string(CONCAT custom_filter "${custom_filter}" "," "${filter}")
endforeach()

if (OV_PLUGIN_ADD_CLANG_TIDY)
if (ENABLE_CLANG_TIDY)
set_target_properties(${OV_PLUGIN_NAME} PROPERTIES CXX_CLANG_TIDY clang-tidy-${CLANG_TIDY_REQUIRED_VERSION})
endif()
endif()

if (OV_PLUGIN_ADD_CLANG_FORMAT)
ov_add_clang_format_target(${OV_PLUGIN_NAME}_clang FOR_SOURCES ${OV_PLUGIN_SOURCES})
else()
Expand Down
1 change: 1 addition & 0 deletions cmake/packaging/debian.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ macro(ov_cpack_settings)
2024.4.0
2024.5.0
2024.6.0
2025.0.0
)

ov_check_conflicts_versions(conflicting_versions)
Expand Down
1 change: 1 addition & 0 deletions cmake/packaging/rpm.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ macro(ov_cpack_settings)
2024.4.0
2024.5.0
2024.6.0
2025.0.0
)

ov_check_conflicts_versions(conflicting_versions)
Expand Down
2 changes: 1 addition & 1 deletion src/bindings/python/constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pytest-timeout==2.3.1
# Python bindings
build<1.3
pygments>=2.8.1
setuptools>=70.1,<75.8
setuptools>=70.1,<75.9
sympy>=1.10
wheel>=0.38.1
patchelf<=0.17.2.1
Expand Down
18 changes: 10 additions & 8 deletions src/common/snippets/docs/snippets_design_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -630,13 +630,15 @@ Let's discuss the target-independent stage first.

The `Preparation` consists of low-level target-independent transformations needed to prepare the `IR` for code generation.
There are currently two such transformations:
1. `AssignRegisters` assigns abstract registers to `Expressions` based on their data dependencies.
The easiest way to think about the assignment logic is that a register is assigned to every `PortConnector` to ensure appropriate data propagation.
However, every `Expression` needs to know the assigned registers, so they are stored is the `PortDescriptors` (and could be obtained via `get_reg()`).
Consequently, all the ports connected to the same `PortConnector` will have the same register in their `PortDescriptors`.
`AssignRegisters` also supports register re-utilization, so if all `ExpressionPorts` connected to this `PortConnector` are evaluated, then the corresponding register may be reused by other `PortConnector`.
In other words, when all the `Expressions` that required input data in a certain register are evaluated, the register may be reused to hold another `Expression's` output.
`AssignRegisters` also supports two types of registers: general-purpose and vector ones.
1. `InitRegisters` assigns registers to `Expressions` based on their data dependencies.
This register assignment is organized in three steps implemented as separate passes: `InitLiveRanges`, `AssignRegisters` and `InsertRegSpills`.
* `InitLiveRanges` assigns an abstract register to every `PortConnector` and determines their live intervals based on data dependencies.
Note that the assigned registers are stored in `PortDescriptors` and could be obtained via `get_reg()`.
Similarly, the `get_live_regs()` method returns live registers for the given expression.
* `AssignRegisters` uses the information collected by `InitLiveRanges` to map abstract register to the physical ones.
Physical registers that have non-overlapping live intervals will be reused.
* Finally, `InsertRegSpills` inserts `RegSpillBegin` and `RegSpillEnd` operations to spill (and restore) some registers to the stack and update live registers for affected expressions.
For example, this is needed to reduce ABI call overheads if we need to call a binary inside a loop.
Different types of registers are managed and assigned independently, and a particular register type required by an `Expression` is provided by the `ov::snippets::Generator` (or a derived generator for target-specific `Ops`).
2. `InsertSpecificIterations` injects initialization section before a loop body and tail-processing section after a loop body if needed.
Note that every loop has two parameters that specify how its body is evaluated: `work_amount` and `increment` The `work_amount` indicates how much of the data needs to be processed, it often equals to the dimension's size the loop is working on.
Expand All @@ -647,7 +649,7 @@ So if a loop's `work_amount` is not evenly divisible by its `increment`, it mean
4. `OptimizeLoopSingleEvaluation` moves all pointer arithmetic to finalization offsets in `LoopEnd`, and marks the loops that will be executed only once.
This information will be used during code emission to eliminate redundant instructions.

Please see [assign_registers.cpp](../src/lowered/pass/assign_registers.cpp) and [insert_specific_iterations.cpp](../src/lowered/pass/insert_specific_iterations.cpp) for more info regarding the main passes in the `Preparation` stage.
Please see [init_registers.cpp](../src/lowered/pass/init_registers.cpp) and [insert_specific_iterations.cpp](../src/lowered/pass/insert_specific_iterations.cpp) for more info regarding the main passes in the `Preparation` stage.
When the `Preparation` is finished, the `Generator` constructs target-specific emitters by calling `init_emitter(target)` method for every `Expression` in the `LinearIR`, where the `target` is a `TargetMachine` instance.

The `TargetMachine` is a class that provides generator with target-specific information, such as supported instruction sets, vector register size etc.
Expand Down
13 changes: 8 additions & 5 deletions src/common/snippets/include/snippets/emitter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,28 @@ namespace snippets {
* @interface RegType
* @brief Register type of input and output operations
*/
enum class RegType { gpr, vec, undefined };
enum class RegType { gpr, vec, mask, undefined };
/**
* @interface Reg
* @brief Register representation: type of register and index
*/
struct Reg {
enum {UNDEFINED_IDX = std::numeric_limits<size_t>::max()};
Reg() = default;
Reg(RegType type_, size_t idx_) : type(type_), idx(idx_) {}

RegType type = RegType::gpr;
size_t idx = 0;
bool is_defined() const { return type != RegType::undefined && idx != UNDEFINED_IDX; }
RegType type = RegType::undefined;
size_t idx = UNDEFINED_IDX;

friend bool operator==(const Reg& lhs, const Reg& rhs);
friend bool operator<(const Reg& lhs, const Reg& rhs);
friend bool operator>(const Reg& lhs, const Reg& rhs);
friend bool operator!=(const Reg& lhs, const Reg& rhs);
friend std::ostream& operator<<(std::ostream& s, const Reg& r);
};
using RegInfo = std::pair<std::vector<Reg>, std::vector<Reg>>;

std::string regTypeToStr(const RegType& type);

/**
* @interface Emitter
* @brief Base class for all target specific code emitters used by generator.
Expand Down
2 changes: 1 addition & 1 deletion src/common/snippets/include/snippets/generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class Schedule {
* @brief Target independent code generator interface
* @ingroup snippets
*/
class Generator {
class Generator : public std::enable_shared_from_this<Generator>{
public:
/**
* @brief Default constructor
Expand Down
3 changes: 3 additions & 0 deletions src/common/snippets/include/snippets/lowered/expression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class Expression : public std::enable_shared_from_this<Expression> {

RegInfo get_reg_info() const;
void set_reg_info(const RegInfo& rinfo);
const std::set<Reg>& get_live_regs() const {return m_live_regs; }
void set_live_regs(std::set<Reg> live_regs) { m_live_regs = std::move(live_regs); }

double get_exec_num() const { return m_exec_num; }

Expand Down Expand Up @@ -130,6 +132,7 @@ class Expression : public std::enable_shared_from_this<Expression> {
// 2. This number can be changed and updated during whole pipeline, so its absolute values are meaningless.
// 3. This number can be negative, positive and zero.
double m_exec_num = 0;
std::set<Reg> m_live_regs{};
};

} // namespace lowered
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "snippets/op/loop.hpp"
#include "snippets/op/buffer.hpp"
#include "snippets/op/perf_count.hpp"
#include "snippets/op/reg_spill.hpp"

namespace ov {
namespace snippets {
Expand All @@ -35,6 +36,10 @@ class ExpressionFactory {
const std::shared_ptr<IShapeInferSnippetsFactory>& shape_infer_factory);
static ExpressionPtr create(const std::shared_ptr<op::LoopEnd>& n, const std::vector<PortConnectorPtr>& inputs,
const std::shared_ptr<IShapeInferSnippetsFactory>& shape_infer_factory);
static ExpressionPtr create(const std::shared_ptr<op::RegSpillBegin>& n, const std::vector<PortConnectorPtr>& inputs,
const std::shared_ptr<IShapeInferSnippetsFactory>& shape_infer_factory);
static ExpressionPtr create(const std::shared_ptr<op::RegSpillEnd>& n, const std::vector<PortConnectorPtr>& inputs,
const std::shared_ptr<IShapeInferSnippetsFactory>& shape_infer_factory);

// Note: PerfCountBegin nodes have a PerfCountEnd ov::Output, but corresponding expression should not have any outputs to avoid register allocation
#ifdef SNIPPETS_DEBUG_CAPS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ namespace pass {
*/
class AllocateBuffers: public RangedPass {
public:
OPENVINO_RTTI("AllocateBuffers", "", RangedPass);
OPENVINO_RTTI("AllocateBuffers", "", RangedPass)
AllocateBuffers(bool is_optimized = true);

/**
* @brief Apply the pass to the Linear IR
* @brief Apply the pass to the Linear IR`
* @param linear_ir the target Linear IR
* @return status of the pass
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "pass.hpp"
#include "snippets/generator.hpp"
#include "snippets/lowered/reg_manager.hpp"

namespace ov {
namespace snippets {
Expand All @@ -20,16 +21,15 @@ namespace pass {
*/
class AssignRegisters : public Pass {
public:
OPENVINO_RTTI("AssignRegisters", "", Pass);
explicit AssignRegisters(const std::function<RegType(const ov::Output<Node>& out)>& mapper, const size_t reg_cnt)
: m_reg_type_mapper(mapper), reg_count(reg_cnt) {}
OPENVINO_RTTI("AssignRegisters", "0", Pass)
explicit AssignRegisters(RegManager& reg_manager) : m_reg_manager(reg_manager) {}
bool run(LinearIR& linear_ir) override;

private:
void set_reg_types(LinearIR& linear_ir);
using RegMap = std::map<Reg, Reg>;
RegMap assign_regs_manually(const LinearIR& linear_ir, std::set<Reg>& gpr_pool, std::set<Reg>& vec_pool);

std::function<RegType(const ov::Output<Node>& out)> m_reg_type_mapper;
size_t reg_count;
RegManager& m_reg_manager;
};

} // namespace pass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ template <typename BRGEMM_TYPE,
typename std::enable_if<std::is_base_of<ov::snippets::op::Brgemm, BRGEMM_TYPE>::value, bool>::type = true>
class BrgemmBlocking : public snippets::lowered::pass::RangedPass, public BrgemmBlockingBase {
public:
OPENVINO_RTTI("BrgemmBlocking", "", RangedPass);
OPENVINO_RTTI("BrgemmBlocking", "", RangedPass)

bool run(snippets::lowered::LinearIR& linear_ir,
snippets::lowered::LinearIR::constExprIt begin,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace pass {
*/
class CleanRepeatedDataPointerShifts: public RangedPass {
public:
OPENVINO_RTTI("CleanRepeatedDataPointerShifts", "", RangedPass);
OPENVINO_RTTI("CleanRepeatedDataPointerShifts", "", RangedPass)
CleanRepeatedDataPointerShifts() = default;

bool run(lowered::LinearIR& linear_ir, lowered::LinearIR::constExprIt begin, lowered::LinearIR::constExprIt end) override;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (C) 2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once

#include "pass.hpp"
#include "snippets/generator.hpp"
#include "snippets/lowered/reg_manager.hpp"

namespace ov {
namespace snippets {
namespace lowered {
namespace pass {

/**
* @interface InitLiveRanges
* @brief Calculates live ranges of registers. This information will be used to assign registers and optimize ABI reg spills.
* @ingroup snippets
*/
class InitLiveRanges : public Pass {
public:
OPENVINO_RTTI("InitLiveRanges", "", Pass)
explicit InitLiveRanges(RegManager& reg_manager) : m_reg_manager(reg_manager) {}
bool run(LinearIR& linear_ir) override;
private:
RegManager& m_reg_manager;
};

} // namespace pass
} // namespace lowered
} // namespace snippets
} // namespace ov
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (C) 2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once

#include "pass.hpp"
#include "snippets/generator.hpp"
#include "snippets/lowered/reg_manager.hpp"

namespace ov {
namespace snippets {
namespace lowered {
namespace pass {

/**
* @interface InitRegisters
* @brief This pass combines all register-related transformations that are needed to initialize register info.
* @ingroup snippets
*/
class InitRegisters : public Pass {
public:
OPENVINO_RTTI("InitRegisters", "0", Pass)
InitRegisters(const std::shared_ptr<const Generator>& generator,
const std::shared_ptr<PassConfig>& pass_config);
bool run(LinearIR& linear_ir) override;

private:
lowered::RegManager m_reg_manager;
const std::shared_ptr<PassConfig>& m_pass_config;
};

} // namespace pass
} // namespace lowered
} // namespace snippets
} // namespace ov
Loading

0 comments on commit 174a18e

Please sign in to comment.