Skip to content

Commit a7397c1

Browse files
committed
Add riscv_cpu_features
1 parent 6b61b1a commit a7397c1

File tree

9 files changed

+110
-18
lines changed

9 files changed

+110
-18
lines changed

.github/workflows/cross-rvv.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ jobs:
5656
-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/.github/toolchains/${{ matrix.sys.compiler }}-riscv64-linux-gnu.cmake
5757
- name: Build
5858
run: cmake --build _build
59+
- name: Set CPU feature test expectations
60+
run: |
61+
echo "XSIMD_TEST_CPU_ASSUME_SSE4_2=0" >> "$GITHUB_ENV"
62+
echo "XSIMD_TEST_CPU_ASSUME_SVE=0" >> "$GITHUB_ENV"
63+
echo "XSIMD_TEST_CPU_ASSUME_RVV=1" >> "$GITHUB_ENV"
5964
- name: Testing xsimd
6065
run: >
6166
QEMU_CPU="rv64,zba=true,zbb=true,zbs=true,v=true,vlen=${{ matrix.vector_bits }},elen=64,vext_spec=v1.0"

.github/workflows/cross-sve.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ jobs:
4343
- name: Set CPU feature test expectations
4444
run: |
4545
echo "XSIMD_TEST_CPU_ASSUME_SSE4_2=0" >> "$GITHUB_ENV"
46+
echo "XSIMD_TEST_CPU_ASSUME_RVV=0" >> "$GITHUB_ENV"
4647
echo "XSIMD_TEST_CPU_ASSUME_NEON64=1" >> "$GITHUB_ENV"
4748
echo "XSIMD_TEST_CPU_ASSUME_SVE=1" >> "$GITHUB_ENV"
4849
echo "XSIMD_TEST_CPU_ASSUME_MANUFACTURER=unknown" >> "$GITHUB_ENV"

.github/workflows/linux.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ jobs:
122122
run: |
123123
# Set CPU feature test expectations, 0 is explicit absence of the feature
124124
export XSIMD_TEST_CPU_ASSUME_NEON64="0"
125+
export XSIMD_TEST_CPU_ASSUME_RVV="0"
125126
cd _build/test
126127
if echo '${{ matrix.sys.flags }}' | grep -q 'avx512' ; then
127128
# Running with emulation, must have AVX512, lower tier are checked by implications in tests

.github/workflows/macos.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ jobs:
2424
run: cmake --build _build --target xbenchmark --verbose
2525
- name: Set CPU feature test expectations
2626
run: |
27+
echo "XSIMD_TEST_CPU_ASSUME_RVV=0" >> "$GITHUB_ENV"
2728
if echo '${{ matrix.os }}' | grep -q intel; then
2829
echo "XSIMD_TEST_CPU_ASSUME_NEON64=0" >> "$GITHUB_ENV"
2930
echo "XSIMD_TEST_CPU_ASSUME_SSE4_2=1" >> "$GITHUB_ENV"

include/xsimd/config/xsimd_config.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,17 @@
464464
#define XSIMD_SVE_BITS 0
465465
#endif
466466

467+
/**
468+
* @ingroup xsimd_config_macro
469+
*
470+
* Set to 1 if the target is the RISC-V architecture family.
471+
*/
472+
#ifdef __riscv
473+
#define XSIMD_TARGET_RISCV 1
474+
#else
475+
#define XSIMD_TARGET_RISCV 0
476+
#endif
477+
467478
/**
468479
* @ingroup xsimd_config_macro
469480
*

include/xsimd/config/xsimd_cpu_features_arm.hpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,6 @@
2222
// Header does not exists on all architectures and masks are architecture
2323
// specific.
2424
#include <asm/hwcap.h>
25-
26-
// Port possibly missing mask. Should only be defined on Arm64.
27-
#if XSIMD_TARGET_ARM64 && !defined(HWCAP2_I8MM)
28-
#define HWCAP2_I8MM (1 << 13)
29-
#endif
3025
#endif // XSIMD_TARGET_ARM && XSIMD_HAVE_LINUX_GETAUXVAL
3126

3227
namespace xsimd
@@ -71,8 +66,14 @@ namespace xsimd
7166

7267
inline bool i8mm() const noexcept
7368
{
69+
7470
#if XSIMD_TARGET_ARM64 && XSIMD_HAVE_LINUX_GETAUXVAL
71+
#ifdef HWCAP2_I8MM
7572
return hwcap2().has_feature(HWCAP2_I8MM);
73+
#else
74+
// Possibly missing on older Linux distributions
75+
return hwcap2().has_feature(1 << 13);
76+
#endif
7677
#else
7778
return false;
7879
#endif
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/***************************************************************************
2+
* Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and *
3+
* Martin Renou *
4+
* Copyright (c) QuantStack *
5+
* Copyright (c) Serge Guelton *
6+
* *
7+
* Distributed under the terms of the BSD 3-Clause License. *
8+
* *
9+
* The full license is in the file LICENSE, distributed with this software. *
10+
***************************************************************************/
11+
12+
#ifndef XSIMD_CPU_FEATURES_RISCV_HPP
13+
#define XSIMD_CPU_FEATURES_RISCV_HPP
14+
15+
#include "./xsimd_config.hpp"
16+
17+
#if XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
18+
#include "../utils/bits.hpp"
19+
#include "./xsimd_getauxval.hpp"
20+
21+
// HWCAP_XXX masks to use on getauxval results.
22+
// Header does not exists on all architectures and masks are architecture
23+
// specific.
24+
#include <asm/hwcap.h>
25+
#endif // XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
26+
27+
namespace xsimd
28+
{
29+
class riscv_cpu_features
30+
{
31+
public:
32+
riscv_cpu_features() noexcept = default;
33+
34+
inline bool rvv() const noexcept
35+
{
36+
#if XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
37+
#ifdef HWCAP_V
38+
return hwcap().has_feature(HWCAP_V);
39+
#else
40+
// Possibly missing on older Linux distributions
41+
return hwcap().has_feature(1 << ('V' - 'A'));
42+
#endif
43+
#else
44+
return false;
45+
#endif
46+
}
47+
48+
private:
49+
#if XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
50+
enum class status
51+
{
52+
hwcap_valid = 0,
53+
};
54+
55+
using status_bitset = utils::uint_bitset<status, std::uint32_t>;
56+
57+
mutable status_bitset m_status {};
58+
59+
mutable xsimd::linux_auxval m_hwcap {};
60+
61+
inline xsimd::linux_auxval const& hwcap() const noexcept
62+
{
63+
if (!m_status.bit_is_set<status::hwcap_valid>())
64+
{
65+
m_hwcap = xsimd::linux_auxval::read(AT_HWCAP);
66+
m_status.set_bit<status::hwcap_valid>();
67+
}
68+
return m_hwcap;
69+
}
70+
#endif
71+
};
72+
}
73+
74+
#endif

include/xsimd/config/xsimd_cpuid.hpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,10 @@
1414

1515
#include "../types/xsimd_all_registers.hpp"
1616
#include "./xsimd_cpu_features_arm.hpp"
17+
#include "./xsimd_cpu_features_riscv.hpp"
1718
#include "./xsimd_cpu_features_x86.hpp"
1819
#include "./xsimd_inline.hpp"
1920

20-
#if XSIMD_HAVE_LINUX_GETAUXVAL && defined(__riscv_vector)
21-
#include <asm/hwcap.h>
22-
#include <sys/auxv.h>
23-
#endif
24-
2521
namespace xsimd
2622
{
2723
namespace detail
@@ -88,15 +84,10 @@ namespace xsimd
8884
vsx = 1;
8985
#endif
9086

91-
#if XSIMD_HAVE_LINUX_GETAUXVAL
92-
#if defined(__riscv_vector) && defined(__riscv_v_fixed_vlen) && __riscv_v_fixed_vlen > 0
87+
// Safe on all platforms, it will be all false if non risc-v.
88+
const auto riscv_cpu = xsimd::riscv_cpu_features();
9389

94-
#ifndef HWCAP_V
95-
#define HWCAP_V (1 << ('V' - 'A'))
96-
#endif
97-
rvv = bool(getauxval(AT_HWCAP) & HWCAP_V);
98-
#endif
99-
#endif
90+
rvv = riscv_cpu.rvv();
10091

10192
// Safe on all platforms, it will be all false if non arm.
10293
const auto arm_cpu = xsimd::arm_cpu_features();

test/test_cpu_features.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,10 @@ TEST_CASE("[cpu_features] arm features from environment")
154154
CHECK_ENV_FEATURE("XSIMD_TEST_CPU_ASSUME_SVE", cpu.sve());
155155
CHECK_ENV_FEATURE("XSIMD_TEST_CPU_ASSUME_I8MM", cpu.i8mm());
156156
}
157+
158+
TEST_CASE("[cpu_features] risc-v features from environment")
159+
{
160+
xsimd::riscv_cpu_features cpu;
161+
162+
CHECK_ENV_FEATURE("XSIMD_TEST_CPU_ASSUME_RVV", cpu.rvv());
163+
}

0 commit comments

Comments
 (0)