Skip to content

Failing to build riscV/rvv #1275

@irieger

Description

@irieger

Hello,

I'm trying to build some code I written and successfully run on SSE4.2, AVX2, arm neon for riscV too. (riscv64 on Orange Pi RV2). So as a minimum viable example, I tried to start with the example from https://xsimd.readthedocs.io/en/latest/api/dispatching.html

In my actual code, I'd like to use the same basic principle. Currently, I have a dispatching file where I use an #if defined .../#elif ... etc. to define my architecture list based on what I build for. And then I have a simple impl file for each of the archs that I then call with the required arch information for the compiler as suggested in the example. Here I just copied the example from the doc into a subfolder of the xsimd checkout (tag for 14.0.0) with adaptation to target rvv.

Source code

So what I have now - just with a few attempts for some debugging output - I have based on the mentioned example.

sum.hpp:

#ifndef _SUM_HPP
#define _SUM_HPP
#include "xsimd/xsimd.hpp"
#include <iostream>

// functor with a call method that depends on `Arch`
struct sum
{
    // It's critical not to use an in-class definition here.
    // In-class and inline definition bypass extern template mechanism.
    template <class Arch, class T>
    T operator()(Arch, T const* data, unsigned size);
};

template <class Arch, class T>
T sum::operator()(Arch, T const* data, unsigned size)
{
    using batch = xsimd::batch<T, Arch>;

std::cout << "Vector size: " << batch::size << '\n';

    batch acc(static_cast<T>(0));
    const unsigned n = size / batch::size * batch::size;
    for (unsigned i = 0; i != n; i += batch::size)
        acc += batch::load_unaligned(data + i);
    //T star_acc = xsimd::reduce_add(acc);
    std::array<T, 128> out_values;
    acc.store_unaligned(out_values.data());
    T star_acc = 0;
    for (unsigned i = 0; i < batch::size; ++i)
        star_acc += out_values[i];
    for (unsigned i = n; i < size; ++i)
        star_acc += data[i];
    return star_acc;
}

// Inform the compiler that sse2 and avx2 implementation are to be found in another compilation unit.
extern template float sum::operator()<xsimd::rvv<128>, float>(xsimd::rvv<128>, float const*, unsigned);
//extern template float sum::operator()<xsimd::sse2, float>(xsimd::sse2, float const*, unsigned);
#endif

sum_rvv128.cpp (this I normally would compile as a seprate object, but to my understanding this shouldn't make a difference in this use case). For this I'd probably do a rvv128 and rvv256 if my assumption is correct and dispatch with priority for 256 and then 128.

#include "sum.hpp"
template float sum::operator()<xsimd::rvv<128>, float>(xsimd::rvv<128>, float const*, unsigned);

Is that understanding correct, that for riscv the length of the target vector is templated and needs to be the number of bits? I didn't see a clear example for it but that is what I condensed from looking at the includes.

sum.cpp (The dispatch, for simplicity with a main to quickly test once it is compiling):

#include "sum.hpp"

#include <iostream>
#include <vector>

// Create the dispatching function, specifying the architecture we want to
// target.
static auto dispatched = xsimd::dispatch<xsimd::arch_list<xsimd::rvv<128>>>(sum{});

// Call the appropriate implementation based on runtime information.
int main(int argc, char* argv[])
{
    std::vector<float> data;

    size_t num_entries = 17;
    for (size_t idx = 0; idx < num_entries; ++idx)
    {
        data.push_back(idx * 2.3456f);
    }

    float res = dispatched(data.data(), num_entries);
    std::cout << "Sum of vector\n";

    return 0;
}

Build attempt

Trying for simplicity to just compile it manually, normally I'd use cmake but wanted to keep it simple.

g++-14 -o sum.o -std=c++20 -I../include sum.cpp sum_rvv128.cpp -march=rv64gcv_zvl128b_zba_zbb_zbs -mrvv-vector-bits=zvl

The build error

Here some excerpt from the from the first errors provided, it goes on like this for a while as anyway usual for templates. This one is huge but if it helps I can provide the full log.

In file included from ../include/xsimd/memory/../config/../types/xsimd_all_registers.hpp:47,
                 from ../include/xsimd/memory/../config/xsimd_arch.hpp:19,
                 from ../include/xsimd/memory/xsimd_aligned_allocator.hpp:27,
                 from ../include/xsimd/xsimd.hpp:63,
                 from sum.hpp:3,
                 from sum.cpp:1:
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:238:27: error: explicit specialization in non-namespace scope ‘struct xsimd::types::detail::rvv_semiblob<T, divisor>’
  238 |                 template <>
      |                           ^
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:239:24: error: too few template-parameter-lists
  239 |                 struct semitype<2>
      |                        ^~~~~~~~~~~
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:243:27: error: explicit specialization in non-namespace scope ‘struct xsimd::types::detail::rvv_semiblob<T, divisor>’
  243 |                 template <>
      |                           ^
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:244:24: error: too few template-parameter-lists
  244 |                 struct semitype<4>
      |                        ^~~~~~~~~~~
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:248:27: error: explicit specialization in non-namespace scope ‘struct xsimd::types::detail::rvv_semiblob<T, divisor>’
  248 |                 template <>
      |                           ^
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:249:24: error: too few template-parameter-lists
  249 |                 struct semitype<8>
      |                        ^~~~~~~~~~~
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:260:27: error: explicit specialization in non-namespace scope ‘struct xsimd::types::detail::rvv_semiblob<T, divisor>’
  260 |                 template <>
      |                           ^
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:261:28: error: template-id ‘get_bytes<2>’ in declaration of primary template
  261 |                 vuint8m1_t get_bytes<2>() const { return __riscv_vlmul_ext_v_u8mf2_u8m1(value); }
      |                            ^~~~~~~~~~~~
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:262:27: error: explicit specialization in non-namespace scope ‘struct xsimd::types::detail::rvv_semiblob<T, divisor>’
  262 |                 template <>
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:263:28: error: template-id ‘get_bytes<4>’ in declaration of primary template
  263 |                 vuint8m1_t get_bytes<4>() const { return __riscv_vlmul_ext_v_u8mf4_u8m1(value); }
      |                            ^~~~~~~~~~~~
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:263:28: error: ‘vuint8m1_t xsimd::types::detail::rvv_semiblob<T, divisor>::get_bytes() const’ cannot be overloaded with ‘vuint8m1_t xsimd::types::detail::rvv_semiblob<T, divisor>::get_bytes() const’
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:261:28: note: previous declaration ‘vuint8m1_t xsimd::types::detail::rvv_semiblob<T, divisor>::get_bytes() const’
  261 |                 vuint8m1_t get_bytes<2>() const { return __riscv_vlmul_ext_v_u8mf2_u8m1(value); }
      |                            ^~~~~~~~~~~~
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:264:27: error: explicit specialization in non-namespace scope ‘struct xsimd::types::detail::rvv_semiblob<T, divisor>’
  264 |                 template <>
      |                           ^
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:265:28: error: template-id ‘get_bytes<8>’ in declaration of primary template
  265 |                 vuint8m1_t get_bytes<8>() const { return __riscv_vlmul_ext_v_u8mf8_u8m1(value); }
      |                            ^~~~~~~~~~~~
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:265:28: error: ‘vuint8m1_t xsimd::types::detail::rvv_semiblob<T, divisor>::get_bytes() const’ cannot be overloaded with ‘vuint8m1_t xsimd::types::detail::rvv_semiblob<T, divisor>::get_bytes() const’
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:261:28: note: previous declaration ‘vuint8m1_t xsimd::types::detail::rvv_semiblob<T, divisor>::get_bytes() const’
  261 |                 vuint8m1_t get_bytes<2>() const { return __riscv_vlmul_ext_v_u8mf2_u8m1(value); }
      |                            ^~~~~~~~~~~~
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:273:27: error: explicit specialization in non-namespace scope ‘struct xsimd::types::detail::rvv_semiblob<T, divisor>’
  273 |                 template <>
      |                           ^
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:274:22: error: template-id ‘set_bytes<2>’ in declaration of primary template
  274 |                 void set_bytes<2>(vuint8m1_t v) { value = __riscv_vlmul_trunc_v_u8m1_u8mf2(v); }
      |                      ^~~~~~~~~~~~
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:275:27: error: explicit specialization in non-namespace scope ‘struct xsimd::types::detail::rvv_semiblob<T, divisor>’
  275 |                 template <>
      |                           ^
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:276:22: error: template-id ‘set_bytes<4>’ in declaration of primary template
  276 |                 void set_bytes<4>(vuint8m1_t v) { value = __riscv_vlmul_trunc_v_u8m1_u8mf4(v); }
      |                      ^~~~~~~~~~~~
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:276:22: error: ‘void xsimd::types::detail::rvv_semiblob<T, divisor>::set_bytes(vuint8m1_t)’ cannot be overloaded with ‘void xsimd::types::detail::rvv_semiblob<T, divisor>::set_bytes(vuint8m1_t)’
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:274:22: note: previous declaration ‘void xsimd::types::detail::rvv_semiblob<T, divisor>::set_bytes(vuint8m1_t)’
  274 |                 void set_bytes<2>(vuint8m1_t v) { value = __riscv_vlmul_trunc_v_u8m1_u8mf2(v); }
      |                      ^~~~~~~~~~~~
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:277:27: error: explicit specialization in non-namespace scope ‘struct xsimd::types::detail::rvv_semiblob<T, divisor>’
  277 |                 template <>
      |                           ^
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:278:22: error: template-id ‘set_bytes<8>’ in declaration of primary template
  278 |                 void set_bytes<8>(vuint8m1_t v) { value = __riscv_vlmul_trunc_v_u8m1_u8mf8(v); }
      |                      ^~~~~~~~~~~~
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:278:22: error: ‘void xsimd::types::detail::rvv_semiblob<T, divisor>::set_bytes(vuint8m1_t)’ cannot be overloaded with ‘void xsimd::types::detail::rvv_semiblob<T, divisor>::set_bytes(vuint8m1_t)’
../include/xsimd/memory/../config/../types/xsimd_rvv_register.hpp:274:22: note: previous declaration ‘void xsimd::types::detail::rvv_semiblob<T, divisor>::set_bytes(vuint8m1_t)’
  274 |                 void set_bytes<2>(vuint8m1_t v) { value = __riscv_vlmul_trunc_v_u8m1_u8mf2(v); }
      |                      ^~~~~~~~~~~~
In file included from ../include/xsimd/types/../arch/xsimd_isa.hpp:128,
                 from ../include/xsimd/types/xsimd_batch.hpp:520,
                 from ../include/xsimd/xsimd.hpp:77:
../include/xsimd/types/../arch/./xsimd_rvv.hpp:157:15: warning: declaration of ‘using xsimd::kernel::detail::rvvid_cruft::impl<signed char, Ret(First, Args ...)>::ctx = struct xsimd::kernel::detail::rvvid_cruft::ctx<signed char>’ changes meaning of ‘ctx’ [-Wchanges-meaning]
  157 |         using ctx = ctx<KEY>;                                        \
      |               ^~~
../include/xsimd/types/../arch/./xsimd_rvv.hpp:221:5: note: in expansion of macro ‘XSIMD_RVV_WRAPPER_DROP_1ST’
  221 |     XSIMD_RVV_WRAPPER##variant(int8_t, XSIMD_RVV_IDENTIFIER(i, 8, name), __VA_ARGS__)   \
      |     ^~~~~~~~~~~~~~~~~
../include/xsimd/types/../arch/./xsimd_rvv.hpp:260:5: note: in expansion of macro ‘XSIMD_RVV_OVERLOAD_i’
  260 |     XSIMD_RVV_OVERLOAD_i(name_i, variant, __VA_ARGS__)                     \
      |     ^~~~~~~~~~~~~~~~~~~~
../include/xsimd/types/../arch/./xsimd_rvv.hpp:265:48: note: in expansion of macro ‘XSIMD_RVV_OVERLOAD3’

So what do I need to do for RVV targets? What am I getting wrong? Do I need to provide something special here?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions