From cf906030ac0da5799d6a8ee7878f64bb20fa8b9c Mon Sep 17 00:00:00 2001 From: Sebastian Luzynski Date: Mon, 28 Mar 2022 16:30:45 +0000 Subject: [PATCH] Add neon intrinsics for aarch64 Related-To: NEO-6452 Signed-off-by: Sebastian Luzynski --- CMakeLists.txt | 1 + shared/source/helpers/aarch64/CMakeLists.txt | 9 +- .../source/helpers/aarch64/local_id_gen.cpp | 16 +- .../helpers/aarch64/local_id_gen_neon.cpp | 17 ++ shared/source/helpers/aarch64/uint16_neon.h | 173 ++++++++++++++++++ .../utilities/aarch64/cpu_info_aarch64.cpp | 7 +- shared/source/utilities/cpu_info.h | 3 +- .../utilities/linux/aarch64/cpu_info.cpp | 4 +- shared/test/unit_test/helpers/CMakeLists.txt | 6 + .../unit_test/helpers/uint16_neon_tests.cpp | 111 +++++++++++ .../utilities/aarch64/CMakeLists.txt | 12 ++ .../aarch64/cpuinfo_tests_aarch64.cpp | 38 ++++ .../utilities/linux/cpuinfo_tests_linux.cpp | 22 +-- .../unit_test/utilities/x86_64/CMakeLists.txt | 4 +- .../utilities/x86_64/linux/CMakeLists.txt | 11 ++ .../linux/cpuinfo_tests_x86_64_linux.cpp | 38 ++++ 16 files changed, 445 insertions(+), 27 deletions(-) create mode 100644 shared/source/helpers/aarch64/local_id_gen_neon.cpp create mode 100644 shared/source/helpers/aarch64/uint16_neon.h create mode 100644 shared/test/unit_test/helpers/uint16_neon_tests.cpp create mode 100644 shared/test/unit_test/utilities/aarch64/CMakeLists.txt create mode 100644 shared/test/unit_test/utilities/aarch64/cpuinfo_tests_aarch64.cpp create mode 100644 shared/test/unit_test/utilities/x86_64/linux/CMakeLists.txt create mode 100644 shared/test/unit_test/utilities/x86_64/linux/cpuinfo_tests_x86_64_linux.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ea83dd0ffe..7e19bd27ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -618,6 +618,7 @@ else() endif() check_cxx_compiler_flag(-msse4.2 COMPILER_SUPPORTS_SSE42) check_cxx_compiler_flag(-mavx2 COMPILER_SUPPORTS_AVX2) + check_cxx_compiler_flag(-march=armv8-a+simd COMPILER_SUPPORTS_NEON) endif() if(NOT MSVC) diff --git a/shared/source/helpers/aarch64/CMakeLists.txt b/shared/source/helpers/aarch64/CMakeLists.txt index 29009e35dc..e034b9ebcb 100644 --- a/shared/source/helpers/aarch64/CMakeLists.txt +++ b/shared/source/helpers/aarch64/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2019-2021 Intel Corporation +# Copyright (C) 2019-2022 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -10,5 +10,12 @@ if(${NEO_TARGET_PROCESSOR} STREQUAL "aarch64") ${CMAKE_CURRENT_SOURCE_DIR}/local_id_gen.cpp ) + if(COMPILER_SUPPORTS_NEON) + list(APPEND NEO_CORE_HELPERS + ${CMAKE_CURRENT_SOURCE_DIR}/local_id_gen_neon.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/uint16_neon.h + ) + endif() + set_property(GLOBAL PROPERTY NEO_CORE_HELPERS ${NEO_CORE_HELPERS}) endif() diff --git a/shared/source/helpers/aarch64/local_id_gen.cpp b/shared/source/helpers/aarch64/local_id_gen.cpp index ed8b9da5b9..37fe325002 100644 --- a/shared/source/helpers/aarch64/local_id_gen.cpp +++ b/shared/source/helpers/aarch64/local_id_gen.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -9,10 +9,12 @@ #include "shared/source/helpers/aligned_memory.h" #include "shared/source/helpers/local_id_gen_special.inl" +#include "shared/source/utilities/cpu_info.h" namespace NEO { struct uint16x8_t; +struct uint16x16_t; // This is the initial value of SIMD for local ID // computation. It correlates to the SIMD lane. @@ -27,6 +29,18 @@ void (*LocalIDHelper::generateSimd8)(void *buffer, const std::array void (*LocalIDHelper::generateSimd16)(void *buffer, const std::array &localWorkgroupSize, uint16_t threadsPerWorkGroup, const std::array &dimensionsOrder, bool chooseMaxRowSize) = generateLocalIDsSimd; void (*LocalIDHelper::generateSimd32)(void *buffer, const std::array &localWorkgroupSize, uint16_t threadsPerWorkGroup, const std::array &dimensionsOrder, bool chooseMaxRowSize) = generateLocalIDsSimd; +// Initialize the lookup table based on CPU capabilities +LocalIDHelper::LocalIDHelper() { + bool supportsNEON = CpuInfo::getInstance().isFeatureSupported(CpuInfo::featureNeon); + if (supportsNEON) { + LocalIDHelper::generateSimd8 = generateLocalIDsSimd; + LocalIDHelper::generateSimd16 = generateLocalIDsSimd; + LocalIDHelper::generateSimd32 = generateLocalIDsSimd; + } +} + +LocalIDHelper LocalIDHelper::initializer; + void generateLocalIDs(void *buffer, uint16_t simd, const std::array &localWorkgroupSize, const std::array &dimensionsOrder, bool isImageOnlyKernel, uint32_t grfSize) { auto threadsPerWorkGroup = static_cast(getThreadsPerWG(simd, localWorkgroupSize[0] * localWorkgroupSize[1] * localWorkgroupSize[2])); bool useLayoutForImages = isImageOnlyKernel && isCompatibleWithLayoutForImages(localWorkgroupSize, dimensionsOrder, simd); diff --git a/shared/source/helpers/aarch64/local_id_gen_neon.cpp b/shared/source/helpers/aarch64/local_id_gen_neon.cpp new file mode 100644 index 0000000000..6149cd5d32 --- /dev/null +++ b/shared/source/helpers/aarch64/local_id_gen_neon.cpp @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/helpers/aarch64/uint16_neon.h" +#include "shared/source/helpers/local_id_gen.inl" + +#include + +namespace NEO { +template void generateLocalIDsSimd(void *b, const std::array &localWorkgroupSize, uint16_t threadsPerWorkGroup, const std::array &dimensionsOrder, bool chooseMaxRowSize); +template void generateLocalIDsSimd(void *b, const std::array &localWorkgroupSize, uint16_t threadsPerWorkGroup, const std::array &dimensionsOrder, bool chooseMaxRowSize); +template void generateLocalIDsSimd(void *b, const std::array &localWorkgroupSize, uint16_t threadsPerWorkGroup, const std::array &dimensionsOrder, bool chooseMaxRowSize); +} // namespace NEO diff --git a/shared/source/helpers/aarch64/uint16_neon.h b/shared/source/helpers/aarch64/uint16_neon.h new file mode 100644 index 0000000000..3e07d179cb --- /dev/null +++ b/shared/source/helpers/aarch64/uint16_neon.h @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/helpers/aligned_memory.h" +#include "shared/source/helpers/debug_helpers.h" + +#include +#include + +namespace NEO { + +struct uint16x16_t { + enum { numChannels = 16 }; + + uint16x8x2_t value; + + uint16x16_t() { + value.val[0] = vdupq_n_u16(0); + value.val[1] = vdupq_n_u16(0); + } + + uint16x16_t(uint16x8_t lo, uint16x8_t hi) { + value.val[0] = lo; + value.val[1] = hi; + } + + uint16x16_t(uint16_t a) { + value.val[0] = vdupq_n_u16(a); + value.val[1] = vdupq_n_u16(a); + } + + explicit uint16x16_t(const void *alignedPtr) { + load(alignedPtr); + } + + inline uint16_t get(unsigned int element) { + DEBUG_BREAK_IF(element >= numChannels); + uint16_t result; + // vgetq_lane requires constant immediate + switch (element) { + case 0: + result = vgetq_lane_u16(value.val[0], 0); + break; + case 1: + result = vgetq_lane_u16(value.val[0], 1); + break; + case 2: + result = vgetq_lane_u16(value.val[0], 2); + break; + case 3: + result = vgetq_lane_u16(value.val[0], 3); + break; + case 4: + result = vgetq_lane_u16(value.val[0], 4); + break; + case 5: + result = vgetq_lane_u16(value.val[0], 5); + break; + case 6: + result = vgetq_lane_u16(value.val[0], 6); + break; + case 7: + result = vgetq_lane_u16(value.val[0], 7); + break; + case 8: + result = vgetq_lane_u16(value.val[1], 0); + break; + case 9: + result = vgetq_lane_u16(value.val[1], 1); + break; + case 10: + result = vgetq_lane_u16(value.val[1], 2); + break; + case 11: + result = vgetq_lane_u16(value.val[1], 3); + break; + case 12: + result = vgetq_lane_u16(value.val[1], 4); + break; + case 13: + result = vgetq_lane_u16(value.val[1], 5); + break; + case 14: + result = vgetq_lane_u16(value.val[1], 6); + break; + case 15: + result = vgetq_lane_u16(value.val[1], 7); + break; + } + + return result; + } + + static inline uint16x16_t zero() { + return uint16x16_t(static_cast(0u)); + } + + static inline uint16x16_t one() { + return uint16x16_t(static_cast(1u)); + } + + static inline uint16x16_t mask() { + return uint16x16_t(static_cast(0xffffu)); + } + + inline void load(const void *alignedPtr) { + DEBUG_BREAK_IF(!isAligned<32>(alignedPtr)); + value = vld1q_u16_x2(reinterpret_cast(alignedPtr)); + } + + inline void store(void *alignedPtr) { + DEBUG_BREAK_IF(!isAligned<32>(alignedPtr)); + vst1q_u16_x2(reinterpret_cast(alignedPtr), value); + } + + inline operator bool() const { + uint64x2_t hi = vreinterpretq_u64_u16(value.val[0]); + uint64x2_t lo = vreinterpretq_u64_u16(value.val[1]); + uint64x2_t tmp = vorrq_u64(hi, lo); + uint64_t result = vget_lane_u64(vorr_u64(vget_high_u64(tmp), vget_low_u64(tmp)), 0); + + return result; + } + + inline uint16x16_t &operator-=(const uint16x16_t &a) { + value.val[0] = vsubq_u16(value.val[0], a.value.val[0]); + value.val[1] = vsubq_u16(value.val[1], a.value.val[1]); + + return *this; + } + + inline uint16x16_t &operator+=(const uint16x16_t &a) { + value.val[0] = vaddq_u16(value.val[0], a.value.val[0]); + value.val[1] = vaddq_u16(value.val[1], a.value.val[1]); + + return *this; + } + + inline friend uint16x16_t operator>=(const uint16x16_t &a, const uint16x16_t &b) { + uint16x16_t result; + + result.value.val[0] = veorq_u16(mask().value.val[0], + vcgtq_u16(b.value.val[0], a.value.val[0])); + result.value.val[1] = veorq_u16(mask().value.val[1], + vcgtq_u16(b.value.val[1], a.value.val[1])); + return result; + } + + inline friend uint16x16_t operator&&(const uint16x16_t &a, const uint16x16_t &b) { + uint16x16_t result; + + result.value.val[0] = vandq_u16(a.value.val[0], b.value.val[0]); + result.value.val[1] = vandq_u16(a.value.val[1], b.value.val[1]); + + return result; + } + + // NOTE: uint16x16_t::blend behaves like mask ? a : b + inline friend uint16x16_t blend(const uint16x16_t &a, const uint16x16_t &b, const uint16x16_t &mask) { + uint16x16_t result; + + result.value.val[0] = vbslq_u16(mask.value.val[0], a.value.val[0], b.value.val[0]); + result.value.val[1] = vbslq_u16(mask.value.val[1], a.value.val[1], b.value.val[1]); + + return result; + } +}; +} // namespace NEO diff --git a/shared/source/utilities/aarch64/cpu_info_aarch64.cpp b/shared/source/utilities/aarch64/cpu_info_aarch64.cpp index cdaf73c0c7..462227fd67 100644 --- a/shared/source/utilities/aarch64/cpu_info_aarch64.cpp +++ b/shared/source/utilities/aarch64/cpu_info_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Intel Corporation + * Copyright (C) 2021-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -7,7 +7,12 @@ #include "shared/source/utilities/cpu_info.h" +#include + namespace NEO { void CpuInfo::detect() const { + uint32_t cpuInfo[4] = {}; + cpuid(cpuInfo, 0u); + features |= cpuInfo[0] & HWCAP_ASIMD ? featureNeon : featureNone; } } // namespace NEO diff --git a/shared/source/utilities/cpu_info.h b/shared/source/utilities/cpu_info.h index ad7f54f0f8..08292e5884 100644 --- a/shared/source/utilities/cpu_info.h +++ b/shared/source/utilities/cpu_info.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -42,6 +42,7 @@ struct CpuInfo { static const uint64_t featureHle = 0x000200000ULL; static const uint64_t featureRtm = 0x000400000ULL; static const uint64_t featureAvX2 = 0x000800000ULL; + static const uint64_t featureNeon = 0x001000000ULL; static const uint64_t featureKncni = 0x004000000ULL; static const uint64_t featureAvX512F = 0x008000000ULL; static const uint64_t featureAdx = 0x010000000ULL; diff --git a/shared/source/utilities/linux/aarch64/cpu_info.cpp b/shared/source/utilities/linux/aarch64/cpu_info.cpp index 570b3357bf..21216e8f7c 100644 --- a/shared/source/utilities/linux/aarch64/cpu_info.cpp +++ b/shared/source/utilities/linux/aarch64/cpu_info.cpp @@ -11,10 +11,12 @@ #include #include +#include namespace NEO { void cpuid_linux_wrapper(int cpuInfo[4], int functionId) { + cpuInfo[0] = getauxval(AT_HWCAP); } void cpuidex_linux_wrapper(int *cpuInfo, int functionId, int subfunctionId) { @@ -24,7 +26,7 @@ void get_cpu_flags_linux(std::string &cpuFlags) { std::ifstream cpuinfo(std::string(Os::sysFsProcPathPrefix) + "/cpuinfo"); std::string line; while (std::getline(cpuinfo, line)) { - if (line.substr(0, 5) == "flags") { + if (line.substr(0, 8) == "Features") { cpuFlags = line; break; } diff --git a/shared/test/unit_test/helpers/CMakeLists.txt b/shared/test/unit_test/helpers/CMakeLists.txt index 35006b8a29..8255f8f5ea 100644 --- a/shared/test/unit_test/helpers/CMakeLists.txt +++ b/shared/test/unit_test/helpers/CMakeLists.txt @@ -25,5 +25,11 @@ set(IGDRCL_SRCS_tests_helpers ${CMAKE_CURRENT_SOURCE_DIR}/test_hw_info_config.cpp ) +if(COMPILER_SUPPORTS_NEON) + list(APPEND IGDRCL_SRCS_tests_helpers + ${CMAKE_CURRENT_SOURCE_DIR}/uint16_neon_tests.cpp + ) +endif() + target_sources(${TARGET_NAME} PRIVATE ${IGDRCL_SRCS_tests_helpers}) add_subdirectories() diff --git a/shared/test/unit_test/helpers/uint16_neon_tests.cpp b/shared/test/unit_test/helpers/uint16_neon_tests.cpp new file mode 100644 index 0000000000..55e7cedb9f --- /dev/null +++ b/shared/test/unit_test/helpers/uint16_neon_tests.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/helpers/aarch64/uint16_neon.h" +#include "shared/source/helpers/aligned_memory.h" + +#include "gtest/gtest.h" + +using namespace NEO; + +TEST(Uint16Neon, GivenNeonAndMaskWhenCastingToBoolThenTrueIsReturned) { + EXPECT_TRUE(static_cast(NEO::uint16x16_t::mask())); +} + +TEST(Uint16Neon, GivenNeonAndZeroWhenCastingToBoolThenFalseIsReturned) { + EXPECT_FALSE(static_cast(NEO::uint16x16_t::zero())); +} + +TEST(Uint16Neon, GivenNeonWhenConjoiningMaskAndZeroThenBooleanResultIsCorrect) { + EXPECT_TRUE(NEO::uint16x16_t::mask() && NEO::uint16x16_t::mask()); + EXPECT_FALSE(NEO::uint16x16_t::mask() && NEO::uint16x16_t::zero()); + EXPECT_FALSE(NEO::uint16x16_t::zero() && NEO::uint16x16_t::mask()); + EXPECT_FALSE(NEO::uint16x16_t::zero() && NEO::uint16x16_t::zero()); +} + +TEST(Uint16Neon, GivenNeonAndOneWhenCreatingThenInstancesAreSame) { + auto one = NEO::uint16x16_t::one(); + NEO::uint16x16_t alsoOne(one); + EXPECT_EQ(0, memcmp(&alsoOne, &one, sizeof(NEO::uint16x16_t))); +} + +TEST(Uint16Neon, GivenNeonAndValueWhenCreatingThenConstructorIsReplicated) { + NEO::uint16x16_t allSevens(7u); + for (int i = 0; i < NEO::uint16x16_t::numChannels; ++i) { + EXPECT_EQ(7u, allSevens.get(i)); + } +} + +ALIGNAS(32) +static const uint16_t laneValues[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + +TEST(Uint16Neon, GivenNeonAndArrayWhenCreatingThenConstructorIsReplicated) { + NEO::uint16x16_t lanes(laneValues); + for (int i = 0; i < NEO::uint16x16_t::numChannels; ++i) { + EXPECT_EQ(static_cast(i), lanes.get(i)); + } +} + +TEST(Uint16Neon, GivenNeonWhenLoadingThenValuesAreSetCorrectly) { + NEO::uint16x16_t lanes; + lanes.load(laneValues); + for (int i = 0; i < NEO::uint16x16_t::numChannels; ++i) { + EXPECT_EQ(static_cast(i), lanes.get(i)); + } +} + +TEST(Uint16Neon, GivenNeonWhenStoringThenValuesAreSetCorrectly) { + uint16_t *alignedMemory = reinterpret_cast(alignedMalloc(1024, 32)); + + NEO::uint16x16_t lanes(laneValues); + lanes.store(alignedMemory); + for (int i = 0; i < NEO::uint16x16_t::numChannels; ++i) { + EXPECT_EQ(static_cast(i), alignedMemory[i]); + } + + alignedFree(alignedMemory); +} + +TEST(Uint16Neon, GivenNeonWhenDecrementingThenValuesAreSetCorrectly) { + NEO::uint16x16_t result(laneValues); + result -= NEO::uint16x16_t::one(); + + for (int i = 0; i < NEO::uint16x16_t::numChannels; ++i) { + EXPECT_EQ(static_cast(i - 1), result.get(i)); + } +} + +TEST(Uint16Neon, GivenNeonWhenIncrementingThenValuesAreSetCorrectly) { + NEO::uint16x16_t result(laneValues); + result += NEO::uint16x16_t::one(); + + for (int i = 0; i < NEO::uint16x16_t::numChannels; ++i) { + EXPECT_EQ(static_cast(i + 1), result.get(i)); + } +} + +TEST(Uint16Sse4, GivenNeonWhenBlendingThenValuesAreSetCorrectly) { + NEO::uint16x16_t a(NEO::uint16x16_t::one()); + NEO::uint16x16_t b(NEO::uint16x16_t::zero()); + NEO::uint16x16_t c; + + // c = mask ? a : b + c = blend(a, b, NEO::uint16x16_t::mask()); + + for (int i = 0; i < NEO::uint16x16_t::numChannels; ++i) { + EXPECT_EQ(a.get(i), c.get(i)); + } + + // c = mask ? a : b + c = blend(a, b, NEO::uint16x16_t::zero()); + + for (int i = 0; i < NEO::uint16x16_t::numChannels; ++i) { + EXPECT_EQ(b.get(i), c.get(i)); + } +} diff --git a/shared/test/unit_test/utilities/aarch64/CMakeLists.txt b/shared/test/unit_test/utilities/aarch64/CMakeLists.txt new file mode 100644 index 0000000000..c1dc057062 --- /dev/null +++ b/shared/test/unit_test/utilities/aarch64/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright (C) 2022 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +if(${NEO_TARGET_PROCESSOR} STREQUAL "aarch64") + target_sources(${TARGET_NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/cpuinfo_tests_aarch64.cpp + ) +endif() diff --git a/shared/test/unit_test/utilities/aarch64/cpuinfo_tests_aarch64.cpp b/shared/test/unit_test/utilities/aarch64/cpuinfo_tests_aarch64.cpp new file mode 100644 index 0000000000..abb0440cb7 --- /dev/null +++ b/shared/test/unit_test/utilities/aarch64/cpuinfo_tests_aarch64.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/helpers/file_io.h" +#include "shared/source/os_interface/linux/os_inc.h" +#include "shared/source/utilities/cpu_info.h" +#include "shared/test/common/helpers/variable_backup.h" + +#include "gtest/gtest.h" + +#include +#include + +using namespace NEO; + +TEST(CpuInfoAarch64, givenProcCpuinfoFileExistsWhenIsCpuFlagPresentIsCalledThenValidValueIsReturned) { + VariableBackup pathPrefixBackup(&Os::sysFsProcPathPrefix, "./test_files"); + std::string cpuinfoFile = "./test_files/cpuinfo"; + EXPECT_FALSE(fileExists(cpuinfoFile)); + + { + std::ofstream cpuinfo(cpuinfoFile); + cpuinfo << "processor\t\t: 0\nFeatures\t\t: flag1 flag2 flag3\n"; + } + + EXPECT_TRUE(fileExists(cpuinfoFile)); + + CpuInfo testCpuInfo; + EXPECT_TRUE(testCpuInfo.isCpuFlagPresent("flag1")); + EXPECT_TRUE(testCpuInfo.isCpuFlagPresent("flag2")); + EXPECT_FALSE(testCpuInfo.isCpuFlagPresent("nonExistingCpuFlag")); + + std::remove(cpuinfoFile.c_str()); +} diff --git a/shared/test/unit_test/utilities/linux/cpuinfo_tests_linux.cpp b/shared/test/unit_test/utilities/linux/cpuinfo_tests_linux.cpp index b0222f5c04..528fc8d1bd 100644 --- a/shared/test/unit_test/utilities/linux/cpuinfo_tests_linux.cpp +++ b/shared/test/unit_test/utilities/linux/cpuinfo_tests_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Intel Corporation + * Copyright (C) 2021-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -17,26 +17,6 @@ using namespace NEO; -TEST(CpuInfo, givenProcCpuinfoFileExistsWhenIsCpuFlagPresentIsCalledThenValidValueIsReturned) { - VariableBackup pathPrefixBackup(&Os::sysFsProcPathPrefix, "./test_files"); - std::string cpuinfoFile = "./test_files/cpuinfo"; - EXPECT_FALSE(fileExists(cpuinfoFile)); - - { - std::ofstream cpuinfo(cpuinfoFile); - cpuinfo << "processor\t\t: 0\nflags\t\t: flag1 flag2 flag3\n"; - } - - EXPECT_TRUE(fileExists(cpuinfoFile)); - - CpuInfo testCpuInfo; - EXPECT_TRUE(testCpuInfo.isCpuFlagPresent("flag1")); - EXPECT_TRUE(testCpuInfo.isCpuFlagPresent("flag2")); - EXPECT_FALSE(testCpuInfo.isCpuFlagPresent("nonExistingCpuFlag")); - - std::remove(cpuinfoFile.c_str()); -} - TEST(CpuInfo, givenProcCpuinfoFileIsNotExistsWhenIsCpuFlagPresentIsCalledThenValidValueIsReturned) { std::string cpuinfoFile = "test_files/linux/proc/cpuinfo"; EXPECT_FALSE(fileExists(cpuinfoFile)); diff --git a/shared/test/unit_test/utilities/x86_64/CMakeLists.txt b/shared/test/unit_test/utilities/x86_64/CMakeLists.txt index 01120cac50..cd26453a94 100644 --- a/shared/test/unit_test/utilities/x86_64/CMakeLists.txt +++ b/shared/test/unit_test/utilities/x86_64/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2021 Intel Corporation +# Copyright (C) 2021-2022 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -9,4 +9,6 @@ if(${NEO_TARGET_PROCESSOR} STREQUAL "x86_64") ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt ${CMAKE_CURRENT_SOURCE_DIR}/cpuinfo_tests_x86_64.cpp ) + + add_subdirectories() endif() diff --git a/shared/test/unit_test/utilities/x86_64/linux/CMakeLists.txt b/shared/test/unit_test/utilities/x86_64/linux/CMakeLists.txt new file mode 100644 index 0000000000..feea4d5605 --- /dev/null +++ b/shared/test/unit_test/utilities/x86_64/linux/CMakeLists.txt @@ -0,0 +1,11 @@ +# +# Copyright (C) 2022 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +if(UNIX) + target_sources(${TARGET_NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/cpuinfo_tests_x86_64_linux.cpp + ) +endif() diff --git a/shared/test/unit_test/utilities/x86_64/linux/cpuinfo_tests_x86_64_linux.cpp b/shared/test/unit_test/utilities/x86_64/linux/cpuinfo_tests_x86_64_linux.cpp new file mode 100644 index 0000000000..f9393da74f --- /dev/null +++ b/shared/test/unit_test/utilities/x86_64/linux/cpuinfo_tests_x86_64_linux.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/helpers/file_io.h" +#include "shared/source/os_interface/linux/os_inc.h" +#include "shared/source/utilities/cpu_info.h" +#include "shared/test/common/helpers/variable_backup.h" + +#include "gtest/gtest.h" + +#include +#include + +using namespace NEO; + +TEST(CpuInfo, givenProcCpuinfoFileExistsWhenIsCpuFlagPresentIsCalledThenValidValueIsReturned) { + VariableBackup pathPrefixBackup(&Os::sysFsProcPathPrefix, "./test_files"); + std::string cpuinfoFile = "./test_files/cpuinfo"; + EXPECT_FALSE(fileExists(cpuinfoFile)); + + { + std::ofstream cpuinfo(cpuinfoFile); + cpuinfo << "processor\t\t: 0\nflags\t\t: flag1 flag2 flag3\n"; + } + + EXPECT_TRUE(fileExists(cpuinfoFile)); + + CpuInfo testCpuInfo; + EXPECT_TRUE(testCpuInfo.isCpuFlagPresent("flag1")); + EXPECT_TRUE(testCpuInfo.isCpuFlagPresent("flag2")); + EXPECT_FALSE(testCpuInfo.isCpuFlagPresent("nonExistingCpuFlag")); + + std::remove(cpuinfoFile.c_str()); +}