plctlab / llvm-project

PLCT实验室的 RISC-V V Spec 实现,基于llvm/llvm-project,rkruppe/rvv-llvm 和 https://repo.hca.bsc.es/gitlab/rferrer/llvm-epi-0.8
159 stars 40 forks source link

[simd] lack implementations of ex::simd public method #53

Closed fepicture closed 1 year ago

fepicture commented 2 years ago

Hi all, in this open issue, I will point out some missing implementations of ex::simd.

[simd] (under 9.7.5casts) concat implement not finish

In the simd code comment or wg21 draft, I notice there have four kinds of concat function implemented (with different input/output)

code comment: https://github.com/plctlab/llvm-project/blob/simd_for_upstream/libcxx/include/experimental/simd#L121-L131

but there still lack 2 implement with concat(std::array\<nested with ex::simd or ex::simd_mask>) see current implement: https://github.com/plctlab/llvm-project/blob/simd_for_upstream/libcxx/include/experimental/simd#L1268-L1282

code to reproduce

  std::array<ex::simd<int, ex::simd_abi::scalar>, 4> arr{};
  ex::concat<int, ex::simd_abi::scalar, 4>(arr);
// expected result : compile pass and meet the basic meaning of concat(std::array<ex::simd or ex::simd_mask>)

error log

/root/llvm-project/libcxx/test/std/experimental/simd/simd.casts/concat.pass.cpp:152:3: error: no matching function for call to 'concat'
  ex::concat<int, ex::simd_abi::scalar, 4>(arr);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/root/llvm-project/really_build/build/include/c++/v1/experimental/simd:1269:70: note: candidate template ignored: invalid explicitly-specified argument for template parameter '_Abis'
simd<_Tp, simd_abi::deduce_t<_Tp, (simd_size_v<_Tp, _Abis> + ...) >> concat(const simd<_Tp, _Abis>&... __v){
                                                                     ^
/root/llvm-project/really_build/build/include/c++/v1/experimental/simd:1282:75: note: candidate template ignored: invalid explicitly-specified argument for template parameter '_Abis'
simd_mask<_Tp, simd_abi::deduce_t<_Tp, (simd_size_v<_Tp, _Abis> + ...) >> concat(const simd_mask<_Tp, _Abis>&... __m){
                                                                          ^
1 error generated.

error: command failed with exit status: 1
fepicture commented 2 years ago

[simd] (under 9.7.5casts) split_by implement not finish

the 2 public API are not finish right now.

joy2myself commented 2 years ago

to_fixed_size/to_native/to_compatible and split/split_by/concat have been implemented.

fepicture commented 2 years ago

[simd] (operator +-*/%|&^>><< ) has type cast implicit for abi scalar specific type in short /unsigned short?

reproduce code text:

 ex::simd<unsigned short, ex::simd_abi::scalar> a(static_cast<unsigned short>(42));
 ex::simd<unsigned short, ex::simd_abi::scalar> b(static_cast<unsigned short>(4));
 a %= b;

error log:

experimental/simd:694:
__simd/abi/scalar.h:48:71: error: non-constant-expression cannot be narrowed from type 'int' to 'unsigned short' in initializer list [-Wc++11-narrowing]
  static _Simd __modulus(_Simd __lhs, _Simd __rhs) noexcept { return {__lhs.__data % __rhs.__data}; }
                                                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
experimental/simd:1868:19: note: in instantiation of member function 'std::experimental::__simd_traits<unsigned short, std::experimental::simd_abi::__scalar>::__modulus' requested here
    return _Impl::__modulus(__lhs.__s_, __rhs.__s_);
                  ^
experimental/simd:1904:91: note: in instantiation of member function 'std::experimental::operator%' requested here
  friend simd& operator%=(simd& __lhs, const simd& __rhs) noexcept { return __lhs = __lhs % __rhs; }
                                                                                          ^
libcxx/test/std/experimental/simd/simd.operators/operators.pass.cpp:300:5: note: in instantiation of member function 'std::experimental::operator%=' requested here
  a %= b;
    ^
__simd/abi/scalar.h:48:71: note: insert an explicit cast to silence this issue
  static _Simd __modulus(_Simd __lhs, _Simd __rhs) noexcept { return {__lhs.__data % __rhs.__data}; }
                                                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
                                                                      static_cast<unsigned short>( )
1 error generated.

error: command failed with exit status: 1

current fail:

in short : check + - * / % << >> | & ^ in abi::scalar impl function related things :  

static _Simd __bitwise_or(_Simd __lhs, _Simd __rhs) noexcept { return {__lhs.__data | __rhs.__data}; } 

* for unsigned short && short 
__simd/abi/scalar.h:44:74: error: non-constant-expression cannot be narrowed from type 'int' to 'unsigned short' in initializer list [-Wc++11-narrowing]
  static _Simd __multiplies(_Simd __lhs, _Simd __rhs) noexcept { return {__lhs.__data * __rhs.__data}; }
                                                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
experimental/simd:1860:19: note: in instantiation of member function 'std::experimental::__simd_traits<unsigned short, std::experimental::simd_abi::__scalar>::__multiplies' requested here
    return _Impl::__multiplies(__lhs.__s_, __rhs.__s_);
                  ^
experimental/simd:1900:91: note: in instantiation of member function 'std::experimental::operator*' requested here
  friend simd& operator*=(simd& __lhs, const simd& __rhs) noexcept { return __lhs = __lhs * __rhs; }
                                                                                          ^

% for unsigned short && short && char16_t && unsigned char && signed char

<< for unsigned short && short :
static _Simd __shift_left(_Simd __lhs, int __rhs) noexcept { return {__lhs.__data << __rhs}; }

>> for unsigned short && short
__simd/abi/scalar.h:58:75: error: non-constant-expression cannot be narrowed from type 'int' to 'unsigned short' in initializer list [-Wc++11-narrowing]
  static _Simd __shift_right(_Simd __lhs, _Simd __rhs) noexcept { return {__lhs.__data >> __rhs.__data}; }

^ & | for short and unsigned short also

@joy2myself please take a look

fepicture commented 2 years ago

[simd]simd_cast for abi::scalar && make_signed_t work fail

the simd_cast will do make_signed_t check and call cast, i am going to test the value_type and whole simd element.

reproduce code:

static_assert(std::is_same_v<std::make_signed_t<unsigned long>, std::make_signed_t<long> >);
auto after_cast = ex::simd_cast<long>(ex::simd<unsigned long, ex::simd_abi::scalar>());
auto expected = ex::simd<long, ex::simd_abi::scalar>{};

static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, "");

error log:

/llvm-project/libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp:173:1: error: static assertion failed
 due to requirement 
'std::is_same_v<std::experimental::simd<long, std::experimental::simd_abi::__builtin<1>>, 
std::experimental::simd<long, std::experimental::simd_abi::__scalar>>': 

static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, "");
^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

error: command failed with exit status: 1

--

Additional

current simd_cast work well for other simd_abi and type for simd_abi::scalar work well for same type cast:

auto after_cast = ex::simd_cast<long>(ex::simd< long, ex::simd_abi::scalar>());
auto expected = ex::simd<long, ex::simd_abi::scalar>{};

static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, "");
joy2myself commented 2 years ago

[simd]simd_cast for abi::scalar && make_signed_t work fail

the simd_cast will do make_signed_t check and call cast, i am going to test the value_type and whole simd element.

reproduce code:

static_assert(std::is_same_v<std::make_signed_t<unsigned long>, std::make_signed_t<long> >);
auto after_cast = ex::simd_cast<long>(ex::simd<unsigned long, ex::simd_abi::scalar>());
auto expected = ex::simd<long, ex::simd_abi::scalar>{};

static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, "");

error log:

/llvm-project/libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp:173:1: error: static assertion failed
 due to requirement 
'std::is_same_v<std::experimental::simd<long, std::experimental::simd_abi::__builtin<1>>, 
std::experimental::simd<long, std::experimental::simd_abi::__scalar>>': 

static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, "");
^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

error: command failed with exit status: 1

--

Additional

current simd_cast work well for other simd_abi and type for simd_abi::scalar work well for same type cast:

auto after_cast = ex::simd_cast<long>(ex::simd< long, ex::simd_abi::scalar>());
auto expected = ex::simd<long, ex::simd_abi::scalar>{};

static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, "");

According to the spec, the static_simd_cast will do make_signed_t but simd_cast will not.

the return type of simd_cast is as follow:

The return type is — T if is_simd_v is true; — otherwise, simd<T, Abi> if U is the same type as T; — otherwise, simd<T, simd_abi::fixed_size<simd<U, Abi>::size()>>

Thus, because long and unsigned long are not the same type, use Rule 3.

joy2myself commented 2 years ago

[simd]simd_cast for abi::scalar && make_signed_t work fail

the simd_cast will do make_signed_t check and call cast, i am going to test the value_type and whole simd element.

reproduce code:

static_assert(std::is_same_v<std::make_signed_t<unsigned long>, std::make_signed_t<long> >);
auto after_cast = ex::simd_cast<long>(ex::simd<unsigned long, ex::simd_abi::scalar>());
auto expected = ex::simd<long, ex::simd_abi::scalar>{};

static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, "");

error log:

/llvm-project/libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp:173:1: error: static assertion failed
 due to requirement 
'std::is_same_v<std::experimental::simd<long, std::experimental::simd_abi::__builtin<1>>, 
std::experimental::simd<long, std::experimental::simd_abi::__scalar>>': 

static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, "");
^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

error: command failed with exit status: 1

--

Additional

current simd_cast work well for other simd_abi and type for simd_abi::scalar work well for same type cast:

auto after_cast = ex::simd_cast<long>(ex::simd< long, ex::simd_abi::scalar>());
auto expected = ex::simd<long, ex::simd_abi::scalar>{};

static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, "");

I tried to give a fix here https://github.com/joy2myself/llvm-project/commit/3e916c1fdf7ab6940235cbc0939f11e17dc326b4. But I have not tested it. If it works please reply to me. I will push it to this repo.

fepicture commented 2 years ago

comparision fail between scalar_simd and other simd

background

Here we cannot directly compare with scalar simd and other simd. But simd_mask works well for all abi and type. And without scalar simd, other simd still works well for comparsion.

test code

  const auto native_simd = ex::simd<long double, ex::simd_abi::native<long double>>();
  const auto deduce_simd = ex::simd<long double, ex::simd_abi::deduce_t<double, 1>>();
  const auto scalar_simd = ex::simd<long double, ex::simd_abi::scalar>();

  auto equal_sub = native_simd == deduce_simd; // pass ,work well!
  auto equal = native_simd == scalar_simd; // fail

error report

# command stderr:
error: invalid operands to binary expression ('const ex::simd<long double, ex::simd_abi::native<long double>>' (aka 'const simd<long double, __builtin<16 / sizeof(long double)>>') and 'const ex::simd<long double, ex::simd_abi::scalar>' (aka 'const simd<long double, std::experimental::simd_abi::__scalar>'))
  auto equal = native_simd == scalar_simd; // fail
               ~~~~~~~~~~~ ^  ~~~~~~~~~~~
build/include/c++/v1/experimental/simd:1863:20: note: candidate function not viable: no known conversion from 'const simd<[...], ex::simd_abi::scalar>' to 'const simd<[...], std::experimental::simd_abi::__builtin<1>>' for 2nd argument
  friend mask_type operator==(const simd& __lhs, const simd& __rhs) noexcept {
                   ^
build/include/c++/v1/experimental/simd:1863:20: note: candidate function not viable: no known conversion from 'const simd<[...], ex::simd_abi::native<long double>>' to 'const simd<[...], std::experimental::simd_abi::__scalar>' for 1st argument
1 error generated.
fepicture commented 2 years ago

ex::resize_simd ex::concat(std::array) not work?

I assume mightbe the ex::concat implement has some missing function? Okay, I think here the implementation should assign value to ex::resize_simd::type or ex::resize_simd_t which is really one about ex::simd

test code

  {
    using _Tp = int;
    using SimdAbi = ex::simd_abi::native<int>;
    constexpr size_t _Np = 2;

    std::array<ex::simd<_Tp, SimdAbi>, _Np> arr;
    auto temp = ex::concat<_Tp, SimdAbi, _Np>(arr);
    std::cout <<TypeName<decltype(temp)>(); // do some thing with temp , even no this line still fail.
  }

error report

# command stderr:
In file included from libcxx/test/std/experimental/simd/simd.casts/concat.pass.cpp:17:
libcxx/test/std/experimental/simd/simd.casts/../test_utils.h:12:
experimental/simd:1271:7: error: type 'resize_simd<__size * 2UL, simd<int, __builtin<4>>>' does not provide a subscript operator
      __s[__i * __size + __j] = __arr[__i][__j];
      ^~~ ~~~~~~~~~~~~~~~~~~
libcxx/test/std/experimental/simd/simd.casts/concat.pass.cpp:193:21: note: in instantiation of function template specialization 'std::experimental::concat<int, std::experimental::simd_abi::__builtin<4>, 2UL>' requested here
    auto temp = ex::concat<_Tp, SimdAbi, _Np>(arr);
                    ^
1 error generated.
fepicture commented 2 years ago

[duplicate] same as above, ex::split_by work fail

test code

    {
        using T = int;
        using A = ex::simd_abi::native<int>;
        constexpr size_t N = 2;

        auto v = ex::simd<T, A>();
        auto cur = ex::split_by<N, T, A>(v);
        std::cout << cur.size()<<'\n';
    }

error report

# command stderr:
In file included from /libcxx/test/std/experimental/simd/simd.casts/split_by.pass.cpp:21:
In file included from /libcxx/test/std/experimental/simd/simd.casts/../test_utils.h:12:
/include/c++/v1/experimental/simd:1222:7: error: type 'value_type' (aka 'std::experimental::resize_simd<2, std::experimental::simd<int, std::experimental::simd_abi::__builtin<4>>>') does not provide a subscript operator
      __arr[__i][__j] = __v[__i * __size + __j];
      ^~~~~~~~~~ ~~~
/libcxx/test/std/experimental/simd/simd.casts/split_by.pass.cpp:80:24: note: in instantiation of function template specialization 'std::experimental::split_by<2UL, int, std::experimental::simd_abi::__builtin<4>>' requested here
        auto cur = ex::split_by<N, T, A>(v);
                       ^
1 error generated.
joy2myself commented 2 years ago

Here we cannot directly compare with scalar simd and other simd.

"operator==" only has been overloaded in class simd & simd_mask. It should be used to compare values between two simd/simd_mask with the same type rather than different types.

And without scalar simd, other simd still works well for comparsion.

This is only because ABIs other than scalar temporarily use the same internal implementation in the current version. This does not mean that "operator==" needs to work between different types of simd.

fepicture commented 2 years ago

vector alignment need simd size to be power of 2

Hi, I cannot find any sentence refer to this rule, shall we consider to check the vector alignment implementation?

I found there some comments to show the __builtin_assume_aligned has built-in check for power-of-2 For your reference: https://github.com/plctlab/llvm-project/blob/simd_for_upstream/libcxx/test/libcxx/utilities/memory/ptr.align/assume_aligned.power2.verify.cpp

test code

{
    using _Tp = double;
    using SimdAbi = ex::simd_abi::fixed_size<12>; // works fail!!
// @@@@@@@@@@@@@@@@@@@@@ here will set the simd size under this `abi`, but only work under `size is power of 2` with `vector_alignment`

// @ 1. generate simd with data by lambda
    const ex::simd<_Tp, SimdAbi> origin_simd([](_Tp i) { return static_cast<_Tp>(i + 1); });

    constexpr auto array_length = origin_simd.size();
    constexpr auto alignas_size = get_next_pow2(ex::memory_alignment_v<ex::simd<_Tp, SimdAbi>, _Tp>);

// @ 2. declare an array with alignas position
    alignas(alignas_size) _Tp expected_buffer[array_length]{};

// @ 3. test for copy to, which enable the array'data assignment with origin_simd value
    origin_simd.copy_to(expected_buffer, ex::vector_aligned_tag());

    for (size_t i = 0; i < origin_simd.size(); i++)  assert(expected_buffer[i] == static_cast<_Tp>(i + 1));

// @ 4. test for copy from, using an empty simd to check value correct.
    ex::simd<_Tp, SimdAbi> expected_simd;
    expected_simd.copy_from(expected_buffer, ex::vector_aligned_tag());

    for (size_t i = 0; i < origin_simd.size(); i++)  assert(expected_simd[i] == static_cast<_Tp>(i + 1));
}

error report

In file included from /libcxx/test/std/experimental/simd/simd.class/simd_copy.pass.cpp:17:
In file included from /libcxx/test/std/experimental/simd/simd.class/../test_utils.h:12:
/experimental/simd:899:4: error: requested alignment is not a power of 2
          __builtin_assume_aligned(__ptr, __alignment<_Tp, _Up>));
          ^                               ~~~~~~~~~~~~~~~~~~~~~
/simd:1753:43: note: in instantiation of function template specialization 'std::experimental::vector_aligned_tag::__apply<std::experimental::simd<int, std::experimental::simd_abi::__builtin<12>>, int>' requested here
    _Impl::__store(__s_, _Flags::template __apply<simd>(__mem));
                                          ^
/simd/simd.class/simd_copy.pass.cpp:168:17: note: in instantiation of function template specialization 'std::experimental::simd<int, std::experimental::simd_abi::__builtin<12>>::copy_to<int, std::experimental::vector_aligned_tag>' requested here
    origin_simd.copy_to(expected_buffer, ex::vector_aligned_tag());
                ^
In file included from /simd/simd.class/simd_copy.pass.cpp:17:
In file included from /simd/simd.class/../test_utils.h:12:
/experimental/simd:899:4: error: requested alignment is not a power of 2
          __builtin_assume_aligned(__ptr, __alignment<_Tp, _Up>));
          ^                               ~~~~~~~~~~~~~~~~~~~~~
/simd:1747:42: note: in instantiation of function template specialization 'std::experimental::vector_aligned_tag::__apply<std::experimental::simd<int, std::experimental::simd_abi::__builtin<12>>, const int>' requested here
    _Impl::__load(__s_, _Flags::template __apply<simd>(__mem));
                                         ^
/simd/simd.class/simd_copy.pass.cpp:173:19: note: in instantiation of function template specialization 'std::experimental::simd<int, std::experimental::simd_abi::__builtin<12>>::copy_from<int, std::experimental::vector_aligned_tag>' requested here
    expected_simd.copy_from(expected_buffer, ex::vector_aligned_tag());
                  ^
2 errors generated.
fepicture commented 2 years ago

simd ctor directly from abi fixed_size not work

seems there lack an convertion from ex::simd to std::array, mightbe we can try reinterpret_cast

test code

    {
    ex::simd<int, ex::simd_abi::fixed_size<4>> origin_simd([](int i){return i;});
    ex::simd<long , ex::simd_abi::fixed_size<4>> ctor_fail(origin_simd);
    std::cout << ctor_fail.size()<<'\n';
    return 0;
  }

error report

In file included from /libcxx/test/std/experimental/simd/simd.class/simd_ctor.pass.cpp:19:
In file included from /libcxx/test/std/experimental/simd/simd.class/../test_utils.h:12:
/build/build/include/c++/v1/experimental/simd:1731:14: error: no matching conversion for static_cast from 'const simd<int, simd_abi::fixed_size<size()>>' (aka 'const simd<int, __builtin<4>>') to 'std::array<int, size()>'
      : simd(static_cast<std::array<_Up, size()>>(__v).data(), vector_aligned) {}
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/libcxx/test/std/experimental/simd/simd.class/simd_ctor.pass.cpp:225:50: note: in instantiation of function template specialization 'std::experimental::simd<long, std::experimental::simd_abi::__builtin<4>>::simd<int, void>' requested here
    ex::simd<long , ex::simd_abi::fixed_size<4>> ctor_fail(origin_simd);
                                                 ^
/build/build/include/c++/v1/array:150:29: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'const simd<int, simd_abi::fixed_size<size()>>' (aka 'const simd<int, __builtin<4>>') to 'const std::array<int, 4>' for 1st argument
struct _LIBCPP_TEMPLATE_VIS array
                            ^
/build/build/include/c++/v1/array:150:29: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'const simd<int, simd_abi::fixed_size<size()>>' (aka 'const simd<int, __builtin<4>>') to 'std::array<int, 4>' for 1st argument
/build/build/include/c++/v1/array:150:29: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided
1 error generated.
fepicture commented 2 years ago

abi scalar with simd::operator!() works fail

the scalar abi works fail , plz check the operator! implementation

test code

  {
    using _Tp = int;
    using SimdAbi = ex::simd_abi::scalar;
    const ex::simd<_Tp, SimdAbi> origin_simd([](_Tp i) { return i; });
    const auto origin_mask = origin_simd.operator!();
    for (size_t i = 0; i < origin_mask.size(); ++i) {
      assert(origin_mask[i] == !origin_simd.operator[](i));
    }
  }

error report

# command stderr:
In file included from test/std/experimental/simd/simd.class/simd_unary.pass.cpp:23:
In file included from test/std/experimental/simd/simd.class/../test_utils.h:12:
/experimental/simd:1784:49: error: no viable conversion from returned value of type '_Simd' (aka '__simd_storage<int, simd_abi::__scalar>') to function return type 'mask_type' (aka 'simd_mask<int, std::experimental::simd_abi::__scalar>')
  mask_type operator!() const noexcept { return _Impl::__negate(__s_); }
                                                ^~~~~~~~~~~~~~~~~~~~~
test/std/experimental/simd/simd.class/simd_unary.pass.cpp:122:44: note: in instantiation of member function 'std::experimental::simd<int, std::experimental::simd_abi::__scalar>::operator!' requested here
      const auto origin_mask = origin_simd.operator!();
                                           ^
/experimental/simd:1890:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from '_Simd' (aka '__simd_storage<int, simd_abi::__scalar>') to 'const std::experimental::simd_mask<int, std::experimental::simd_abi::__scalar> &' for 1st argument
class simd_mask {
      ^
/experimental/simd:1890:7: note: candidate constructor (the implicit move constructor) not viable: no known conversion from '_Simd' (aka '__simd_storage<int, simd_abi::__scalar>') to 'std::experimental::simd_mask<int, std::experimental::simd_abi::__scalar> &&' for 1st argument
class simd_mask {
      ^
/experimental/simd:1938:3: note: candidate constructor not viable: no known conversion from '_Simd' (aka '__simd_storage<int, simd_abi::__scalar>') to '_Storage' (aka '__mask_storage<int, simd_abi::__scalar>') for 1st argument
  simd_mask(_Storage __s) : __s_(__s) {}
  ^
/experimental/simd:1946:3: note: candidate template ignored: could not match 'simd_mask' against '__simd_storage'
  simd_mask(const simd_mask<_Up, simd_abi::fixed_size<size()>>& __v) noexcept
  ^
/experimental/simd:1941:12: note: explicit constructor is not a candidate
  explicit simd_mask(value_type __v) noexcept : __s_(_Impl::__broadcast(__v)) {}
           ^
1 error generated.
joy2myself commented 2 years ago

abi scalar with simd::operator!() works fail

Fixed.

simd ctor directly from abi fixed_size not work

Fixed.

vector alignment need simd size to be power of 2

Can not reproduce with https://github.com/fepicture/llvm-project/tree/simd_for_upstream

ex::resize_simd ex::concat(std::array) not work?

Can not reproduce with https://github.com/fepicture/llvm-project/tree/simd_for_upstream

fepicture commented 2 years ago

Thank you~ I guess mightbe our compiler different? In my local which is the build-output "/root/llvm-project/build/build/./bin/clang++" "/root/llvm-project/libcxx/test/std/experimental/simd/simd.casts/concat.pass.cpp"

ex::resize_simd ex::concat(std::array) not work?

I am using latest /llvm-project/.gitlab-ci.yml to test. In my local, it will still report error same as above. does there exist subscript operator for ex::resize_simd implement?

{
  std::array<ex::simd<int, ex::simd_abi::native<int>>, 2> arr;
  const auto temp(ex::concat<int, ex::simd_abi::native<int>, 2>(arr));
}

vector alignment need simd size to be power of 2

still fail

    const ex::simd<double, ex::simd_abi::fixed_size<12>> origin_simd([](double i) { return static_cast<double>(i + 1); });

    constexpr auto array_length = origin_simd.size();
    constexpr auto alignas_size = (ex::memory_alignment_v<ex::simd<double, ex::simd_abi::fixed_size<16>>, double>);

    alignas(alignas_size) double expected_buffer[array_length]{};

    origin_simd.copy_to(expected_buffer, ex::vector_aligned_tag());

    for (size_t i = 0; i < origin_simd.size(); i++)  assert(expected_buffer[i] == static_cast<double>(i + 1));
joy2myself commented 2 years ago

vector alignment need simd size to be power of 2

ex::resize_simd ex::concat(std::array) not work?

There are no such fails turning out from the tests. Have you not submitted the code that triggered the relevant error to the test file or commented out the relevant test codes?

fepicture commented 2 years ago

maybe there still exist error in concat and split_by ?

build/include/c++/v1/experimental/simd:1277:11: error: cannot refer to type member 'type' in 'resize_simd<__size * 1UL, simd<int, __builtin<4>>>' with '.'
      __s.type[__i * __size + __j] = __arr[__i][__j];
fepicture commented 2 years ago

simd_ctor for fixed_size_simd

 // simd:1765
  template <class _Up, 
  class = std::enable_if_t<
  std::is_same_v<abi_type, simd_abi::fixed_size<size()>> &&
    __is_non_narrowing_arithmetic_convertible<_Up, value_type>()>>

  simd(const simd<_Up, simd_abi::fixed_size<size()>>& __v) 
  noexcept { ... skip other code ...  }

// utility.h:38
template <class _From, class _To>
constexpr bool __is_non_narrowing_arithmetic_convertible() {
  if constexpr(std::is_arithmetic_v<_To> && std::is_arithmetic_v<_From>)
    return __is_non_narrowing_convertible_impl<_To>(_From{});
  } 

template <class _To, class _From>
constexpr decltype(_To{std::declval<_From>()}, true)

 __is_non_narrowing_convertible_impl(_From){return true;}

template <class _To>
constexpr bool 

__is_non_narrowing_convertible_impl(...) {return false;}

I strongly doubt the weird issue is due to the narrow convert work not well and write a small code to test:

  {
    using _Tp = unsigned long;
    std::cout <<"from = char     "<< "to = unsigned long "<<" ex::is non_narrow convertible = "<< __is_non_narrowing_arithmetic_convertible<char, _Tp>()    <<" is std::converti = "<<std::is_convertible_v<char, _Tp><<"\n";   
    std::cout <<"from = short    "<< "to = unsigned long "<<" ex::is non_narrow convertible = "<< __is_non_narrowing_arithmetic_convertible<short, _Tp>()   <<" is std::converti = "<<std::is_convertible_v<short, _Tp><<"\n"; 
    std::cout <<"from = wchar_t  "<< "to = unsigned long "<<" ex::is non_narrow convertible = "<< __is_non_narrowing_arithmetic_convertible<wchar_t, _Tp>() <<" is std::converti = "<<std::is_convertible_v<wchar_t, _Tp><<"\n";  
    std::cout <<"from = char16_t "<< "to = unsigned long "<<" ex::is non_narrow convertible = "<< __is_non_narrowing_arithmetic_convertible<char16_t, _Tp>()<<" is std::converti = "<<std::is_convertible_v<char16_t, _Tp><<"\n";  
    std::cout <<"from = int      "<< "to = unsigned long "<<" ex::is non_narrow convertible = "<< __is_non_narrowing_arithmetic_convertible<int, _Tp>()     <<" is std::converti = "<<std::is_convertible_v<int, _Tp><<"\n";  
    std::cout <<"from = char32_t "<< "to = unsigned long "<<" ex::is non_narrow convertible = "<< __is_non_narrowing_arithmetic_convertible<char32_t, _Tp>()<<" is std::converti = "<<std::is_convertible_v<char32_t, _Tp><<"\n";  
    std::cout <<"from = long     "<< "to = unsigned long "<<" ex::is non_narrow convertible = "<< __is_non_narrowing_arithmetic_convertible<long, _Tp>()    <<" is std::converti = "<<std::is_convertible_v<long, _Tp><<"\n";  
  }

test result shows below:

from = char     to = unsigned long  ex::is non_narrow convertible = 0 is std::converti = 1
from = short    to = unsigned long  ex::is non_narrow convertible = 0 is std::converti = 1
from = wchar_t  to = unsigned long  ex::is non_narrow convertible = 0 is std::converti = 1
from = char16_t to = unsigned long  ex::is non_narrow convertible = 1 is std::converti = 1
from = int      to = unsigned long  ex::is non_narrow convertible = 0 is std::converti = 1
from = char32_t to = unsigned long  ex::is non_narrow convertible = 1 is std::converti = 1
from = long     to = unsigned long  ex::is non_narrow convertible = 0 is std::converti = 1