Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/cross-rvv.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ jobs:
-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/.github/toolchains/${{ matrix.sys.compiler }}-riscv64-linux-gnu.cmake
- name: Build
run: cmake --build _build
- name: Set CPU feature test expectations
run: |
echo "XSIMD_TEST_CPU_ASSUME_SSE4_2=0" >> "$GITHUB_ENV"
echo "XSIMD_TEST_CPU_ASSUME_SVE=0" >> "$GITHUB_ENV"
echo "XSIMD_TEST_CPU_ASSUME_RVV=1" >> "$GITHUB_ENV"
- name: Testing xsimd
run: >
QEMU_CPU="rv64,zba=true,zbb=true,zbs=true,v=true,vlen=${{ matrix.vector_bits }},elen=64,vext_spec=v1.0"
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/cross-sve.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ jobs:
- name: Set CPU feature test expectations
run: |
echo "XSIMD_TEST_CPU_ASSUME_SSE4_2=0" >> "$GITHUB_ENV"
echo "XSIMD_TEST_CPU_ASSUME_RVV=0" >> "$GITHUB_ENV"
echo "XSIMD_TEST_CPU_ASSUME_NEON64=1" >> "$GITHUB_ENV"
echo "XSIMD_TEST_CPU_ASSUME_SVE=1" >> "$GITHUB_ENV"
echo "XSIMD_TEST_CPU_ASSUME_MANUFACTURER=unknown" >> "$GITHUB_ENV"
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ jobs:
run: |
# Set CPU feature test expectations, 0 is explicit absence of the feature
export XSIMD_TEST_CPU_ASSUME_NEON64="0"
export XSIMD_TEST_CPU_ASSUME_RVV="0"
cd _build/test
if echo '${{ matrix.sys.flags }}' | grep -q 'avx512' ; then
# Running with emulation, must have AVX512, lower tier are checked by implications in tests
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
run: cmake --build _build --target xbenchmark --verbose
- name: Set CPU feature test expectations
run: |
echo "XSIMD_TEST_CPU_ASSUME_RVV=0" >> "$GITHUB_ENV"
if echo '${{ matrix.os }}' | grep -q intel; then
echo "XSIMD_TEST_CPU_ASSUME_NEON64=0" >> "$GITHUB_ENV"
echo "XSIMD_TEST_CPU_ASSUME_SSE4_2=1" >> "$GITHUB_ENV"
Expand Down
11 changes: 11 additions & 0 deletions include/xsimd/config/xsimd_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,17 @@
#define XSIMD_SVE_BITS 0
#endif

/**
* @ingroup xsimd_config_macro
*
* Set to 1 if the target is the RISC-V architecture family.
*/
#ifdef __riscv
#define XSIMD_TARGET_RISCV 1
#else
#define XSIMD_TARGET_RISCV 0
#endif

/**
* @ingroup xsimd_config_macro
*
Expand Down
11 changes: 6 additions & 5 deletions include/xsimd/config/xsimd_cpu_features_arm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@
// Header does not exists on all architectures and masks are architecture
// specific.
#include <asm/hwcap.h>

// Port possibly missing mask. Should only be defined on Arm64.
#if XSIMD_TARGET_ARM64 && !defined(HWCAP2_I8MM)
#define HWCAP2_I8MM (1 << 13)
#endif
#endif // XSIMD_TARGET_ARM && XSIMD_HAVE_LINUX_GETAUXVAL

namespace xsimd
Expand Down Expand Up @@ -71,8 +66,14 @@ namespace xsimd

inline bool i8mm() const noexcept
{

#if XSIMD_TARGET_ARM64 && XSIMD_HAVE_LINUX_GETAUXVAL
#ifdef HWCAP2_I8MM
return hwcap2().has_feature(HWCAP2_I8MM);
#else
// Possibly missing on older Linux distributions
return hwcap2().has_feature(1 << 13);
#endif
#else
return false;
#endif
Expand Down
74 changes: 74 additions & 0 deletions include/xsimd/config/xsimd_cpu_features_riscv.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/***************************************************************************
* Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and *
* Martin Renou *
* Copyright (c) QuantStack *
* Copyright (c) Serge Guelton *
* *
* Distributed under the terms of the BSD 3-Clause License. *
* *
* The full license is in the file LICENSE, distributed with this software. *
***************************************************************************/

#ifndef XSIMD_CPU_FEATURES_RISCV_HPP
#define XSIMD_CPU_FEATURES_RISCV_HPP

#include "./xsimd_config.hpp"

#if XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
#include "../utils/bits.hpp"
#include "./xsimd_getauxval.hpp"

// HWCAP_XXX masks to use on getauxval results.
// Header does not exists on all architectures and masks are architecture
// specific.
#include <asm/hwcap.h>
#endif // XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL

namespace xsimd
{
class riscv_cpu_features
{
public:
riscv_cpu_features() noexcept = default;

inline bool rvv() const noexcept
{
#if XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
#ifdef HWCAP_V
return hwcap().has_feature(HWCAP_V);
#else
// Possibly missing on older Linux distributions
return hwcap().has_feature(1 << ('V' - 'A'));
#endif
#else
return false;
#endif
}

private:
#if XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
enum class status
{
hwcap_valid = 0,
};

using status_bitset = utils::uint_bitset<status, std::uint32_t>;

mutable status_bitset m_status {};

mutable xsimd::linux_auxval m_hwcap {};

inline xsimd::linux_auxval const& hwcap() const noexcept
{
if (!m_status.bit_is_set<status::hwcap_valid>())
{
m_hwcap = xsimd::linux_auxval::read(AT_HWCAP);
m_status.set_bit<status::hwcap_valid>();
}
return m_hwcap;
}
#endif
};
}

#endif
17 changes: 4 additions & 13 deletions include/xsimd/config/xsimd_cpuid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,10 @@

#include "../types/xsimd_all_registers.hpp"
#include "./xsimd_cpu_features_arm.hpp"
#include "./xsimd_cpu_features_riscv.hpp"
#include "./xsimd_cpu_features_x86.hpp"
#include "./xsimd_inline.hpp"

#if XSIMD_HAVE_LINUX_GETAUXVAL && defined(__riscv_vector)
#include <asm/hwcap.h>
#include <sys/auxv.h>
#endif

namespace xsimd
{
namespace detail
Expand Down Expand Up @@ -88,15 +84,10 @@ namespace xsimd
vsx = 1;
#endif

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

#ifndef HWCAP_V
#define HWCAP_V (1 << ('V' - 'A'))
#endif
rvv = bool(getauxval(AT_HWCAP) & HWCAP_V);
#endif
#endif
rvv = riscv_cpu.rvv();

// Safe on all platforms, it will be all false if non arm.
const auto arm_cpu = xsimd::arm_cpu_features();
Expand Down
7 changes: 7 additions & 0 deletions test/test_cpu_features.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,10 @@ TEST_CASE("[cpu_features] arm features from environment")
CHECK_ENV_FEATURE("XSIMD_TEST_CPU_ASSUME_SVE", cpu.sve());
CHECK_ENV_FEATURE("XSIMD_TEST_CPU_ASSUME_I8MM", cpu.i8mm());
}

TEST_CASE("[cpu_features] risc-v features from environment")
{
xsimd::riscv_cpu_features cpu;

CHECK_ENV_FEATURE("XSIMD_TEST_CPU_ASSUME_RVV", cpu.rvv());
}
Loading