diff --git a/libcxx/docs/Status/ParallelismProjects.csv b/libcxx/docs/Status/ParallelismProjects.csv --- a/libcxx/docs/Status/ParallelismProjects.csv +++ b/libcxx/docs/Status/ParallelismProjects.csv @@ -3,10 +3,19 @@ | `[parallel.execpol] `_, "Execution policies", None, unassigned, |Not Started| | `[parallel.alg] `_, "Parallel algorithms", None, unassigned, |Not Started| | `[parallel.taskblock] `_, "Task Block", None, unassigned, |Not Started| -| `[parallel.simd.abi] `_, "simd ABI tags", None, Yin Zhang, |In Progress| -| `[parallel.simd.traits] `_, "simd type traits", None, Yin Zhang, |In Progress| +| `[parallel.simd.abi] `_, "`simd ABI tags `_", [parallel.simd.class] [parallel.simd.mask.class] declarations and alias, Yin Zhang, |Complete| +| `[parallel.simd.traits] `_, "`simd type traits is_abi_tag[_v] `_", [parallel.simd.abi], Yin Zhang, |Complete| +| `[parallel.simd.traits] `_, "`simd type traits is_simd[_v] `_", [parallel.simd.class] declaration and alias, Yin Zhang, |Complete| +| `[parallel.simd.traits] `_, "`simd type traits is_simd_mask[_v] `_", [parallel.simd.mask.class] declaration and alias, Yin Zhang, |Complete| +| `[parallel.simd.traits] `_, "simd type traits is_simd_flag_type", None, Yin Zhang, |In Progress| +| `[parallel.simd.traits] `_, "simd type traits simd_size", None, Yin Zhang, |In Progress| +| `[parallel.simd.traits] `_, "simd type traits memory_alignment", None, Yin Zhang, |In Progress| +| `[parallel.simd.traits] `_, "simd type traits rebind_simd", None, Yin Zhang, |In Progress| +| `[parallel.simd.traits] `_, "simd type traits resize_simd", None, Yin Zhang, |In Progress| | `[parallel.simd.whereexpr] `_, "Where expression class templates", None, Yin Zhang, |In Progress| -| `[parallel.simd.class] `_, "Class template simd", None, Yin Zhang, |In Progress| +| `[parallel.simd.class] `_, "`Class template simd declaration and alias `_", [parallel.simd.abi], Yin Zhang, |Complete| +| `[parallel.simd.class] `_, "Class template simd implementation", None, Yin Zhang, |In Progress| | `[parallel.simd.nonmembers] `_, "simd non-member operations", None, Yin Zhang, |In Progress| -| `[parallel.simd.mask.class] `_, "Class template simd_mask", None, Yin Zhang, |In Progress| +| `[parallel.simd.mask.class] `_, "`Class template simd_mask declaration and alias `_", [parallel.simd.abi], Yin Zhang, |Complete| +| `[parallel.simd.mask.class] `_, "Class template simd_mask implementation", None, Yin Zhang, |In Progress| | `[parallel.simd.mask.nonmembers] `_, "simd_mask non-member operations", None, Yin Zhang, |In Progress| diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -885,6 +885,12 @@ expected experimental/__config experimental/__memory + experimental/__simd/abi_tag.h + experimental/__simd/scalar.h + experimental/__simd/simd.h + experimental/__simd/simd_mask.h + experimental/__simd/traits.h + experimental/__simd/vec_ext.h experimental/deque experimental/forward_list experimental/iterator diff --git a/libcxx/include/experimental/__config b/libcxx/include/experimental/__config --- a/libcxx/include/experimental/__config +++ b/libcxx/include/experimental/__config @@ -32,4 +32,11 @@ #define _LIBCPP_END_NAMESPACE_LFTS_PMR _LIBCPP_END_NAMESPACE_LFTS } #define _VSTD_LFTS_PMR _VSTD_LFTS::pmr +// TODO: support more targets +#if defined(__AVX__) +#define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 32 +#else +#define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 16 +#endif + #endif diff --git a/libcxx/include/experimental/__simd/abi_tag.h b/libcxx/include/experimental/__simd/abi_tag.h new file mode 100644 --- /dev/null +++ b/libcxx/include/experimental/__simd/abi_tag.h @@ -0,0 +1,51 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL___SIMD_ABI_TAG_H +#define _LIBCPP_EXPERIMENTAL___SIMD_ABI_TAG_H + +#include +#include + +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL +inline namespace parallelism_v2 { +namespace simd_abi { + +using scalar = __scalar; + +// TODO: make this platform dependent +template +using fixed_size = __vec_ext<_Np>; + +template +inline constexpr int max_fixed_size = 32; + +// TODO: make this platform dependent +template +using compatible = __vec_ext<16 / sizeof(_Tp)>; + +// TODO: make this platform dependent +template +using native = __vec_ext<_LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(_Tp)>; + +// TODO: make this platform dependent +template +struct deduce { + using type = fixed_size<_Np>; +}; + +// TODO: make this platform dependent +template +using deduce_t = typename deduce<_Tp, _Np, _Abis...>::type; + +} // namespace simd_abi +} // namespace parallelism_v2 +_LIBCPP_END_NAMESPACE_EXPERIMENTAL + +#endif // _LIBCPP_EXPERIMENTAL___SIMD_ABI_TAG_H diff --git a/libcxx/include/experimental/__simd/scalar.h b/libcxx/include/experimental/__simd/scalar.h new file mode 100644 --- /dev/null +++ b/libcxx/include/experimental/__simd/scalar.h @@ -0,0 +1,26 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL___SIMD_SCALAR_H +#define _LIBCPP_EXPERIMENTAL___SIMD_SCALAR_H + +#include + +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL +inline namespace parallelism_v2 { +namespace simd_abi { +struct __scalar { + static constexpr size_t __simd_size = 1; +}; + +} // namespace simd_abi +} // namespace parallelism_v2 +_LIBCPP_END_NAMESPACE_EXPERIMENTAL + +#endif // _LIBCPP_EXPERIMENTAL___SIMD_SCALAR_H diff --git a/libcxx/include/experimental/__simd/simd.h b/libcxx/include/experimental/__simd/simd.h new file mode 100644 --- /dev/null +++ b/libcxx/include/experimental/__simd/simd.h @@ -0,0 +1,32 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H +#define _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H + +#include + +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL +inline namespace parallelism_v2 { + +// class template simd [simd.class] +// TODO: implement simd class +template > +class simd; + +template +using native_simd = simd<_Tp, simd_abi::native<_Tp>>; + +template +using fixed_size_simd = simd<_Tp, simd_abi::fixed_size<_Np>>; + +} // namespace parallelism_v2 +_LIBCPP_END_NAMESPACE_EXPERIMENTAL + +#endif // _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H diff --git a/libcxx/include/experimental/__simd/simd_mask.h b/libcxx/include/experimental/__simd/simd_mask.h new file mode 100644 --- /dev/null +++ b/libcxx/include/experimental/__simd/simd_mask.h @@ -0,0 +1,32 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL___SIMD_SIMD_MASK_H +#define _LIBCPP_EXPERIMENTAL___SIMD_SIMD_MASK_H + +#include + +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL +inline namespace parallelism_v2 { + +// class template simd_mask [simd.mask.class] +// TODO: implement simd_mask class +template > +class simd_mask; + +template +using native_simd_mask = simd_mask<_Tp, simd_abi::native<_Tp>>; + +template +using fixed_size_simd_mask = simd_mask<_Tp, simd_abi::fixed_size<_Np>>; + +} // namespace parallelism_v2 +_LIBCPP_END_NAMESPACE_EXPERIMENTAL + +#endif // _LIBCPP_EXPERIMENTAL___SIMD_SIMD_MASK_H diff --git a/libcxx/include/experimental/__simd/traits.h b/libcxx/include/experimental/__simd/traits.h new file mode 100644 --- /dev/null +++ b/libcxx/include/experimental/__simd/traits.h @@ -0,0 +1,54 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL___SIMD_TRAITS_H +#define _LIBCPP_EXPERIMENTAL___SIMD_TRAITS_H + +#include +#include +#include + +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL +inline namespace parallelism_v2 { + +// traits [simd.traits] +template +inline constexpr bool is_abi_tag_v = false; + +template <> +inline constexpr bool is_abi_tag_v = true; + +template +inline constexpr bool is_abi_tag_v> = _Np > 0 && _Np <= 32; + +template +struct is_abi_tag : bool_constant> {}; + +template +inline constexpr bool is_simd_v = false; + +template +inline constexpr bool is_simd_v> = true; + +template +struct is_simd : bool_constant> {}; + +template +inline constexpr bool is_simd_mask_v = false; + +template +inline constexpr bool is_simd_mask_v> = true; + +template +struct is_simd_mask : bool_constant> {}; + +} // namespace parallelism_v2 +_LIBCPP_END_NAMESPACE_EXPERIMENTAL + +#endif // _LIBCPP_EXPERIMENTAL___SIMD_TRAITS_H diff --git a/libcxx/include/experimental/__simd/vec_ext.h b/libcxx/include/experimental/__simd/vec_ext.h new file mode 100644 --- /dev/null +++ b/libcxx/include/experimental/__simd/vec_ext.h @@ -0,0 +1,27 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL___SIMD_VEC_EXT_H +#define _LIBCPP_EXPERIMENTAL___SIMD_VEC_EXT_H + +#include + +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL +inline namespace parallelism_v2 { +namespace simd_abi { +template +struct __vec_ext { + static constexpr size_t __simd_size = _Np; +}; + +} // namespace simd_abi +} // namespace parallelism_v2 +_LIBCPP_END_NAMESPACE_EXPERIMENTAL + +#endif // _LIBCPP_EXPERIMENTAL___SIMD_VEC_EXT_H diff --git a/libcxx/include/experimental/simd b/libcxx/include/experimental/simd --- a/libcxx/include/experimental/simd +++ b/libcxx/include/experimental/simd @@ -10,6 +10,63 @@ #ifndef _LIBCPP_EXPERIMENTAL_SIMD #define _LIBCPP_EXPERIMENTAL_SIMD +/* + experimental/simd synopsis + +namespace std::experimental { +inline namespace parallelism_v2 { + namespace simd_abi { + using scalar = see below; + template using fixed_size = see below; + template inline constexpr int max_fixed_size = implementation-defined; + template using compatible = implementation-defined; + template using native = implementation-defined; + + template struct deduce { using type = see below; }; + template using deduce_t = + typename deduce::type; + } // namespace simd_abi + + // class template simd [simd.class] + template > class simd; + template using native_simd = simd>; + template using fixed_size_simd = simd>; + + // class template simd_mask [simd.mask.class] + template > class simd_mask; + template using native_simd_mask = simd_mask>; + template using fixed_size_simd_mask = simd_mask>; + + // traits [simd.traits] + template struct is_abi_tag; + template inline constexpr bool is_abi_tag_v = is_abi_tag::value; + + template struct is_simd; + template inline constexpr bool is_simd_v = is_simd::value; + + template struct is_simd_mask; + template inline constexpr bool is_simd_mask_v = is_simd_mask::value; + +} // namespace parallelism_v2 +} // namespace std::experimental + +*/ + #include <__assert> // all public C++ headers provide the assertion handler +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) + +# include +# include +# include +# include +# include +# include +# include + +#endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) #endif /* _LIBCPP_EXPERIMENTAL_SIMD */ diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv --- a/libcxx/test/libcxx/transitive_includes/cxx17.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv @@ -261,6 +261,7 @@ experimental/regex regex experimental/set experimental/memory_resource experimental/set set +experimental/simd cstddef experimental/string experimental/memory_resource experimental/string string experimental/type_traits initializer_list diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv --- a/libcxx/test/libcxx/transitive_includes/cxx20.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv @@ -268,6 +268,7 @@ experimental/regex regex experimental/set experimental/memory_resource experimental/set set +experimental/simd cstddef experimental/string experimental/memory_resource experimental/string string experimental/type_traits initializer_list diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv --- a/libcxx/test/libcxx/transitive_includes/cxx26.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv @@ -174,6 +174,7 @@ experimental/regex regex experimental/set experimental/memory_resource experimental/set set +experimental/simd cstddef experimental/string experimental/memory_resource experimental/string string experimental/type_traits initializer_list diff --git a/libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp b/libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +// +// +// [simd.traits] +// template struct is_abi_tag; +// template inline constexpr bool ex::is_abi_tag_v = ex::is_abi_tag::value; + +#include "../test_utils.h" +#include + +namespace ex = std::experimental::parallelism_v2; + +class EmptyEntry {}; + +template +void test_simd_abi() {} +template +void test_simd_abi() { + static_assert(ex::is_abi_tag::value); + + static_assert(!ex::is_abi_tag<_Tp>::value); + static_assert(!ex::is_abi_tag>::value); + static_assert(!ex::is_abi_tag>::value); + + static_assert(ex::is_abi_tag_v); + + static_assert(!ex::is_abi_tag_v<_Tp>); + static_assert(!ex::is_abi_tag_v>); + static_assert(!ex::is_abi_tag_v>); + + test_simd_abi(); +} + +int main(int, char**) { + test_all_simd_abi(); + return 0; +} diff --git a/libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp b/libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +// +// +// [simd.traits] +// template struct ex::is_simd; +// template inline constexpr bool ex::is_simd_v = +// ex::is_simd::value; + +#include "../test_utils.h" +#include + +namespace ex = std::experimental::parallelism_v2; + +class EmptyEntry {}; + +template +void test_simd_abi() {} +template +void test_simd_abi() { + static_assert(ex::is_simd>::value); + + static_assert(!ex::is_simd<_Tp>::value); + static_assert(!ex::is_simd>::value); + + static_assert(ex::is_simd_v>); + + static_assert(!ex::is_simd_v<_Tp>); + static_assert(!ex::is_simd_v>); + + test_simd_abi(); +} + +int main(int, char**) { + test_all_simd_abi(); + return 0; +} diff --git a/libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp b/libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +// +// +// [simd.traits] +// template struct ex::is_simd_mask; +// template inline constexpr bool ex::is_simd_mask_v = ex::is_simd_mask::value; + +#include "../test_utils.h" +#include + +namespace ex = std::experimental::parallelism_v2; + +class EmptyEntry {}; + +template +void test_simd_abi() {} +template +void test_simd_abi() { + static_assert(ex::is_simd_mask>::value); + + static_assert(!ex::is_simd_mask<_Tp>::value); + static_assert(!ex::is_simd_mask>::value); + + static_assert(ex::is_simd_mask_v>); + + static_assert(!ex::is_simd_mask_v<_Tp>); + static_assert(!ex::is_simd_mask_v>); + + test_simd_abi(); +} + +int main(int, char**) { + test_all_simd_abi(); + return 0; +} diff --git a/libcxx/test/std/experimental/simd/test_utils.h b/libcxx/test/std/experimental/simd/test_utils.h new file mode 100644 --- /dev/null +++ b/libcxx/test/std/experimental/simd/test_utils.h @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef TEST_UTIL_H +#define TEST_UTIL_H + +#include +#include +#include "type_algorithms.h" + +namespace ex = std::experimental::parallelism_v2; + +constexpr std::size_t max_simd_size = 32; + +using arithmetic_no_bool_types = types::concatenate_t; + +template +void test_simd_abi(); + +template +void test_native_compatible_scalar() { + test_simd_abi, ex::simd_abi::compatible<_Tp>>(); +} + +template +void test_fixed_size_deduce_t(std::integer_sequence) { + (test_simd_abi, ex::simd_abi::deduce_t<_Tp, _Np + 1>>(), ...); +} + +template +void test_all_simd_abi() { + test_native_compatible_scalar(); + + constexpr static auto integer_seq_from_make_integer = std::make_integer_sequence(); + + test_fixed_size_deduce_t(integer_seq_from_make_integer); +} + +template +struct TestAllSimdAbiFunctor { + template + void operator()() { + test_all_simd_abi(); + } +}; + +template +void test_all_simd_abi() { + types::for_each(arithmetic_no_bool_types(), TestAllSimdAbiFunctor()); +} + +#endif // TEST_UTIL_H