Merge a0527fefad into 43de73cbd6
This commit is contained in:
commit
b4e89fdf3d
|
|
@ -26,13 +26,13 @@ using namespace dnnl::impl::utils;
|
||||||
using namespace dnnl::impl::cpu::x64;
|
using namespace dnnl::impl::cpu::x64;
|
||||||
using namespace Xbyak;
|
using namespace Xbyak;
|
||||||
|
|
||||||
template <typename src_t, typename dst_t>
|
template <typename src_t, typename dst_t, int isa>
|
||||||
void convert_vec(jit_generator & gen,
|
void convert_vec(jit_generator & gen,
|
||||||
const RegExp & src,
|
const RegExp & src,
|
||||||
const RegExp & dst);
|
const RegExp & dst);
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void convert_vec<ov::float16, float>(jit_generator & gen,
|
void convert_vec<ov::float16, float, cpu_isa_t::avx2>(jit_generator & gen,
|
||||||
const RegExp & src,
|
const RegExp & src,
|
||||||
const RegExp & dst) {
|
const RegExp & dst) {
|
||||||
auto const & f16vec = gen.xmm3;
|
auto const & f16vec = gen.xmm3;
|
||||||
|
|
@ -44,7 +44,7 @@ void convert_vec<ov::float16, float>(jit_generator & gen,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void convert_vec<float, ov::float16>(jit_generator & gen,
|
void convert_vec<float, ov::float16, cpu_isa_t::avx2>(jit_generator & gen,
|
||||||
const RegExp & src,
|
const RegExp & src,
|
||||||
const RegExp & dst) {
|
const RegExp & dst) {
|
||||||
auto const & f16vec = gen.xmm3;
|
auto const & f16vec = gen.xmm3;
|
||||||
|
|
@ -55,6 +55,31 @@ void convert_vec<float, ov::float16>(jit_generator & gen,
|
||||||
gen.movdqu(gen.xword[dst], f16vec);
|
gen.movdqu(gen.xword[dst], f16vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AVX512 instructions for ov::float16 to float conversion
|
||||||
|
template <>
|
||||||
|
void convert_vec<ov::float16, float, cpu_isa_t::avx512_core>(jit_generator & gen,
|
||||||
|
const RegExp & src,
|
||||||
|
const RegExp & dst) {
|
||||||
|
auto const & f16vec = gen.ymm3;
|
||||||
|
auto const & f32vec = gen.zmm4;
|
||||||
|
|
||||||
|
gen.movdqu(f16vec, gen.yword[src]);
|
||||||
|
gen.vcvtph2ps(f32vec, f16vec);
|
||||||
|
gen.vmovups(gen.zword[dst], f32vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void convert_vec<float, ov::float16, cpu_isa_t::avx512_core>(jit_generator & gen,
|
||||||
|
const RegExp & src,
|
||||||
|
const RegExp & dst) {
|
||||||
|
auto const & f16vec = gen.ymm3;
|
||||||
|
auto const & f32vec = gen.zmm4;
|
||||||
|
|
||||||
|
gen.vmovups(f32vec, gen.zword[src]);
|
||||||
|
gen.vcvtps2ph(f16vec, f32vec, 0);
|
||||||
|
gen.movdqu(gen.yword[dst], f16vec);
|
||||||
|
}
|
||||||
|
|
||||||
class jit_convert_array : public jit_kernel {
|
class jit_convert_array : public jit_kernel {
|
||||||
DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_convert_array)
|
DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_convert_array)
|
||||||
|
|
||||||
|
|
@ -125,10 +150,15 @@ public:
|
||||||
|
|
||||||
template<typename src_t, typename dst_t>
|
template<typename src_t, typename dst_t>
|
||||||
static fn_t get() {
|
static fn_t get() {
|
||||||
if (mayiuse(cpu_isa_t::avx2)
|
// fallback to AVX2 if AVX512 is not available
|
||||||
&& dnnl::impl::cpu::x64::cpu().has(Xbyak::util::Cpu::tF16C)) {
|
if (mayiuse(cpu_isa_t::avx512_core)) {
|
||||||
static jit_convert_array converter(convert_vec<src_t, dst_t>, sizeof(src_t), sizeof(dst_t));
|
static jit_convert_array converter(convert_vec<src_t, dst_t, cpu_isa_t::avx512_core>, sizeof(src_t), sizeof(dst_t));
|
||||||
auto & generator = static_cast<jit_generator&>(converter);
|
auto& generator = static_cast<jit_generator&>(converter);
|
||||||
|
generator.create_kernel();
|
||||||
|
return (fn_t)generator.jit_ker();
|
||||||
|
} else if (mayiuse(cpu_isa_t::avx2) && dnnl::impl::cpu::x64::cpu().has(Xbyak::util::Cpu::tF16C)) {
|
||||||
|
static jit_convert_array converter(convert_vec<src_t, dst_t, cpu_isa_t::avx2>, sizeof(src_t), sizeof(dst_t));
|
||||||
|
auto& generator = static_cast<jit_generator&>(converter);
|
||||||
generator.create_kernel();
|
generator.create_kernel();
|
||||||
return (fn_t)generator.jit_ker();
|
return (fn_t)generator.jit_ker();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ if(NOT X86_64)
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/transformations/x64
|
${CMAKE_CURRENT_SOURCE_DIR}/transformations/x64
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/snippets_transformations/x64
|
${CMAKE_CURRENT_SOURCE_DIR}/snippets_transformations/x64
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/nodes/eltwise_node_test.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/nodes/eltwise_node_test.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/nodes/avx_512_test.cpp)
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/brgemm_executor_test.cpp)
|
${CMAKE_CURRENT_SOURCE_DIR}/brgemm_executor_test.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright (C) 2018-2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "nodes/common/cpu_convert.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
using namespace std::chrono;
|
||||||
|
using namespace ov::intel_cpu;
|
||||||
|
|
||||||
|
TEST(cpu_convert, AVX512_fp16_load_store) {
|
||||||
|
std::vector<size_t> sizes = {1000, 10000, 100000, 1000000};
|
||||||
|
for (size_t size : sizes) {
|
||||||
|
std::vector<float> input_data(size, 1.23f);
|
||||||
|
std::vector<short> output_data(size);
|
||||||
|
|
||||||
|
auto start = high_resolution_clock::now();
|
||||||
|
cpu_convert(input_data.data(), output_data.data(), ov::element::f32, ov::element::f16, size);
|
||||||
|
auto stop = high_resolution_clock::now();
|
||||||
|
auto duration = duration_cast<microseconds>(stop - start);
|
||||||
|
std::cout << "size " << size << ": " << duration.count() << " microseconds\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue