mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
Compare commits
12 Commits
v4.0.0
...
riscv_develop
| Author | SHA1 | Date | |
|---|---|---|---|
| 11d9dbb7b7 | |||
| 896fb5d6a5 | |||
| e3d3b4b5a4 | |||
| 08e5943efc | |||
| 8aae14931d | |||
| 7068894be3 | |||
| ef3d1ac25f | |||
| 9292480a9b | |||
| 611ea97dbd | |||
| f249e7e128 | |||
| 44fddaa807 | |||
| be16e1ae04 |
@@ -0,0 +1,22 @@
|
|||||||
|
name: Ubuntu 24.04 CI (CXX 20, noexcept)
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
ubuntu-build:
|
||||||
|
if: >-
|
||||||
|
! contains(toJSON(github.event.commits.*.message), '[skip ci]') &&
|
||||||
|
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
cxx: [g++-13, clang++-16]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||||
|
- name: Prepare
|
||||||
|
run: cmake -DSIMDJSON_CXX_STANDARD=20 -DSIMDJSON_EXCEPTIONS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -B build
|
||||||
|
env:
|
||||||
|
CXX: ${{matrix.cxx}}
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build build -j=2
|
||||||
|
- name: Test
|
||||||
|
run: ctest --output-on-failure --test-dir build
|
||||||
@@ -88,6 +88,7 @@ objs
|
|||||||
# Build outputs
|
# Build outputs
|
||||||
/build*/
|
/build*/
|
||||||
/visual_studio/
|
/visual_studio/
|
||||||
|
/originbuild/
|
||||||
|
|
||||||
# Fuzzer outputs generated by instructions in fuzz/Fuzzing.md
|
# Fuzzer outputs generated by instructions in fuzz/Fuzzing.md
|
||||||
/corpus.zip
|
/corpus.zip
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14)
|
|||||||
project(
|
project(
|
||||||
simdjson
|
simdjson
|
||||||
# The version number is modified by tools/release.py
|
# The version number is modified by tools/release.py
|
||||||
VERSION 4.0.0
|
VERSION 4.0.2
|
||||||
DESCRIPTION "Parsing gigabytes of JSON per second"
|
DESCRIPTION "Parsing gigabytes of JSON per second"
|
||||||
HOMEPAGE_URL "https://simdjson.org/"
|
HOMEPAGE_URL "https://simdjson.org/"
|
||||||
LANGUAGES CXX C
|
LANGUAGES CXX C
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ PROJECT_NAME = simdjson
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = "4.0.0"
|
PROJECT_NUMBER = "4.0.2"
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ Godbolt
|
|||||||
Some users may want to browse code along with the compiled assembly. You want to check out the following lists of examples:
|
Some users may want to browse code along with the compiled assembly. You want to check out the following lists of examples:
|
||||||
* [simdjson examples with errors handled through exceptions](https://godbolt.org/z/7G5qE4sr9)
|
* [simdjson examples with errors handled through exceptions](https://godbolt.org/z/7G5qE4sr9)
|
||||||
* [simdjson examples with errors without exceptions](https://godbolt.org/z/e9dWb9E4v)
|
* [simdjson examples with errors without exceptions](https://godbolt.org/z/e9dWb9E4v)
|
||||||
|
* [C++26 reflection example](https://godbolt.org/z/xK5TGKdPb)
|
||||||
|
|
||||||
Performance results
|
Performance results
|
||||||
-------------------
|
-------------------
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
add_library(simdjson-internal-flags INTERFACE)
|
add_library(simdjson-internal-flags INTERFACE)
|
||||||
if(NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE)
|
if(NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE)
|
||||||
# We default to ON for all targets, so that we can use the library in shared libraries.
|
# We default to ON for all targets, so that we can use the library in shared libraries.
|
||||||
set_target_properties(simdjson-internal-flags PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
set_target_properties(simdjson-internal-flags PROPERTIES INTERFACE_POSITION_INDEPENDENT_CODE ON)
|
||||||
endif(NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE)
|
endif(NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE)
|
||||||
|
|
||||||
option(SIMDJSON_CHECK_EOF "Check for the end of the input buffer. The setting is unnecessary since we require padding of the inputs. You should expect tests to fail with this option turned on." OFF)
|
option(SIMDJSON_CHECK_EOF "Check for the end of the input buffer. The setting is unnecessary since we require padding of the inputs. You should expect tests to fail with this option turned on." OFF)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Implementation selection
|
# Implementation selection
|
||||||
#
|
#
|
||||||
set(SIMDJSON_ALL_IMPLEMENTATIONS fallback westmere haswell icelake arm64 ppc64)
|
set(SIMDJSON_ALL_IMPLEMENTATIONS fallback westmere haswell icelake arm64 ppc64 rvv)
|
||||||
|
|
||||||
set(
|
set(
|
||||||
SIMDJSON_IMPLEMENTATION ""
|
SIMDJSON_IMPLEMENTATION ""
|
||||||
@@ -15,7 +15,7 @@ set(
|
|||||||
SIMDJSON_EXCLUDE_IMPLEMENTATION ""
|
SIMDJSON_EXCLUDE_IMPLEMENTATION ""
|
||||||
CACHE STRING "\
|
CACHE STRING "\
|
||||||
Semicolon-separated list of implementations to exclude \
|
Semicolon-separated list of implementations to exclude \
|
||||||
(icelake/haswell/westmere/arm64/ppc64/fallback). By default, excludes any \
|
(icelake/haswell/westmere/arm64/ppc64/rvv/fallback). By default, excludes any \
|
||||||
implementations that are unsupported at compile time or cannot be selected at \
|
implementations that are unsupported at compile time or cannot be selected at \
|
||||||
runtime."
|
runtime."
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
#include "simdjson/lsx.h"
|
#include "simdjson/lsx.h"
|
||||||
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
|
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
|
||||||
#include "simdjson/lasx.h"
|
#include "simdjson/lasx.h"
|
||||||
|
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(rvv)
|
||||||
|
#include "simdjson/rvv.h"
|
||||||
#else
|
#else
|
||||||
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
|
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ namespace simdjson {
|
|||||||
namespace lsx {}
|
namespace lsx {}
|
||||||
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
|
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
|
||||||
namespace lasx {}
|
namespace lasx {}
|
||||||
|
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(rvv)
|
||||||
|
namespace rvv {}
|
||||||
#else
|
#else
|
||||||
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
|
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
#include "simdjson/lsx/implementation.h"
|
#include "simdjson/lsx/implementation.h"
|
||||||
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
|
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
|
||||||
#include "simdjson/lasx/implementation.h"
|
#include "simdjson/lasx/implementation.h"
|
||||||
|
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(rvv)
|
||||||
|
#include "simdjson/rvv/implementation.h"
|
||||||
#else
|
#else
|
||||||
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
|
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
#include "simdjson/lsx/ondemand.h"
|
#include "simdjson/lsx/ondemand.h"
|
||||||
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
|
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
|
||||||
#include "simdjson/lasx/ondemand.h"
|
#include "simdjson/lasx/ondemand.h"
|
||||||
|
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(rvv)
|
||||||
|
#include "simdjson/rvv/ondemand.h"
|
||||||
#else
|
#else
|
||||||
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
|
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <experimental/meta>
|
#include <meta>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|||||||
@@ -253,7 +253,9 @@ error_code tag_invoke(deserialize_tag, auto &val, T &out) noexcept(nothrow_deser
|
|||||||
using value_type = typename std::remove_cvref_t<T>::value_type;
|
using value_type = typename std::remove_cvref_t<T>::value_type;
|
||||||
|
|
||||||
// Check if the value is null
|
// Check if the value is null
|
||||||
if (val.is_null()) {
|
bool is_null_value;
|
||||||
|
SIMDJSON_TRY( val.is_null().get(is_null_value) );
|
||||||
|
if (is_null_value) {
|
||||||
out.reset(); // Set to nullopt
|
out.reset(); // Set to nullopt
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -361,7 +363,9 @@ error_code tag_invoke(deserialize_tag, simdjson_value &val, std::shared_ptr<T> &
|
|||||||
// Unique pointers
|
// Unique pointers
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<bool> &out) noexcept {
|
error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<bool> &out) noexcept {
|
||||||
if (val.is_null()) {
|
bool is_null_value;
|
||||||
|
SIMDJSON_TRY( val.is_null().get(is_null_value) );
|
||||||
|
if (is_null_value) {
|
||||||
out.reset();
|
out.reset();
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -374,7 +378,9 @@ error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<bool> &out) no
|
|||||||
}
|
}
|
||||||
|
|
||||||
error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<int64_t> &out) noexcept {
|
error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<int64_t> &out) noexcept {
|
||||||
if (val.is_null()) {
|
bool is_null_value;
|
||||||
|
SIMDJSON_TRY( val.is_null().get(is_null_value) );
|
||||||
|
if (is_null_value) {
|
||||||
out.reset();
|
out.reset();
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -387,7 +393,9 @@ error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<int64_t> &out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<uint64_t> &out) noexcept {
|
error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<uint64_t> &out) noexcept {
|
||||||
if (val.is_null()) {
|
bool is_null_value;
|
||||||
|
SIMDJSON_TRY( val.is_null().get(is_null_value) );
|
||||||
|
if (is_null_value) {
|
||||||
out.reset();
|
out.reset();
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -400,7 +408,9 @@ error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<uint64_t> &out
|
|||||||
}
|
}
|
||||||
|
|
||||||
error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<double> &out) noexcept {
|
error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<double> &out) noexcept {
|
||||||
if (val.is_null()) {
|
bool is_null_value;
|
||||||
|
SIMDJSON_TRY( val.is_null().get(is_null_value) );
|
||||||
|
if (is_null_value) {
|
||||||
out.reset();
|
out.reset();
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -413,7 +423,9 @@ error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<double> &out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<std::string_view> &out) noexcept {
|
error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<std::string_view> &out) noexcept {
|
||||||
if (val.is_null()) {
|
bool is_null_value;
|
||||||
|
SIMDJSON_TRY( val.is_null().get(is_null_value) );
|
||||||
|
if (is_null_value) {
|
||||||
out.reset();
|
out.reset();
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -430,7 +442,9 @@ error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<std::string_vi
|
|||||||
// Shared pointers
|
// Shared pointers
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<bool> &out) noexcept {
|
error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<bool> &out) noexcept {
|
||||||
if (val.is_null()) {
|
bool is_null_value;
|
||||||
|
SIMDJSON_TRY( val.is_null().get(is_null_value) );
|
||||||
|
if (is_null_value) {
|
||||||
out.reset();
|
out.reset();
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -443,7 +457,9 @@ error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<bool> &out) no
|
|||||||
}
|
}
|
||||||
|
|
||||||
error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<int64_t> &out) noexcept {
|
error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<int64_t> &out) noexcept {
|
||||||
if (val.is_null()) {
|
bool is_null_value;
|
||||||
|
SIMDJSON_TRY( val.is_null().get(is_null_value) );
|
||||||
|
if (is_null_value) {
|
||||||
out.reset();
|
out.reset();
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -456,7 +472,9 @@ error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<int64_t> &out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<uint64_t> &out) noexcept {
|
error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<uint64_t> &out) noexcept {
|
||||||
if (val.is_null()) {
|
bool is_null_value;
|
||||||
|
SIMDJSON_TRY( val.is_null().get(is_null_value) );
|
||||||
|
if (is_null_value) {
|
||||||
out.reset();
|
out.reset();
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -469,7 +487,9 @@ error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<uint64_t> &out
|
|||||||
}
|
}
|
||||||
|
|
||||||
error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<double> &out) noexcept {
|
error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<double> &out) noexcept {
|
||||||
if (val.is_null()) {
|
bool is_null_value;
|
||||||
|
SIMDJSON_TRY( val.is_null().get(is_null_value) );
|
||||||
|
if (is_null_value) {
|
||||||
out.reset();
|
out.reset();
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -482,7 +502,9 @@ error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<double> &out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<std::string_view> &out) noexcept {
|
error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<std::string_view> &out) noexcept {
|
||||||
if (val.is_null()) {
|
bool is_null_value;
|
||||||
|
SIMDJSON_TRY( val.is_null().get(is_null_value) );
|
||||||
|
if (is_null_value) {
|
||||||
out.reset();
|
out.reset();
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -504,7 +526,9 @@ error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<std::string_vi
|
|||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<std::string> &out) noexcept {
|
error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<std::string> &out) noexcept {
|
||||||
// Check if the value is null
|
// Check if the value is null
|
||||||
if (val.is_null()) {
|
bool is_null_value;
|
||||||
|
SIMDJSON_TRY( val.is_null().get(is_null_value) );
|
||||||
|
if (is_null_value) {
|
||||||
out.reset(); // Set to nullptr
|
out.reset(); // Set to nullptr
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -520,7 +544,9 @@ error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<std::string> &
|
|||||||
|
|
||||||
error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<std::string> &out) noexcept {
|
error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<std::string> &out) noexcept {
|
||||||
// Check if the value is null
|
// Check if the value is null
|
||||||
if (val.is_null()) {
|
bool is_null_value;
|
||||||
|
SIMDJSON_TRY( val.is_null().get(is_null_value) );
|
||||||
|
if (is_null_value) {
|
||||||
out.reset(); // Set to nullptr
|
out.reset(); // Set to nullptr
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -536,7 +562,9 @@ error_code tag_invoke(deserialize_tag, auto &val, std::shared_ptr<std::string> &
|
|||||||
|
|
||||||
error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<int> &out) noexcept {
|
error_code tag_invoke(deserialize_tag, auto &val, std::unique_ptr<int> &out) noexcept {
|
||||||
// Check if the value is null
|
// Check if the value is null
|
||||||
if (val.is_null()) {
|
bool is_null_value;
|
||||||
|
SIMDJSON_TRY( val.is_null().get(is_null_value) );
|
||||||
|
if (is_null_value) {
|
||||||
out.reset(); // Set to nullptr
|
out.reset(); // Set to nullptr
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,9 @@ public:
|
|||||||
using value_type = typename std::remove_cvref_t<T>::value_type;
|
using value_type = typename std::remove_cvref_t<T>::value_type;
|
||||||
|
|
||||||
// Check if the value is null
|
// Check if the value is null
|
||||||
if (is_null()) {
|
bool is_null_value;
|
||||||
|
SIMDJSON_TRY( is_null().get(is_null_value) );
|
||||||
|
if (is_null_value) {
|
||||||
out.reset(); // Set to nullopt
|
out.reset(); // Set to nullopt
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#define SIMDJSON_IMPLEMENTATION_ID_westmere 6
|
#define SIMDJSON_IMPLEMENTATION_ID_westmere 6
|
||||||
#define SIMDJSON_IMPLEMENTATION_ID_lsx 7
|
#define SIMDJSON_IMPLEMENTATION_ID_lsx 7
|
||||||
#define SIMDJSON_IMPLEMENTATION_ID_lasx 8
|
#define SIMDJSON_IMPLEMENTATION_ID_lasx 8
|
||||||
|
#define SIMDJSON_IMPLEMENTATION_ID_rvv 9
|
||||||
|
|
||||||
#define SIMDJSON_IMPLEMENTATION_ID_FOR(IMPL) SIMDJSON_CAT(SIMDJSON_IMPLEMENTATION_ID_, IMPL)
|
#define SIMDJSON_IMPLEMENTATION_ID_FOR(IMPL) SIMDJSON_CAT(SIMDJSON_IMPLEMENTATION_ID_, IMPL)
|
||||||
#define SIMDJSON_IMPLEMENTATION_ID SIMDJSON_IMPLEMENTATION_ID_FOR(SIMDJSON_IMPLEMENTATION)
|
#define SIMDJSON_IMPLEMENTATION_ID SIMDJSON_IMPLEMENTATION_ID_FOR(SIMDJSON_IMPLEMENTATION)
|
||||||
@@ -23,6 +24,15 @@
|
|||||||
// in which we include them.
|
// in which we include them.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_IMPLEMENTATION_RVV
|
||||||
|
#define SIMDJSON_IMPLEMENTATION_RVV (SIMDJSON_IS_RISCV64 && SIMDJSON_IS_RVV)
|
||||||
|
#endif
|
||||||
|
#if SIMDJSON_IMPLEMENTATION_RVV && SIMDJSON_IS_RISCV64 && SIMDJSON_IS_RVV
|
||||||
|
#define SIMDJSON_CAN_ALWAYS_RUN_RVV 1
|
||||||
|
#else
|
||||||
|
#define SIMDJSON_CAN_ALWAYS_RUN_RVV 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SIMDJSON_IMPLEMENTATION_ARM64
|
#ifndef SIMDJSON_IMPLEMENTATION_ARM64
|
||||||
#define SIMDJSON_IMPLEMENTATION_ARM64 (SIMDJSON_IS_ARM64)
|
#define SIMDJSON_IMPLEMENTATION_ARM64 (SIMDJSON_IS_ARM64)
|
||||||
#endif
|
#endif
|
||||||
@@ -128,7 +138,7 @@
|
|||||||
|
|
||||||
// Default Fallback to on unless a builtin implementation has already been selected.
|
// Default Fallback to on unless a builtin implementation has already been selected.
|
||||||
#ifndef SIMDJSON_IMPLEMENTATION_FALLBACK
|
#ifndef SIMDJSON_IMPLEMENTATION_FALLBACK
|
||||||
#if SIMDJSON_CAN_ALWAYS_RUN_ARM64 || SIMDJSON_CAN_ALWAYS_RUN_ICELAKE || SIMDJSON_CAN_ALWAYS_RUN_HASWELL || SIMDJSON_CAN_ALWAYS_RUN_WESTMERE || SIMDJSON_CAN_ALWAYS_RUN_PPC64 || SIMDJSON_CAN_ALWAYS_RUN_LSX || SIMDJSON_CAN_ALWAYS_RUN_LASX
|
#if SIMDJSON_CAN_ALWAYS_RUN_ARM64 || SIMDJSON_CAN_ALWAYS_RUN_ICELAKE || SIMDJSON_CAN_ALWAYS_RUN_HASWELL || SIMDJSON_CAN_ALWAYS_RUN_WESTMERE || SIMDJSON_CAN_ALWAYS_RUN_PPC64 || SIMDJSON_CAN_ALWAYS_RUN_LSX || SIMDJSON_CAN_ALWAYS_RUN_LASX || SIMDJSON_CAN_ALWAYS_RUN_RVV
|
||||||
// if anything at all except fallback can always run, then disable fallback.
|
// if anything at all except fallback can always run, then disable fallback.
|
||||||
#define SIMDJSON_IMPLEMENTATION_FALLBACK 0
|
#define SIMDJSON_IMPLEMENTATION_FALLBACK 0
|
||||||
#else
|
#else
|
||||||
@@ -154,6 +164,8 @@
|
|||||||
#define SIMDJSON_BUILTIN_IMPLEMENTATION lsx
|
#define SIMDJSON_BUILTIN_IMPLEMENTATION lsx
|
||||||
#elif SIMDJSON_CAN_ALWAYS_RUN_LASX
|
#elif SIMDJSON_CAN_ALWAYS_RUN_LASX
|
||||||
#define SIMDJSON_BUILTIN_IMPLEMENTATION lasx
|
#define SIMDJSON_BUILTIN_IMPLEMENTATION lasx
|
||||||
|
#elif SIMDJSON_CAN_ALWAYS_RUN_RVV
|
||||||
|
#define SIMDJSON_BUILTIN_IMPLEMENTATION rvv
|
||||||
#elif SIMDJSON_CAN_ALWAYS_RUN_FALLBACK
|
#elif SIMDJSON_CAN_ALWAYS_RUN_FALLBACK
|
||||||
#define SIMDJSON_BUILTIN_IMPLEMENTATION fallback
|
#define SIMDJSON_BUILTIN_IMPLEMENTATION fallback
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef SIMDJSON_RVV_H
|
||||||
|
#define SIMDJSON_RVV_H
|
||||||
|
|
||||||
|
#include "simdjson/rvv/begin.h"
|
||||||
|
#include "simdjson/generic/amalgamated.h"
|
||||||
|
#include "simdjson/rvv/end.h"
|
||||||
|
|
||||||
|
#endif // SIMDJSON_RVV_H
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef SIMDJSON_RVV_BASE_H
|
||||||
|
#define SIMDJSON_RVV_BASE_H
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#include "simdjson/base.h"
|
||||||
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
namespace simdjson {
|
||||||
|
namespace rvv {
|
||||||
|
|
||||||
|
class implementation;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
namespace simd {
|
||||||
|
template <typename T> struct simd8;
|
||||||
|
template <typename T> struct simd8x64;
|
||||||
|
} // namespace simd
|
||||||
|
} // unnamed namespace
|
||||||
|
} // namespace rvv
|
||||||
|
} // namespace simdjson
|
||||||
|
#endif // SIMDJSON_RVV_BASE_H
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#define SIMDJSON_IMPLEMENTATION rvv
|
||||||
|
|
||||||
|
// include RVV intrinsics and definitions
|
||||||
|
#include <riscv_vector.h>
|
||||||
|
#include "simdjson/rvv/base.h"
|
||||||
|
#include "simdjson/rvv/intrinsics.h"
|
||||||
|
#include "simdjson/rvv/bitmanipulation.h"
|
||||||
|
#include "simdjson/rvv/bitmask.h"
|
||||||
|
#include "simdjson/rvv/numberparsing_defs.h"
|
||||||
|
#include "simdjson/rvv/simd.h"
|
||||||
|
#include "simdjson/rvv/stringparsing_defs.h"
|
||||||
|
|
||||||
|
#define SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT 1
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#ifndef SIMDJSON_RVV_BITMANIPULATION_H
|
||||||
|
#define SIMDJSON_RVV_BITMANIPULATION_H
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#include "simdjson/rvv/base.h"
|
||||||
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
|
namespace simdjson {
|
||||||
|
namespace rvv {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
/* result might be undefined when input_num is zero */
|
||||||
|
simdjson_inline int leading_zeroes(uint64_t input_num) {
|
||||||
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
|
unsigned long leading_zero = 0;
|
||||||
|
if (_BitScanReverse64(&leading_zero, input_num))
|
||||||
|
return (int)(63 - leading_zero);
|
||||||
|
else
|
||||||
|
return 64;
|
||||||
|
#else
|
||||||
|
return __builtin_clzll(input_num);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) {
|
||||||
|
return input_num & (input_num - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
simdjson_inline int count_ones(uint64_t input_num) {
|
||||||
|
return __builtin_popcountll(input_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline simdjson::internal::value128 full_multiplication(uint64_t a, uint64_t b) {
|
||||||
|
#if __SIZEOF_INT128__
|
||||||
|
unsigned __int128 p = (unsigned __int128)a * b;
|
||||||
|
return { (uint64_t)p, (uint64_t)(p >> 64) };
|
||||||
|
#else
|
||||||
|
uint64_t lo = a * b;
|
||||||
|
uint64_t a0 = (uint32_t)a, a1 = a >> 32;
|
||||||
|
uint64_t b0 = (uint32_t)b, b1 = b >> 32;
|
||||||
|
uint64_t mid1 = a0 * b1;
|
||||||
|
uint64_t mid2 = a1 * b0;
|
||||||
|
uint64_t carry = ((mid1 & 0xFFFFFFFF) + (mid2 & 0xFFFFFFFF) + (lo >> 32)) >> 32;
|
||||||
|
uint64_t hi = a1 * b1 + (mid1 >> 32) + (mid2 >> 32) + carry;
|
||||||
|
return { lo, hi };
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // unnamed namespace
|
||||||
|
} // namespace rvv
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
|
#endif // SIMDJSON_RVV_BITMANIPULATION_H
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#include "simdjson/rvv/base.h"
|
||||||
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
|
#undef SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT
|
||||||
|
#undef SIMDJSON_IMPLEMENTATION
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef SIMDJSON_RVV_IMPLEMENTATION_H
|
||||||
|
#define SIMDJSON_RVV_IMPLEMENTATION_H
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#define SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#include "simdjson/base.h"
|
||||||
|
#include "simdjson/implementation.h"
|
||||||
|
#include "simdjson/internal/instruction_set.h"
|
||||||
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
|
namespace simdjson {
|
||||||
|
namespace rvv {
|
||||||
|
|
||||||
|
class implementation final: public simdjson::implementation {
|
||||||
|
public:
|
||||||
|
simdjson_inline implementation() : simdjson::implementation("rvv", "RISC-V Vector Extension", 0) {}
|
||||||
|
simdjson_warn_unused error_code create_dom_parser_implementation(
|
||||||
|
size_t capacity,
|
||||||
|
size_t max_depth,
|
||||||
|
std::unique_ptr<internal::dom_parser_implementation>& dst
|
||||||
|
) const noexcept final;
|
||||||
|
simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final;
|
||||||
|
simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace rvv
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
|
#endif // SIMDJSON_RVV_IMPLEMENTATION_H
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef SIMDJSON_RVV_INTRINSICS_H
|
||||||
|
#define SIMDJSON_RVV_INTRINSICS_H
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#include "simdjson/rvv/base.h"
|
||||||
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#endif // SIMDJSON_RVV_INTRINSICS_H
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#ifndef SIMDJSON_RVV_ONDEMAND_H
|
||||||
|
#define SIMDJSON_RVV_ONDEMAND_H
|
||||||
|
|
||||||
|
#include "simdjson/rvv/begin.h"
|
||||||
|
#include "simdjson/generic/ondemand/amalgamated.h"
|
||||||
|
#include "simdjson/rvv/end.h"
|
||||||
|
|
||||||
|
#endif // SIMDJSON_RVV_ONDEMAND_H
|
||||||
|
|
||||||
@@ -0,0 +1,298 @@
|
|||||||
|
#ifndef SIMDJSON_RVV_SIMD_H
|
||||||
|
#define SIMDJSON_RVV_SIMD_H
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#include "simdjson/rvv/base.h"
|
||||||
|
#include "simdjson/rvv/intrinsics.h"
|
||||||
|
#include "simdjson/internal/simdprune_tables.h"
|
||||||
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
|
namespace simdjson {
|
||||||
|
namespace rvv {
|
||||||
|
namespace {
|
||||||
|
namespace simd {
|
||||||
|
|
||||||
|
// ---------- 128-bit fixed vectors ----------
|
||||||
|
using vuint8x16 = vuint8m1_t __attribute__((riscv_rvv_vector_bits(128)));
|
||||||
|
using vint8x16 = vint8m1_t __attribute__((riscv_rvv_vector_bits(128)));
|
||||||
|
using vbool8x16 = vbool8_t;
|
||||||
|
static constexpr size_t fixed_vl = 16;
|
||||||
|
|
||||||
|
// ---------- forward ----------
|
||||||
|
template<typename T> struct simd8;
|
||||||
|
template<typename T> struct simd8x64;
|
||||||
|
|
||||||
|
// ---------- base<Child> ----------
|
||||||
|
template<typename Child>
|
||||||
|
struct base {
|
||||||
|
vuint8x16 value{};
|
||||||
|
base() = default;
|
||||||
|
base(vuint8x16 v) : value(v) {}
|
||||||
|
operator vuint8x16() const { return value; }
|
||||||
|
operator vuint8x16&() { return value; }
|
||||||
|
|
||||||
|
simdjson_inline Child operator|(const Child o) const { return __riscv_vor_vv_u8m1(value, o, fixed_vl); }
|
||||||
|
simdjson_inline Child operator&(const Child o) const { return __riscv_vand_vv_u8m1(value, o, fixed_vl); }
|
||||||
|
simdjson_inline Child operator^(const Child o) const { return __riscv_vxor_vv_u8m1(value, o, fixed_vl); }
|
||||||
|
simdjson_inline Child bit_andnot(const Child o) const { return __riscv_vandn_vv_u8m1(value, o, fixed_vl); }
|
||||||
|
|
||||||
|
simdjson_inline Child& operator|=(const Child o) { auto* c = static_cast<Child*>(this); *c = *c | o; return *c; }
|
||||||
|
simdjson_inline Child& operator&=(const Child o) { auto* c = static_cast<Child*>(this); *c = *c & o; return *c; }
|
||||||
|
simdjson_inline Child& operator^=(const Child o) { auto* c = static_cast<Child*>(this); *c = *c ^ o; return *c; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------- base8<T,Mask> ----------
|
||||||
|
template<typename T, typename Mask = simd8<bool>>
|
||||||
|
struct base8 : base<simd8<T>> {
|
||||||
|
using base<simd8<T>>::value;
|
||||||
|
using bitmask_t = uint32_t;
|
||||||
|
base8() = default;
|
||||||
|
base8(vuint8x16 v) : base<simd8<T>>(v) {}
|
||||||
|
|
||||||
|
friend simdjson_inline Mask operator==(const simd8<T> a, const simd8<T> b) {
|
||||||
|
return simd8<bool>(__riscv_vmseq_vv_u8m1_b8(a, b, fixed_vl));
|
||||||
|
}
|
||||||
|
template<int N=1>
|
||||||
|
simdjson_inline simd8<T> prev(const simd8<T> prev_chunk) const {
|
||||||
|
return __riscv_vslideup_vx_u8m1(prev_chunk, value, fixed_vl - N, 2 * fixed_vl);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------- simd8<bool> ----------
|
||||||
|
template<>
|
||||||
|
struct simd8<bool> : base8<bool> {
|
||||||
|
simd8() = default;
|
||||||
|
simd8(vuint8x16 v) : base8(v) {}
|
||||||
|
simd8(vbool8_t m) : base8(__riscv_vmerge_vvm_u8m1(
|
||||||
|
__riscv_vmv_v_x_u8m1(0, fixed_vl),
|
||||||
|
__riscv_vmv_v_x_u8m1(0xFFu, fixed_vl),
|
||||||
|
m, fixed_vl)) {}
|
||||||
|
|
||||||
|
static simdjson_inline simd8<bool> splat(bool b) {
|
||||||
|
return __riscv_vmv_v_x_u8m1(uint8_t(-b), fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8(bool b) : simd8(splat(b)) {}
|
||||||
|
|
||||||
|
simdjson_inline int to_bitmask() const {
|
||||||
|
vuint8x16 bits = __riscv_vand_vx_u8m1(value, 0xFFu, fixed_vl);
|
||||||
|
vbool8x16 mask = __riscv_vmseq_vx_u8m1_b8(bits, 0xFFu, fixed_vl);
|
||||||
|
return __riscv_vcpop_m_b8(mask, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline bool any_bits_set_anywhere() const {
|
||||||
|
return to_bitmask() != 0;
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<bool> operator~() const { return *this ^ splat(true); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------- simd8<uint8_t> ----------
|
||||||
|
template<>
|
||||||
|
struct simd8<uint8_t> : base8<uint8_t> {
|
||||||
|
simd8() = default;
|
||||||
|
simd8(vuint8x16 v) : base8(v) {}
|
||||||
|
static simdjson_inline simd8<uint8_t> splat(uint8_t v) {
|
||||||
|
return __riscv_vmv_v_x_u8m1(v, fixed_vl);
|
||||||
|
}
|
||||||
|
static simdjson_inline simd8<uint8_t> zero() { return splat(0); }
|
||||||
|
static simdjson_inline simd8<uint8_t> load(const uint8_t* p) {
|
||||||
|
return __riscv_vle8_v_u8m1(p, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8(uint8_t v) : simd8(splat(v)) {}
|
||||||
|
simdjson_inline simd8(const uint8_t* p) : simd8(load(p)) {}
|
||||||
|
|
||||||
|
simdjson_inline void store(uint8_t* p) const {
|
||||||
|
__riscv_vse8_v_u8m1(p, value, fixed_vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
simdjson_inline simd8<uint8_t> operator+(const simd8<uint8_t> o) const {
|
||||||
|
return __riscv_vadd_vv_u8m1(value, o, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<uint8_t> operator-(const simd8<uint8_t> o) const {
|
||||||
|
return __riscv_vsub_vv_u8m1(value, o, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<uint8_t>& operator+=(const simd8<uint8_t> o) {
|
||||||
|
*this = *this + o; return *this;
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<uint8_t>& operator-=(const simd8<uint8_t> o) {
|
||||||
|
*this = *this - o; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
simdjson_inline simd8<uint8_t> saturating_add(const simd8<uint8_t> o) const {
|
||||||
|
return __riscv_vsaddu_vv_u8m1(value, o, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<uint8_t> saturating_sub(const simd8<uint8_t> o) const {
|
||||||
|
return __riscv_vssubu_vv_u8m1(value, o, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<uint8_t> max_val(const simd8<uint8_t> o) const {
|
||||||
|
return __riscv_vmaxu_vv_u8m1(value, o, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<uint8_t> min_val(const simd8<uint8_t> o) const {
|
||||||
|
return __riscv_vminu_vv_u8m1(value, o, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<bool> operator>(const simd8<uint8_t> o) const {
|
||||||
|
return simd8<bool>(__riscv_vmsgtu_vv_u8m1_b8(value, o, fixed_vl));
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<bool> operator<(const simd8<uint8_t> o) const {
|
||||||
|
return simd8<bool>(__riscv_vmsgtu_vv_u8m1_b8(o, value, fixed_vl));
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<bool> operator<=(const simd8<uint8_t> o) const {
|
||||||
|
return simd8<bool>(__riscv_vmsleu_vv_u8m1_b8(value, o, fixed_vl));
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<bool> operator>=(const simd8<uint8_t> o) const {
|
||||||
|
return simd8<bool>(__riscv_vmsleu_vv_u8m1_b8(o, value, fixed_vl));
|
||||||
|
}
|
||||||
|
template<int NS>
|
||||||
|
simdjson_inline simd8<uint8_t> shr() const {
|
||||||
|
return __riscv_vsrl_vx_u8m1(value, NS, fixed_vl);
|
||||||
|
}
|
||||||
|
template<int NS>
|
||||||
|
simdjson_inline simd8<uint8_t> shl() const {
|
||||||
|
return __riscv_vsll_vx_u8m1(value, NS, fixed_vl);
|
||||||
|
}
|
||||||
|
template <typename Ret>
|
||||||
|
simdjson_inline simd8<Ret> lookup_16(const Ret* table) const {
|
||||||
|
alignas(16) uint8_t idx[16];
|
||||||
|
store(idx);
|
||||||
|
alignas(16) Ret res[16];
|
||||||
|
for (int i = 0; i < 16; ++i) res[i] = table[idx[i]];
|
||||||
|
return simd8<Ret>::load(reinterpret_cast<const Ret*>(res));
|
||||||
|
}
|
||||||
|
simdjson_inline void compress(uint16_t mask, uint8_t* out) const {
|
||||||
|
alignas(16) uint8_t tmp[16];
|
||||||
|
store(tmp);
|
||||||
|
for (int i = 0, j = 0; i < 16; ++i)
|
||||||
|
if (mask & (1u << i)) out[j++] = tmp[i];
|
||||||
|
}
|
||||||
|
simdjson_inline uint64_t gt_bits(uint8_t max_value) const {
|
||||||
|
return (*this > splat(max_value)).to_bitmask();
|
||||||
|
}
|
||||||
|
simdjson_inline uint64_t gt_bits(const simd8<uint8_t>& max_vec) const {
|
||||||
|
return (*this > max_vec).to_bitmask();
|
||||||
|
}
|
||||||
|
simdjson_inline bool any_bits_set_anywhere() const {
|
||||||
|
return (*this > zero()).any_bits_set_anywhere();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------- simd8<int8_t> ----------
|
||||||
|
template<>
|
||||||
|
struct simd8<int8_t> {
|
||||||
|
vint8x16 value{};
|
||||||
|
simd8() = default;
|
||||||
|
simd8(vint8x16 v) : value(v) {}
|
||||||
|
static simdjson_inline simd8<int8_t> splat(int8_t v) {
|
||||||
|
return __riscv_vmv_v_x_i8m1(v, fixed_vl);
|
||||||
|
}
|
||||||
|
static simdjson_inline simd8<int8_t> zero() { return splat(0); }
|
||||||
|
static simdjson_inline simd8<int8_t> load(const int8_t* p) {
|
||||||
|
return __riscv_vle8_v_i8m1(p, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8(int8_t v) : simd8(splat(v)) {}
|
||||||
|
simdjson_inline simd8(const int8_t* p) : simd8(load(p)) {}
|
||||||
|
|
||||||
|
simdjson_inline void store(int8_t* p) const {
|
||||||
|
__riscv_vse8_v_i8m1(p, value, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<int8_t> operator+(const simd8<int8_t> o) const {
|
||||||
|
return __riscv_vadd_vv_i8m1(value, o.value, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<int8_t> operator-(const simd8<int8_t> o) const {
|
||||||
|
return __riscv_vsub_vv_i8m1(value, o.value, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<int8_t> max_val(const simd8<int8_t> o) const {
|
||||||
|
return __riscv_vmax_vv_i8m1(value, o.value, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<int8_t> min_val(const simd8<int8_t> o) const {
|
||||||
|
return __riscv_vmin_vv_i8m1(value, o.value, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<bool> operator>(const simd8<int8_t> o) const {
|
||||||
|
return simd8<bool>(__riscv_vmsgt_vv_i8m1_b8(value, o.value, fixed_vl));
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<bool> operator<(const simd8<int8_t> o) const {
|
||||||
|
return simd8<bool>(__riscv_vmsgt_vv_i8m1_b8(o.value, value, fixed_vl));
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<bool> operator==(const simd8<int8_t> o) const {
|
||||||
|
return simd8<bool>(__riscv_vmseq_vv_i8m1_b8(value, o.value, fixed_vl));
|
||||||
|
}
|
||||||
|
template<int N=1>
|
||||||
|
simdjson_inline simd8<int8_t> prev(const simd8<int8_t> prev_chunk) const {
|
||||||
|
return __riscv_vslideup_vx_i8m1(prev_chunk.value, value, fixed_vl - N, 2 * fixed_vl);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------- simd8x64<T> ----------
|
||||||
|
template<typename T>
|
||||||
|
struct simd8x64 {
|
||||||
|
static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>);
|
||||||
|
static_assert(NUM_CHUNKS == 4, "RVV kernel uses 4×128-bit chunks per 64-byte block.");
|
||||||
|
const simd8<T> chunks[4];
|
||||||
|
|
||||||
|
simd8x64(const simd8x64&) = delete;
|
||||||
|
simd8x64& operator=(const simd8x64&) = delete;
|
||||||
|
simd8x64() = delete;
|
||||||
|
|
||||||
|
simdjson_inline simd8x64(const simd8<T> c0, const simd8<T> c1,
|
||||||
|
const simd8<T> c2, const simd8<T> c3)
|
||||||
|
: chunks{c0, c1, c2, c3} {}
|
||||||
|
simdjson_inline simd8x64(const T* ptr)
|
||||||
|
: chunks{simd8<T>::load(ptr),
|
||||||
|
simd8<T>::load(ptr + 16),
|
||||||
|
simd8<T>::load(ptr + 32),
|
||||||
|
simd8<T>::load(ptr + 48)} {}
|
||||||
|
|
||||||
|
simdjson_inline void store(T* ptr) const {
|
||||||
|
chunks[0].store(ptr);
|
||||||
|
chunks[1].store(ptr + 16);
|
||||||
|
chunks[2].store(ptr + 32);
|
||||||
|
chunks[3].store(ptr + 48);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<T> reduce_or() const {
|
||||||
|
return (chunks[0] | chunks[1]) | (chunks[2] | chunks[3]);
|
||||||
|
}
|
||||||
|
simdjson_inline uint64_t to_bitmask() const {
|
||||||
|
uint16_t m0 = uint16_t(chunks[0].to_bitmask());
|
||||||
|
uint16_t m1 = uint16_t(chunks[1].to_bitmask());
|
||||||
|
uint16_t m2 = uint16_t(chunks[2].to_bitmask());
|
||||||
|
uint16_t m3 = uint16_t(chunks[3].to_bitmask());
|
||||||
|
return m0 | (uint64_t(m1) << 16) | (uint64_t(m2) << 32) | (uint64_t(m3) << 48);
|
||||||
|
}
|
||||||
|
simdjson_inline uint64_t eq(const T m) const {
|
||||||
|
simd8<T> spl = simd8<T>::splat(m);
|
||||||
|
return simd8x64<bool>(chunks[0] == spl,
|
||||||
|
chunks[1] == spl,
|
||||||
|
chunks[2] == spl,
|
||||||
|
chunks[3] == spl).to_bitmask();
|
||||||
|
}
|
||||||
|
simdjson_inline uint64_t lteq(const T m) const {
|
||||||
|
simd8<T> spl = simd8<T>::splat(m);
|
||||||
|
return simd8x64<bool>(chunks[0] <= spl,
|
||||||
|
chunks[1] <= spl,
|
||||||
|
chunks[2] <= spl,
|
||||||
|
chunks[3] <= spl).to_bitmask();
|
||||||
|
}
|
||||||
|
simdjson_inline uint64_t compress(uint64_t mask, T* out) const {
|
||||||
|
using internal::BitsSetTable256mul2;
|
||||||
|
uint32_t m0 = uint32_t(mask);
|
||||||
|
uint32_t m1 = uint32_t(mask >> 16);
|
||||||
|
uint32_t m2 = uint32_t(mask >> 32);
|
||||||
|
uint32_t m3 = uint32_t(mask >> 48);
|
||||||
|
|
||||||
|
int pop0 = BitsSetTable256mul2[uint8_t(m0)];
|
||||||
|
int pop1 = BitsSetTable256mul2[uint8_t(m1)];
|
||||||
|
int pop2 = BitsSetTable256mul2[uint8_t(m2)];
|
||||||
|
|
||||||
|
chunks[0].compress(uint16_t(m0), out);
|
||||||
|
chunks[1].compress(uint16_t(m1), out + 16 - pop0);
|
||||||
|
chunks[2].compress(uint16_t(m2), out + 32 - pop0 - pop1);
|
||||||
|
chunks[3].compress(uint16_t(m3), out + 48 - pop0 - pop1 - pop2);
|
||||||
|
return 64 - __builtin_popcountll(mask);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace simd
|
||||||
|
} // unnamed namespace
|
||||||
|
} // namespace rvv
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
|
|
||||||
|
#endif // SIMDJSON_RVV_SIMD_H
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
#define SIMDJSON_SIMDJSON_VERSION_H
|
#define SIMDJSON_SIMDJSON_VERSION_H
|
||||||
|
|
||||||
/** The version of simdjson being used (major.minor.revision) */
|
/** The version of simdjson being used (major.minor.revision) */
|
||||||
#define SIMDJSON_VERSION "4.0.0"
|
#define SIMDJSON_VERSION "4.0.2"
|
||||||
|
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
enum {
|
enum {
|
||||||
@@ -19,7 +19,7 @@ enum {
|
|||||||
/**
|
/**
|
||||||
* The revision (major.minor.REVISION) of simdjson being used.
|
* The revision (major.minor.REVISION) of simdjson being used.
|
||||||
*/
|
*/
|
||||||
SIMDJSON_VERSION_REVISION = 0
|
SIMDJSON_VERSION_REVISION = 2
|
||||||
};
|
};
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ else:
|
|||||||
RelativeRoot = str # Literal['src','include'] # Literal not supported in Python 3.7 (CI)
|
RelativeRoot = str # Literal['src','include'] # Literal not supported in Python 3.7 (CI)
|
||||||
RELATIVE_ROOTS: List[RelativeRoot] = ['src', 'include' ]
|
RELATIVE_ROOTS: List[RelativeRoot] = ['src', 'include' ]
|
||||||
Implementation = str # Literal['arm64', 'fallback', 'haswell', 'icelake', 'ppc64', 'westmere', 'lsx', 'lasx'] # Literal not supported in Python 3.7 (CI)
|
Implementation = str # Literal['arm64', 'fallback', 'haswell', 'icelake', 'ppc64', 'westmere', 'lsx', 'lasx'] # Literal not supported in Python 3.7 (CI)
|
||||||
IMPLEMENTATIONS: List[Implementation] = [ 'arm64', 'haswell', 'icelake', 'lasx', 'lsx', 'ppc64', 'westmere', 'fallback' ]
|
IMPLEMENTATIONS: List[Implementation] = [ 'arm64', 'haswell', 'icelake', 'lasx', 'lsx', 'ppc64', 'westmere', 'fallback', 'rvv' ]
|
||||||
GENERIC_INCLUDE = "simdjson/generic"
|
GENERIC_INCLUDE = "simdjson/generic"
|
||||||
GENERIC_SRC = "generic"
|
GENERIC_SRC = "generic"
|
||||||
BUILTIN = "simdjson/builtin"
|
BUILTIN = "simdjson/builtin"
|
||||||
@@ -358,7 +358,6 @@ class Amalgamator:
|
|||||||
self.include_stack.append(file)
|
self.include_stack.append(file)
|
||||||
|
|
||||||
file.processed = False
|
file.processed = False
|
||||||
|
|
||||||
self.write(f"/* begin file {self.file_to_str(file)} */")
|
self.write(f"/* begin file {self.file_to_str(file)} */")
|
||||||
|
|
||||||
if file == BUILTIN_BEGIN_H:
|
if file == BUILTIN_BEGIN_H:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* auto-generated on 2025-09-09 18:44:21 -0400. version 4.0.0 Do not edit! */
|
/* auto-generated on 2025-09-14 09:01:41 -0600. version 4.0.2 Do not edit! */
|
||||||
/* including simdjson.cpp: */
|
/* including simdjson.cpp: */
|
||||||
/* begin file simdjson.cpp */
|
/* begin file simdjson.cpp */
|
||||||
#define SIMDJSON_SRC_SIMDJSON_CPP
|
#define SIMDJSON_SRC_SIMDJSON_CPP
|
||||||
|
|||||||
+371
-131
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -21,6 +21,19 @@ bool implementation::supported_by_runtime_system() const {
|
|||||||
|
|
||||||
#define SIMDJSON_CONDITIONAL_INCLUDE
|
#define SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
|
#if SIMDJSON_IMPLEMENTATION_RVV
|
||||||
|
#include <simdjson/rvv/implementation.h>
|
||||||
|
namespace simdjson {
|
||||||
|
namespace internal {
|
||||||
|
static const rvv::implementation* get_rvv_singleton() {
|
||||||
|
static const rvv::implementation rvv_singleton{};
|
||||||
|
return &rvv_singleton;
|
||||||
|
}
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace simdjson
|
||||||
|
#endif // SIMDJSON_IMPLEMENTATION_RVV
|
||||||
|
|
||||||
|
|
||||||
#if SIMDJSON_IMPLEMENTATION_ARM64
|
#if SIMDJSON_IMPLEMENTATION_ARM64
|
||||||
#include <simdjson/arm64/implementation.h>
|
#include <simdjson/arm64/implementation.h>
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
@@ -130,6 +143,7 @@ namespace internal {
|
|||||||
+ SIMDJSON_IMPLEMENTATION_HASWELL + SIMDJSON_IMPLEMENTATION_WESTMERE \
|
+ SIMDJSON_IMPLEMENTATION_HASWELL + SIMDJSON_IMPLEMENTATION_WESTMERE \
|
||||||
+ SIMDJSON_IMPLEMENTATION_ARM64 + SIMDJSON_IMPLEMENTATION_PPC64 \
|
+ SIMDJSON_IMPLEMENTATION_ARM64 + SIMDJSON_IMPLEMENTATION_PPC64 \
|
||||||
+ SIMDJSON_IMPLEMENTATION_LSX + SIMDJSON_IMPLEMENTATION_LASX \
|
+ SIMDJSON_IMPLEMENTATION_LSX + SIMDJSON_IMPLEMENTATION_LASX \
|
||||||
|
+ SIMDJSON_IMPLEMENTATION_RVV \
|
||||||
+ SIMDJSON_IMPLEMENTATION_FALLBACK == 1)
|
+ SIMDJSON_IMPLEMENTATION_FALLBACK == 1)
|
||||||
|
|
||||||
#if SIMDJSON_SINGLE_IMPLEMENTATION
|
#if SIMDJSON_SINGLE_IMPLEMENTATION
|
||||||
@@ -156,6 +170,9 @@ namespace internal {
|
|||||||
#if SIMDJSON_IMPLEMENTATION_LASX
|
#if SIMDJSON_IMPLEMENTATION_LASX
|
||||||
get_lasx_singleton();
|
get_lasx_singleton();
|
||||||
#endif
|
#endif
|
||||||
|
#if SIMDJSON_IMPLEMENTATION_RVV
|
||||||
|
get_rvv_singleton();
|
||||||
|
#endif
|
||||||
#if SIMDJSON_IMPLEMENTATION_FALLBACK
|
#if SIMDJSON_IMPLEMENTATION_FALLBACK
|
||||||
get_fallback_singleton();
|
get_fallback_singleton();
|
||||||
#endif
|
#endif
|
||||||
@@ -216,6 +233,9 @@ static const std::initializer_list<const implementation *>& get_available_implem
|
|||||||
#if SIMDJSON_IMPLEMENTATION_LASX
|
#if SIMDJSON_IMPLEMENTATION_LASX
|
||||||
get_lasx_singleton(),
|
get_lasx_singleton(),
|
||||||
#endif
|
#endif
|
||||||
|
#if SIMDJSON_IMPLEMENTATION_RVV
|
||||||
|
get_rvv_singleton(),
|
||||||
|
#endif
|
||||||
#if SIMDJSON_IMPLEMENTATION_FALLBACK
|
#if SIMDJSON_IMPLEMENTATION_FALLBACK
|
||||||
get_fallback_singleton(),
|
get_fallback_singleton(),
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef SIMDJSON_SRC_RVV_CPP
|
||||||
|
#define SIMDJSON_SRC_RVV_CPP
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#include <base.h>
|
||||||
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
|
|
||||||
|
#include <simdjson/rvv.h>
|
||||||
|
#include <simdjson/rvv/implementation.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace simdjson {
|
||||||
|
namespace rvv {
|
||||||
|
error_code implementation::create_dom_parser_implementation(
|
||||||
|
size_t, size_t,
|
||||||
|
std::unique_ptr<simdjson::internal::dom_parser_implementation>&) const noexcept {
|
||||||
|
return error_code::UNSUPPORTED_ARCHITECTURE;
|
||||||
|
}
|
||||||
|
} // namespace rvv
|
||||||
|
} // namespace simdjson
|
||||||
|
#endif // SIMDJSON_SRC_RVV_CPP
|
||||||
@@ -41,6 +41,9 @@ SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS
|
|||||||
#if SIMDJSON_IMPLEMENTATION_LASX
|
#if SIMDJSON_IMPLEMENTATION_LASX
|
||||||
#include <lasx.cpp>
|
#include <lasx.cpp>
|
||||||
#endif
|
#endif
|
||||||
|
#if SIMDJSON_IMPLEMENTATION_RVV
|
||||||
|
#include <rvv.cpp>
|
||||||
|
#endif
|
||||||
#if SIMDJSON_IMPLEMENTATION_FALLBACK
|
#if SIMDJSON_IMPLEMENTATION_FALLBACK
|
||||||
#include <fallback.cpp>
|
#include <fallback.cpp>
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
using namespace simdjson;
|
using namespace simdjson;
|
||||||
namespace ranges_test {
|
namespace ranges_test {
|
||||||
|
#if SIMDJSON_EXCEPTIONS
|
||||||
bool printout() {
|
bool printout() {
|
||||||
TEST_START();
|
TEST_START();
|
||||||
auto cars_json = R"( [
|
auto cars_json = R"( [
|
||||||
@@ -43,6 +43,7 @@ namespace ranges_test {
|
|||||||
ASSERT_TRUE(std::ranges::equal(cars, expected));
|
ASSERT_TRUE(std::ranges::equal(cars, expected));
|
||||||
TEST_SUCCEED();
|
TEST_SUCCEED();
|
||||||
}
|
}
|
||||||
|
#endif // SIMDJSON_EXCEPTIONS
|
||||||
|
|
||||||
bool run() {
|
bool run() {
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user