Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WASM SUpport - Take II #1710

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
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
39 changes: 36 additions & 3 deletions .github/workflows/unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
run: |
cd build
ninja unit.exe -j 4
- name: Running Random Sampling Tests
- name: Running Unit Tests
run: |
cd build
ctest --output-on-failure -j 4 -E ^doc.*.exe
Expand Down Expand Up @@ -164,7 +164,7 @@ jobs:
run: |
cd build
ninja unit.exe -j 10
- name: Running Random Sampling Tests
- name: Running Unit Tests
run: |
cd build
ctest --output-on-failure -j 10 -E ^doc.*.exe
Expand Down Expand Up @@ -292,7 +292,40 @@ jobs:
run: |
cd build
ninja unit.exe -j 12
- name: Running Random Sampling Tests
- name: Running Unit Tests
run: |
cd build
ctest --output-on-failure -j 12 -E ^doc.*.exe

##################################################################################################
## WASM runner
##################################################################################################
wasm:
runs-on: ubuntu-latest
container:
image: ghcr.io/jfalcou/compilers:v7
options: -u root
strategy:
fail-fast: false
steps:
- name: Fetch current branch
uses: actions/checkout@v3
- name: Prepare EVE with WASM
run: |
mkdir build
cd build
emcmake cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE="../cmake/toolchain/emcc.cmake"
- name: Compile Unit Tests
run: |
cd build
ninja unit.arch.exe -j 4
ninja unit.meta.exe -j 4
ninja unit.internals.exe -j 4
ninja unit.api.exe -j 4
ninja unit.memory.exe -j 4
ninja unit.regression.exe -j 4
ninja unit.exe -j 4
- name: Running Unit Tests
run: |
cd build
ctest --output-on-failure -j 4 -E ^doc.*.exe
3 changes: 2 additions & 1 deletion cmake/toolchain/emcc.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
set(CMAKE_C_COMPILER emcc )
set(CMAKE_CXX_COMPILER em++ )

set(CMAKE_CXX_FLAGS "-DEVE_NO_FORCEINLINE ${EVE_OPTIONS}" )
set(CMAKE_CXX_FLAGS "-DEVE_NO_FORCEINLINE ${EVE_OPTIONS} -fexceptions -msimd128" )
set(CMAKE_EXE_LINKER_FLAGS "-s WASM_BIGINT -s WASM=1 ")

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
Expand Down
6 changes: 3 additions & 3 deletions cmake/toolchain/run_wasm.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
##==================================================================================================
## EVE - Expressive Vector Engine
## Copyright : EVE Project Contributors
## SPDX-License-Identifier: BSL-1.0
## Copyright : EVE Contributors & Maintainers
## SPDX-License-Identifier: MIT
##==================================================================================================
#!/bin/sh

node $@
node --experimental-wasm-simd $@
125 changes: 62 additions & 63 deletions include/eve/arch/abi_of.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,85 +7,84 @@
//==================================================================================================
#pragma once

#include <eve/detail/spy.hpp>
#include <eve/arch/tags.hpp>
#include <eve/arch/spec.hpp>
#include <eve/arch/tags.hpp>
#include <eve/detail/spy.hpp>

namespace eve
{
template<typename T> struct logical;
template<typename T> struct logical;

//================================================================================================
// Select ABI from Type x Cardinal combo
template<typename Type, int Cardinal> struct abi_of
//==================================================================================================
// Select ABI from Type x Cardinal combo
template<typename Type, int Cardinal> struct abi_of
{
static constexpr auto find()
{
static constexpr auto find()
if constexpr( supports_simd )
{
if constexpr(supports_simd)
{
constexpr auto width = sizeof(Type) * Cardinal;
constexpr bool f64 = std::is_same_v<Type,double>;
constexpr auto width = sizeof(Type) * Cardinal;
constexpr bool f64 = std::is_same_v<Type, double>;

if constexpr( spy::simd_instruction_set == spy::x86_simd_ )
{
if constexpr( width <= 16) return x86_128_{};
else if constexpr( width == 32) return x86_256_{};
else if constexpr( width == 64) return x86_512_{};
else return aggregated_{};
}
else if constexpr( spy::simd_instruction_set >= spy::vsx_ )
{
if constexpr(width <= 16) return ppc_{};
else return emulated_{};
}
else if constexpr( spy::simd_instruction_set >= spy::vmx_ )
{
if constexpr(!f64 && width <= 16) return ppc_{};
else return emulated_{};
}
else if constexpr( spy::simd_instruction_set == spy::fixed_sve_ )
{
if constexpr(spy::simd_instruction_set.width == 128) return arm_sve_128_{};
else if constexpr(spy::simd_instruction_set.width == 256) return arm_sve_256_{};
else if constexpr(spy::simd_instruction_set.width == 512) return arm_sve_512_{};
else return emulated_{};
}
else if constexpr( spy::simd_instruction_set == spy::arm_simd_ )
if constexpr( spy::simd_instruction_set == spy::wasm_simd_ )
{
if constexpr( width <= 16 ) return wasm_128_ {};
else return aggregated_ {};
}
else if constexpr( spy::simd_instruction_set == spy::x86_simd_ )
{
if constexpr( width <= 16 ) return x86_128_ {};
else if constexpr( width == 32 ) return x86_256_ {};
else if constexpr( width == 64 ) return x86_512_ {};
else return aggregated_ {};
}
else if constexpr( spy::simd_instruction_set >= spy::vsx_ )
{
if constexpr( width <= 16 ) return ppc_ {};
else return emulated_ {};
}
else if constexpr( spy::simd_instruction_set >= spy::vmx_ )
{
if constexpr( !f64 && width <= 16 ) return ppc_ {};
else return emulated_ {};
}
else if constexpr( spy::simd_instruction_set == spy::fixed_sve_ )
{
if constexpr( spy::simd_instruction_set.width == 128 ) return arm_sve_128_ {};
else if constexpr( spy::simd_instruction_set.width == 256 ) return arm_sve_256_ {};
else if constexpr( spy::simd_instruction_set.width == 512 ) return arm_sve_512_ {};
else return emulated_ {};
}
else if constexpr( spy::simd_instruction_set == spy::arm_simd_ )
{
if constexpr( spy::simd_instruction_set == spy::asimd_ )
{
if constexpr( spy::simd_instruction_set == spy::asimd_ )
{
if constexpr(width <= 8) return arm_64_{};
else if constexpr(width == 16) return arm_128_{};
else return emulated_{};
}
else
{
if constexpr(!f64 && width <= 8) return arm_64_{};
else if constexpr(!f64 && width == 16) return arm_128_{};
else return emulated_{};
}
if constexpr( width <= 8 ) return arm_64_ {};
else if constexpr( width == 16 ) return arm_128_ {};
else return emulated_ {};
}
else
{
return emulated_{};
if constexpr( !f64 && width <= 8 ) return arm_64_ {};
else if constexpr( !f64 && width == 16 ) return arm_128_ {};
else return emulated_ {};
}
}
else
{
return emulated_{};
}
else { return emulated_ {}; }
}
else { return emulated_ {}; }
}

using type = decltype(find());
};
using type = decltype(find());
};

//================================================================================================
// ABI for logical<T>
template<typename Type, int Cardinal>
struct abi_of<logical<Type>, Cardinal> : abi_of<Type, Cardinal> {};
//==================================================================================================
// ABI for logical<T>
template<typename Type, int Cardinal>
struct abi_of<logical<Type>, Cardinal> : abi_of<Type, Cardinal>
{};

//================================================================================================
// Typename shortcut
template<typename Type, int Cardinal>
using abi_of_t = typename abi_of<Type, Cardinal>::type;
//==================================================================================================
// Typename shortcut
template<typename Type, int Cardinal> using abi_of_t = typename abi_of<Type, Cardinal>::type;
}
1 change: 1 addition & 0 deletions include/eve/arch/as_register.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <eve/arch/cpu/as_register.hpp>

#if !defined(EVE_NO_SIMD)
#include <eve/arch/wasm/as_register.hpp>
#include <eve/arch/x86/as_register.hpp>
#include <eve/arch/ppc/as_register.hpp>
#include <eve/arch/arm/sve/as_register.hpp>
Expand Down
2 changes: 1 addition & 1 deletion include/eve/arch/cpu/spec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

#if !defined(EVE_ABI_DETECTED)
# define EVE_CURRENT_ABI ::eve::emulated_
# define EVE_CURRENT_API ::eve::cpu_
# define EVE_CURRENT_API ::eve::undefined_simd_
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this change?

# define EVE_STRICT_EMULATION
# define EVE_ABI_DETECTED
# define EVE_ABI_NAMESPACE cpu_abi_v0
Expand Down
1 change: 1 addition & 0 deletions include/eve/arch/spec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#pragma once

#if !defined(EVE_NO_SIMD)
# include <eve/arch/wasm/spec.hpp>
# include <eve/arch/x86/spec.hpp>
# include <eve/arch/ppc/spec.hpp>
# include <eve/arch/arm/sve/spec.hpp>
Expand Down
1 change: 1 addition & 0 deletions include/eve/arch/tags.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#pragma once

#include <eve/arch/cpu/tags.hpp>
#include <eve/arch/wasm/tags.hpp>
#include <eve/arch/x86/tags.hpp>
#include <eve/arch/ppc/tags.hpp>
#include <eve/arch/arm/sve/tags.hpp>
Expand Down
48 changes: 48 additions & 0 deletions include/eve/arch/wasm/as_register.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//==================================================================================================
/*
EVE - Expressive Vector Engine
Copyright : EVE Contributors & Maintainers
SPDX-License-Identifier: MIT
*/
//==================================================================================================
#pragma once

#include <eve/arch/wasm/predef.hpp>

#include <type_traits>

namespace eve
{
template<typename T> struct logical;
struct wasm_128_;
}

#if defined(EVE_HW_WASM)

namespace eve
{
// Check the types are fine then return *the* WASM SIMD type: v128_t
template<typename Type, typename Size> struct as_register<Type, Size, eve::wasm_128_>
{
static constexpr auto find()
{
constexpr auto width = sizeof(Type) * Size::value;
if constexpr( width <= 16 )
{
if constexpr( std::is_same_v<Type, double> ) return v128_t {};
else if constexpr( std::is_same_v<Type, float> ) return v128_t {};
else if constexpr( std::is_integral_v<Type> ) return v128_t {};
}
}

using type = decltype(find());
static_assert(!std::is_void_v<type>, "[eve WASM] - Type is not usable in a SIMD register");
};

// logical uses same registers
template<typename T, typename Size>
struct as_logical_register<T, Size, eve::wasm_128_> : as_register<T, Size, eve::wasm_128_>
{};
}

#endif
27 changes: 27 additions & 0 deletions include/eve/arch/wasm/detection.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//==================================================================================================
/*
EVE - Expressive Vector Engine
Copyright : EVE Contributors & Maintainers
SPDX-License-Identifier: MIT
*/
//==================================================================================================
#pragma once

#include <eve/arch/wasm/tags.hpp>
#include <eve/detail/spy.hpp>

namespace eve
{
//==================================================================================================
// Runtime detection of CPU support
//==================================================================================================
template<auto Version>
inline bool is_supported(spy::wasm_simd_info<Version> const&) noexcept
{
#if defined(EVE_HW_WASM)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

current_api >= eve::wasm?

return true;
#else
return false;
#endif
}
}
17 changes: 17 additions & 0 deletions include/eve/arch/wasm/predef.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//==================================================================================================
/*
EVE - Expressive Vector Engine
Copyright : EVE Contributors & Maintainers
SPDX-License-Identifier: MIT
*/
//==================================================================================================
#pragma once

#include <eve/detail/spy.hpp>

// We successfully detected some native SIMD
#if defined(SPY_ARCH_IS_WASM) && !defined(EVE_NO_SIMD)
# define EVE_SUPPORTS_NATIVE_SIMD
# define EVE_HW_WASM
# define EVE_INCLUDE_WASM_HEADER
#endif
37 changes: 37 additions & 0 deletions include/eve/arch/wasm/spec.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//==================================================================================================
/*
EVE - Expressive Vector Engine
Copyright : EVE Contributors & Maintainers
SPDX-License-Identifier: MIT
*/
//==================================================================================================
#pragma once

#include <eve/arch/wasm/predef.hpp>

#include <cstddef>
#include <cstdint>

//==================================================================================================
// WASM Info
#if defined(EVE_HW_WASM)
namespace eve
{
struct register_count
{
static constexpr std::size_t general = 2 * sizeof(void *);
static constexpr std::size_t simd = 2 * sizeof(void *);
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you remind me what this is? especially * sizeof(void *)? are you being too cute with no comments?

}

//==================================================================================================
// WASM SIMD API/ABI
# if !defined(EVE_CURRENT_API) && defined(SPY_SIMD_IS_WASM)
# include <wasm_simd128.h>
# define EVE_ABI_DETECTED
# define EVE_CURRENT_ABI ::eve::wasm_128_
# define EVE_CURRENT_API ::eve::simd128_
# define EVE_ABI_NAMESPACE wasm128_abi_v0
# endif

#endif
Loading
Loading