From df3b24e837f86f20e3df1dfad5816728f37ff6c3 Mon Sep 17 00:00:00 2001 From: DerThorsten Date: Mon, 18 Sep 2023 12:12:32 +0200 Subject: [PATCH 01/55] minimal setup for wasm ci --- .github/workflows/emscripten.yml | 26 ++ test/CMakeLists.txt | 317 +++++++++++++------------ test/test_wasm/browser_main.html | 12 + test/test_wasm/test_wasm.cpp | 33 +++ test/test_wasm/test_wasm.sh | 26 ++ test/test_wasm/test_wasm_playwright.py | 125 ++++++++++ 6 files changed, 388 insertions(+), 151 deletions(-) create mode 100644 .github/workflows/emscripten.yml create mode 100644 test/test_wasm/browser_main.html create mode 100644 test/test_wasm/test_wasm.cpp create mode 100755 test/test_wasm/test_wasm.sh create mode 100644 test/test_wasm/test_wasm_playwright.py diff --git a/.github/workflows/emscripten.yml b/.github/workflows/emscripten.yml new file mode 100644 index 000000000..c1fab2547 --- /dev/null +++ b/.github/workflows/emscripten.yml @@ -0,0 +1,26 @@ +name: Emscripten build +on: [push, pull_request] +concurrency: + group: ${{ github.workflow }}-${{ github.job }}-${{ github.ref }} + cancel-in-progress: true +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - uses: mamba-org/setup-micromamba@v1 + with: + environment-name: xsimd + create-args: >- + microsoft::playwright + python + + + - name: Build script + run: | + echo "Build script for wasm" + playwright install + ./test/test_wasm/test_wasm.sh \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index daaf97ed7..ab29dd5ab 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -35,175 +35,190 @@ OPTION(XSIMD_ENABLE_WERROR "Turn on -Werror" OFF) -################ -# ARM SETTINGS # -################ - -OPTION(CROSS_COMPILE_ARM "cross compile for ARM targets" OFF) - -# Note: to compile on ARM (or cross compile), you may need to add the following: -# -DTARGET_ARCH="armv8-a -mfpu=neon -mfloat-abi=softfp -target arm-linux-gnueabi" -set(TARGET_ARCH "native" CACHE STRING "Target architecture arguments") - -if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Intel") - if (NOT WIN32 AND NOT ANDROID) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused-parameter -Wextra -Wreorder") - # Users may override the c++ standard: - if(NOT DEFINED CMAKE_CXX_STANDARD OR "${CMAKE_CXX_STANDARD}" STREQUAL "") - if (ENABLE_XTL_COMPLEX) - CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG) - if (NOT HAS_CPP14_FLAG) - message(FATAL_ERROR "Unsupported compiler -- xsimd requires C++14 support when xtl complex support is enabled") - endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") - else() - CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_CPP11_FLAG) - if (NOT HAS_CPP11_FLAG) - message(FATAL_ERROR "Unsupported compiler -- xsimd requires C++11 support!") +if(NOT EMSCRIPTEN) + ################ + # ARM SETTINGS # + ################ + + OPTION(CROSS_COMPILE_ARM "cross compile for ARM targets" OFF) + + # Note: to compile on ARM (or cross compile), you may need to add the following: + # -DTARGET_ARCH="armv8-a -mfpu=neon -mfloat-abi=softfp -target arm-linux-gnueabi" + set(TARGET_ARCH "native" CACHE STRING "Target architecture arguments") + + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Intel") + if (NOT WIN32 AND NOT ANDROID) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused-parameter -Wextra -Wreorder") + # Users may override the c++ standard: + if(NOT DEFINED CMAKE_CXX_STANDARD OR "${CMAKE_CXX_STANDARD}" STREQUAL "") + if (ENABLE_XTL_COMPLEX) + CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG) + if (NOT HAS_CPP14_FLAG) + message(FATAL_ERROR "Unsupported compiler -- xsimd requires C++14 support when xtl complex support is enabled") + endif() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_CPP11_FLAG) + if (NOT HAS_CPP11_FLAG) + message(FATAL_ERROR "Unsupported compiler -- xsimd requires C++11 support!") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + endif() endif() endif() + + if (NOT CROSS_COMPILE_ARM) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fPIC") + endif() endif() - if (NOT CROSS_COMPILE_ARM) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fPIC") + if (ANDROID) + # Nothing to do here, we assume the cmake Android NDK toolchain sets the + # correct options for arm and neon. + elseif (CROSS_COMPILE_ARM) + # We're cross-compiling with clang++ on Azure Pipelines, this is all pretty specific and just for testing + set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) + set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) + set(CMAKE_THREAD_LIBS_INIT) + + set(CMAKE_SYSTEM_PROCESSOR arm) + set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabi) + set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabi) + + set(ARM_ARCH_DIRECTORY "arm-linux-gnueabi" CACHE STRING "ARM arch header dir") + set(ARM_GCC_VER "4.7.3" CACHE STRING "ARM GCC header dir") + include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/c++/${ARM_GCC_VER}/${ARM_ARCH_DIRECTORY}/) + include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/c++/${ARM_GCC_VER}/) + include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/) + if(NOT CMAKE_CXX_FLAGS MATCHES "-march") + message(STATUS "SETTING ARCH TO ${TARGET_ARCH}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TARGET_ARCH}") + endif() + if(ARM_ARCH_DIRECTORY MATCHES "arm-linux-gnueabi") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -mfloat-abi=softfp -target arm-linux-gnueabi") + else () + # delegating to gcc here + endif() + message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") + message(STATUS "CMAKE_CXX_LINK_EXECUTABLE: ${CMAKE_CXX_LINK_EXECUTABLE}") + elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^ppc64" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=${TARGET_ARCH} -mtune=${TARGET_ARCH}") + elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "riscv64") + # Nothing specific + elseif(NOT WIN32) + if(NOT CMAKE_CXX_FLAGS MATCHES "-march" AND NOT CMAKE_CXX_FLAGS MATCHES "-arch" AND NOT CMAKE_OSX_ARCHITECTURES) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TARGET_ARCH}") + endif() endif() endif() - if (ANDROID) - # Nothing to do here, we assume the cmake Android NDK toolchain sets the - # correct options for arm and neon. - elseif (CROSS_COMPILE_ARM) - # We're cross-compiling with clang++ on Azure Pipelines, this is all pretty specific and just for testing - set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) - set(CMAKE_THREAD_LIBS_INIT) - - set(CMAKE_SYSTEM_PROCESSOR arm) - set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabi) - set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabi) - - set(ARM_ARCH_DIRECTORY "arm-linux-gnueabi" CACHE STRING "ARM arch header dir") - set(ARM_GCC_VER "4.7.3" CACHE STRING "ARM GCC header dir") - include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/c++/${ARM_GCC_VER}/${ARM_ARCH_DIRECTORY}/) - include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/c++/${ARM_GCC_VER}/) - include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/) - if(NOT CMAKE_CXX_FLAGS MATCHES "-march") - message(STATUS "SETTING ARCH TO ${TARGET_ARCH}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TARGET_ARCH}") - endif() - if(ARM_ARCH_DIRECTORY MATCHES "arm-linux-gnueabi") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -mfloat-abi=softfp -target arm-linux-gnueabi") - else () - # delegating to gcc here - endif() - message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") - message(STATUS "CMAKE_CXX_LINK_EXECUTABLE: ${CMAKE_CXX_LINK_EXECUTABLE}") - elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^ppc64" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=${TARGET_ARCH} -mtune=${TARGET_ARCH}") - elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "riscv64") - # Nothing specific - elseif(NOT WIN32) - if(NOT CMAKE_CXX_FLAGS MATCHES "-march" AND NOT CMAKE_CXX_FLAGS MATCHES "-arch" AND NOT CMAKE_OSX_ARCHITECTURES) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TARGET_ARCH}") - endif() + if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /MP /bigobj") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244 /wd4267 /wd4005 /wd4146 /wd4800") + set(CMAKE_EXE_LINKER_FLAGS /MANIFEST:NO) endif() -endif() -if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /MP /bigobj") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244 /wd4267 /wd4005 /wd4146 /wd4800") - set(CMAKE_EXE_LINKER_FLAGS /MANIFEST:NO) -endif() + if(CMAKE_CXX_COMPILER_ID MATCHES Clang AND MSVC AND WIN32) # We are using clang-cl + add_compile_options(/EHsc /bigobj) + set(CMAKE_EXE_LINKER_FLAGS /MANIFEST:NO) + endif() -if(CMAKE_CXX_COMPILER_ID MATCHES Clang AND MSVC AND WIN32) # We are using clang-cl - add_compile_options(/EHsc /bigobj) - set(CMAKE_EXE_LINKER_FLAGS /MANIFEST:NO) -endif() + set(XSIMD_TESTS + main.cpp + test_api.cpp + test_arch.cpp + test_basic_math.cpp + test_batch.cpp + test_batch_bool.cpp + test_batch_cast.cpp + test_batch_complex.cpp + test_batch_float.cpp + test_batch_int.cpp + test_bitwise_cast.cpp + test_batch_constant.cpp + test_batch_manip.cpp + test_complex_exponential.cpp + test_complex_hyperbolic.cpp + test_complex_power.cpp + test_complex_trigonometric.cpp + test_conversion.cpp + test_custom_default_arch.cpp + test_error_gamma.cpp + test_explicit_batch_instantiation.cpp + test_exponential.cpp + test_extract_pair.cpp + test_fp_manipulation.cpp + test_hyperbolic.cpp + test_load_store.cpp + test_memory.cpp + test_poly_evaluation.cpp + test_power.cpp + test_rounding.cpp + test_select.cpp + test_shuffle.cpp + test_sum.cpp + test_traits.cpp + test_trigonometric.cpp + test_xsimd_api.cpp + test_utils.hpp + ) + + if(NOT MSVC) + list(APPEND XSIMD_TESTS test_gnu_source.cpp) + endif() -set(XSIMD_TESTS - main.cpp - test_api.cpp - test_arch.cpp - test_basic_math.cpp - test_batch.cpp - test_batch_bool.cpp - test_batch_cast.cpp - test_batch_complex.cpp - test_batch_float.cpp - test_batch_int.cpp - test_bitwise_cast.cpp - test_batch_constant.cpp - test_batch_manip.cpp - test_complex_exponential.cpp - test_complex_hyperbolic.cpp - test_complex_power.cpp - test_complex_trigonometric.cpp - test_conversion.cpp - test_custom_default_arch.cpp - test_error_gamma.cpp - test_explicit_batch_instantiation.cpp - test_exponential.cpp - test_extract_pair.cpp - test_fp_manipulation.cpp - test_hyperbolic.cpp - test_load_store.cpp - test_memory.cpp - test_poly_evaluation.cpp - test_power.cpp - test_rounding.cpp - test_select.cpp - test_shuffle.cpp - test_sum.cpp - test_traits.cpp - test_trigonometric.cpp - test_xsimd_api.cpp - test_utils.hpp -) - -if(NOT MSVC) - list(APPEND XSIMD_TESTS test_gnu_source.cpp) -endif() + add_executable(test_xsimd ${XSIMD_TESTS} ${XSIMD_HEADERS}) + target_include_directories(test_xsimd PRIVATE ${XSIMD_INCLUDE_DIR}) -add_executable(test_xsimd ${XSIMD_TESTS} ${XSIMD_HEADERS}) -target_include_directories(test_xsimd PRIVATE ${XSIMD_INCLUDE_DIR}) + option(XSIMD_DOWNLOAD_DOCTEST OFF) + find_package(doctest QUIET) + if (doctest_FOUND) + set(DOCTEST_MINIMAL_VERSION 2.4.9) + if (doctest_VERSION VERSION_LESS DOCTEST_MINIMAL_VERSION) + message(FATAL_ERROR "Requires doctest >= ${DOCTEST_MINIMAL_VERSION}") + endif() + target_link_libraries(test_xsimd PRIVATE doctest::doctest) + elseif(DOWNLOAD_DOCTEST) + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/doctest") + file(DOWNLOAD + "https://github.com/doctest/doctest/releases/download/v2.4.9/doctest.h" + "${CMAKE_CURRENT_BINARY_DIR}/doctest/doctest.h") + target_include_directories(test_xsimd PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + else() + message(FATAL_ERROR " + Cannot find required doctest component. + Please either set CMAKE_PREFIX_PATH to the location of doctestConfig.cmake, + or set DOWNLOAD_DOCTEST=ON") + endif() -option(XSIMD_DOWNLOAD_DOCTEST OFF) -find_package(doctest QUIET) -if (doctest_FOUND) - set(DOCTEST_MINIMAL_VERSION 2.4.9) - if (doctest_VERSION VERSION_LESS DOCTEST_MINIMAL_VERSION) - message(FATAL_ERROR "Requires doctest >= ${DOCTEST_MINIMAL_VERSION}") + if(ENABLE_XTL_COMPLEX) + target_include_directories(test_xsimd PRIVATE ${xtl_INCLUDE_DIRS}) endif() - target_link_libraries(test_xsimd PRIVATE doctest::doctest) -elseif(DOWNLOAD_DOCTEST) - file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/doctest") - file(DOWNLOAD - "https://github.com/doctest/doctest/releases/download/v2.4.9/doctest.h" - "${CMAKE_CURRENT_BINARY_DIR}/doctest/doctest.h") - target_include_directories(test_xsimd PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) -else() - message(FATAL_ERROR " - Cannot find required doctest component. - Please either set CMAKE_PREFIX_PATH to the location of doctestConfig.cmake, - or set DOWNLOAD_DOCTEST=ON") -endif() + add_test(NAME test_xsimd COMMAND test_xsimd) -if(ENABLE_XTL_COMPLEX) - target_include_directories(test_xsimd PRIVATE ${xtl_INCLUDE_DIRS}) -endif() -add_test(NAME test_xsimd COMMAND test_xsimd) + if (CROSS_COMPILE_ARM) + add_custom_target(xtest COMMAND qemu-arm -L /usr/arm-linux-gnueabi/ test_xsimd DEPENDS test_xsimd) + else() + add_executable(test_xsimd_wasm xsimd_wasm.cpp) + endif() + + if (XSIMD_ENABLE_WERROR) + target_compile_options(test_xsimd PRIVATE -Werror -Wall -DXSIMD_SKIP_ON_WERROR) + endif() -if (CROSS_COMPILE_ARM) - add_custom_target(xtest COMMAND qemu-arm -L /usr/arm-linux-gnueabi/ test_xsimd DEPENDS test_xsimd) + add_subdirectory(doc) else() - add_custom_target(xtest COMMAND test_xsimd DEPENDS test_xsimd) -endif() + add_executable(test_xsimd_wasm test_wasm/test_wasm.cpp) + target_include_directories(test_xsimd_wasm PRIVATE ${XSIMD_INCLUDE_DIR}) -if (XSIMD_ENABLE_WERROR) - target_compile_options(test_xsimd PRIVATE -Werror -Wall -DXSIMD_SKIP_ON_WERROR) -endif() + # set compile flgs -msimd128 -add_subdirectory(doc) + target_compile_options(test_xsimd_wasm + PUBLIC --std=c++17 + PUBLIC "SHELL: -msimd128" + ) + # add flags embind, modularize + + set_target_properties(test_xsimd_wasm PROPERTIES LINK_FLAGS "-s MODULARIZE=1 -s EXPORT_NAME=test_xsimd_wasm -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -lembind") +endif() diff --git a/test/test_wasm/browser_main.html b/test/test_wasm/browser_main.html new file mode 100644 index 000000000..6f5e7e26a --- /dev/null +++ b/test/test_wasm/browser_main.html @@ -0,0 +1,12 @@ + + + + + TEST_TITLE + + + + + + + diff --git a/test/test_wasm/test_wasm.cpp b/test/test_wasm/test_wasm.cpp new file mode 100644 index 000000000..b909d4a58 --- /dev/null +++ b/test/test_wasm/test_wasm.cpp @@ -0,0 +1,33 @@ +#include +#include "xsimd/xsimd.hpp" + + +#include +#include // for reporting errors + +using namespace emscripten; + + + +int test_mean() +{ + // std::cout<<"test_mean"< a = {1.5, 2.5, 3.5, 4.5}; + // xsimd::batch b = {2.5, 3.5, 4.5, 5.5}; + // auto mean = (a + b) / 2; + // std::cout << mean << std::endl; + return 0; +} + + +int run_tests() { + // todo add actual tests + if(auto ret = test_mean(); ret != 0) { + return ret; + } + return 0; +} + +EMSCRIPTEN_BINDINGS(my_module) { + emscripten::function("run_tests", &run_tests); +} \ No newline at end of file diff --git a/test/test_wasm/test_wasm.sh b/test/test_wasm/test_wasm.sh new file mode 100755 index 000000000..e547b349a --- /dev/null +++ b/test/test_wasm/test_wasm.sh @@ -0,0 +1,26 @@ +#!/bin/bash +set -e + +# this dir +TEST_WASM_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +SRC_DIR=$TEST_WASM_DIR/../.. + + +# emsdk +# git clone https://github.com/emscripten-core/emsdk +# cd emsdk +# ./emsdk install latest +# ./emsdk activate latest +# source ./emsdk_env.sh +source ~/src/emsdk/emsdk_env.sh + + + +# build wasm +mkdir -p build +cd build +emcmake cmake -DBUILD_TESTS=ON $SRC_DIR +emmake make -j4 +cd .. + +python $TEST_WASM_DIR/test_wasm_playwright.py build/test \ No newline at end of file diff --git a/test/test_wasm/test_wasm_playwright.py b/test/test_wasm/test_wasm_playwright.py new file mode 100644 index 000000000..03feb5457 --- /dev/null +++ b/test/test_wasm/test_wasm_playwright.py @@ -0,0 +1,125 @@ + +from tempfile import TemporaryDirectory +import shutil +import socket +import threading +from contextlib import closing, contextmanager +from http.server import HTTPServer, SimpleHTTPRequestHandler +import os +import asyncio +from pathlib import Path +from playwright.async_api import async_playwright + +THIS_DIR = os.path.dirname(os.path.realpath(__file__)) +WORK_DIR = os.path.join(THIS_DIR, "work_dir") + + +def find_free_port(): + with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: + s.bind(("", 0)) + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + return s.getsockname()[1] + + +def start_server(work_dir, port): + class Handler(SimpleHTTPRequestHandler): + def __init__(self, *args, **kwargs): + super().__init__(*args, directory=work_dir, **kwargs) + + def log_message(self, fmt, *args): + return + + httpd = HTTPServer(("127.0.0.1", port), Handler) + + thread = threading.Thread(target=httpd.serve_forever) + thread.start() + return thread, httpd + + +@contextmanager +def server_context(work_dir, port): + thread, server = start_server(work_dir=work_dir, port=port) + try: + yield server, f"http://127.0.0.1:{port}" + finally: + server.shutdown() + thread.join() + +async def playwright_run_page(page_url, headless=False, slow_mo=None): + async with async_playwright() as p: + if slow_mo is None: + browser = await p.chromium.launch(headless=headless) + else: + browser = await p.chromium.launch( + headless=headless, slow_mo=slow_mo + ) + page = await browser.new_page() + await page.goto(page_url) + # n min = n_min * 60 * 1000 ms + n_min = 4 + page.set_default_timeout(n_min * 60 * 1000) + + async def handle_console(msg): + txt = str(msg) + print(txt) + + page.on("console", handle_console) + + # await page.goto(page_url) + status = await page.evaluate( + f"""async () => {{ + + let test_module = await test_xsimd_wasm(); + console.log("\\n\\n************************************************************"); + console.log("XSIMD WASM TESTS:"); + console.log("************************************************************"); + let r = test_module.run_tests(); + if (r == 0) {{ + console.log("\\n\\n************************************************************"); + console.log("XSIMD WASM TESTS PASSED"); + console.log("************************************************************"); + return r; + }} + else {{ + console.log("************************************************************"); + console.log("XSIMD WASM TESTS FAILED"); + console.log("************************************************************"); + return r; + }} + + }}""" + ) + return_code = int(status) + return return_code +def main(build_dir): + + work_dir = WORK_DIR# TemporaryDirectory() + + with TemporaryDirectory() as temp_dir: + work_dir = Path(temp_dir) + + + shutil.copy(f"{build_dir}/test_xsimd_wasm.wasm", work_dir) + shutil.copy(f"{build_dir}/test_xsimd_wasm.js", work_dir) + shutil.copy(f"{THIS_DIR}/browser_main.html", work_dir) + + port = find_free_port() + with server_context(work_dir=work_dir, port=port) as (server, url): + page_url = f"{url}/browser_main.html" + ret = asyncio.run(playwright_run_page(page_url=page_url)) + + return ret + + + +if __name__ == "__main__": + import pytest + import sys + + # get arg from args + build_dir = sys.argv[1] + + print(f"build_dir: {build_dir}") + + ret_code = main(build_dir) + sys.exit(ret_code) \ No newline at end of file From 6809356bc22cb0d3497ab88cb0cd1d17f388f27d Mon Sep 17 00:00:00 2001 From: DerThorsten Date: Mon, 18 Sep 2023 12:15:47 +0200 Subject: [PATCH 02/55] fix --- test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ab29dd5ab..3d34646df 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -199,7 +199,7 @@ if(NOT EMSCRIPTEN) if (CROSS_COMPILE_ARM) add_custom_target(xtest COMMAND qemu-arm -L /usr/arm-linux-gnueabi/ test_xsimd DEPENDS test_xsimd) else() - add_executable(test_xsimd_wasm xsimd_wasm.cpp) + add_custom_target(xtest COMMAND test_xsimd DEPENDS test_xsimd) endif() if (XSIMD_ENABLE_WERROR) From 7d0aff93e3f009caccd2930a966552c898280e57 Mon Sep 17 00:00:00 2001 From: DerThorsten Date: Mon, 18 Sep 2023 12:16:50 +0200 Subject: [PATCH 03/55] install emscripten --- test/test_wasm/test_wasm.sh | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/test/test_wasm/test_wasm.sh b/test/test_wasm/test_wasm.sh index e547b349a..8caea3970 100755 --- a/test/test_wasm/test_wasm.sh +++ b/test/test_wasm/test_wasm.sh @@ -6,14 +6,13 @@ TEST_WASM_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd ) SRC_DIR=$TEST_WASM_DIR/../.. -# emsdk -# git clone https://github.com/emscripten-core/emsdk -# cd emsdk -# ./emsdk install latest -# ./emsdk activate latest -# source ./emsdk_env.sh -source ~/src/emsdk/emsdk_env.sh - +emsdk +git clone https://github.com/emscripten-core/emsdk +cd emsdk +./emsdk install latest +./emsdk activate latest +source ./emsdk_env.sh +cd .. # build wasm From fa7304f87c4f9aa046c308fe9e7d16e6d1253700 Mon Sep 17 00:00:00 2001 From: DerThorsten Date: Mon, 18 Sep 2023 12:21:21 +0200 Subject: [PATCH 04/55] specifing shell --- .github/workflows/emscripten.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/emscripten.yml b/.github/workflows/emscripten.yml index c1fab2547..159c1edbe 100644 --- a/.github/workflows/emscripten.yml +++ b/.github/workflows/emscripten.yml @@ -17,9 +17,12 @@ jobs: create-args: >- microsoft::playwright python + init-shell: bash + - name: Build script + shell: bash -el {0} run: | echo "Build script for wasm" playwright install From 4a90d2301909f043c5edcab7b205fdc6364edb05 Mon Sep 17 00:00:00 2001 From: DerThorsten Date: Mon, 18 Sep 2023 12:24:28 +0200 Subject: [PATCH 05/55] remove superflous emsdk --- test/test_wasm/test_wasm.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/test_wasm/test_wasm.sh b/test/test_wasm/test_wasm.sh index 8caea3970..a786e095c 100755 --- a/test/test_wasm/test_wasm.sh +++ b/test/test_wasm/test_wasm.sh @@ -5,8 +5,7 @@ set -e TEST_WASM_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" SRC_DIR=$TEST_WASM_DIR/../.. - -emsdk +# setup emsdk git clone https://github.com/emscripten-core/emsdk cd emsdk ./emsdk install latest From 696bc220718493a01b1e99652618876eb2e59672 Mon Sep 17 00:00:00 2001 From: DerThorsten Date: Mon, 18 Sep 2023 12:27:11 +0200 Subject: [PATCH 06/55] remove superflous imports --- test/test_wasm/test_wasm_playwright.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_wasm/test_wasm_playwright.py b/test/test_wasm/test_wasm_playwright.py index 03feb5457..2df9898d9 100644 --- a/test/test_wasm/test_wasm_playwright.py +++ b/test/test_wasm/test_wasm_playwright.py @@ -113,7 +113,6 @@ def main(build_dir): if __name__ == "__main__": - import pytest import sys # get arg from args From 930c675fc8535e79adb8d0eed489097ca1164cce Mon Sep 17 00:00:00 2001 From: DerThorsten Date: Mon, 18 Sep 2023 12:33:45 +0200 Subject: [PATCH 07/55] make headless default --- test/test_wasm/test_wasm_playwright.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_wasm/test_wasm_playwright.py b/test/test_wasm/test_wasm_playwright.py index 2df9898d9..420d0bf4e 100644 --- a/test/test_wasm/test_wasm_playwright.py +++ b/test/test_wasm/test_wasm_playwright.py @@ -45,7 +45,7 @@ def server_context(work_dir, port): server.shutdown() thread.join() -async def playwright_run_page(page_url, headless=False, slow_mo=None): +async def playwright_run_page(page_url, headless=True, slow_mo=None): async with async_playwright() as p: if slow_mo is None: browser = await p.chromium.launch(headless=headless) From b7c7048914685b3abfc9381c24a9e6febde25456 Mon Sep 17 00:00:00 2001 From: DerThorsten Date: Mon, 18 Sep 2023 13:36:38 +0200 Subject: [PATCH 08/55] use sse2 instructoion --- test/CMakeLists.txt | 1 + test/test_wasm/test_wasm.cpp | 11 ++++++----- test/test_wasm/test_wasm.sh | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3d34646df..2ea234419 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -216,6 +216,7 @@ else() target_compile_options(test_xsimd_wasm PUBLIC --std=c++17 PUBLIC "SHELL: -msimd128" + PUBLIC "SHELL: -msse2" ) # add flags embind, modularize diff --git a/test/test_wasm/test_wasm.cpp b/test/test_wasm/test_wasm.cpp index b909d4a58..36d4ba840 100644 --- a/test/test_wasm/test_wasm.cpp +++ b/test/test_wasm/test_wasm.cpp @@ -1,3 +1,4 @@ +#include #include #include "xsimd/xsimd.hpp" @@ -11,11 +12,11 @@ using namespace emscripten; int test_mean() { - // std::cout<<"test_mean"< a = {1.5, 2.5, 3.5, 4.5}; - // xsimd::batch b = {2.5, 3.5, 4.5, 5.5}; - // auto mean = (a + b) / 2; - // std::cout << mean << std::endl; + std::cout<<"test_mean"< a = {1.5, 2.5, 3.5, 4.5}; + xsimd::batch b = {2.5, 3.5, 4.5, 5.5}; + auto mean = (a + b) / 2; + std::cout << mean << std::endl; return 0; } diff --git a/test/test_wasm/test_wasm.sh b/test/test_wasm/test_wasm.sh index a786e095c..1199a1c37 100755 --- a/test/test_wasm/test_wasm.sh +++ b/test/test_wasm/test_wasm.sh @@ -5,13 +5,13 @@ set -e TEST_WASM_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" SRC_DIR=$TEST_WASM_DIR/../.. -# setup emsdk + git clone https://github.com/emscripten-core/emsdk cd emsdk ./emsdk install latest ./emsdk activate latest source ./emsdk_env.sh -cd .. + # build wasm From 53e0807ab946679ed6127429e1e7f8e8542e9c47 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Mon, 2 Oct 2023 16:10:15 +0530 Subject: [PATCH 09/55] Initial Implementation for the Wasm based instruction set --- CMakeLists.txt | 2 + include/xsimd/arch/xsimd_isa.hpp | 4 + include/xsimd/arch/xsimd_wasm.hpp | 114 ++++++++++++++++++++ include/xsimd/config/xsimd_arch.hpp | 3 +- include/xsimd/config/xsimd_config.hpp | 13 ++- include/xsimd/types/xsimd_all_registers.hpp | 2 + include/xsimd/types/xsimd_wasm_register.hpp | 61 +++++++++++ test/test_wasm/test_wasm.cpp | 16 +-- test/test_wasm/test_wasm_playwright.py | 4 +- 9 files changed, 204 insertions(+), 15 deletions(-) create mode 100644 include/xsimd/arch/xsimd_wasm.hpp create mode 100644 include/xsimd/types/xsimd_wasm_register.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c7dcdb26..4d6adfa02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,7 @@ ${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_sse4_1.hpp ${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_sse4_2.hpp ${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_ssse3.hpp ${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_sve.hpp +${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_wasm.hpp ${XSIMD_INCLUDE_DIR}/xsimd/config/xsimd_arch.hpp ${XSIMD_INCLUDE_DIR}/xsimd/config/xsimd_config.hpp ${XSIMD_INCLUDE_DIR}/xsimd/config/xsimd_cpuid.hpp @@ -75,6 +76,7 @@ ${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_sse4_1_register.hpp ${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_sse4_2_register.hpp ${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_ssse3_register.hpp ${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_sve_register.hpp +${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_wasm_register.hpp ${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_traits.hpp ${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_utils.hpp ${XSIMD_INCLUDE_DIR}/xsimd/xsimd.hpp diff --git a/include/xsimd/arch/xsimd_isa.hpp b/include/xsimd/arch/xsimd_isa.hpp index cf0f796a1..8f05a5dab 100644 --- a/include/xsimd/arch/xsimd_isa.hpp +++ b/include/xsimd/arch/xsimd_isa.hpp @@ -80,6 +80,10 @@ #include "./xsimd_sve.hpp" #endif +#if XSIMD_WITH_WASM +#include "./xsimd_wasm.hpp" +#endif + // Must come last to have access to all conversion specializations. #include "./xsimd_generic.hpp" diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp new file mode 100644 index 000000000..be515670c --- /dev/null +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -0,0 +1,114 @@ +/*************************************************************************** + * Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and * + * Martin Renou * + * Copyright (c) QuantStack * + * Copyright (c) Serge Guelton * + * Copyright (c) Anutosh Bhat * + * * + * Distributed under the terms of the BSD 3-Clause License. * + * * + * The full license is in the file LICENSE, distributed with this software. * + ****************************************************************************/ + +#ifndef XSIMD_WASM_HPP +#define XSIMD_WASM_HPP + +#include + +#include "../types/xsimd_wasm_register.hpp" + +namespace xsimd +{ + + namespace kernel + { + using namespace types; + + // abs + template + inline batch abs(batch const& self, requires_arch) noexcept + { + XSIMD_IF_CONSTEXPR(std::is_integral_v && std::is_signed_v) + { + XSIMD_IF_CONSTEXPR(sizeof(T) == 1) + { + return wasm_i8x16_abs(self); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 2) + { + return wasm_i16x8_abs(self); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 4) + { + return wasm_i32x4_abs(self); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) + { + return wasm_i64x2_abs(self); + } + else + { + assert(false && "unsupported arch/op combination"); + return {}; + } + } + else XSIMD_IF_CONSTEXPR(std::is_floating_point_v) + { + XSIMD_IF_CONSTEXPR(sizeof(T) == 4) + { + return wasm_f32x4_abs(self); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) + { + return wasm_f64x2_abs(self); + } + else + { + assert(false && "unsupported arch/op combination"); + return {}; + } + } + else + { + assert(false && "unsupported arch/op combination"); + return {}; + } + } + + //set + template ::value, void>::type> + inline batch set(batch const&, requires_arch, T v0, T v1) noexcept + { + return wasm_i64x2_make(v0, v1); + } + + template ::value, void>::type> + inline batch set(batch const&, requires_arch, T v0, T v1, T v2, T v3) noexcept + { + return wasm_i32x4_make(v0, v1, v2, v3); + } + + template ::value, void>::type> + inline batch set(batch const&, requires_arch, T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7) noexcept + { + return wasm_i16x8_make(v0, v1, v2, v3, v4, v5, v6, v7); + } + + template ::value, void>::type> + inline batch set(batch const&, requires_arch, T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15) noexcept + { + return wasm_i8x16_make(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15); + } + + //store_aligned + template ::value, void>::type> + inline void store_aligned(T* mem, batch const& self, requires_arch) noexcept + { + // Assuming that mem is aligned properly, you can use wasm_v128_store to store the batch. + return wasm_v128_store((v128_t*)mem, self); + } + } +} + +#endif \ No newline at end of file diff --git a/include/xsimd/config/xsimd_arch.hpp b/include/xsimd/config/xsimd_arch.hpp index 81cada583..ab9ecbc29 100644 --- a/include/xsimd/config/xsimd_arch.hpp +++ b/include/xsimd/config/xsimd_arch.hpp @@ -193,7 +193,8 @@ namespace xsimd using all_x86_architectures = arch_list, avx2, fma3, avx, fma4, fma3, sse4_2, sse4_1, /*sse4a,*/ ssse3, sse3, sse2>; using all_sve_architectures = arch_list, detail::sve<256>, detail::sve<128>>; using all_arm_architectures = typename detail::join>::type; - using all_architectures = typename detail::join::type; + using all_wasm_architectures = arch_list; + using all_architectures = typename detail::join::type; using supported_architectures = typename detail::supported::type; diff --git a/include/xsimd/config/xsimd_config.hpp b/include/xsimd/config/xsimd_config.hpp index d36ed1ee5..c682b4d93 100644 --- a/include/xsimd/config/xsimd_config.hpp +++ b/include/xsimd/config/xsimd_config.hpp @@ -285,6 +285,17 @@ #define XSIMD_SVE_BITS 0 #endif +/** + * @ingroup xsimd_config_macro + * + * Set to 1 if WebAssembly SIMD is available at compile-time, to 0 otherwise. + */ +#ifdef __EMSCRIPTEN__ +#define XSIMD_WITH_WASM 1 +#else +#define XSIMD_WITH_WASM 0 +#endif + // Workaround for MSVC compiler #ifdef _MSC_VER @@ -343,7 +354,7 @@ #endif -#if !XSIMD_WITH_SSE2 && !XSIMD_WITH_SSE3 && !XSIMD_WITH_SSSE3 && !XSIMD_WITH_SSE4_1 && !XSIMD_WITH_SSE4_2 && !XSIMD_WITH_AVX && !XSIMD_WITH_AVX2 && !XSIMD_WITH_FMA3_SSE && !XSIMD_WITH_FMA4 && !XSIMD_WITH_FMA3_AVX && !XSIMD_WITH_FMA3_AVX2 && !XSIMD_WITH_AVX512F && !XSIMD_WITH_AVX512CD && !XSIMD_WITH_AVX512DQ && !XSIMD_WITH_AVX512BW && !XSIMD_WITH_NEON && !XSIMD_WITH_NEON64 && !XSIMD_WITH_SVE +#if !XSIMD_WITH_SSE2 && !XSIMD_WITH_SSE3 && !XSIMD_WITH_SSSE3 && !XSIMD_WITH_SSE4_1 && !XSIMD_WITH_SSE4_2 && !XSIMD_WITH_AVX && !XSIMD_WITH_AVX2 && !XSIMD_WITH_FMA3_SSE && !XSIMD_WITH_FMA4 && !XSIMD_WITH_FMA3_AVX && !XSIMD_WITH_FMA3_AVX2 && !XSIMD_WITH_AVX512F && !XSIMD_WITH_AVX512CD && !XSIMD_WITH_AVX512DQ && !XSIMD_WITH_AVX512BW && !XSIMD_WITH_NEON && !XSIMD_WITH_NEON64 && !XSIMD_WITH_SVE && !XSIMD_WITH_WASM #define XSIMD_NO_SUPPORTED_ARCHITECTURE #endif diff --git a/include/xsimd/types/xsimd_all_registers.hpp b/include/xsimd/types/xsimd_all_registers.hpp index 1fe077325..7047ef144 100644 --- a/include/xsimd/types/xsimd_all_registers.hpp +++ b/include/xsimd/types/xsimd_all_registers.hpp @@ -30,3 +30,5 @@ #include "xsimd_neon_register.hpp" #include "xsimd_sve_register.hpp" + +#include "xsimd_wasm_register.hpp" \ No newline at end of file diff --git a/include/xsimd/types/xsimd_wasm_register.hpp b/include/xsimd/types/xsimd_wasm_register.hpp new file mode 100644 index 000000000..f68d20336 --- /dev/null +++ b/include/xsimd/types/xsimd_wasm_register.hpp @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and * + * Martin Renou * + * Copyright (c) QuantStack * + * Copyright (c) Serge Guelton * + * Copyright (c) Anutosh Bhat * + * * + * Distributed under the terms of the BSD 3-Clause License. * + * * + * The full license is in the file LICENSE, distributed with this software. * + ****************************************************************************/ + +#ifndef XSIMD_WASM_REGISTER_HPP +#define XSIMD_WASM_REGISTER_HPP + +#include "xsimd_generic_arch.hpp" +#include "xsimd_register.hpp" + +#if XSIMD_WITH_WASM +#include +#endif + +namespace xsimd +{ + /** + * @ingroup architectures + * + * WASM instructions + */ + struct wasm : generic + { + static constexpr bool supported() noexcept { return XSIMD_WITH_WASM; } + static constexpr bool available() noexcept { return true; } + static constexpr bool requires_alignment() noexcept { return true; } + static constexpr unsigned version() noexcept { return generic::version(10, 0, 0); } + static constexpr std::size_t alignment() noexcept { return 16; } + static constexpr char const* name() noexcept { return "wasm"; } + }; + +#if XSIMD_WITH_WASM + namespace types + { + XSIMD_DECLARE_SIMD_REGISTER(bool, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(signed char, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(unsigned char, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(char, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(unsigned short, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(short, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(unsigned int, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(int, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(unsigned long int, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(long int, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(unsigned long long int, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(long long int, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(float, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(double, wasm, v128_t); + } +#endif +} + +#endif \ No newline at end of file diff --git a/test/test_wasm/test_wasm.cpp b/test/test_wasm/test_wasm.cpp index 36d4ba840..94e6b6c49 100644 --- a/test/test_wasm/test_wasm.cpp +++ b/test/test_wasm/test_wasm.cpp @@ -2,28 +2,22 @@ #include #include "xsimd/xsimd.hpp" - #include #include // for reporting errors using namespace emscripten; - - -int test_mean() +int test_abs() { - std::cout<<"test_mean"< a = {1.5, 2.5, 3.5, 4.5}; - xsimd::batch b = {2.5, 3.5, 4.5, 5.5}; - auto mean = (a + b) / 2; - std::cout << mean << std::endl; + xsimd::batch a(1, -2, 3, -4); + auto ans = xsimd::abs(a); + std::cout << ans << std::endl; return 0; } - int run_tests() { // todo add actual tests - if(auto ret = test_mean(); ret != 0) { + if(auto ret = test_abs(); ret != 0) { return ret; } return 0; diff --git a/test/test_wasm/test_wasm_playwright.py b/test/test_wasm/test_wasm_playwright.py index 420d0bf4e..f88db0079 100644 --- a/test/test_wasm/test_wasm_playwright.py +++ b/test/test_wasm/test_wasm_playwright.py @@ -48,9 +48,9 @@ def server_context(work_dir, port): async def playwright_run_page(page_url, headless=True, slow_mo=None): async with async_playwright() as p: if slow_mo is None: - browser = await p.chromium.launch(headless=headless) + browser = await p.firefox.launch(headless=headless) else: - browser = await p.chromium.launch( + browser = await p.firefox.launch( headless=headless, slow_mo=slow_mo ) page = await browser.new_page() From bcbe2872369d8af370f3dc4ecb0011082df5a19e Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Tue, 3 Oct 2023 16:45:20 +0530 Subject: [PATCH 10/55] Added the add instruction --- include/xsimd/arch/xsimd_wasm.hpp | 41 ++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index be515670c..dbd834744 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -75,7 +75,46 @@ namespace xsimd } } - //set + // add + template ::value, void>::type> + inline batch add(batch const& self, batch const& other, requires_arch) noexcept + { + XSIMD_IF_CONSTEXPR(sizeof(T) == 1) + { + return wasm_i8x16_add(self, other); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 2) + { + return wasm_i16x8_add(self, other); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 4) + { + return wasm_i32x4_add(self, other); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) + { + return wasm_i64x2_add(self, other); + } + else + { + assert(false && "unsupported arch/op combination"); + return {}; + } + } + + template + inline batch add(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_add(self, other); + } + + template + inline batch add(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_add(self, other); + } + + // set template ::value, void>::type> inline batch set(batch const&, requires_arch, T v0, T v1) noexcept { From 95680fb2258585f20c64ee154e4727965885552d Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Tue, 3 Oct 2023 18:32:01 +0530 Subject: [PATCH 11/55] Added support for set and stored_aligned operations --- include/xsimd/arch/xsimd_wasm.hpp | 48 +++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index dbd834744..4f31115ec 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -114,6 +114,23 @@ namespace xsimd return wasm_f64x2_add(self, other); } + // all + template + inline bool all(batch_bool const& self, requires_arch) noexcept + { + return wasm_i32x4_bitmask(self) == 0x0F; + } + template + inline bool all(batch_bool const& self, requires_arch) noexcept + { + return wasm_i64x2_bitmask(self) == 0x03; + } + template ::value, void>::type> + inline bool all(batch_bool const& self, requires_arch) noexcept + { + return wasm_i8x16_bitmask(self) == 0xFFFF; + } + // set template ::value, void>::type> inline batch set(batch const&, requires_arch, T v0, T v1) noexcept @@ -140,13 +157,44 @@ namespace xsimd return wasm_i8x16_make(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15); } + template + inline batch set(batch const&, requires_arch, Values... values) noexcept + { + static_assert(sizeof...(Values) == batch::size, "consistent init"); + return wasm_f64x2_make(values...); + } + + template ::value, void>::type> + inline batch_bool set(batch_bool const&, requires_arch, Values... values) noexcept + { + return set(batch(), A {}, static_cast(values ? -1LL : 0LL)...).data; + } + //store_aligned + template + inline void store_aligned(float* mem, batch const& self, requires_arch) noexcept + { + // Assuming that mem is aligned properly, you can use wasm_v128_store to store the batch. + return wasm_v128_store(mem, self); + } template ::value, void>::type> inline void store_aligned(T* mem, batch const& self, requires_arch) noexcept { // Assuming that mem is aligned properly, you can use wasm_v128_store to store the batch. return wasm_v128_store((v128_t*)mem, self); } + template ::value, void>::type> + inline void store_aligned(T* mem, batch_bool const& self, requires_arch) noexcept + { + // Assuming that mem is aligned properly, you can use wasm_v128_store to store the batch. + return wasm_v128_store((v128_t*)mem, self); + } + template + inline void store_aligned(double* mem, batch const& self, requires_arch) noexcept + { + // Assuming that mem is aligned properly, you can use wasm_v128_store to store the batch. + return wasm_v128_store(mem, self); + } } } From fb24126bbe45615ef689c10da7ada87c9a0e8a8e Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Tue, 3 Oct 2023 19:18:46 +0530 Subject: [PATCH 12/55] added support any, bitwise_and, broadcast --- include/xsimd/arch/xsimd_wasm.hpp | 83 +++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index 4f31115ec..308c3102d 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -131,7 +131,90 @@ namespace xsimd return wasm_i8x16_bitmask(self) == 0xFFFF; } + // any + template + inline bool any(batch_bool const& self, requires_arch) noexcept + { + return wasm_i32x4_bitmask(self) != 0; + } + template + inline bool any(batch_bool const& self, requires_arch) noexcept + { + return wasm_i64x2_bitmask(self) != 0; + } + template ::value, void>::type> + inline bool any(batch_bool const& self, requires_arch) noexcept + { + return wasm_i8x16_bitmask(self) != 0; + } + + // bitwise_and + template + inline batch bitwise_and(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_and(self, other); + } + template + inline batch_bool bitwise_and(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_and(self, other); + } + template ::value, void>::type> + inline batch bitwise_and(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_and(self, other); + } + template ::value, void>::type> + inline batch_bool bitwise_and(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_and(self, other); + } + + // broadcast + template + batch inline broadcast(float val, requires_arch) noexcept + { + return wasm_f32x4_splat(val); + } + template ::value, void>::type> + inline batch broadcast(T val, requires_arch) noexcept + { + XSIMD_IF_CONSTEXPR(sizeof(T) == 1) + { + return wasm_i8x16_splat(val); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 2) + { + return wasm_i16x8_splat(val); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 4) + { + return wasm_i32x4_splat(val); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) + { + return wasm_i64x2_splat(val); + } + else + { + assert(false && "unsupported arch/op combination"); + return {}; + } + } + template + inline batch broadcast(double val, requires_arch) noexcept + { + return wasm_f64x2_splat(val); + } + // set + template + inline batch set(batch const&, requires_arch, Values... values) noexcept + { + static_assert(sizeof...(Values) == batch::size, "consistent init"); + return wasm_f32x4_make(values...); + } + template ::value, void>::type> inline batch set(batch const&, requires_arch, T v0, T v1) noexcept { From ed186629541df9a1e4dcf9fb254b9a9f22dcdb8f Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Tue, 3 Oct 2023 19:37:29 +0530 Subject: [PATCH 13/55] Added support for bitwise_andnot and bitwise_or --- include/xsimd/arch/xsimd_wasm.hpp | 81 +++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index 308c3102d..ec7d37062 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -170,6 +170,87 @@ namespace xsimd return wasm_v128_and(self, other); } + template + batch inline bitwise_and(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_and(self, other); + } + + template + inline batch_bool bitwise_and(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_and(self, other); + } + + // bitwise_andnot + template + inline batch bitwise_andnot(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_andnot(other, self); + } + + template + inline batch_bool bitwise_andnot(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_andnot(other, self); + } + template ::value, void>::type> + inline batch bitwise_andnot(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_andnot(other, self); + } + template ::value, void>::type> + inline batch_bool bitwise_andnot(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_andnot(other, self); + } + + template + inline batch bitwise_andnot(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_andnot(other, self); + } + + template + inline batch_bool bitwise_andnot(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_andnot(other, self); + } + + // bitwise_or + template + inline batch bitwise_or(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + template + inline batch_bool bitwise_or(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + template ::value, void>::type> + inline batch bitwise_or(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + template ::value, void>::type> + inline batch_bool bitwise_or(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + + template + inline batch bitwise_or(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + + template + inline batch_bool bitwise_or(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + // broadcast template batch inline broadcast(float val, requires_arch) noexcept From 158aa5e969bb030c9f4030dba930ac455c2b27b3 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Tue, 3 Oct 2023 19:51:57 +0530 Subject: [PATCH 14/55] Added support for bitwise_xor and div --- include/xsimd/arch/xsimd_wasm.hpp | 44 +++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index ec7d37062..6717b6ffa 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -251,6 +251,38 @@ namespace xsimd return wasm_v128_or(self, other); } + // bitwise_xor + template + inline batch bitwise_xor(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_xor(self, other); + } + template + inline batch_bool bitwise_xor(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_xor(self, other); + } + template ::value, void>::type> + inline batch bitwise_xor(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + template + inline batch bitwise_xor(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + template + inline batch_bool bitwise_xor(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + template ::value, void>::type> + inline batch bitwise_xor(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + // broadcast template batch inline broadcast(float val, requires_arch) noexcept @@ -288,6 +320,18 @@ namespace xsimd return wasm_f64x2_splat(val); } + // div + template + inline batch div(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_div(self, other); + } + template + inline batch div(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_div(self, other); + } + // set template inline batch set(batch const&, requires_arch, Values... values) noexcept From acc457a7ab45842b1c0381e8149a9cd586b66d9c Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Tue, 3 Oct 2023 19:58:51 +0530 Subject: [PATCH 15/55] Added support for load_aligned --- include/xsimd/arch/xsimd_wasm.hpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index 6717b6ffa..80d7119d9 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -332,6 +332,26 @@ namespace xsimd return wasm_f64x2_div(self, other); } + // load_aligned + template + inline batch load_aligned(float const* mem, convert, requires_arch) noexcept + { + // Assuming that mem is aligned properly, you can use wasm_v128_load to load the mem. + return wasm_v128_load(mem); + } + template ::value, void>::type> + inline batch load_aligned(T const* mem, convert, requires_arch) noexcept + { + // Assuming that mem is aligned properly, you can use wasm_v128_load to load the mem. + return wasm_v128_load((v128_t const*)mem); + } + template + inline batch load_aligned(double const* mem, convert, requires_arch) noexcept + { + // Assuming that mem is aligned properly, you can use wasm_v128_load to load the mem. + return wasm_v128_load(mem); + } + // set template inline batch set(batch const&, requires_arch, Values... values) noexcept From d9d73fc1f41a7be5bdc93f46b1a3410b0ae0a2de Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Wed, 4 Oct 2023 15:49:55 +0530 Subject: [PATCH 16/55] added support for min, max, mul and select --- include/xsimd/arch/xsimd_wasm.hpp | 69 +++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index 80d7119d9..27c3b28a6 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -352,6 +352,75 @@ namespace xsimd return wasm_v128_load(mem); } + // max + template + inline batch max(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_pmax(self, other); + } + template ::value, void>::type> + inline batch max(batch const& self, batch const& other, requires_arch) noexcept + { + return select(self > other, self, other); + } + template + inline batch max(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_pmax(self, other); + } + + // min + template + inline batch min(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_pmin(self, other); + } + template ::value, void>::type> + inline batch min(batch const& self, batch const& other, requires_arch) noexcept + { + return select(self <= other, self, other); + } + template + inline batch min(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_pmin(self, other); + } + + // mul + template + inline batch mul(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_mul(self, other); + } + template + inline batch mul(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_mul(self, other); + } + + // select + template + inline batch select(batch_bool const& cond, batch const& true_br, batch const& false_br, requires_arch) noexcept + { + return wasm_v128_or(wasm_v128_and(cond, true_br), wasm_v128_andnot(cond, false_br)); + } + + template ::value, void>::type> + inline batch select(batch_bool const& cond, batch const& true_br, batch const& false_br, requires_arch) noexcept + { + return wasm_v128_or(wasm_v128_and(cond, true_br), wasm_v128_andnot(cond, false_br)); + } + template ::value, void>::type> + inline batch select(batch_bool_constant, Values...> const&, batch const& true_br, batch const& false_br, requires_arch) noexcept + { + return select(batch_bool { Values... }, true_br, false_br, wasm {}); + } + template + inline batch select(batch_bool const& cond, batch const& true_br, batch const& false_br, requires_arch) noexcept + { + return wasm_v128_or(wasm_v128_and(cond, true_br), wasm_v128_andnot(cond, false_br)); + } + // set template inline batch set(batch const&, requires_arch, Values... values) noexcept From 0be3b98d7f32fe93b81caf5ef76cc749bbf05fdd Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Wed, 4 Oct 2023 16:07:47 +0530 Subject: [PATCH 17/55] added support for sub --- include/xsimd/arch/xsimd_wasm.hpp | 39 ++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index 27c3b28a6..1993d8284 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -467,7 +467,7 @@ namespace xsimd return set(batch(), A {}, static_cast(values ? -1LL : 0LL)...).data; } - //store_aligned + // store_aligned template inline void store_aligned(float* mem, batch const& self, requires_arch) noexcept { @@ -492,6 +492,43 @@ namespace xsimd // Assuming that mem is aligned properly, you can use wasm_v128_store to store the batch. return wasm_v128_store(mem, self); } + + // sub + template + inline batch sub(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_sub(self, other); + } + template ::value, void>::type> + inline batch sub(batch const& self, batch const& other, requires_arch) noexcept + { + XSIMD_IF_CONSTEXPR(sizeof(T) == 1) + { + return wasm_i8x16_sub(self, other); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 2) + { + return wasm_i16x8_sub(self, other); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 4) + { + return wasm_i32x4_sub(self, other); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) + { + return wasm_i64x2_sub(self, other); + } + else + { + assert(false && "unsupported arch/op combination"); + return {}; + } + } + template + inline batch sub(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_sub(self, other); + } } } From c2725899b1b37ae4adf8ec54141785ab2525ddbf Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Wed, 4 Oct 2023 16:17:32 +0530 Subject: [PATCH 18/55] Added support for store_unaligned --- include/xsimd/arch/xsimd_wasm.hpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index 1993d8284..b9c4adcb8 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -493,6 +493,28 @@ namespace xsimd return wasm_v128_store(mem, self); } + // store_unaligned + template + inline void store_unaligned(float* mem, batch const& self, requires_arch) noexcept + { + return wasm_v128_store(mem, self); + } + template ::value, void>::type> + inline void store_unaligned(T* mem, batch const& self, requires_arch) noexcept + { + return wasm_v128_store((v128_t*)mem, self); + } + template ::value, void>::type> + inline void store_unaligned(T* mem, batch_bool const& self, requires_arch) noexcept + { + return wasm_v128_store((v128_t*)mem, self); + } + template + inline void store_unaligned(double* mem, batch const& self, requires_arch) noexcept + { + return wasm_v128_store(mem, self); + } + // sub template inline batch sub(batch const& self, batch const& other, requires_arch) noexcept From 03350e24b608d861114b448bb067e96b46ab4201 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Wed, 4 Oct 2023 16:40:40 +0530 Subject: [PATCH 19/55] Added support for load_unaligned and sqrt operations --- include/xsimd/arch/xsimd_wasm.hpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index b9c4adcb8..2fb57e445 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -352,6 +352,23 @@ namespace xsimd return wasm_v128_load(mem); } + // load_unaligned + template + inline batch load_unaligned(float const* mem, convert, requires_arch) noexcept + { + return wasm_v128_load(mem); + } + template ::value, void>::type> + inline batch load_unaligned(T const* mem, convert, requires_arch) noexcept + { + return wasm_v128_load((v128_t const*)mem); + } + template + inline batch load_unaligned(double const* mem, convert, requires_arch) noexcept + { + return wasm_v128_load(mem); + } + // max template inline batch max(batch const& self, batch const& other, requires_arch) noexcept @@ -551,6 +568,18 @@ namespace xsimd { return wasm_f64x2_sub(self, other); } + + // sqrt + template + inline batch sqrt(batch const& val, requires_arch) noexcept + { + return wasm_f32x4_sqrt(val); + } + template + inline batch sqrt(batch const& val, requires_arch) noexcept + { + return wasm_f64x2_sqrt(val); + } } } From edb851885920e7477dd5475620b2fb3cdea6851d Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Wed, 4 Oct 2023 17:29:05 +0530 Subject: [PATCH 20/55] Added support for ge and le operations --- include/xsimd/arch/xsimd_wasm.hpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index 2fb57e445..ee5727242 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -332,6 +332,30 @@ namespace xsimd return wasm_f64x2_div(self, other); } + // ge + template + inline batch_bool ge(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_ge(self, other); + } + template + inline batch_bool ge(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_ge(self, other); + } + + // le + template + inline batch_bool le(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_le(self, other); + } + template + inline batch_bool le(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_le(self, other); + } + // load_aligned template inline batch load_aligned(float const* mem, convert, requires_arch) noexcept From 5ad20b2a7025f5388db538dace2f242e5d741b52 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Thu, 5 Oct 2023 13:45:51 +0530 Subject: [PATCH 21/55] fixed implementations for abs, bitwise_and, bitwise_andnot & bitwise_xor --- include/xsimd/arch/xsimd_wasm.hpp | 148 ++++++++---------------------- 1 file changed, 36 insertions(+), 112 deletions(-) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index ee5727242..630a221ac 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -25,48 +25,24 @@ namespace xsimd using namespace types; // abs - template + template ::value && std::is_signed::value, void>::type> inline batch abs(batch const& self, requires_arch) noexcept { - XSIMD_IF_CONSTEXPR(std::is_integral_v && std::is_signed_v) + XSIMD_IF_CONSTEXPR(sizeof(T) == 1) + { + return wasm_i8x16_abs(self); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 2) { - XSIMD_IF_CONSTEXPR(sizeof(T) == 1) - { - return wasm_i8x16_abs(self); - } - else XSIMD_IF_CONSTEXPR(sizeof(T) == 2) - { - return wasm_i16x8_abs(self); - } - else XSIMD_IF_CONSTEXPR(sizeof(T) == 4) - { - return wasm_i32x4_abs(self); - } - else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) - { - return wasm_i64x2_abs(self); - } - else - { - assert(false && "unsupported arch/op combination"); - return {}; - } + return wasm_i16x8_abs(self); } - else XSIMD_IF_CONSTEXPR(std::is_floating_point_v) + else XSIMD_IF_CONSTEXPR(sizeof(T) == 4) { - XSIMD_IF_CONSTEXPR(sizeof(T) == 4) - { - return wasm_f32x4_abs(self); - } - else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) - { - return wasm_f64x2_abs(self); - } - else - { - assert(false && "unsupported arch/op combination"); - return {}; - } + return wasm_i32x4_abs(self); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) + { + return wasm_i64x2_abs(self); } else { @@ -75,6 +51,18 @@ namespace xsimd } } + template + inline batch abs(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_abs(self, other); + } + + template + inline batch abs(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_abs(self, other); + } + // add template ::value, void>::type> inline batch add(batch const& self, batch const& other, requires_arch) noexcept @@ -149,104 +137,40 @@ namespace xsimd } // bitwise_and - template - inline batch bitwise_and(batch const& self, batch const& other, requires_arch) noexcept - { - return wasm_v128_and(self, other); - } - template - inline batch_bool bitwise_and(batch_bool const& self, batch_bool const& other, requires_arch) noexcept - { - return wasm_v128_and(self, other); - } - template ::value, void>::type> + template inline batch bitwise_and(batch const& self, batch const& other, requires_arch) noexcept { return wasm_v128_and(self, other); } - template ::value, void>::type> - inline batch_bool bitwise_and(batch_bool const& self, batch_bool const& other, requires_arch) noexcept - { - return wasm_v128_and(self, other); - } - template - batch inline bitwise_and(batch const& self, batch const& other, requires_arch) noexcept - { - return wasm_v128_and(self, other); - } - - template - inline batch_bool bitwise_and(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + template + inline batch_bool bitwise_and(batch_bool const& self, batch_bool const& other, requires_arch) noexcept { return wasm_v128_and(self, other); } // bitwise_andnot - template - inline batch bitwise_andnot(batch const& self, batch const& other, requires_arch) noexcept - { - return wasm_v128_andnot(other, self); - } - - template - inline batch_bool bitwise_andnot(batch_bool const& self, batch_bool const& other, requires_arch) noexcept - { - return wasm_v128_andnot(other, self); - } - template ::value, void>::type> + template inline batch bitwise_andnot(batch const& self, batch const& other, requires_arch) noexcept { - return wasm_v128_andnot(other, self); - } - template ::value, void>::type> - inline batch_bool bitwise_andnot(batch_bool const& self, batch_bool const& other, requires_arch) noexcept - { - return wasm_v128_andnot(other, self); + return wasm_v128_andnot(self, other); } - template - inline batch bitwise_andnot(batch const& self, batch const& other, requires_arch) noexcept - { - return wasm_v128_andnot(other, self); - } - - template - inline batch_bool bitwise_andnot(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + template + inline batch_bool bitwise_andnot(batch_bool const& self, batch_bool const& other, requires_arch) noexcept { - return wasm_v128_andnot(other, self); + return wasm_v128_andnot(self, other); } // bitwise_or - template - inline batch bitwise_or(batch const& self, batch const& other, requires_arch) noexcept - { - return wasm_v128_or(self, other); - } - template - inline batch_bool bitwise_or(batch_bool const& self, batch_bool const& other, requires_arch) noexcept - { - return wasm_v128_or(self, other); - } - template ::value, void>::type> + template inline batch bitwise_or(batch const& self, batch const& other, requires_arch) noexcept { return wasm_v128_or(self, other); } - template ::value, void>::type> - inline batch_bool bitwise_or(batch_bool const& self, batch_bool const& other, requires_arch) noexcept - { - return wasm_v128_or(self, other); - } - - template - inline batch bitwise_or(batch const& self, batch const& other, requires_arch) noexcept - { - return wasm_v128_or(self, other); - } - template - inline batch_bool bitwise_or(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + template + inline batch_bool bitwise_or(batch_bool const& self, batch_bool const& other, requires_arch) noexcept { return wasm_v128_or(self, other); } From 6a78841ac49c83ee83de9c131f95a4ba82069249 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Thu, 5 Oct 2023 14:06:53 +0530 Subject: [PATCH 22/55] Fixed implementation for bitwise_xor --- include/xsimd/arch/xsimd_wasm.hpp | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index 630a221ac..f8ed6f69e 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -176,36 +176,17 @@ namespace xsimd } // bitwise_xor - template - inline batch bitwise_xor(batch const& self, batch const& other, requires_arch) noexcept + template + inline batch bitwise_xor(batch const& self, batch const& other, requires_arch) noexcept { return wasm_v128_xor(self, other); } - template - inline batch_bool bitwise_xor(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + + template + inline batch_bool bitwise_xor(batch_bool const& self, batch_bool const& other, requires_arch) noexcept { return wasm_v128_xor(self, other); } - template ::value, void>::type> - inline batch bitwise_xor(batch const& self, batch const& other, requires_arch) noexcept - { - return wasm_v128_or(self, other); - } - template - inline batch bitwise_xor(batch const& self, batch const& other, requires_arch) noexcept - { - return wasm_v128_or(self, other); - } - template - inline batch_bool bitwise_xor(batch_bool const& self, batch_bool const& other, requires_arch) noexcept - { - return wasm_v128_or(self, other); - } - template ::value, void>::type> - inline batch bitwise_xor(batch_bool const& self, batch_bool const& other, requires_arch) noexcept - { - return wasm_v128_or(self, other); - } // broadcast template From 83e57d24b72429943549711e9c3c3bcdb29afd3f Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Thu, 5 Oct 2023 15:50:25 +0530 Subject: [PATCH 23/55] added support for bitwise_lshift operation --- include/xsimd/arch/xsimd_wasm.hpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index f8ed6f69e..b897fa0d9 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -175,6 +175,33 @@ namespace xsimd return wasm_v128_or(self, other); } + // bitwise_lshift + template ::value, void>::type> + inline batch bitwise_lshift(batch const& self, int32_t other, requires_arch) noexcept + { + XSIMD_IF_CONSTEXPR(sizeof(T) == 1) + { + return wasm_v128_and(wasm_i8x16_splat(0xFF << other), wasm_i32x4_shl(self, other)); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 2) + { + return wasm_i16x8_shl(self, other); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 4) + { + return wasm_i32x4_shl(self, other); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) + { + return wasm_i64x2_shl(self, other); + } + else + { + assert(false && "unsupported arch/op combination"); + return {}; + } + } + // bitwise_xor template inline batch bitwise_xor(batch const& self, batch const& other, requires_arch) noexcept From ec703baa52066498a3a98db10078bc22f6e9df79 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Mon, 9 Oct 2023 10:14:09 +0530 Subject: [PATCH 24/55] Fixed CMakeLists.txt file --- test/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bf123a998..07b61c9c3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -191,8 +191,10 @@ else() endif() if(ENABLE_XTL_COMPLEX) -target_include_directories(test_xsimd PRIVATE ${xtl_INCLUDE_DIRS}) + add_compile_definitions(XSIMD_ENABLE_XTL_COMPLEX=1) + target_include_directories(test_xsimd PRIVATE ${xtl_INCLUDE_DIRS}) endif() + add_test(NAME test_xsimd COMMAND test_xsimd) if (CROSS_COMPILE_ARM) From 175e0bc167e7afb01f8550754a21557085679c1c Mon Sep 17 00:00:00 2001 From: DerThorsten Date: Mon, 18 Sep 2023 12:12:32 +0200 Subject: [PATCH 25/55] minimal setup for wasm ci --- .github/workflows/emscripten.yml | 26 ++ test/CMakeLists.txt | 317 +++++++++++++------------ test/test_wasm/browser_main.html | 12 + test/test_wasm/test_wasm.cpp | 33 +++ test/test_wasm/test_wasm.sh | 26 ++ test/test_wasm/test_wasm_playwright.py | 125 ++++++++++ 6 files changed, 388 insertions(+), 151 deletions(-) create mode 100644 .github/workflows/emscripten.yml create mode 100644 test/test_wasm/browser_main.html create mode 100644 test/test_wasm/test_wasm.cpp create mode 100755 test/test_wasm/test_wasm.sh create mode 100644 test/test_wasm/test_wasm_playwright.py diff --git a/.github/workflows/emscripten.yml b/.github/workflows/emscripten.yml new file mode 100644 index 000000000..c1fab2547 --- /dev/null +++ b/.github/workflows/emscripten.yml @@ -0,0 +1,26 @@ +name: Emscripten build +on: [push, pull_request] +concurrency: + group: ${{ github.workflow }}-${{ github.job }}-${{ github.ref }} + cancel-in-progress: true +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - uses: mamba-org/setup-micromamba@v1 + with: + environment-name: xsimd + create-args: >- + microsoft::playwright + python + + + - name: Build script + run: | + echo "Build script for wasm" + playwright install + ./test/test_wasm/test_wasm.sh \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index daaf97ed7..ab29dd5ab 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -35,175 +35,190 @@ OPTION(XSIMD_ENABLE_WERROR "Turn on -Werror" OFF) -################ -# ARM SETTINGS # -################ - -OPTION(CROSS_COMPILE_ARM "cross compile for ARM targets" OFF) - -# Note: to compile on ARM (or cross compile), you may need to add the following: -# -DTARGET_ARCH="armv8-a -mfpu=neon -mfloat-abi=softfp -target arm-linux-gnueabi" -set(TARGET_ARCH "native" CACHE STRING "Target architecture arguments") - -if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Intel") - if (NOT WIN32 AND NOT ANDROID) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused-parameter -Wextra -Wreorder") - # Users may override the c++ standard: - if(NOT DEFINED CMAKE_CXX_STANDARD OR "${CMAKE_CXX_STANDARD}" STREQUAL "") - if (ENABLE_XTL_COMPLEX) - CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG) - if (NOT HAS_CPP14_FLAG) - message(FATAL_ERROR "Unsupported compiler -- xsimd requires C++14 support when xtl complex support is enabled") - endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") - else() - CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_CPP11_FLAG) - if (NOT HAS_CPP11_FLAG) - message(FATAL_ERROR "Unsupported compiler -- xsimd requires C++11 support!") +if(NOT EMSCRIPTEN) + ################ + # ARM SETTINGS # + ################ + + OPTION(CROSS_COMPILE_ARM "cross compile for ARM targets" OFF) + + # Note: to compile on ARM (or cross compile), you may need to add the following: + # -DTARGET_ARCH="armv8-a -mfpu=neon -mfloat-abi=softfp -target arm-linux-gnueabi" + set(TARGET_ARCH "native" CACHE STRING "Target architecture arguments") + + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Intel") + if (NOT WIN32 AND NOT ANDROID) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused-parameter -Wextra -Wreorder") + # Users may override the c++ standard: + if(NOT DEFINED CMAKE_CXX_STANDARD OR "${CMAKE_CXX_STANDARD}" STREQUAL "") + if (ENABLE_XTL_COMPLEX) + CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG) + if (NOT HAS_CPP14_FLAG) + message(FATAL_ERROR "Unsupported compiler -- xsimd requires C++14 support when xtl complex support is enabled") + endif() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_CPP11_FLAG) + if (NOT HAS_CPP11_FLAG) + message(FATAL_ERROR "Unsupported compiler -- xsimd requires C++11 support!") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + endif() endif() endif() + + if (NOT CROSS_COMPILE_ARM) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fPIC") + endif() endif() - if (NOT CROSS_COMPILE_ARM) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fPIC") + if (ANDROID) + # Nothing to do here, we assume the cmake Android NDK toolchain sets the + # correct options for arm and neon. + elseif (CROSS_COMPILE_ARM) + # We're cross-compiling with clang++ on Azure Pipelines, this is all pretty specific and just for testing + set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) + set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) + set(CMAKE_THREAD_LIBS_INIT) + + set(CMAKE_SYSTEM_PROCESSOR arm) + set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabi) + set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabi) + + set(ARM_ARCH_DIRECTORY "arm-linux-gnueabi" CACHE STRING "ARM arch header dir") + set(ARM_GCC_VER "4.7.3" CACHE STRING "ARM GCC header dir") + include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/c++/${ARM_GCC_VER}/${ARM_ARCH_DIRECTORY}/) + include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/c++/${ARM_GCC_VER}/) + include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/) + if(NOT CMAKE_CXX_FLAGS MATCHES "-march") + message(STATUS "SETTING ARCH TO ${TARGET_ARCH}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TARGET_ARCH}") + endif() + if(ARM_ARCH_DIRECTORY MATCHES "arm-linux-gnueabi") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -mfloat-abi=softfp -target arm-linux-gnueabi") + else () + # delegating to gcc here + endif() + message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") + message(STATUS "CMAKE_CXX_LINK_EXECUTABLE: ${CMAKE_CXX_LINK_EXECUTABLE}") + elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^ppc64" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=${TARGET_ARCH} -mtune=${TARGET_ARCH}") + elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "riscv64") + # Nothing specific + elseif(NOT WIN32) + if(NOT CMAKE_CXX_FLAGS MATCHES "-march" AND NOT CMAKE_CXX_FLAGS MATCHES "-arch" AND NOT CMAKE_OSX_ARCHITECTURES) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TARGET_ARCH}") + endif() endif() endif() - if (ANDROID) - # Nothing to do here, we assume the cmake Android NDK toolchain sets the - # correct options for arm and neon. - elseif (CROSS_COMPILE_ARM) - # We're cross-compiling with clang++ on Azure Pipelines, this is all pretty specific and just for testing - set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) - set(CMAKE_THREAD_LIBS_INIT) - - set(CMAKE_SYSTEM_PROCESSOR arm) - set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabi) - set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabi) - - set(ARM_ARCH_DIRECTORY "arm-linux-gnueabi" CACHE STRING "ARM arch header dir") - set(ARM_GCC_VER "4.7.3" CACHE STRING "ARM GCC header dir") - include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/c++/${ARM_GCC_VER}/${ARM_ARCH_DIRECTORY}/) - include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/c++/${ARM_GCC_VER}/) - include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/) - if(NOT CMAKE_CXX_FLAGS MATCHES "-march") - message(STATUS "SETTING ARCH TO ${TARGET_ARCH}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TARGET_ARCH}") - endif() - if(ARM_ARCH_DIRECTORY MATCHES "arm-linux-gnueabi") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -mfloat-abi=softfp -target arm-linux-gnueabi") - else () - # delegating to gcc here - endif() - message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") - message(STATUS "CMAKE_CXX_LINK_EXECUTABLE: ${CMAKE_CXX_LINK_EXECUTABLE}") - elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^ppc64" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=${TARGET_ARCH} -mtune=${TARGET_ARCH}") - elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "riscv64") - # Nothing specific - elseif(NOT WIN32) - if(NOT CMAKE_CXX_FLAGS MATCHES "-march" AND NOT CMAKE_CXX_FLAGS MATCHES "-arch" AND NOT CMAKE_OSX_ARCHITECTURES) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TARGET_ARCH}") - endif() + if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /MP /bigobj") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244 /wd4267 /wd4005 /wd4146 /wd4800") + set(CMAKE_EXE_LINKER_FLAGS /MANIFEST:NO) endif() -endif() -if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /MP /bigobj") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244 /wd4267 /wd4005 /wd4146 /wd4800") - set(CMAKE_EXE_LINKER_FLAGS /MANIFEST:NO) -endif() + if(CMAKE_CXX_COMPILER_ID MATCHES Clang AND MSVC AND WIN32) # We are using clang-cl + add_compile_options(/EHsc /bigobj) + set(CMAKE_EXE_LINKER_FLAGS /MANIFEST:NO) + endif() -if(CMAKE_CXX_COMPILER_ID MATCHES Clang AND MSVC AND WIN32) # We are using clang-cl - add_compile_options(/EHsc /bigobj) - set(CMAKE_EXE_LINKER_FLAGS /MANIFEST:NO) -endif() + set(XSIMD_TESTS + main.cpp + test_api.cpp + test_arch.cpp + test_basic_math.cpp + test_batch.cpp + test_batch_bool.cpp + test_batch_cast.cpp + test_batch_complex.cpp + test_batch_float.cpp + test_batch_int.cpp + test_bitwise_cast.cpp + test_batch_constant.cpp + test_batch_manip.cpp + test_complex_exponential.cpp + test_complex_hyperbolic.cpp + test_complex_power.cpp + test_complex_trigonometric.cpp + test_conversion.cpp + test_custom_default_arch.cpp + test_error_gamma.cpp + test_explicit_batch_instantiation.cpp + test_exponential.cpp + test_extract_pair.cpp + test_fp_manipulation.cpp + test_hyperbolic.cpp + test_load_store.cpp + test_memory.cpp + test_poly_evaluation.cpp + test_power.cpp + test_rounding.cpp + test_select.cpp + test_shuffle.cpp + test_sum.cpp + test_traits.cpp + test_trigonometric.cpp + test_xsimd_api.cpp + test_utils.hpp + ) + + if(NOT MSVC) + list(APPEND XSIMD_TESTS test_gnu_source.cpp) + endif() -set(XSIMD_TESTS - main.cpp - test_api.cpp - test_arch.cpp - test_basic_math.cpp - test_batch.cpp - test_batch_bool.cpp - test_batch_cast.cpp - test_batch_complex.cpp - test_batch_float.cpp - test_batch_int.cpp - test_bitwise_cast.cpp - test_batch_constant.cpp - test_batch_manip.cpp - test_complex_exponential.cpp - test_complex_hyperbolic.cpp - test_complex_power.cpp - test_complex_trigonometric.cpp - test_conversion.cpp - test_custom_default_arch.cpp - test_error_gamma.cpp - test_explicit_batch_instantiation.cpp - test_exponential.cpp - test_extract_pair.cpp - test_fp_manipulation.cpp - test_hyperbolic.cpp - test_load_store.cpp - test_memory.cpp - test_poly_evaluation.cpp - test_power.cpp - test_rounding.cpp - test_select.cpp - test_shuffle.cpp - test_sum.cpp - test_traits.cpp - test_trigonometric.cpp - test_xsimd_api.cpp - test_utils.hpp -) - -if(NOT MSVC) - list(APPEND XSIMD_TESTS test_gnu_source.cpp) -endif() + add_executable(test_xsimd ${XSIMD_TESTS} ${XSIMD_HEADERS}) + target_include_directories(test_xsimd PRIVATE ${XSIMD_INCLUDE_DIR}) -add_executable(test_xsimd ${XSIMD_TESTS} ${XSIMD_HEADERS}) -target_include_directories(test_xsimd PRIVATE ${XSIMD_INCLUDE_DIR}) + option(XSIMD_DOWNLOAD_DOCTEST OFF) + find_package(doctest QUIET) + if (doctest_FOUND) + set(DOCTEST_MINIMAL_VERSION 2.4.9) + if (doctest_VERSION VERSION_LESS DOCTEST_MINIMAL_VERSION) + message(FATAL_ERROR "Requires doctest >= ${DOCTEST_MINIMAL_VERSION}") + endif() + target_link_libraries(test_xsimd PRIVATE doctest::doctest) + elseif(DOWNLOAD_DOCTEST) + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/doctest") + file(DOWNLOAD + "https://github.com/doctest/doctest/releases/download/v2.4.9/doctest.h" + "${CMAKE_CURRENT_BINARY_DIR}/doctest/doctest.h") + target_include_directories(test_xsimd PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + else() + message(FATAL_ERROR " + Cannot find required doctest component. + Please either set CMAKE_PREFIX_PATH to the location of doctestConfig.cmake, + or set DOWNLOAD_DOCTEST=ON") + endif() -option(XSIMD_DOWNLOAD_DOCTEST OFF) -find_package(doctest QUIET) -if (doctest_FOUND) - set(DOCTEST_MINIMAL_VERSION 2.4.9) - if (doctest_VERSION VERSION_LESS DOCTEST_MINIMAL_VERSION) - message(FATAL_ERROR "Requires doctest >= ${DOCTEST_MINIMAL_VERSION}") + if(ENABLE_XTL_COMPLEX) + target_include_directories(test_xsimd PRIVATE ${xtl_INCLUDE_DIRS}) endif() - target_link_libraries(test_xsimd PRIVATE doctest::doctest) -elseif(DOWNLOAD_DOCTEST) - file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/doctest") - file(DOWNLOAD - "https://github.com/doctest/doctest/releases/download/v2.4.9/doctest.h" - "${CMAKE_CURRENT_BINARY_DIR}/doctest/doctest.h") - target_include_directories(test_xsimd PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) -else() - message(FATAL_ERROR " - Cannot find required doctest component. - Please either set CMAKE_PREFIX_PATH to the location of doctestConfig.cmake, - or set DOWNLOAD_DOCTEST=ON") -endif() + add_test(NAME test_xsimd COMMAND test_xsimd) -if(ENABLE_XTL_COMPLEX) - target_include_directories(test_xsimd PRIVATE ${xtl_INCLUDE_DIRS}) -endif() -add_test(NAME test_xsimd COMMAND test_xsimd) + if (CROSS_COMPILE_ARM) + add_custom_target(xtest COMMAND qemu-arm -L /usr/arm-linux-gnueabi/ test_xsimd DEPENDS test_xsimd) + else() + add_executable(test_xsimd_wasm xsimd_wasm.cpp) + endif() + + if (XSIMD_ENABLE_WERROR) + target_compile_options(test_xsimd PRIVATE -Werror -Wall -DXSIMD_SKIP_ON_WERROR) + endif() -if (CROSS_COMPILE_ARM) - add_custom_target(xtest COMMAND qemu-arm -L /usr/arm-linux-gnueabi/ test_xsimd DEPENDS test_xsimd) + add_subdirectory(doc) else() - add_custom_target(xtest COMMAND test_xsimd DEPENDS test_xsimd) -endif() + add_executable(test_xsimd_wasm test_wasm/test_wasm.cpp) + target_include_directories(test_xsimd_wasm PRIVATE ${XSIMD_INCLUDE_DIR}) -if (XSIMD_ENABLE_WERROR) - target_compile_options(test_xsimd PRIVATE -Werror -Wall -DXSIMD_SKIP_ON_WERROR) -endif() + # set compile flgs -msimd128 -add_subdirectory(doc) + target_compile_options(test_xsimd_wasm + PUBLIC --std=c++17 + PUBLIC "SHELL: -msimd128" + ) + # add flags embind, modularize + + set_target_properties(test_xsimd_wasm PROPERTIES LINK_FLAGS "-s MODULARIZE=1 -s EXPORT_NAME=test_xsimd_wasm -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -lembind") +endif() diff --git a/test/test_wasm/browser_main.html b/test/test_wasm/browser_main.html new file mode 100644 index 000000000..6f5e7e26a --- /dev/null +++ b/test/test_wasm/browser_main.html @@ -0,0 +1,12 @@ + + + + + TEST_TITLE + + + + + + + diff --git a/test/test_wasm/test_wasm.cpp b/test/test_wasm/test_wasm.cpp new file mode 100644 index 000000000..b909d4a58 --- /dev/null +++ b/test/test_wasm/test_wasm.cpp @@ -0,0 +1,33 @@ +#include +#include "xsimd/xsimd.hpp" + + +#include +#include // for reporting errors + +using namespace emscripten; + + + +int test_mean() +{ + // std::cout<<"test_mean"< a = {1.5, 2.5, 3.5, 4.5}; + // xsimd::batch b = {2.5, 3.5, 4.5, 5.5}; + // auto mean = (a + b) / 2; + // std::cout << mean << std::endl; + return 0; +} + + +int run_tests() { + // todo add actual tests + if(auto ret = test_mean(); ret != 0) { + return ret; + } + return 0; +} + +EMSCRIPTEN_BINDINGS(my_module) { + emscripten::function("run_tests", &run_tests); +} \ No newline at end of file diff --git a/test/test_wasm/test_wasm.sh b/test/test_wasm/test_wasm.sh new file mode 100755 index 000000000..e547b349a --- /dev/null +++ b/test/test_wasm/test_wasm.sh @@ -0,0 +1,26 @@ +#!/bin/bash +set -e + +# this dir +TEST_WASM_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +SRC_DIR=$TEST_WASM_DIR/../.. + + +# emsdk +# git clone https://github.com/emscripten-core/emsdk +# cd emsdk +# ./emsdk install latest +# ./emsdk activate latest +# source ./emsdk_env.sh +source ~/src/emsdk/emsdk_env.sh + + + +# build wasm +mkdir -p build +cd build +emcmake cmake -DBUILD_TESTS=ON $SRC_DIR +emmake make -j4 +cd .. + +python $TEST_WASM_DIR/test_wasm_playwright.py build/test \ No newline at end of file diff --git a/test/test_wasm/test_wasm_playwright.py b/test/test_wasm/test_wasm_playwright.py new file mode 100644 index 000000000..03feb5457 --- /dev/null +++ b/test/test_wasm/test_wasm_playwright.py @@ -0,0 +1,125 @@ + +from tempfile import TemporaryDirectory +import shutil +import socket +import threading +from contextlib import closing, contextmanager +from http.server import HTTPServer, SimpleHTTPRequestHandler +import os +import asyncio +from pathlib import Path +from playwright.async_api import async_playwright + +THIS_DIR = os.path.dirname(os.path.realpath(__file__)) +WORK_DIR = os.path.join(THIS_DIR, "work_dir") + + +def find_free_port(): + with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: + s.bind(("", 0)) + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + return s.getsockname()[1] + + +def start_server(work_dir, port): + class Handler(SimpleHTTPRequestHandler): + def __init__(self, *args, **kwargs): + super().__init__(*args, directory=work_dir, **kwargs) + + def log_message(self, fmt, *args): + return + + httpd = HTTPServer(("127.0.0.1", port), Handler) + + thread = threading.Thread(target=httpd.serve_forever) + thread.start() + return thread, httpd + + +@contextmanager +def server_context(work_dir, port): + thread, server = start_server(work_dir=work_dir, port=port) + try: + yield server, f"http://127.0.0.1:{port}" + finally: + server.shutdown() + thread.join() + +async def playwright_run_page(page_url, headless=False, slow_mo=None): + async with async_playwright() as p: + if slow_mo is None: + browser = await p.chromium.launch(headless=headless) + else: + browser = await p.chromium.launch( + headless=headless, slow_mo=slow_mo + ) + page = await browser.new_page() + await page.goto(page_url) + # n min = n_min * 60 * 1000 ms + n_min = 4 + page.set_default_timeout(n_min * 60 * 1000) + + async def handle_console(msg): + txt = str(msg) + print(txt) + + page.on("console", handle_console) + + # await page.goto(page_url) + status = await page.evaluate( + f"""async () => {{ + + let test_module = await test_xsimd_wasm(); + console.log("\\n\\n************************************************************"); + console.log("XSIMD WASM TESTS:"); + console.log("************************************************************"); + let r = test_module.run_tests(); + if (r == 0) {{ + console.log("\\n\\n************************************************************"); + console.log("XSIMD WASM TESTS PASSED"); + console.log("************************************************************"); + return r; + }} + else {{ + console.log("************************************************************"); + console.log("XSIMD WASM TESTS FAILED"); + console.log("************************************************************"); + return r; + }} + + }}""" + ) + return_code = int(status) + return return_code +def main(build_dir): + + work_dir = WORK_DIR# TemporaryDirectory() + + with TemporaryDirectory() as temp_dir: + work_dir = Path(temp_dir) + + + shutil.copy(f"{build_dir}/test_xsimd_wasm.wasm", work_dir) + shutil.copy(f"{build_dir}/test_xsimd_wasm.js", work_dir) + shutil.copy(f"{THIS_DIR}/browser_main.html", work_dir) + + port = find_free_port() + with server_context(work_dir=work_dir, port=port) as (server, url): + page_url = f"{url}/browser_main.html" + ret = asyncio.run(playwright_run_page(page_url=page_url)) + + return ret + + + +if __name__ == "__main__": + import pytest + import sys + + # get arg from args + build_dir = sys.argv[1] + + print(f"build_dir: {build_dir}") + + ret_code = main(build_dir) + sys.exit(ret_code) \ No newline at end of file From 303dbfb9e7a9a96844e09adb90ac94f901188e95 Mon Sep 17 00:00:00 2001 From: DerThorsten Date: Mon, 18 Sep 2023 12:15:47 +0200 Subject: [PATCH 26/55] fix --- test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ab29dd5ab..3d34646df 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -199,7 +199,7 @@ if(NOT EMSCRIPTEN) if (CROSS_COMPILE_ARM) add_custom_target(xtest COMMAND qemu-arm -L /usr/arm-linux-gnueabi/ test_xsimd DEPENDS test_xsimd) else() - add_executable(test_xsimd_wasm xsimd_wasm.cpp) + add_custom_target(xtest COMMAND test_xsimd DEPENDS test_xsimd) endif() if (XSIMD_ENABLE_WERROR) From 42cb05422ab8aa947babf9d02f994cc24d80cd48 Mon Sep 17 00:00:00 2001 From: DerThorsten Date: Mon, 18 Sep 2023 12:16:50 +0200 Subject: [PATCH 27/55] install emscripten --- test/test_wasm/test_wasm.sh | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/test/test_wasm/test_wasm.sh b/test/test_wasm/test_wasm.sh index e547b349a..8caea3970 100755 --- a/test/test_wasm/test_wasm.sh +++ b/test/test_wasm/test_wasm.sh @@ -6,14 +6,13 @@ TEST_WASM_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd ) SRC_DIR=$TEST_WASM_DIR/../.. -# emsdk -# git clone https://github.com/emscripten-core/emsdk -# cd emsdk -# ./emsdk install latest -# ./emsdk activate latest -# source ./emsdk_env.sh -source ~/src/emsdk/emsdk_env.sh - +emsdk +git clone https://github.com/emscripten-core/emsdk +cd emsdk +./emsdk install latest +./emsdk activate latest +source ./emsdk_env.sh +cd .. # build wasm From c912e4aadedfd5c95be3edcd8d7744c1272e1696 Mon Sep 17 00:00:00 2001 From: DerThorsten Date: Mon, 18 Sep 2023 12:21:21 +0200 Subject: [PATCH 28/55] specifing shell --- .github/workflows/emscripten.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/emscripten.yml b/.github/workflows/emscripten.yml index c1fab2547..159c1edbe 100644 --- a/.github/workflows/emscripten.yml +++ b/.github/workflows/emscripten.yml @@ -17,9 +17,12 @@ jobs: create-args: >- microsoft::playwright python + init-shell: bash + - name: Build script + shell: bash -el {0} run: | echo "Build script for wasm" playwright install From 2853a772664225d17a988868ee0898bf6ad98a7a Mon Sep 17 00:00:00 2001 From: DerThorsten Date: Mon, 18 Sep 2023 12:24:28 +0200 Subject: [PATCH 29/55] remove superflous emsdk --- test/test_wasm/test_wasm.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/test_wasm/test_wasm.sh b/test/test_wasm/test_wasm.sh index 8caea3970..a786e095c 100755 --- a/test/test_wasm/test_wasm.sh +++ b/test/test_wasm/test_wasm.sh @@ -5,8 +5,7 @@ set -e TEST_WASM_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" SRC_DIR=$TEST_WASM_DIR/../.. - -emsdk +# setup emsdk git clone https://github.com/emscripten-core/emsdk cd emsdk ./emsdk install latest From 08b9150af6282b9e6f431ccadb1eddc756c41597 Mon Sep 17 00:00:00 2001 From: DerThorsten Date: Mon, 18 Sep 2023 12:27:11 +0200 Subject: [PATCH 30/55] remove superflous imports --- test/test_wasm/test_wasm_playwright.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_wasm/test_wasm_playwright.py b/test/test_wasm/test_wasm_playwright.py index 03feb5457..2df9898d9 100644 --- a/test/test_wasm/test_wasm_playwright.py +++ b/test/test_wasm/test_wasm_playwright.py @@ -113,7 +113,6 @@ def main(build_dir): if __name__ == "__main__": - import pytest import sys # get arg from args From 1a5c17f4a6d946960eac6795281d0459707097bd Mon Sep 17 00:00:00 2001 From: DerThorsten Date: Mon, 18 Sep 2023 12:33:45 +0200 Subject: [PATCH 31/55] make headless default --- test/test_wasm/test_wasm_playwright.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_wasm/test_wasm_playwright.py b/test/test_wasm/test_wasm_playwright.py index 2df9898d9..420d0bf4e 100644 --- a/test/test_wasm/test_wasm_playwright.py +++ b/test/test_wasm/test_wasm_playwright.py @@ -45,7 +45,7 @@ def server_context(work_dir, port): server.shutdown() thread.join() -async def playwright_run_page(page_url, headless=False, slow_mo=None): +async def playwright_run_page(page_url, headless=True, slow_mo=None): async with async_playwright() as p: if slow_mo is None: browser = await p.chromium.launch(headless=headless) From 3ad52538f3db0dc96e11afc34bd0a0e8c3b2828b Mon Sep 17 00:00:00 2001 From: DerThorsten Date: Mon, 18 Sep 2023 13:36:38 +0200 Subject: [PATCH 32/55] use sse2 instructoion --- test/CMakeLists.txt | 1 + test/test_wasm/test_wasm.cpp | 11 ++++++----- test/test_wasm/test_wasm.sh | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3d34646df..2ea234419 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -216,6 +216,7 @@ else() target_compile_options(test_xsimd_wasm PUBLIC --std=c++17 PUBLIC "SHELL: -msimd128" + PUBLIC "SHELL: -msse2" ) # add flags embind, modularize diff --git a/test/test_wasm/test_wasm.cpp b/test/test_wasm/test_wasm.cpp index b909d4a58..36d4ba840 100644 --- a/test/test_wasm/test_wasm.cpp +++ b/test/test_wasm/test_wasm.cpp @@ -1,3 +1,4 @@ +#include #include #include "xsimd/xsimd.hpp" @@ -11,11 +12,11 @@ using namespace emscripten; int test_mean() { - // std::cout<<"test_mean"< a = {1.5, 2.5, 3.5, 4.5}; - // xsimd::batch b = {2.5, 3.5, 4.5, 5.5}; - // auto mean = (a + b) / 2; - // std::cout << mean << std::endl; + std::cout<<"test_mean"< a = {1.5, 2.5, 3.5, 4.5}; + xsimd::batch b = {2.5, 3.5, 4.5, 5.5}; + auto mean = (a + b) / 2; + std::cout << mean << std::endl; return 0; } diff --git a/test/test_wasm/test_wasm.sh b/test/test_wasm/test_wasm.sh index a786e095c..1199a1c37 100755 --- a/test/test_wasm/test_wasm.sh +++ b/test/test_wasm/test_wasm.sh @@ -5,13 +5,13 @@ set -e TEST_WASM_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" SRC_DIR=$TEST_WASM_DIR/../.. -# setup emsdk + git clone https://github.com/emscripten-core/emsdk cd emsdk ./emsdk install latest ./emsdk activate latest source ./emsdk_env.sh -cd .. + # build wasm From 056672787712e59b6463e12dbae29fd6195ccaf2 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Mon, 2 Oct 2023 16:10:15 +0530 Subject: [PATCH 33/55] Initial Implementation for the Wasm based instruction set --- CMakeLists.txt | 2 + include/xsimd/arch/xsimd_isa.hpp | 4 + include/xsimd/arch/xsimd_wasm.hpp | 114 ++++++++++++++++++++ include/xsimd/config/xsimd_arch.hpp | 3 +- include/xsimd/config/xsimd_config.hpp | 13 ++- include/xsimd/types/xsimd_all_registers.hpp | 2 + include/xsimd/types/xsimd_wasm_register.hpp | 61 +++++++++++ test/test_wasm/test_wasm.cpp | 16 +-- test/test_wasm/test_wasm_playwright.py | 4 +- 9 files changed, 204 insertions(+), 15 deletions(-) create mode 100644 include/xsimd/arch/xsimd_wasm.hpp create mode 100644 include/xsimd/types/xsimd_wasm_register.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c7dcdb26..4d6adfa02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,7 @@ ${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_sse4_1.hpp ${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_sse4_2.hpp ${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_ssse3.hpp ${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_sve.hpp +${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_wasm.hpp ${XSIMD_INCLUDE_DIR}/xsimd/config/xsimd_arch.hpp ${XSIMD_INCLUDE_DIR}/xsimd/config/xsimd_config.hpp ${XSIMD_INCLUDE_DIR}/xsimd/config/xsimd_cpuid.hpp @@ -75,6 +76,7 @@ ${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_sse4_1_register.hpp ${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_sse4_2_register.hpp ${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_ssse3_register.hpp ${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_sve_register.hpp +${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_wasm_register.hpp ${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_traits.hpp ${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_utils.hpp ${XSIMD_INCLUDE_DIR}/xsimd/xsimd.hpp diff --git a/include/xsimd/arch/xsimd_isa.hpp b/include/xsimd/arch/xsimd_isa.hpp index cf0f796a1..8f05a5dab 100644 --- a/include/xsimd/arch/xsimd_isa.hpp +++ b/include/xsimd/arch/xsimd_isa.hpp @@ -80,6 +80,10 @@ #include "./xsimd_sve.hpp" #endif +#if XSIMD_WITH_WASM +#include "./xsimd_wasm.hpp" +#endif + // Must come last to have access to all conversion specializations. #include "./xsimd_generic.hpp" diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp new file mode 100644 index 000000000..be515670c --- /dev/null +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -0,0 +1,114 @@ +/*************************************************************************** + * Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and * + * Martin Renou * + * Copyright (c) QuantStack * + * Copyright (c) Serge Guelton * + * Copyright (c) Anutosh Bhat * + * * + * Distributed under the terms of the BSD 3-Clause License. * + * * + * The full license is in the file LICENSE, distributed with this software. * + ****************************************************************************/ + +#ifndef XSIMD_WASM_HPP +#define XSIMD_WASM_HPP + +#include + +#include "../types/xsimd_wasm_register.hpp" + +namespace xsimd +{ + + namespace kernel + { + using namespace types; + + // abs + template + inline batch abs(batch const& self, requires_arch) noexcept + { + XSIMD_IF_CONSTEXPR(std::is_integral_v && std::is_signed_v) + { + XSIMD_IF_CONSTEXPR(sizeof(T) == 1) + { + return wasm_i8x16_abs(self); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 2) + { + return wasm_i16x8_abs(self); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 4) + { + return wasm_i32x4_abs(self); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) + { + return wasm_i64x2_abs(self); + } + else + { + assert(false && "unsupported arch/op combination"); + return {}; + } + } + else XSIMD_IF_CONSTEXPR(std::is_floating_point_v) + { + XSIMD_IF_CONSTEXPR(sizeof(T) == 4) + { + return wasm_f32x4_abs(self); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) + { + return wasm_f64x2_abs(self); + } + else + { + assert(false && "unsupported arch/op combination"); + return {}; + } + } + else + { + assert(false && "unsupported arch/op combination"); + return {}; + } + } + + //set + template ::value, void>::type> + inline batch set(batch const&, requires_arch, T v0, T v1) noexcept + { + return wasm_i64x2_make(v0, v1); + } + + template ::value, void>::type> + inline batch set(batch const&, requires_arch, T v0, T v1, T v2, T v3) noexcept + { + return wasm_i32x4_make(v0, v1, v2, v3); + } + + template ::value, void>::type> + inline batch set(batch const&, requires_arch, T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7) noexcept + { + return wasm_i16x8_make(v0, v1, v2, v3, v4, v5, v6, v7); + } + + template ::value, void>::type> + inline batch set(batch const&, requires_arch, T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15) noexcept + { + return wasm_i8x16_make(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15); + } + + //store_aligned + template ::value, void>::type> + inline void store_aligned(T* mem, batch const& self, requires_arch) noexcept + { + // Assuming that mem is aligned properly, you can use wasm_v128_store to store the batch. + return wasm_v128_store((v128_t*)mem, self); + } + } +} + +#endif \ No newline at end of file diff --git a/include/xsimd/config/xsimd_arch.hpp b/include/xsimd/config/xsimd_arch.hpp index 81cada583..ab9ecbc29 100644 --- a/include/xsimd/config/xsimd_arch.hpp +++ b/include/xsimd/config/xsimd_arch.hpp @@ -193,7 +193,8 @@ namespace xsimd using all_x86_architectures = arch_list, avx2, fma3, avx, fma4, fma3, sse4_2, sse4_1, /*sse4a,*/ ssse3, sse3, sse2>; using all_sve_architectures = arch_list, detail::sve<256>, detail::sve<128>>; using all_arm_architectures = typename detail::join>::type; - using all_architectures = typename detail::join::type; + using all_wasm_architectures = arch_list; + using all_architectures = typename detail::join::type; using supported_architectures = typename detail::supported::type; diff --git a/include/xsimd/config/xsimd_config.hpp b/include/xsimd/config/xsimd_config.hpp index d36ed1ee5..c682b4d93 100644 --- a/include/xsimd/config/xsimd_config.hpp +++ b/include/xsimd/config/xsimd_config.hpp @@ -285,6 +285,17 @@ #define XSIMD_SVE_BITS 0 #endif +/** + * @ingroup xsimd_config_macro + * + * Set to 1 if WebAssembly SIMD is available at compile-time, to 0 otherwise. + */ +#ifdef __EMSCRIPTEN__ +#define XSIMD_WITH_WASM 1 +#else +#define XSIMD_WITH_WASM 0 +#endif + // Workaround for MSVC compiler #ifdef _MSC_VER @@ -343,7 +354,7 @@ #endif -#if !XSIMD_WITH_SSE2 && !XSIMD_WITH_SSE3 && !XSIMD_WITH_SSSE3 && !XSIMD_WITH_SSE4_1 && !XSIMD_WITH_SSE4_2 && !XSIMD_WITH_AVX && !XSIMD_WITH_AVX2 && !XSIMD_WITH_FMA3_SSE && !XSIMD_WITH_FMA4 && !XSIMD_WITH_FMA3_AVX && !XSIMD_WITH_FMA3_AVX2 && !XSIMD_WITH_AVX512F && !XSIMD_WITH_AVX512CD && !XSIMD_WITH_AVX512DQ && !XSIMD_WITH_AVX512BW && !XSIMD_WITH_NEON && !XSIMD_WITH_NEON64 && !XSIMD_WITH_SVE +#if !XSIMD_WITH_SSE2 && !XSIMD_WITH_SSE3 && !XSIMD_WITH_SSSE3 && !XSIMD_WITH_SSE4_1 && !XSIMD_WITH_SSE4_2 && !XSIMD_WITH_AVX && !XSIMD_WITH_AVX2 && !XSIMD_WITH_FMA3_SSE && !XSIMD_WITH_FMA4 && !XSIMD_WITH_FMA3_AVX && !XSIMD_WITH_FMA3_AVX2 && !XSIMD_WITH_AVX512F && !XSIMD_WITH_AVX512CD && !XSIMD_WITH_AVX512DQ && !XSIMD_WITH_AVX512BW && !XSIMD_WITH_NEON && !XSIMD_WITH_NEON64 && !XSIMD_WITH_SVE && !XSIMD_WITH_WASM #define XSIMD_NO_SUPPORTED_ARCHITECTURE #endif diff --git a/include/xsimd/types/xsimd_all_registers.hpp b/include/xsimd/types/xsimd_all_registers.hpp index 1fe077325..7047ef144 100644 --- a/include/xsimd/types/xsimd_all_registers.hpp +++ b/include/xsimd/types/xsimd_all_registers.hpp @@ -30,3 +30,5 @@ #include "xsimd_neon_register.hpp" #include "xsimd_sve_register.hpp" + +#include "xsimd_wasm_register.hpp" \ No newline at end of file diff --git a/include/xsimd/types/xsimd_wasm_register.hpp b/include/xsimd/types/xsimd_wasm_register.hpp new file mode 100644 index 000000000..f68d20336 --- /dev/null +++ b/include/xsimd/types/xsimd_wasm_register.hpp @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and * + * Martin Renou * + * Copyright (c) QuantStack * + * Copyright (c) Serge Guelton * + * Copyright (c) Anutosh Bhat * + * * + * Distributed under the terms of the BSD 3-Clause License. * + * * + * The full license is in the file LICENSE, distributed with this software. * + ****************************************************************************/ + +#ifndef XSIMD_WASM_REGISTER_HPP +#define XSIMD_WASM_REGISTER_HPP + +#include "xsimd_generic_arch.hpp" +#include "xsimd_register.hpp" + +#if XSIMD_WITH_WASM +#include +#endif + +namespace xsimd +{ + /** + * @ingroup architectures + * + * WASM instructions + */ + struct wasm : generic + { + static constexpr bool supported() noexcept { return XSIMD_WITH_WASM; } + static constexpr bool available() noexcept { return true; } + static constexpr bool requires_alignment() noexcept { return true; } + static constexpr unsigned version() noexcept { return generic::version(10, 0, 0); } + static constexpr std::size_t alignment() noexcept { return 16; } + static constexpr char const* name() noexcept { return "wasm"; } + }; + +#if XSIMD_WITH_WASM + namespace types + { + XSIMD_DECLARE_SIMD_REGISTER(bool, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(signed char, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(unsigned char, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(char, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(unsigned short, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(short, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(unsigned int, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(int, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(unsigned long int, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(long int, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(unsigned long long int, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(long long int, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(float, wasm, v128_t); + XSIMD_DECLARE_SIMD_REGISTER(double, wasm, v128_t); + } +#endif +} + +#endif \ No newline at end of file diff --git a/test/test_wasm/test_wasm.cpp b/test/test_wasm/test_wasm.cpp index 36d4ba840..94e6b6c49 100644 --- a/test/test_wasm/test_wasm.cpp +++ b/test/test_wasm/test_wasm.cpp @@ -2,28 +2,22 @@ #include #include "xsimd/xsimd.hpp" - #include #include // for reporting errors using namespace emscripten; - - -int test_mean() +int test_abs() { - std::cout<<"test_mean"< a = {1.5, 2.5, 3.5, 4.5}; - xsimd::batch b = {2.5, 3.5, 4.5, 5.5}; - auto mean = (a + b) / 2; - std::cout << mean << std::endl; + xsimd::batch a(1, -2, 3, -4); + auto ans = xsimd::abs(a); + std::cout << ans << std::endl; return 0; } - int run_tests() { // todo add actual tests - if(auto ret = test_mean(); ret != 0) { + if(auto ret = test_abs(); ret != 0) { return ret; } return 0; diff --git a/test/test_wasm/test_wasm_playwright.py b/test/test_wasm/test_wasm_playwright.py index 420d0bf4e..f88db0079 100644 --- a/test/test_wasm/test_wasm_playwright.py +++ b/test/test_wasm/test_wasm_playwright.py @@ -48,9 +48,9 @@ def server_context(work_dir, port): async def playwright_run_page(page_url, headless=True, slow_mo=None): async with async_playwright() as p: if slow_mo is None: - browser = await p.chromium.launch(headless=headless) + browser = await p.firefox.launch(headless=headless) else: - browser = await p.chromium.launch( + browser = await p.firefox.launch( headless=headless, slow_mo=slow_mo ) page = await browser.new_page() From a4195df27b0aa9e02e845b1d05df7ee40f3f48e7 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Tue, 3 Oct 2023 16:45:20 +0530 Subject: [PATCH 34/55] Added the add instruction --- include/xsimd/arch/xsimd_wasm.hpp | 41 ++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index be515670c..dbd834744 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -75,7 +75,46 @@ namespace xsimd } } - //set + // add + template ::value, void>::type> + inline batch add(batch const& self, batch const& other, requires_arch) noexcept + { + XSIMD_IF_CONSTEXPR(sizeof(T) == 1) + { + return wasm_i8x16_add(self, other); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 2) + { + return wasm_i16x8_add(self, other); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 4) + { + return wasm_i32x4_add(self, other); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) + { + return wasm_i64x2_add(self, other); + } + else + { + assert(false && "unsupported arch/op combination"); + return {}; + } + } + + template + inline batch add(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_add(self, other); + } + + template + inline batch add(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_add(self, other); + } + + // set template ::value, void>::type> inline batch set(batch const&, requires_arch, T v0, T v1) noexcept { From a8ddf8f82f9c34e46842b72b456a0670a082c7bb Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Tue, 3 Oct 2023 18:32:01 +0530 Subject: [PATCH 35/55] Added support for set and stored_aligned operations --- include/xsimd/arch/xsimd_wasm.hpp | 48 +++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index dbd834744..4f31115ec 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -114,6 +114,23 @@ namespace xsimd return wasm_f64x2_add(self, other); } + // all + template + inline bool all(batch_bool const& self, requires_arch) noexcept + { + return wasm_i32x4_bitmask(self) == 0x0F; + } + template + inline bool all(batch_bool const& self, requires_arch) noexcept + { + return wasm_i64x2_bitmask(self) == 0x03; + } + template ::value, void>::type> + inline bool all(batch_bool const& self, requires_arch) noexcept + { + return wasm_i8x16_bitmask(self) == 0xFFFF; + } + // set template ::value, void>::type> inline batch set(batch const&, requires_arch, T v0, T v1) noexcept @@ -140,13 +157,44 @@ namespace xsimd return wasm_i8x16_make(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15); } + template + inline batch set(batch const&, requires_arch, Values... values) noexcept + { + static_assert(sizeof...(Values) == batch::size, "consistent init"); + return wasm_f64x2_make(values...); + } + + template ::value, void>::type> + inline batch_bool set(batch_bool const&, requires_arch, Values... values) noexcept + { + return set(batch(), A {}, static_cast(values ? -1LL : 0LL)...).data; + } + //store_aligned + template + inline void store_aligned(float* mem, batch const& self, requires_arch) noexcept + { + // Assuming that mem is aligned properly, you can use wasm_v128_store to store the batch. + return wasm_v128_store(mem, self); + } template ::value, void>::type> inline void store_aligned(T* mem, batch const& self, requires_arch) noexcept { // Assuming that mem is aligned properly, you can use wasm_v128_store to store the batch. return wasm_v128_store((v128_t*)mem, self); } + template ::value, void>::type> + inline void store_aligned(T* mem, batch_bool const& self, requires_arch) noexcept + { + // Assuming that mem is aligned properly, you can use wasm_v128_store to store the batch. + return wasm_v128_store((v128_t*)mem, self); + } + template + inline void store_aligned(double* mem, batch const& self, requires_arch) noexcept + { + // Assuming that mem is aligned properly, you can use wasm_v128_store to store the batch. + return wasm_v128_store(mem, self); + } } } From 1441b7fa8245d374eddca34bf8a248e776906e81 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Tue, 3 Oct 2023 19:18:46 +0530 Subject: [PATCH 36/55] added support any, bitwise_and, broadcast --- include/xsimd/arch/xsimd_wasm.hpp | 83 +++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index 4f31115ec..308c3102d 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -131,7 +131,90 @@ namespace xsimd return wasm_i8x16_bitmask(self) == 0xFFFF; } + // any + template + inline bool any(batch_bool const& self, requires_arch) noexcept + { + return wasm_i32x4_bitmask(self) != 0; + } + template + inline bool any(batch_bool const& self, requires_arch) noexcept + { + return wasm_i64x2_bitmask(self) != 0; + } + template ::value, void>::type> + inline bool any(batch_bool const& self, requires_arch) noexcept + { + return wasm_i8x16_bitmask(self) != 0; + } + + // bitwise_and + template + inline batch bitwise_and(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_and(self, other); + } + template + inline batch_bool bitwise_and(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_and(self, other); + } + template ::value, void>::type> + inline batch bitwise_and(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_and(self, other); + } + template ::value, void>::type> + inline batch_bool bitwise_and(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_and(self, other); + } + + // broadcast + template + batch inline broadcast(float val, requires_arch) noexcept + { + return wasm_f32x4_splat(val); + } + template ::value, void>::type> + inline batch broadcast(T val, requires_arch) noexcept + { + XSIMD_IF_CONSTEXPR(sizeof(T) == 1) + { + return wasm_i8x16_splat(val); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 2) + { + return wasm_i16x8_splat(val); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 4) + { + return wasm_i32x4_splat(val); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) + { + return wasm_i64x2_splat(val); + } + else + { + assert(false && "unsupported arch/op combination"); + return {}; + } + } + template + inline batch broadcast(double val, requires_arch) noexcept + { + return wasm_f64x2_splat(val); + } + // set + template + inline batch set(batch const&, requires_arch, Values... values) noexcept + { + static_assert(sizeof...(Values) == batch::size, "consistent init"); + return wasm_f32x4_make(values...); + } + template ::value, void>::type> inline batch set(batch const&, requires_arch, T v0, T v1) noexcept { From 7cecf8f4840a73eea2d1a4a741550806172c33ad Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Tue, 3 Oct 2023 19:37:29 +0530 Subject: [PATCH 37/55] Added support for bitwise_andnot and bitwise_or --- include/xsimd/arch/xsimd_wasm.hpp | 81 +++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index 308c3102d..ec7d37062 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -170,6 +170,87 @@ namespace xsimd return wasm_v128_and(self, other); } + template + batch inline bitwise_and(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_and(self, other); + } + + template + inline batch_bool bitwise_and(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_and(self, other); + } + + // bitwise_andnot + template + inline batch bitwise_andnot(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_andnot(other, self); + } + + template + inline batch_bool bitwise_andnot(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_andnot(other, self); + } + template ::value, void>::type> + inline batch bitwise_andnot(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_andnot(other, self); + } + template ::value, void>::type> + inline batch_bool bitwise_andnot(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_andnot(other, self); + } + + template + inline batch bitwise_andnot(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_andnot(other, self); + } + + template + inline batch_bool bitwise_andnot(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_andnot(other, self); + } + + // bitwise_or + template + inline batch bitwise_or(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + template + inline batch_bool bitwise_or(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + template ::value, void>::type> + inline batch bitwise_or(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + template ::value, void>::type> + inline batch_bool bitwise_or(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + + template + inline batch bitwise_or(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + + template + inline batch_bool bitwise_or(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + // broadcast template batch inline broadcast(float val, requires_arch) noexcept From 2dfab94f13fe60b6ddd5be0c365e7f467594a371 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Tue, 3 Oct 2023 19:51:57 +0530 Subject: [PATCH 38/55] Added support for bitwise_xor and div --- include/xsimd/arch/xsimd_wasm.hpp | 44 +++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index ec7d37062..6717b6ffa 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -251,6 +251,38 @@ namespace xsimd return wasm_v128_or(self, other); } + // bitwise_xor + template + inline batch bitwise_xor(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_xor(self, other); + } + template + inline batch_bool bitwise_xor(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_xor(self, other); + } + template ::value, void>::type> + inline batch bitwise_xor(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + template + inline batch bitwise_xor(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + template + inline batch_bool bitwise_xor(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + template ::value, void>::type> + inline batch bitwise_xor(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + { + return wasm_v128_or(self, other); + } + // broadcast template batch inline broadcast(float val, requires_arch) noexcept @@ -288,6 +320,18 @@ namespace xsimd return wasm_f64x2_splat(val); } + // div + template + inline batch div(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_div(self, other); + } + template + inline batch div(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_div(self, other); + } + // set template inline batch set(batch const&, requires_arch, Values... values) noexcept From dfbd467e6067c57549a4f3a2296db05c5200ac92 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Tue, 3 Oct 2023 19:58:51 +0530 Subject: [PATCH 39/55] Added support for load_aligned --- include/xsimd/arch/xsimd_wasm.hpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index 6717b6ffa..80d7119d9 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -332,6 +332,26 @@ namespace xsimd return wasm_f64x2_div(self, other); } + // load_aligned + template + inline batch load_aligned(float const* mem, convert, requires_arch) noexcept + { + // Assuming that mem is aligned properly, you can use wasm_v128_load to load the mem. + return wasm_v128_load(mem); + } + template ::value, void>::type> + inline batch load_aligned(T const* mem, convert, requires_arch) noexcept + { + // Assuming that mem is aligned properly, you can use wasm_v128_load to load the mem. + return wasm_v128_load((v128_t const*)mem); + } + template + inline batch load_aligned(double const* mem, convert, requires_arch) noexcept + { + // Assuming that mem is aligned properly, you can use wasm_v128_load to load the mem. + return wasm_v128_load(mem); + } + // set template inline batch set(batch const&, requires_arch, Values... values) noexcept From e044b280770c8ee2ac14c59af26e007291ffc233 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Wed, 4 Oct 2023 15:49:55 +0530 Subject: [PATCH 40/55] added support for min, max, mul and select --- include/xsimd/arch/xsimd_wasm.hpp | 69 +++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index 80d7119d9..27c3b28a6 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -352,6 +352,75 @@ namespace xsimd return wasm_v128_load(mem); } + // max + template + inline batch max(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_pmax(self, other); + } + template ::value, void>::type> + inline batch max(batch const& self, batch const& other, requires_arch) noexcept + { + return select(self > other, self, other); + } + template + inline batch max(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_pmax(self, other); + } + + // min + template + inline batch min(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_pmin(self, other); + } + template ::value, void>::type> + inline batch min(batch const& self, batch const& other, requires_arch) noexcept + { + return select(self <= other, self, other); + } + template + inline batch min(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_pmin(self, other); + } + + // mul + template + inline batch mul(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_mul(self, other); + } + template + inline batch mul(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_mul(self, other); + } + + // select + template + inline batch select(batch_bool const& cond, batch const& true_br, batch const& false_br, requires_arch) noexcept + { + return wasm_v128_or(wasm_v128_and(cond, true_br), wasm_v128_andnot(cond, false_br)); + } + + template ::value, void>::type> + inline batch select(batch_bool const& cond, batch const& true_br, batch const& false_br, requires_arch) noexcept + { + return wasm_v128_or(wasm_v128_and(cond, true_br), wasm_v128_andnot(cond, false_br)); + } + template ::value, void>::type> + inline batch select(batch_bool_constant, Values...> const&, batch const& true_br, batch const& false_br, requires_arch) noexcept + { + return select(batch_bool { Values... }, true_br, false_br, wasm {}); + } + template + inline batch select(batch_bool const& cond, batch const& true_br, batch const& false_br, requires_arch) noexcept + { + return wasm_v128_or(wasm_v128_and(cond, true_br), wasm_v128_andnot(cond, false_br)); + } + // set template inline batch set(batch const&, requires_arch, Values... values) noexcept From 371a067e7e96c4b1d30d53f8b87aeae4d7be1894 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Wed, 4 Oct 2023 16:07:47 +0530 Subject: [PATCH 41/55] added support for sub --- include/xsimd/arch/xsimd_wasm.hpp | 39 ++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index 27c3b28a6..1993d8284 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -467,7 +467,7 @@ namespace xsimd return set(batch(), A {}, static_cast(values ? -1LL : 0LL)...).data; } - //store_aligned + // store_aligned template inline void store_aligned(float* mem, batch const& self, requires_arch) noexcept { @@ -492,6 +492,43 @@ namespace xsimd // Assuming that mem is aligned properly, you can use wasm_v128_store to store the batch. return wasm_v128_store(mem, self); } + + // sub + template + inline batch sub(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_sub(self, other); + } + template ::value, void>::type> + inline batch sub(batch const& self, batch const& other, requires_arch) noexcept + { + XSIMD_IF_CONSTEXPR(sizeof(T) == 1) + { + return wasm_i8x16_sub(self, other); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 2) + { + return wasm_i16x8_sub(self, other); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 4) + { + return wasm_i32x4_sub(self, other); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) + { + return wasm_i64x2_sub(self, other); + } + else + { + assert(false && "unsupported arch/op combination"); + return {}; + } + } + template + inline batch sub(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_sub(self, other); + } } } From 8ba25c7b036010f55813a1b1b04f039d462ba04a Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Wed, 4 Oct 2023 16:17:32 +0530 Subject: [PATCH 42/55] Added support for store_unaligned --- include/xsimd/arch/xsimd_wasm.hpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index 1993d8284..b9c4adcb8 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -493,6 +493,28 @@ namespace xsimd return wasm_v128_store(mem, self); } + // store_unaligned + template + inline void store_unaligned(float* mem, batch const& self, requires_arch) noexcept + { + return wasm_v128_store(mem, self); + } + template ::value, void>::type> + inline void store_unaligned(T* mem, batch const& self, requires_arch) noexcept + { + return wasm_v128_store((v128_t*)mem, self); + } + template ::value, void>::type> + inline void store_unaligned(T* mem, batch_bool const& self, requires_arch) noexcept + { + return wasm_v128_store((v128_t*)mem, self); + } + template + inline void store_unaligned(double* mem, batch const& self, requires_arch) noexcept + { + return wasm_v128_store(mem, self); + } + // sub template inline batch sub(batch const& self, batch const& other, requires_arch) noexcept From e1e16caa57a811a7d35516dcba8ec1cc6cf224dc Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Wed, 4 Oct 2023 16:40:40 +0530 Subject: [PATCH 43/55] Added support for load_unaligned and sqrt operations --- include/xsimd/arch/xsimd_wasm.hpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index b9c4adcb8..2fb57e445 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -352,6 +352,23 @@ namespace xsimd return wasm_v128_load(mem); } + // load_unaligned + template + inline batch load_unaligned(float const* mem, convert, requires_arch) noexcept + { + return wasm_v128_load(mem); + } + template ::value, void>::type> + inline batch load_unaligned(T const* mem, convert, requires_arch) noexcept + { + return wasm_v128_load((v128_t const*)mem); + } + template + inline batch load_unaligned(double const* mem, convert, requires_arch) noexcept + { + return wasm_v128_load(mem); + } + // max template inline batch max(batch const& self, batch const& other, requires_arch) noexcept @@ -551,6 +568,18 @@ namespace xsimd { return wasm_f64x2_sub(self, other); } + + // sqrt + template + inline batch sqrt(batch const& val, requires_arch) noexcept + { + return wasm_f32x4_sqrt(val); + } + template + inline batch sqrt(batch const& val, requires_arch) noexcept + { + return wasm_f64x2_sqrt(val); + } } } From 409a1b3adeb370ff37bfea8c7e58163c8cf9529e Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Wed, 4 Oct 2023 17:29:05 +0530 Subject: [PATCH 44/55] Added support for ge and le operations --- include/xsimd/arch/xsimd_wasm.hpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index 2fb57e445..ee5727242 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -332,6 +332,30 @@ namespace xsimd return wasm_f64x2_div(self, other); } + // ge + template + inline batch_bool ge(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_ge(self, other); + } + template + inline batch_bool ge(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_ge(self, other); + } + + // le + template + inline batch_bool le(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_le(self, other); + } + template + inline batch_bool le(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_le(self, other); + } + // load_aligned template inline batch load_aligned(float const* mem, convert, requires_arch) noexcept From 56b4688dc78eecb54c88f928091bbc5e5d4db1f1 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Thu, 5 Oct 2023 13:45:51 +0530 Subject: [PATCH 45/55] fixed implementations for abs, bitwise_and, bitwise_andnot & bitwise_xor --- include/xsimd/arch/xsimd_wasm.hpp | 148 ++++++++---------------------- 1 file changed, 36 insertions(+), 112 deletions(-) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index ee5727242..630a221ac 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -25,48 +25,24 @@ namespace xsimd using namespace types; // abs - template + template ::value && std::is_signed::value, void>::type> inline batch abs(batch const& self, requires_arch) noexcept { - XSIMD_IF_CONSTEXPR(std::is_integral_v && std::is_signed_v) + XSIMD_IF_CONSTEXPR(sizeof(T) == 1) + { + return wasm_i8x16_abs(self); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 2) { - XSIMD_IF_CONSTEXPR(sizeof(T) == 1) - { - return wasm_i8x16_abs(self); - } - else XSIMD_IF_CONSTEXPR(sizeof(T) == 2) - { - return wasm_i16x8_abs(self); - } - else XSIMD_IF_CONSTEXPR(sizeof(T) == 4) - { - return wasm_i32x4_abs(self); - } - else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) - { - return wasm_i64x2_abs(self); - } - else - { - assert(false && "unsupported arch/op combination"); - return {}; - } + return wasm_i16x8_abs(self); } - else XSIMD_IF_CONSTEXPR(std::is_floating_point_v) + else XSIMD_IF_CONSTEXPR(sizeof(T) == 4) { - XSIMD_IF_CONSTEXPR(sizeof(T) == 4) - { - return wasm_f32x4_abs(self); - } - else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) - { - return wasm_f64x2_abs(self); - } - else - { - assert(false && "unsupported arch/op combination"); - return {}; - } + return wasm_i32x4_abs(self); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) + { + return wasm_i64x2_abs(self); } else { @@ -75,6 +51,18 @@ namespace xsimd } } + template + inline batch abs(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f32x4_abs(self, other); + } + + template + inline batch abs(batch const& self, batch const& other, requires_arch) noexcept + { + return wasm_f64x2_abs(self, other); + } + // add template ::value, void>::type> inline batch add(batch const& self, batch const& other, requires_arch) noexcept @@ -149,104 +137,40 @@ namespace xsimd } // bitwise_and - template - inline batch bitwise_and(batch const& self, batch const& other, requires_arch) noexcept - { - return wasm_v128_and(self, other); - } - template - inline batch_bool bitwise_and(batch_bool const& self, batch_bool const& other, requires_arch) noexcept - { - return wasm_v128_and(self, other); - } - template ::value, void>::type> + template inline batch bitwise_and(batch const& self, batch const& other, requires_arch) noexcept { return wasm_v128_and(self, other); } - template ::value, void>::type> - inline batch_bool bitwise_and(batch_bool const& self, batch_bool const& other, requires_arch) noexcept - { - return wasm_v128_and(self, other); - } - template - batch inline bitwise_and(batch const& self, batch const& other, requires_arch) noexcept - { - return wasm_v128_and(self, other); - } - - template - inline batch_bool bitwise_and(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + template + inline batch_bool bitwise_and(batch_bool const& self, batch_bool const& other, requires_arch) noexcept { return wasm_v128_and(self, other); } // bitwise_andnot - template - inline batch bitwise_andnot(batch const& self, batch const& other, requires_arch) noexcept - { - return wasm_v128_andnot(other, self); - } - - template - inline batch_bool bitwise_andnot(batch_bool const& self, batch_bool const& other, requires_arch) noexcept - { - return wasm_v128_andnot(other, self); - } - template ::value, void>::type> + template inline batch bitwise_andnot(batch const& self, batch const& other, requires_arch) noexcept { - return wasm_v128_andnot(other, self); - } - template ::value, void>::type> - inline batch_bool bitwise_andnot(batch_bool const& self, batch_bool const& other, requires_arch) noexcept - { - return wasm_v128_andnot(other, self); + return wasm_v128_andnot(self, other); } - template - inline batch bitwise_andnot(batch const& self, batch const& other, requires_arch) noexcept - { - return wasm_v128_andnot(other, self); - } - - template - inline batch_bool bitwise_andnot(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + template + inline batch_bool bitwise_andnot(batch_bool const& self, batch_bool const& other, requires_arch) noexcept { - return wasm_v128_andnot(other, self); + return wasm_v128_andnot(self, other); } // bitwise_or - template - inline batch bitwise_or(batch const& self, batch const& other, requires_arch) noexcept - { - return wasm_v128_or(self, other); - } - template - inline batch_bool bitwise_or(batch_bool const& self, batch_bool const& other, requires_arch) noexcept - { - return wasm_v128_or(self, other); - } - template ::value, void>::type> + template inline batch bitwise_or(batch const& self, batch const& other, requires_arch) noexcept { return wasm_v128_or(self, other); } - template ::value, void>::type> - inline batch_bool bitwise_or(batch_bool const& self, batch_bool const& other, requires_arch) noexcept - { - return wasm_v128_or(self, other); - } - - template - inline batch bitwise_or(batch const& self, batch const& other, requires_arch) noexcept - { - return wasm_v128_or(self, other); - } - template - inline batch_bool bitwise_or(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + template + inline batch_bool bitwise_or(batch_bool const& self, batch_bool const& other, requires_arch) noexcept { return wasm_v128_or(self, other); } From 2e113c31076364020ccea784759abb1aa256e006 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Thu, 5 Oct 2023 14:06:53 +0530 Subject: [PATCH 46/55] Fixed implementation for bitwise_xor --- include/xsimd/arch/xsimd_wasm.hpp | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index 630a221ac..f8ed6f69e 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -176,36 +176,17 @@ namespace xsimd } // bitwise_xor - template - inline batch bitwise_xor(batch const& self, batch const& other, requires_arch) noexcept + template + inline batch bitwise_xor(batch const& self, batch const& other, requires_arch) noexcept { return wasm_v128_xor(self, other); } - template - inline batch_bool bitwise_xor(batch_bool const& self, batch_bool const& other, requires_arch) noexcept + + template + inline batch_bool bitwise_xor(batch_bool const& self, batch_bool const& other, requires_arch) noexcept { return wasm_v128_xor(self, other); } - template ::value, void>::type> - inline batch bitwise_xor(batch const& self, batch const& other, requires_arch) noexcept - { - return wasm_v128_or(self, other); - } - template - inline batch bitwise_xor(batch const& self, batch const& other, requires_arch) noexcept - { - return wasm_v128_or(self, other); - } - template - inline batch_bool bitwise_xor(batch_bool const& self, batch_bool const& other, requires_arch) noexcept - { - return wasm_v128_or(self, other); - } - template ::value, void>::type> - inline batch bitwise_xor(batch_bool const& self, batch_bool const& other, requires_arch) noexcept - { - return wasm_v128_or(self, other); - } // broadcast template From b269501d62993783863f7454f5515376f11f3ce4 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Thu, 5 Oct 2023 15:50:25 +0530 Subject: [PATCH 47/55] added support for bitwise_lshift operation --- include/xsimd/arch/xsimd_wasm.hpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index f8ed6f69e..b897fa0d9 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -175,6 +175,33 @@ namespace xsimd return wasm_v128_or(self, other); } + // bitwise_lshift + template ::value, void>::type> + inline batch bitwise_lshift(batch const& self, int32_t other, requires_arch) noexcept + { + XSIMD_IF_CONSTEXPR(sizeof(T) == 1) + { + return wasm_v128_and(wasm_i8x16_splat(0xFF << other), wasm_i32x4_shl(self, other)); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 2) + { + return wasm_i16x8_shl(self, other); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 4) + { + return wasm_i32x4_shl(self, other); + } + else XSIMD_IF_CONSTEXPR(sizeof(T) == 8) + { + return wasm_i64x2_shl(self, other); + } + else + { + assert(false && "unsupported arch/op combination"); + return {}; + } + } + // bitwise_xor template inline batch bitwise_xor(batch const& self, batch const& other, requires_arch) noexcept From a59068bbed107f6f348dc7e6c1aecf22b9c95e52 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Tue, 26 Sep 2023 14:01:08 +0530 Subject: [PATCH 48/55] Fixing some documentation issues --- docs/source/api/arch.rst | 2 +- docs/source/vectorized_code.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/api/arch.rst b/docs/source/api/arch.rst index 21434eb86..af854dd2d 100644 --- a/docs/source/api/arch.rst +++ b/docs/source/api/arch.rst @@ -8,7 +8,7 @@ Architecture manipulation ========================= xsimd provides an high level description of the instruction sets it manipulates. -The mentionned types are primarily used as template parameters for :ref:`batch +The mentioned types are primarily used as template parameters for :ref:`batch `, and when interacting with :cpp:func:`xsimd::dispatch()`. The best available architecture is available at compile time through diff --git a/docs/source/vectorized_code.rst b/docs/source/vectorized_code.rst index 01a032df8..18fcf8524 100644 --- a/docs/source/vectorized_code.rst +++ b/docs/source/vectorized_code.rst @@ -11,7 +11,7 @@ Assume that we have a simple function that computes the mean of two vectors, som .. literalinclude:: ../../test/doc/writing_vectorized_code.cpp -How can we used `xsimd` to take advantage of vectorization? +How can we use `xsimd` to take advantage of vectorization? Explicit use of an instruction set ---------------------------------- From a93865b1eded4ce5ba273e08969f6e7fcf3c7a0d Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 2 Oct 2023 16:56:45 +0200 Subject: [PATCH 49/55] Upgraded clang-format-action --- .github/workflows/style-check.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/style-check.yml b/.github/workflows/style-check.yml index f6c57bbfe..befbbe97c 100644 --- a/.github/workflows/style-check.yml +++ b/.github/workflows/style-check.yml @@ -10,9 +10,9 @@ jobs: steps: - uses: actions/checkout@v2 - name: Run clang-format style check for C/C++ programs. - uses: jidicula/clang-format-action@v4.2.0 + uses: jidicula/clang-format-action@v4.11.0 with: - clang-format-version: '13' + clang-format-version: '16' exclude-regex: 'doctest.h' inlining-check: runs-on: ubuntu-latest From fb5fa43dc1069972df27994917193f1ef90f80b5 Mon Sep 17 00:00:00 2001 From: Thorsten Beier Date: Fri, 6 Oct 2023 13:56:29 +0200 Subject: [PATCH 50/55] test emscripten-32wasm in the browser (#943) added emscripten-wasm32 tests --- .../xsimd/arch/generic/xsimd_generic_math.hpp | 4 ++ include/xsimd/math/xsimd_rem_pio2.hpp | 2 +- test/CMakeLists.txt | 62 ++++++++++++++----- test/main.cpp | 20 +++++- test/test_power.cpp | 3 +- test/test_wasm/browser_main.html | 2 +- test/test_wasm/test_wasm.sh | 31 ++++++++-- test/test_wasm/test_wasm_playwright.py | 9 ++- test/test_xsimd_api.cpp | 9 +++ 9 files changed, 113 insertions(+), 29 deletions(-) diff --git a/include/xsimd/arch/generic/xsimd_generic_math.hpp b/include/xsimd/arch/generic/xsimd_generic_math.hpp index 90d9c8a15..f9be00d6c 100644 --- a/include/xsimd/arch/generic/xsimd_generic_math.hpp +++ b/include/xsimd/arch/generic/xsimd_generic_math.hpp @@ -974,8 +974,12 @@ namespace xsimd template inline batch, A> polar(const batch& r, const batch& theta, requires_arch) noexcept { +#ifndef EMSCRIPTEN auto sincosTheta = sincos(theta); return { r * sincosTheta.second, r * sincosTheta.first }; +#else + return { r * cos(theta), r * sin(theta) }; +#endif } // fdim diff --git a/include/xsimd/math/xsimd_rem_pio2.hpp b/include/xsimd/math/xsimd_rem_pio2.hpp index 4e65b689c..05371ee52 100644 --- a/include/xsimd/math/xsimd_rem_pio2.hpp +++ b/include/xsimd/math/xsimd_rem_pio2.hpp @@ -52,7 +52,7 @@ namespace xsimd #define XSIMD_LITTLE_ENDIAN #endif #elif defined(_WIN32) -// We can safely assume that Windows is always little endian + // We can safely assume that Windows is always little endian #define XSIMD_LITTLE_ENDIAN #elif defined(i386) || defined(i486) || defined(intel) || defined(x86) || defined(i86pc) || defined(__alpha) || defined(__osf__) #define XSIMD_LITTLE_ENDIAN diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2ea234419..8fb658a41 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -112,10 +112,43 @@ if(NOT EMSCRIPTEN) endif() endif() - if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /MP /bigobj") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244 /wd4267 /wd4005 /wd4146 /wd4800") - set(CMAKE_EXE_LINKER_FLAGS /MANIFEST:NO) + if (ANDROID) + # Nothing to do here, we assume the cmake Android NDK toolchain sets the + # correct options for arm and neon. + elseif (CROSS_COMPILE_ARM) + # We're cross-compiling with clang++ on Azure Pipelines, this is all pretty specific and just for testing + set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) + set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) + set(CMAKE_THREAD_LIBS_INIT) + + set(CMAKE_SYSTEM_PROCESSOR arm) + set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabi) + set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabi) + + set(ARM_ARCH_DIRECTORY "arm-linux-gnueabi" CACHE STRING "ARM arch header dir") + set(ARM_GCC_VER "4.7.3" CACHE STRING "ARM GCC header dir") + include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/c++/${ARM_GCC_VER}/${ARM_ARCH_DIRECTORY}/) + include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/c++/${ARM_GCC_VER}/) + include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/) + if(NOT CMAKE_CXX_FLAGS MATCHES "-march") + message(STATUS "SETTING ARCH TO ${TARGET_ARCH}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TARGET_ARCH}") + endif() + if(ARM_ARCH_DIRECTORY MATCHES "arm-linux-gnueabi") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -mfloat-abi=softfp -target arm-linux-gnueabi") + else () + # delegating to gcc here + endif() + message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") + message(STATUS "CMAKE_CXX_LINK_EXECUTABLE: ${CMAKE_CXX_LINK_EXECUTABLE}") + elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^ppc64" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=${TARGET_ARCH} -mtune=${TARGET_ARCH}") + elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "riscv64") + # Nothing specific + elseif(NOT WIN32 AND NOT EMSCRIPTEN) + if(NOT CMAKE_CXX_FLAGS MATCHES "-march" AND NOT CMAKE_CXX_FLAGS MATCHES "-arch" AND NOT CMAKE_OSX_ARCHITECTURES) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TARGET_ARCH}") + endif() endif() if(CMAKE_CXX_COMPILER_ID MATCHES Clang AND MSVC AND WIN32) # We are using clang-cl @@ -196,15 +229,10 @@ if(NOT EMSCRIPTEN) endif() add_test(NAME test_xsimd COMMAND test_xsimd) - if (CROSS_COMPILE_ARM) - add_custom_target(xtest COMMAND qemu-arm -L /usr/arm-linux-gnueabi/ test_xsimd DEPENDS test_xsimd) - else() - add_custom_target(xtest COMMAND test_xsimd DEPENDS test_xsimd) - endif() - - if (XSIMD_ENABLE_WERROR) - target_compile_options(test_xsimd PRIVATE -Werror -Wall -DXSIMD_SKIP_ON_WERROR) - endif() +if(ENABLE_XTL_COMPLEX) +target_include_directories(test_xsimd PRIVATE ${xtl_INCLUDE_DIRS}) +endif() +add_test(NAME test_xsimd COMMAND test_xsimd) add_subdirectory(doc) else() @@ -221,5 +249,11 @@ else() # add flags embind, modularize - set_target_properties(test_xsimd_wasm PROPERTIES LINK_FLAGS "-s MODULARIZE=1 -s EXPORT_NAME=test_xsimd_wasm -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -lembind") +if(EMSCRIPTEN) + set_target_properties(test_xsimd PROPERTIES LINK_FLAGS "-s MODULARIZE=1 -s EXPORT_NAME=test_xsimd_wasm -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -lembind") + target_compile_options(test_xsimd + PUBLIC --std=c++14 + PUBLIC "SHELL: -msimd128" + PUBLIC "SHELL: -msse2" + ) endif() diff --git a/test/main.cpp b/test/main.cpp index 1b6d8915c..ef6681811 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -8,6 +8,24 @@ * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ - +#ifndef EMSCRIPTEN #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include "doctest/doctest.h" +#else + +#define DOCTEST_CONFIG_IMPLEMENT +#include "doctest/doctest.h" +#include + +int run_tests() +{ + doctest::Context context; + return context.run(); +} + +EMSCRIPTEN_BINDINGS(my_module) +{ + emscripten::function("run_tests", &run_tests); +} + +#endif \ No newline at end of file diff --git a/test/test_power.cpp b/test/test_power.cpp index dd0c762df..d63bdc153 100644 --- a/test/test_power.cpp +++ b/test/test_power.cpp @@ -82,7 +82,8 @@ struct power_test INFO("pow"); CHECK_EQ(diff, 0); -#ifdef __SSE__ +// use of undeclared identifier '_MM_SET_EXCEPTION_MASK for emscripten +#if defined(__SSE__) && !defined(EMSCRIPTEN) // Test with FE_INVALID... unsigned mask = _MM_GET_EXCEPTION_MASK(); _MM_SET_EXCEPTION_MASK(mask & ~_MM_MASK_INVALID); diff --git a/test/test_wasm/browser_main.html b/test/test_wasm/browser_main.html index 6f5e7e26a..72b63dd79 100644 --- a/test/test_wasm/browser_main.html +++ b/test/test_wasm/browser_main.html @@ -4,7 +4,7 @@ TEST_TITLE - + diff --git a/test/test_wasm/test_wasm.sh b/test/test_wasm/test_wasm.sh index 1199a1c37..b4770af6d 100755 --- a/test/test_wasm/test_wasm.sh +++ b/test/test_wasm/test_wasm.sh @@ -6,19 +6,38 @@ TEST_WASM_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd ) SRC_DIR=$TEST_WASM_DIR/../.. -git clone https://github.com/emscripten-core/emsdk -cd emsdk -./emsdk install latest -./emsdk activate latest -source ./emsdk_env.sh +# the emsdk dir can be passed as optional argument +# if not passed, it will be downloaded in the current dir +if [ $# -eq 0 ] +then + git clone https://github.com/emscripten-core/emsdk + cd emsdk + ./emsdk install latest + ./emsdk activate latest + source ./emsdk_env.sh +else + EMSCRIPTEN_DIR=$1 + source $EMSCRIPTEN_DIR/emsdk_env.sh +fi +export LDFLAGS="" +export CFLAGS="" +export CXXFLAGS="" + # build wasm mkdir -p build cd build -emcmake cmake -DBUILD_TESTS=ON $SRC_DIR +emcmake cmake \ + -DBUILD_TESTS=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_STANDARD=14 \ + -DDOWNLOAD_DOCTEST=ON \ + $SRC_DIR + emmake make -j4 cd .. +# run tests in browser python $TEST_WASM_DIR/test_wasm_playwright.py build/test \ No newline at end of file diff --git a/test/test_wasm/test_wasm_playwright.py b/test/test_wasm/test_wasm_playwright.py index f88db0079..381639757 100644 --- a/test/test_wasm/test_wasm_playwright.py +++ b/test/test_wasm/test_wasm_playwright.py @@ -65,10 +65,9 @@ async def handle_console(msg): page.on("console", handle_console) - # await page.goto(page_url) + status = await page.evaluate( f"""async () => {{ - let test_module = await test_xsimd_wasm(); console.log("\\n\\n************************************************************"); console.log("XSIMD WASM TESTS:"); @@ -87,7 +86,7 @@ async def handle_console(msg): return r; }} - }}""" + }}""" ) return_code = int(status) return return_code @@ -99,8 +98,8 @@ def main(build_dir): work_dir = Path(temp_dir) - shutil.copy(f"{build_dir}/test_xsimd_wasm.wasm", work_dir) - shutil.copy(f"{build_dir}/test_xsimd_wasm.js", work_dir) + shutil.copy(f"{build_dir}/test_xsimd.wasm", work_dir) + shutil.copy(f"{build_dir}/test_xsimd.js", work_dir) shutil.copy(f"{THIS_DIR}/browser_main.html", work_dir) port = find_free_port() diff --git a/test/test_xsimd_api.cpp b/test/test_xsimd_api.cpp index 84b4b0bfe..283f4232e 100644 --- a/test/test_xsimd_api.cpp +++ b/test/test_xsimd_api.cpp @@ -518,7 +518,11 @@ struct xsimd_api_float_types_functions void test_exp10() { value_type val(2); +#ifdef EMSCRIPTEN + CHECK_EQ(extract(xsimd::exp10(T(val))), doctest::Approx(std::pow(value_type(10), val))); +#else CHECK_EQ(extract(xsimd::exp10(T(val))), std::pow(value_type(10), val)); +#endif } void test_exp2() { @@ -661,7 +665,12 @@ struct xsimd_api_float_types_functions { value_type val0(3); value_type val1(4); +#ifndef EMSCRIPTEN CHECK_EQ(extract(xsimd::polar(T(val0), T(val1))), std::polar(val0, val1)); +#else + CHECK_EQ(std::real(extract(xsimd::polar(T(val0), T(val1)))), doctest::Approx(std::real(std::polar(val0, val1)))); + CHECK_EQ(std::imag(extract(xsimd::polar(T(val0), T(val1)))), doctest::Approx(std::imag(std::polar(val0, val1)))); +#endif } void test_pow() { From 7239b9a2c7e28b906102f860d2f6e3b8f9b31fc6 Mon Sep 17 00:00:00 2001 From: serge-sans-paille Date: Sun, 8 Oct 2023 20:56:43 +0200 Subject: [PATCH 51/55] Fix minor warnings They clutter the build output for no reason. --- examples/mandelbrot.cpp | 3 +-- test/doc/explicit_use_of_an_instruction_set.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/mandelbrot.cpp b/examples/mandelbrot.cpp index 02f5f6b16..323ae2702 100644 --- a/examples/mandelbrot.cpp +++ b/examples/mandelbrot.cpp @@ -274,8 +274,7 @@ struct run_archlist> int maxIters, std::vector>& buffer) { - using expand_type = int[]; - expand_type { (run_arch(bencher, x0, y0, x1, x1, width, height, maxIters, buffer), 0)... }; + (void)std::initializer_list { (run_arch(bencher, x0, y0, x1, x1, width, height, maxIters, buffer), 0)... }; } }; diff --git a/test/doc/explicit_use_of_an_instruction_set.cpp b/test/doc/explicit_use_of_an_instruction_set.cpp index 62c1b763d..ab3d0e7e7 100644 --- a/test/doc/explicit_use_of_an_instruction_set.cpp +++ b/test/doc/explicit_use_of_an_instruction_set.cpp @@ -3,7 +3,7 @@ namespace xs = xsimd; -int main(int argc, char* argv[]) +int main(int, char*[]) { xs::batch a = { 1.5, 2.5, 3.5, 4.5 }; xs::batch b = { 2.5, 3.5, 4.5, 5.5 }; From 4d4be50bfa674c346dda977905bb83d135892d46 Mon Sep 17 00:00:00 2001 From: serge-sans-paille Date: Sun, 8 Oct 2023 21:00:36 +0200 Subject: [PATCH 52/55] Add proper compile definition when XTL has been configured Basically so that -DENABLE_XTL_COMPLEX=On at configuration step implies -DXSIMD_ENABLE_XTL_COMPLEX=1 for the tests. Fix #942 --- CMakeLists.txt | 9 +++------ test/CMakeLists.txt | 4 +++- test/doc/CMakeLists.txt | 5 +++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d6adfa02..691597bbc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,19 +88,16 @@ target_include_directories(xsimd INTERFACE $ $) -if (ENABLE_XTL_COMPLEX) - target_compile_features(xsimd INTERFACE cxx_std_14) -else() - target_compile_features(xsimd INTERFACE cxx_std_11) -endif() - OPTION(ENABLE_XTL_COMPLEX "enables support for xcomplex defined in xtl" OFF) OPTION(BUILD_TESTS "xsimd test suite" OFF) if(ENABLE_XTL_COMPLEX) find_package(xtl 0.7.0 REQUIRED) + target_compile_features(xsimd INTERFACE cxx_std_14) target_compile_definitions(xsimd INTERFACE XSIMD_ENABLE_XTL_COMPLEX=1) target_link_libraries(xsimd INTERFACE xtl) +else() + target_compile_features(xsimd INTERFACE cxx_std_11) endif() if(BUILD_TESTS) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8fb658a41..7ebd7eb2f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -230,8 +230,10 @@ if(NOT EMSCRIPTEN) add_test(NAME test_xsimd COMMAND test_xsimd) if(ENABLE_XTL_COMPLEX) -target_include_directories(test_xsimd PRIVATE ${xtl_INCLUDE_DIRS}) + add_compile_definitions(XSIMD_ENABLE_XTL_COMPLEX=1) + target_include_directories(test_xsimd PRIVATE ${xtl_INCLUDE_DIRS}) endif() + add_test(NAME test_xsimd COMMAND test_xsimd) add_subdirectory(doc) diff --git a/test/doc/CMakeLists.txt b/test/doc/CMakeLists.txt index d5ea12f53..be3385df8 100644 --- a/test/doc/CMakeLists.txt +++ b/test/doc/CMakeLists.txt @@ -3,6 +3,11 @@ if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64" AND NOT CMAKE_OSX_ARCHITECTURES) +if(ENABLE_XTL_COMPLEX) + add_compile_definitions(XSIMD_ENABLE_XTL_COMPLEX=1) + include_directories(${xtl_INCLUDE_DIRS}) +endif() + add_library(test_doc_any_arch OBJECT explicit_use_of_an_instruction_set_mean_aligned.cpp explicit_use_of_an_instruction_set_mean_arch_independent.cpp From 982ca6212bb636d55bd86107f49182d4bc605004 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Mon, 9 Oct 2023 10:32:01 +0530 Subject: [PATCH 53/55] applied clang format --- include/xsimd/arch/xsimd_wasm.hpp | 3 +-- test/test_wasm/test_wasm.cpp | 15 +++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/include/xsimd/arch/xsimd_wasm.hpp b/include/xsimd/arch/xsimd_wasm.hpp index b897fa0d9..63d77ab19 100644 --- a/include/xsimd/arch/xsimd_wasm.hpp +++ b/include/xsimd/arch/xsimd_wasm.hpp @@ -421,8 +421,7 @@ namespace xsimd } template ::value, void>::type> - inline batch set(batch const&, requires_arch, T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, - T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15) noexcept + inline batch set(batch const&, requires_arch, T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15) noexcept { return wasm_i8x16_make(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15); } diff --git a/test/test_wasm/test_wasm.cpp b/test/test_wasm/test_wasm.cpp index 94e6b6c49..7db87e757 100644 --- a/test/test_wasm/test_wasm.cpp +++ b/test/test_wasm/test_wasm.cpp @@ -1,6 +1,6 @@ -#include -#include #include "xsimd/xsimd.hpp" +#include +#include #include #include // for reporting errors @@ -9,20 +9,23 @@ using namespace emscripten; int test_abs() { - xsimd::batch a(1, -2, 3, -4); + std::cout << "test_abs" << std::endl; auto ans = xsimd::abs(a); std::cout << ans << std::endl; return 0; } -int run_tests() { +int run_tests() +{ // todo add actual tests - if(auto ret = test_abs(); ret != 0) { + if (auto ret = test_abs(); ret != 0) + { return ret; } return 0; } -EMSCRIPTEN_BINDINGS(my_module) { +EMSCRIPTEN_BINDINGS(my_module) +{ emscripten::function("run_tests", &run_tests); } \ No newline at end of file From 1559359ba2d901b5a43d3b7f2021e01e7c9dc7c3 Mon Sep 17 00:00:00 2001 From: Anutosh Bhat <87052487+anutosh491@users.noreply.github.com> Date: Mon, 9 Oct 2023 12:15:03 +0530 Subject: [PATCH 54/55] Update CMakeLists.txt --- test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 07b61c9c3..bd0670e87 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -216,4 +216,4 @@ if(EMSCRIPTEN) PUBLIC "SHELL: -msimd128" PUBLIC "SHELL: -msse2" ) -endif() \ No newline at end of file +endif() From a729b2d4070e7d6736378ca39f160279e8840ed8 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Mon, 9 Oct 2023 10:38:17 +0530 Subject: [PATCH 55/55] fixed CMakeLists.txt --- test/CMakeLists.txt | 262 +++++++++++++++-------------------- test/test_wasm/test_wasm.cpp | 22 +-- 2 files changed, 111 insertions(+), 173 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7ebd7eb2f..bd0670e87 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -35,80 +35,39 @@ OPTION(XSIMD_ENABLE_WERROR "Turn on -Werror" OFF) -if(NOT EMSCRIPTEN) - ################ - # ARM SETTINGS # - ################ - - OPTION(CROSS_COMPILE_ARM "cross compile for ARM targets" OFF) - - # Note: to compile on ARM (or cross compile), you may need to add the following: - # -DTARGET_ARCH="armv8-a -mfpu=neon -mfloat-abi=softfp -target arm-linux-gnueabi" - set(TARGET_ARCH "native" CACHE STRING "Target architecture arguments") - - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Intel") - if (NOT WIN32 AND NOT ANDROID) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused-parameter -Wextra -Wreorder") - # Users may override the c++ standard: - if(NOT DEFINED CMAKE_CXX_STANDARD OR "${CMAKE_CXX_STANDARD}" STREQUAL "") - if (ENABLE_XTL_COMPLEX) - CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG) - if (NOT HAS_CPP14_FLAG) - message(FATAL_ERROR "Unsupported compiler -- xsimd requires C++14 support when xtl complex support is enabled") - endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") +################ +# ARM SETTINGS # +################ + +OPTION(CROSS_COMPILE_ARM "cross compile for ARM targets" OFF) + +# Note: to compile on ARM (or cross compile), you may need to add the following: +# -DTARGET_ARCH="armv8-a -mfpu=neon -mfloat-abi=softfp -target arm-linux-gnueabi" +set(TARGET_ARCH "native" CACHE STRING "Target architecture arguments") + +if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Intel") + if (NOT WIN32 AND NOT ANDROID) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused-parameter -Wextra -Wreorder") + # Users may override the c++ standard: + if(NOT DEFINED CMAKE_CXX_STANDARD OR "${CMAKE_CXX_STANDARD}" STREQUAL "") + if (ENABLE_XTL_COMPLEX) + CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG) + if (NOT HAS_CPP14_FLAG) + message(FATAL_ERROR "Unsupported compiler -- xsimd requires C++14 support when xtl complex support is enabled") + endif() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") + else() + CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_CPP11_FLAG) + if (NOT HAS_CPP11_FLAG) + message(FATAL_ERROR "Unsupported compiler -- xsimd requires C++11 support!") else() - CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_CPP11_FLAG) - if (NOT HAS_CPP11_FLAG) - message(FATAL_ERROR "Unsupported compiler -- xsimd requires C++11 support!") - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - endif() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") endif() endif() - - if (NOT CROSS_COMPILE_ARM) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fPIC") - endif() endif() - if (ANDROID) - # Nothing to do here, we assume the cmake Android NDK toolchain sets the - # correct options for arm and neon. - elseif (CROSS_COMPILE_ARM) - # We're cross-compiling with clang++ on Azure Pipelines, this is all pretty specific and just for testing - set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) - set(CMAKE_THREAD_LIBS_INIT) - - set(CMAKE_SYSTEM_PROCESSOR arm) - set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabi) - set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabi) - - set(ARM_ARCH_DIRECTORY "arm-linux-gnueabi" CACHE STRING "ARM arch header dir") - set(ARM_GCC_VER "4.7.3" CACHE STRING "ARM GCC header dir") - include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/c++/${ARM_GCC_VER}/${ARM_ARCH_DIRECTORY}/) - include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/c++/${ARM_GCC_VER}/) - include_directories(/usr/${ARM_ARCH_DIRECTORY}/include/) - if(NOT CMAKE_CXX_FLAGS MATCHES "-march") - message(STATUS "SETTING ARCH TO ${TARGET_ARCH}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TARGET_ARCH}") - endif() - if(ARM_ARCH_DIRECTORY MATCHES "arm-linux-gnueabi") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -mfloat-abi=softfp -target arm-linux-gnueabi") - else () - # delegating to gcc here - endif() - message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") - message(STATUS "CMAKE_CXX_LINK_EXECUTABLE: ${CMAKE_CXX_LINK_EXECUTABLE}") - elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^ppc64" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=${TARGET_ARCH} -mtune=${TARGET_ARCH}") - elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "riscv64") - # Nothing specific - elseif(NOT WIN32) - if(NOT CMAKE_CXX_FLAGS MATCHES "-march" AND NOT CMAKE_CXX_FLAGS MATCHES "-arch" AND NOT CMAKE_OSX_ARCHITECTURES) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TARGET_ARCH}") - endif() + if (NOT CROSS_COMPILE_ARM) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fPIC") endif() endif() @@ -150,84 +109,86 @@ if(NOT EMSCRIPTEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TARGET_ARCH}") endif() endif() +endif() - if(CMAKE_CXX_COMPILER_ID MATCHES Clang AND MSVC AND WIN32) # We are using clang-cl - add_compile_options(/EHsc /bigobj) - set(CMAKE_EXE_LINKER_FLAGS /MANIFEST:NO) - endif() - - set(XSIMD_TESTS - main.cpp - test_api.cpp - test_arch.cpp - test_basic_math.cpp - test_batch.cpp - test_batch_bool.cpp - test_batch_cast.cpp - test_batch_complex.cpp - test_batch_float.cpp - test_batch_int.cpp - test_bitwise_cast.cpp - test_batch_constant.cpp - test_batch_manip.cpp - test_complex_exponential.cpp - test_complex_hyperbolic.cpp - test_complex_power.cpp - test_complex_trigonometric.cpp - test_conversion.cpp - test_custom_default_arch.cpp - test_error_gamma.cpp - test_explicit_batch_instantiation.cpp - test_exponential.cpp - test_extract_pair.cpp - test_fp_manipulation.cpp - test_hyperbolic.cpp - test_load_store.cpp - test_memory.cpp - test_poly_evaluation.cpp - test_power.cpp - test_rounding.cpp - test_select.cpp - test_shuffle.cpp - test_sum.cpp - test_traits.cpp - test_trigonometric.cpp - test_xsimd_api.cpp - test_utils.hpp - ) +if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /MP /bigobj") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244 /wd4267 /wd4005 /wd4146 /wd4800") + set(CMAKE_EXE_LINKER_FLAGS /MANIFEST:NO) +endif() - if(NOT MSVC) - list(APPEND XSIMD_TESTS test_gnu_source.cpp) - endif() +if(CMAKE_CXX_COMPILER_ID MATCHES Clang AND MSVC AND WIN32) # We are using clang-cl + add_compile_options(/EHsc /bigobj) + set(CMAKE_EXE_LINKER_FLAGS /MANIFEST:NO) +endif() - add_executable(test_xsimd ${XSIMD_TESTS} ${XSIMD_HEADERS}) - target_include_directories(test_xsimd PRIVATE ${XSIMD_INCLUDE_DIR}) +set(XSIMD_TESTS + main.cpp + test_api.cpp + test_arch.cpp + test_basic_math.cpp + test_batch.cpp + test_batch_bool.cpp + test_batch_cast.cpp + test_batch_complex.cpp + test_batch_float.cpp + test_batch_int.cpp + test_bitwise_cast.cpp + test_batch_constant.cpp + test_batch_manip.cpp + test_complex_exponential.cpp + test_complex_hyperbolic.cpp + test_complex_power.cpp + test_complex_trigonometric.cpp + test_conversion.cpp + test_custom_default_arch.cpp + test_error_gamma.cpp + test_explicit_batch_instantiation.cpp + test_exponential.cpp + test_extract_pair.cpp + test_fp_manipulation.cpp + test_hyperbolic.cpp + test_load_store.cpp + test_memory.cpp + test_poly_evaluation.cpp + test_power.cpp + test_rounding.cpp + test_select.cpp + test_shuffle.cpp + test_sum.cpp + test_traits.cpp + test_trigonometric.cpp + test_xsimd_api.cpp + test_utils.hpp +) + +if(NOT MSVC) + list(APPEND XSIMD_TESTS test_gnu_source.cpp) +endif() - option(XSIMD_DOWNLOAD_DOCTEST OFF) - find_package(doctest QUIET) - if (doctest_FOUND) - set(DOCTEST_MINIMAL_VERSION 2.4.9) - if (doctest_VERSION VERSION_LESS DOCTEST_MINIMAL_VERSION) - message(FATAL_ERROR "Requires doctest >= ${DOCTEST_MINIMAL_VERSION}") - endif() - target_link_libraries(test_xsimd PRIVATE doctest::doctest) - elseif(DOWNLOAD_DOCTEST) - file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/doctest") - file(DOWNLOAD - "https://github.com/doctest/doctest/releases/download/v2.4.9/doctest.h" - "${CMAKE_CURRENT_BINARY_DIR}/doctest/doctest.h") - target_include_directories(test_xsimd PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) - else() - message(FATAL_ERROR " - Cannot find required doctest component. - Please either set CMAKE_PREFIX_PATH to the location of doctestConfig.cmake, - or set DOWNLOAD_DOCTEST=ON") - endif() +add_executable(test_xsimd ${XSIMD_TESTS} ${XSIMD_HEADERS}) +target_include_directories(test_xsimd PRIVATE ${XSIMD_INCLUDE_DIR}) - if(ENABLE_XTL_COMPLEX) - target_include_directories(test_xsimd PRIVATE ${xtl_INCLUDE_DIRS}) +option(XSIMD_DOWNLOAD_DOCTEST OFF) +find_package(doctest QUIET) +if (doctest_FOUND) + set(DOCTEST_MINIMAL_VERSION 2.4.9) + if (doctest_VERSION VERSION_LESS DOCTEST_MINIMAL_VERSION) + message(FATAL_ERROR "Requires doctest >= ${DOCTEST_MINIMAL_VERSION}") endif() - add_test(NAME test_xsimd COMMAND test_xsimd) + target_link_libraries(test_xsimd PRIVATE doctest::doctest) +elseif(DOWNLOAD_DOCTEST) + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/doctest") + file(DOWNLOAD + "https://github.com/doctest/doctest/releases/download/v2.4.9/doctest.h" + "${CMAKE_CURRENT_BINARY_DIR}/doctest/doctest.h") + target_include_directories(test_xsimd PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +else() + message(FATAL_ERROR " + Cannot find required doctest component. + Please either set CMAKE_PREFIX_PATH to the location of doctestConfig.cmake, + or set DOWNLOAD_DOCTEST=ON") +endif() if(ENABLE_XTL_COMPLEX) add_compile_definitions(XSIMD_ENABLE_XTL_COMPLEX=1) @@ -236,20 +197,17 @@ endif() add_test(NAME test_xsimd COMMAND test_xsimd) - add_subdirectory(doc) +if (CROSS_COMPILE_ARM) + add_custom_target(xtest COMMAND qemu-arm -L /usr/arm-linux-gnueabi/ test_xsimd DEPENDS test_xsimd) else() - add_executable(test_xsimd_wasm test_wasm/test_wasm.cpp) - target_include_directories(test_xsimd_wasm PRIVATE ${XSIMD_INCLUDE_DIR}) + add_custom_target(xtest COMMAND test_xsimd DEPENDS test_xsimd) +endif() - # set compile flgs -msimd128 +if (XSIMD_ENABLE_WERROR) + target_compile_options(test_xsimd PRIVATE -Werror -Wall -DXSIMD_SKIP_ON_WERROR) +endif() - target_compile_options(test_xsimd_wasm - PUBLIC --std=c++17 - PUBLIC "SHELL: -msimd128" - PUBLIC "SHELL: -msse2" - ) - # add flags embind, modularize - +add_subdirectory(doc) if(EMSCRIPTEN) set_target_properties(test_xsimd PROPERTIES LINK_FLAGS "-s MODULARIZE=1 -s EXPORT_NAME=test_xsimd_wasm -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -lembind") diff --git a/test/test_wasm/test_wasm.cpp b/test/test_wasm/test_wasm.cpp index d1ddfdd83..65ee6f89c 100644 --- a/test/test_wasm/test_wasm.cpp +++ b/test/test_wasm/test_wasm.cpp @@ -1,12 +1,6 @@ -<<<<<<< HEAD #include "xsimd/xsimd.hpp" #include #include -======= -#include -#include -#include "xsimd/xsimd.hpp" ->>>>>>> 1559359ba2d901b5a43d3b7f2021e01e7c9dc7c3 #include #include // for reporting errors @@ -15,37 +9,23 @@ using namespace emscripten; int test_abs() { -<<<<<<< HEAD std::cout << "test_abs" << std::endl; -======= - xsimd::batch a(1, -2, 3, -4); ->>>>>>> 1559359ba2d901b5a43d3b7f2021e01e7c9dc7c3 auto ans = xsimd::abs(a); std::cout << ans << std::endl; return 0; } -<<<<<<< HEAD int run_tests() { // todo add actual tests - if (auto ret = test_abs(); ret != 0) + if (auto ret = test_(); ret != 0) { -======= -int run_tests() { - // todo add actual tests - if(auto ret = test_abs(); ret != 0) { ->>>>>>> 1559359ba2d901b5a43d3b7f2021e01e7c9dc7c3 return ret; } return 0; } -<<<<<<< HEAD EMSCRIPTEN_BINDINGS(my_module) { -======= -EMSCRIPTEN_BINDINGS(my_module) { ->>>>>>> 1559359ba2d901b5a43d3b7f2021e01e7c9dc7c3 emscripten::function("run_tests", &run_tests); } \ No newline at end of file