diff --git a/src/plugins/intel_cpu/src/nodes/executors/dnnl/dnnl_convolution_primitive.cpp b/src/plugins/intel_cpu/src/nodes/executors/dnnl/dnnl_convolution_primitive.cpp index 11309c408da..c8426b4b28c 100644 --- a/src/plugins/intel_cpu/src/nodes/executors/dnnl/dnnl_convolution_primitive.cpp +++ b/src/plugins/intel_cpu/src/nodes/executors/dnnl/dnnl_convolution_primitive.cpp @@ -6,15 +6,17 @@ #include #include +#include #include "dnnl_extension_utils.h" -#include "memory_desc/cpu_memory_desc.h" +#include "dnnl_postops_composer.h" #include "memory_desc/cpu_memory_desc_utils.h" #include "memory_desc/dnnl_memory_desc.h" #include "nodes/executors/convolution_config.hpp" #include "nodes/executors/dnnl/dnnl_aliases.hpp" #include "nodes/executors/dnnl/dnnl_shape_agnostic_data.hpp" #include "nodes/executors/executor.hpp" +#include "nodes/executors/fullyconnected_config.hpp" #include "nodes/executors/memory_arguments.hpp" #include "onednn/iml_type_mapper.h" @@ -64,7 +66,8 @@ bool DnnlConvolutionPrimitive::Key::operator==(const Key& rhs) const { } // make a fake shape: N, C, W -static dnnl::memory::dims normalizeDims(const dnnl::memory::dims& dims) { +template +static std::vector normalizeDims(const std::vector& dims) { assert(one_of(static_cast(dims.size()), 2, 3)); if (dims.size() == 3) { @@ -138,6 +141,47 @@ static primitive_desc createPrimitiveDesc(const dnnl::engine& engine, return std::move(first_desc); } +static DnnlPrimitiveAttrs createPrimitiveAttrs(const ConvAttrs& attrs, + const PostOps& postOps, + const MemoryArgs& memory, + ExecutorContext::CPtr context) { + const auto& srcDesc = memory.at(ARG_SRC)->getDescPtr(); + const auto& weiDesc = memory.at(ARG_WEI)->getDescPtr(); + const auto& dstDesc = memory.at(ARG_DST)->getDescPtr(); + + const auto& originalDims = dstDesc->getShape().getMinDims(); + const auto& dims = normalizeDims(originalDims); + + auto isINT8 = + one_of(srcDesc->getPrecision(), ov::element::u8, ov::element::i8) && weiDesc->getPrecision() == ov::element::i8; + auto outputDataType = DnnlExtensionUtils::ElementTypeToDataType(dstDesc->getPrecision()); + + DnnlPostOpsComposer dnnlpoc(postOps, + context->getEngine(), + dims, + 1, + isINT8, + 1 << 0, + {}, + attrs.withBias, + outputDataType); + + return dnnlpoc.compose(); +} + +DnnlShapeAgnosticDataPtr DnnlConvolutionPrimitive::createShapeAgnosticData(const FCAttrs& attrs, + const PostOps& postOps, + const MemoryArgs& memory, + const ExecutorContext::CPtr context, + const bool cacheWeights) { + DEBUG_LOG("Creating shape agnostic data"); + ConvAttrs convAttrs{attrs.withBias}; + + const auto postOpData = createPrimitiveAttrs(convAttrs, postOps, memory, context); + + return std::make_shared(postOpData); +} + void DnnlConvolutionPrimitive::execute(const dnnl_primitive_args& primArgs) const { m_prim.execute(m_stream, primArgs); } diff --git a/src/plugins/intel_cpu/src/nodes/executors/dnnl/dnnl_convolution_primitive.hpp b/src/plugins/intel_cpu/src/nodes/executors/dnnl/dnnl_convolution_primitive.hpp index 1a7fb3c08b3..4fdd83abc8a 100644 --- a/src/plugins/intel_cpu/src/nodes/executors/dnnl/dnnl_convolution_primitive.hpp +++ b/src/plugins/intel_cpu/src/nodes/executors/dnnl/dnnl_convolution_primitive.hpp @@ -7,13 +7,13 @@ #include #include -#include "cpu_memory.h" #include "memory_desc/dnnl_memory_desc.h" #include "nodes/executors/convolution_config.hpp" #include "nodes/executors/dnnl/dnnl_aliases.hpp" #include "nodes/executors/dnnl/dnnl_shape_agnostic_data.hpp" #include "nodes/executors/dnnl/dnnl_utils.hpp" #include "nodes/executors/executor.hpp" +#include "nodes/executors/fullyconnected_config.hpp" namespace ov { namespace intel_cpu { @@ -61,6 +61,13 @@ public: return m_implType; } + // create shape agnostic data using FC attributes (1x1 Convolution as FC executor) + static DnnlShapeAgnosticDataPtr createShapeAgnosticData(const FCAttrs& attrs, + const PostOps& postOps, + const MemoryArgs& memory, + const ExecutorContext::CPtr context, + const bool cacheWeights); + static std::shared_ptr create(const MemoryArgs& memory, const ConvAttrs& attrs, const ExecutorContext::CPtr context, diff --git a/src/plugins/intel_cpu/src/nodes/executors/dnnl/dnnl_fullyconnected.hpp b/src/plugins/intel_cpu/src/nodes/executors/dnnl/dnnl_fullyconnected.hpp index b972fb71277..013771602da 100644 --- a/src/plugins/intel_cpu/src/nodes/executors/dnnl/dnnl_fullyconnected.hpp +++ b/src/plugins/intel_cpu/src/nodes/executors/dnnl/dnnl_fullyconnected.hpp @@ -10,6 +10,7 @@ #include "cpu_memory.h" #include "memory_desc/cpu_memory_desc.h" #include "nodes/executors/dnnl/dnnl_fullyconnected_primitive.hpp" +#include "nodes/executors/dnnl/dnnl_convolution_primitive.hpp" #include "nodes/executors/dnnl/dnnl_aliases.hpp" #include "nodes/executors/executor.hpp" #include "nodes/executors/executor_config.hpp" @@ -43,7 +44,7 @@ public: const bool cacheWeights) : m_attrs(attrs), m_context(context), - m_shapeAgnosticData(DnnlFCPrimitive::createShapeAgnosticData(m_attrs, postOps, memory, m_context, cacheWeights)), + m_shapeAgnosticData(Primitive::createShapeAgnosticData(m_attrs, postOps, memory, m_context, cacheWeights)), m_primArgs(m_shapeAgnosticData->primAttrs.dnnlArgs) {} bool update(const MemoryArgs& memory) override { const auto primitive = createPrimitive(memory); diff --git a/src/plugins/intel_cpu/src/nodes/executors/dnnl/dnnl_utils.hpp b/src/plugins/intel_cpu/src/nodes/executors/dnnl/dnnl_utils.hpp index 2cee78428cf..4e310c7465f 100644 --- a/src/plugins/intel_cpu/src/nodes/executors/dnnl/dnnl_utils.hpp +++ b/src/plugins/intel_cpu/src/nodes/executors/dnnl/dnnl_utils.hpp @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // // @file dnnl_utils.hpp -// Contains utility methods supposed used by oneDNN backend executors +// Contains utility methods used by oneDNN backend executors // #pragma once diff --git a/src/plugins/intel_cpu/src/nodes/executors/executor.hpp b/src/plugins/intel_cpu/src/nodes/executors/executor.hpp index 9524ac0d1c3..0d9d4cb8bfc 100644 --- a/src/plugins/intel_cpu/src/nodes/executors/executor.hpp +++ b/src/plugins/intel_cpu/src/nodes/executors/executor.hpp @@ -41,6 +41,12 @@ namespace intel_cpu { # define OV_CPU_INSTANCE_X64(...) #endif +#if defined(OV_CPU_WITH_MLAS) && defined(OPENVINO_ARCH_X86_64) +# define OV_CPU_INSTANCE_MLAS_X64(...) {__VA_ARGS__}, +#else +# define OV_CPU_INSTANCE_MLAS_X64(...) +#endif + #define OV_CPU_INSTANCE_COMMON(...) {__VA_ARGS__}, // @todo another option is to determine shape relation by executor type diff --git a/src/plugins/intel_cpu/src/nodes/executors/fullyconnected_implementations.cpp b/src/plugins/intel_cpu/src/nodes/executors/fullyconnected_implementations.cpp index f0a09b6bb30..0c66c37394a 100644 --- a/src/plugins/intel_cpu/src/nodes/executors/fullyconnected_implementations.cpp +++ b/src/plugins/intel_cpu/src/nodes/executors/fullyconnected_implementations.cpp @@ -146,7 +146,7 @@ OV_CPU_MAYBE_UNUSED_FUNCTION static inline bool noPostOps(const FCConfig& config template <> const std::vector>& getImplementations() { static const std::vector> fullyconnectedImplementations { - OV_CPU_INSTANCE_X64( + OV_CPU_INSTANCE_MLAS_X64( "fullyconnected_mlas", ExecutorType::Mlas, OperationType::MatMul, diff --git a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/x64/matmul.cpp b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/x64/matmul.cpp index ae1101fbba9..33889dbcbd1 100644 --- a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/x64/matmul.cpp +++ b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/x64/matmul.cpp @@ -191,6 +191,7 @@ std::vector fusingParamsSet2D_Brgemm_smoke { fusingMultiplyPerChannel, #endif fusingFakeQuantizePerTensorRelu, + fusingReluScaleShift }; const auto fullyConnectedParams2D_Brgemm_smoke = ::testing::Combine(::testing::ValuesIn(IS2D_Brgemm_smoke),