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 Xbyak;
|
||||
|
||||
template <typename src_t, typename dst_t>
|
||||
template <typename src_t, typename dst_t, int isa>
|
||||
void convert_vec(jit_generator & gen,
|
||||
const RegExp & src,
|
||||
const RegExp & dst);
|
||||
|
||||
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 & dst) {
|
||||
auto const & f16vec = gen.xmm3;
|
||||
|
|
@ -44,7 +44,7 @@ void convert_vec<ov::float16, float>(jit_generator & gen,
|
|||
}
|
||||
|
||||
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 & dst) {
|
||||
auto const & f16vec = gen.xmm3;
|
||||
|
|
@ -55,6 +55,31 @@ void convert_vec<float, ov::float16>(jit_generator & gen,
|
|||
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 {
|
||||
DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_convert_array)
|
||||
|
||||
|
|
@ -125,10 +150,15 @@ public:
|
|||
|
||||
template<typename src_t, typename dst_t>
|
||||
static fn_t get() {
|
||||
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>, sizeof(src_t), sizeof(dst_t));
|
||||
auto & generator = static_cast<jit_generator&>(converter);
|
||||
// fallback to AVX2 if AVX512 is not available
|
||||
if (mayiuse(cpu_isa_t::avx512_core)) {
|
||||
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);
|
||||
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();
|
||||
return (fn_t)generator.jit_ker();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ if(NOT X86_64)
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/transformations/x64
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/snippets_transformations/x64
|
||||
${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)
|
||||
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