stringzillas-cuda 4.2.2__tar.gz → 4.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {stringzillas_cuda-4.2.2/stringzillas_cuda.egg-info → stringzillas_cuda-4.3.0}/PKG-INFO +13 -6
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/README.md +11 -4
- stringzillas_cuda-4.3.0/VERSION +1 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/c/stringzilla.c +84 -11
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzilla/compare.h +2 -2
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzilla/find.h +70 -37
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzilla/hash.h +241 -191
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzilla/intersect.h +2 -2
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzilla/memory.h +7 -6
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzilla/stringzilla.h +4 -2
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzilla/stringzilla.hpp +839 -200
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzilla/types.h +93 -32
- stringzillas_cuda-4.3.0/include/stringzilla/utf8.h +1554 -0
- stringzillas_cuda-4.3.0/include/stringzilla/utf8_unpack.h +1079 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/python/stringzilla.c +590 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/scripts/test_stringzilla.py +345 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0/stringzillas_cuda.egg-info}/PKG-INFO +13 -6
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/stringzillas_cuda.egg-info/SOURCES.txt +2 -0
- stringzillas_cuda-4.3.0/stringzillas_cuda.egg-info/requires.txt +1 -0
- stringzillas_cuda-4.2.2/VERSION +0 -1
- stringzillas_cuda-4.2.2/stringzillas_cuda.egg-info/requires.txt +0 -1
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/LICENSE +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/MANIFEST.in +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/SZ_TARGET.env +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/build_backend.py +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/c/stringzillas.cpp +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/c/stringzillas.cu +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/c/stringzillas.cuh +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/cli/__init__.py +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/cli/split.py +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/cli/wc.py +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/fork_union/include/fork_union.h +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/fork_union/include/fork_union.hpp +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzilla/module.modulemap +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzilla/small_string.h +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzilla/sort.h +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzilla/types.hpp +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzillas/fingerprints.cuh +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzillas/fingerprints.hpp +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzillas/similarities.cuh +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzillas/similarities.hpp +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzillas/stringzillas.h +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzillas/types.cuh +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/include/stringzillas/types.hpp +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/pyproject.toml +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/python/stringzillas.c +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/scripts/test_stringzillas.py +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/setup.cfg +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/setup.py +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/stringzillas_cuda.egg-info/dependency_links.txt +0 -0
- {stringzillas_cuda-4.2.2 → stringzillas_cuda-4.3.0}/stringzillas_cuda.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stringzillas-cuda
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3.0
|
|
4
4
|
Summary: Search, hash, sort, fingerprint, and fuzzy-match strings faster via SWAR, SIMD, and CUDA on Nvidia GPUs
|
|
5
5
|
Home-page: https://github.com/ashvardanian/StringZilla
|
|
6
6
|
Author: Ash Vardanian
|
|
@@ -30,7 +30,7 @@ Classifier: Topic :: Text Processing :: Indexing
|
|
|
30
30
|
Requires-Python: >=3.8
|
|
31
31
|
Description-Content-Type: text/markdown
|
|
32
32
|
License-File: LICENSE
|
|
33
|
-
Requires-Dist: stringzilla==4.
|
|
33
|
+
Requires-Dist: stringzilla==4.3.0
|
|
34
34
|
Dynamic: author
|
|
35
35
|
Dynamic: author-email
|
|
36
36
|
Dynamic: classifier
|
|
@@ -1134,10 +1134,10 @@ Similar to GCC, StringZilla is 32 bytes in size, and similar to Clang it can fit
|
|
|
1134
1134
|
Our layout might be preferential, if you want to avoid branches.
|
|
1135
1135
|
If you use a different compiler, you may want to check its SSO buffer size with a [simple Gist](https://gist.github.com/ashvardanian/c197f15732d9855c4e070797adf17b21).
|
|
1136
1136
|
|
|
1137
|
-
|
|
|
1138
|
-
|
|
|
1139
|
-
| `sizeof
|
|
1140
|
-
|
|
|
1137
|
+
| | `libstdc++` in GCC 13 | `libc++` in Clang 17 | StringZilla |
|
|
1138
|
+
| :-------------- | ---------------------: | -------------------: | ----------: |
|
|
1139
|
+
| String `sizeof` | 32 | 24 | 32 |
|
|
1140
|
+
| Inner Capacity | 15 | __22__ | __22__ |
|
|
1141
1141
|
|
|
1142
1142
|
This design has been since ported to many high-level programming languages.
|
|
1143
1143
|
Swift, for example, [can store 15 bytes](https://developer.apple.com/documentation/swift/substring/withutf8(_:)#discussion) in the `String` instance itself.
|
|
@@ -1530,6 +1530,13 @@ __`SZ_USE_CUDA`, `SZ_USE_KEPLER`, `SZ_USE_HOPPER`__:
|
|
|
1530
1530
|
> One can explicitly disable certain families of PTX instructions for compatibility purposes.
|
|
1531
1531
|
> Default values are inferred at compile time depending on compiler support (for dynamic dispatch) and the target architecture (for static dispatch).
|
|
1532
1532
|
|
|
1533
|
+
__`SZ_ENFORCE_SVE_OVER_NEON`__:
|
|
1534
|
+
|
|
1535
|
+
> SVE and SVE2 are expected to supersede NEON on ARM architectures.
|
|
1536
|
+
> Still, oftentimes the equivalent SVE kernels are slower due to equally small register files and higher complexity of the instructions.
|
|
1537
|
+
> By default, when both SVE and NEON are available, SVE is used selectively only for the algorithms that benefit from it.
|
|
1538
|
+
> If you want to enforce SVE usage everywhere, define this flag.
|
|
1539
|
+
|
|
1533
1540
|
__`SZ_DYNAMIC_DISPATCH`__:
|
|
1534
1541
|
|
|
1535
1542
|
> By default, StringZilla is a header-only library.
|
|
@@ -1089,10 +1089,10 @@ Similar to GCC, StringZilla is 32 bytes in size, and similar to Clang it can fit
|
|
|
1089
1089
|
Our layout might be preferential, if you want to avoid branches.
|
|
1090
1090
|
If you use a different compiler, you may want to check its SSO buffer size with a [simple Gist](https://gist.github.com/ashvardanian/c197f15732d9855c4e070797adf17b21).
|
|
1091
1091
|
|
|
1092
|
-
|
|
|
1093
|
-
|
|
|
1094
|
-
| `sizeof
|
|
1095
|
-
|
|
|
1092
|
+
| | `libstdc++` in GCC 13 | `libc++` in Clang 17 | StringZilla |
|
|
1093
|
+
| :-------------- | ---------------------: | -------------------: | ----------: |
|
|
1094
|
+
| String `sizeof` | 32 | 24 | 32 |
|
|
1095
|
+
| Inner Capacity | 15 | __22__ | __22__ |
|
|
1096
1096
|
|
|
1097
1097
|
This design has been since ported to many high-level programming languages.
|
|
1098
1098
|
Swift, for example, [can store 15 bytes](https://developer.apple.com/documentation/swift/substring/withutf8(_:)#discussion) in the `String` instance itself.
|
|
@@ -1485,6 +1485,13 @@ __`SZ_USE_CUDA`, `SZ_USE_KEPLER`, `SZ_USE_HOPPER`__:
|
|
|
1485
1485
|
> One can explicitly disable certain families of PTX instructions for compatibility purposes.
|
|
1486
1486
|
> Default values are inferred at compile time depending on compiler support (for dynamic dispatch) and the target architecture (for static dispatch).
|
|
1487
1487
|
|
|
1488
|
+
__`SZ_ENFORCE_SVE_OVER_NEON`__:
|
|
1489
|
+
|
|
1490
|
+
> SVE and SVE2 are expected to supersede NEON on ARM architectures.
|
|
1491
|
+
> Still, oftentimes the equivalent SVE kernels are slower due to equally small register files and higher complexity of the instructions.
|
|
1492
|
+
> By default, when both SVE and NEON are available, SVE is used selectively only for the algorithms that benefit from it.
|
|
1493
|
+
> If you want to enforce SVE usage everywhere, define this flag.
|
|
1494
|
+
|
|
1488
1495
|
__`SZ_DYNAMIC_DISPATCH`__:
|
|
1489
1496
|
|
|
1490
1497
|
> By default, StringZilla is a header-only library.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4.3.0
|
|
@@ -58,6 +58,13 @@ typedef struct sz_implementations_t {
|
|
|
58
58
|
sz_find_byteset_t find_byteset;
|
|
59
59
|
sz_find_byteset_t rfind_byteset;
|
|
60
60
|
|
|
61
|
+
sz_utf8_count_t utf8_count;
|
|
62
|
+
sz_utf8_find_nth_t utf8_find_nth;
|
|
63
|
+
sz_utf8_unpack_chunk_t utf8_unpack_chunk;
|
|
64
|
+
sz_utf8_find_boundary_t utf8_find_newline;
|
|
65
|
+
sz_utf8_find_boundary_t utf8_find_whitespace;
|
|
66
|
+
sz_utf8_case_fold_t utf8_case_fold;
|
|
67
|
+
|
|
61
68
|
sz_sequence_argsort_t sequence_argsort;
|
|
62
69
|
sz_sequence_intersect_t sequence_intersect;
|
|
63
70
|
sz_pgrams_sort_t pgrams_sort;
|
|
@@ -99,6 +106,13 @@ static void sz_dispatch_table_update_implementation_(sz_capability_t caps) {
|
|
|
99
106
|
impl->find_byteset = sz_find_byteset_serial;
|
|
100
107
|
impl->rfind_byteset = sz_rfind_byteset_serial;
|
|
101
108
|
|
|
109
|
+
impl->utf8_count = sz_utf8_count_serial;
|
|
110
|
+
impl->utf8_find_nth = sz_utf8_find_nth_serial;
|
|
111
|
+
impl->utf8_unpack_chunk = sz_utf8_unpack_chunk_serial;
|
|
112
|
+
impl->utf8_find_newline = sz_utf8_find_newline_serial;
|
|
113
|
+
impl->utf8_find_whitespace = sz_utf8_find_whitespace_serial;
|
|
114
|
+
impl->utf8_case_fold = sz_utf8_case_fold_serial;
|
|
115
|
+
|
|
102
116
|
impl->sequence_argsort = sz_sequence_argsort_serial;
|
|
103
117
|
impl->sequence_intersect = sz_sequence_intersect_serial;
|
|
104
118
|
impl->pgrams_sort = sz_pgrams_sort_serial;
|
|
@@ -147,6 +161,13 @@ static void sz_dispatch_table_update_implementation_(sz_capability_t caps) {
|
|
|
147
161
|
impl->rfind = sz_rfind_haswell;
|
|
148
162
|
impl->find_byteset = sz_find_byteset_haswell;
|
|
149
163
|
impl->rfind_byteset = sz_rfind_byteset_haswell;
|
|
164
|
+
|
|
165
|
+
impl->utf8_count = sz_utf8_count_haswell;
|
|
166
|
+
impl->utf8_find_nth = sz_utf8_find_nth_haswell;
|
|
167
|
+
impl->utf8_unpack_chunk = sz_utf8_unpack_chunk_haswell;
|
|
168
|
+
impl->utf8_find_newline = sz_utf8_find_newline_haswell;
|
|
169
|
+
impl->utf8_find_whitespace = sz_utf8_find_whitespace_haswell;
|
|
170
|
+
impl->utf8_case_fold = sz_utf8_case_fold_haswell;
|
|
150
171
|
}
|
|
151
172
|
#endif
|
|
152
173
|
|
|
@@ -181,6 +202,13 @@ static void sz_dispatch_table_update_implementation_(sz_capability_t caps) {
|
|
|
181
202
|
impl->find_byteset = sz_find_byteset_ice;
|
|
182
203
|
impl->rfind_byteset = sz_rfind_byteset_ice;
|
|
183
204
|
|
|
205
|
+
impl->utf8_count = sz_utf8_count_ice;
|
|
206
|
+
impl->utf8_find_nth = sz_utf8_find_nth_ice;
|
|
207
|
+
impl->utf8_unpack_chunk = sz_utf8_unpack_chunk_ice;
|
|
208
|
+
impl->utf8_find_newline = sz_utf8_find_newline_ice;
|
|
209
|
+
impl->utf8_find_whitespace = sz_utf8_find_whitespace_ice;
|
|
210
|
+
impl->utf8_case_fold = sz_utf8_case_fold_ice;
|
|
211
|
+
|
|
184
212
|
impl->lookup = sz_lookup_ice;
|
|
185
213
|
|
|
186
214
|
impl->bytesum = sz_bytesum_ice;
|
|
@@ -215,6 +243,13 @@ static void sz_dispatch_table_update_implementation_(sz_capability_t caps) {
|
|
|
215
243
|
impl->rfind_byte = sz_rfind_byte_neon;
|
|
216
244
|
impl->find_byteset = sz_find_byteset_neon;
|
|
217
245
|
impl->rfind_byteset = sz_rfind_byteset_neon;
|
|
246
|
+
|
|
247
|
+
impl->utf8_count = sz_utf8_count_neon;
|
|
248
|
+
impl->utf8_find_nth = sz_utf8_find_nth_neon;
|
|
249
|
+
impl->utf8_unpack_chunk = sz_utf8_unpack_chunk_neon;
|
|
250
|
+
impl->utf8_find_newline = sz_utf8_find_newline_neon;
|
|
251
|
+
impl->utf8_find_whitespace = sz_utf8_find_whitespace_neon;
|
|
252
|
+
impl->utf8_case_fold = sz_utf8_case_fold_neon;
|
|
218
253
|
}
|
|
219
254
|
#endif
|
|
220
255
|
|
|
@@ -238,16 +273,19 @@ static void sz_dispatch_table_update_implementation_(sz_capability_t caps) {
|
|
|
238
273
|
|
|
239
274
|
#if SZ_USE_SVE
|
|
240
275
|
if (caps & sz_cap_sve_k) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
276
|
+
if (SZ_ENFORCE_SVE_OVER_NEON) {
|
|
277
|
+
impl->equal = sz_equal_sve;
|
|
278
|
+
impl->order = sz_order_sve;
|
|
279
|
+
|
|
280
|
+
impl->copy = sz_copy_sve;
|
|
281
|
+
impl->move = sz_move_sve;
|
|
282
|
+
impl->fill = sz_fill_sve;
|
|
283
|
+
impl->lookup = sz_lookup_sve;
|
|
284
|
+
|
|
285
|
+
impl->find = sz_find_sve;
|
|
286
|
+
// TODO: impl->rfind = sz_rfind_sve;
|
|
287
|
+
}
|
|
288
|
+
|
|
251
289
|
impl->find_byte = sz_find_byte_sve;
|
|
252
290
|
impl->rfind_byte = sz_rfind_byte_sve;
|
|
253
291
|
|
|
@@ -260,7 +298,17 @@ static void sz_dispatch_table_update_implementation_(sz_capability_t caps) {
|
|
|
260
298
|
#endif
|
|
261
299
|
|
|
262
300
|
#if SZ_USE_SVE2
|
|
263
|
-
if (caps & sz_cap_sve2_k) {
|
|
301
|
+
if (caps & sz_cap_sve2_k) {
|
|
302
|
+
impl->bytesum = sz_bytesum_sve2;
|
|
303
|
+
|
|
304
|
+
impl->utf8_count = sz_utf8_count_sve2;
|
|
305
|
+
impl->utf8_find_nth = sz_utf8_find_nth_sve2;
|
|
306
|
+
|
|
307
|
+
if (SZ_ENFORCE_SVE_OVER_NEON) {
|
|
308
|
+
impl->utf8_find_newline = sz_utf8_find_newline_sve2;
|
|
309
|
+
impl->utf8_find_whitespace = sz_utf8_find_whitespace_sve2;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
264
312
|
#endif
|
|
265
313
|
|
|
266
314
|
#if SZ_USE_SVE2_AES
|
|
@@ -434,6 +482,31 @@ SZ_DYNAMIC sz_status_t sz_sequence_intersect(sz_sequence_t const *first_array, s
|
|
|
434
482
|
first_positions, second_positions);
|
|
435
483
|
}
|
|
436
484
|
|
|
485
|
+
SZ_DYNAMIC sz_size_t sz_utf8_count(sz_cptr_t text, sz_size_t length) {
|
|
486
|
+
return sz_dispatch_table.utf8_count(text, length);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
SZ_DYNAMIC sz_cptr_t sz_utf8_find_nth(sz_cptr_t text, sz_size_t length, sz_size_t n) {
|
|
490
|
+
return sz_dispatch_table.utf8_find_nth(text, length, n);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
SZ_DYNAMIC sz_cptr_t sz_utf8_unpack_chunk(sz_cptr_t text, sz_size_t length, sz_rune_t *runes, sz_size_t runes_capacity,
|
|
494
|
+
sz_size_t *runes_unpacked) {
|
|
495
|
+
return sz_dispatch_table.utf8_unpack_chunk(text, length, runes, runes_capacity, runes_unpacked);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
SZ_DYNAMIC sz_cptr_t sz_utf8_find_newline(sz_cptr_t text, sz_size_t length, sz_size_t *matched_length) {
|
|
499
|
+
return sz_dispatch_table.utf8_find_newline(text, length, matched_length);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
SZ_DYNAMIC sz_cptr_t sz_utf8_find_whitespace(sz_cptr_t text, sz_size_t length, sz_size_t *matched_length) {
|
|
503
|
+
return sz_dispatch_table.utf8_find_whitespace(text, length, matched_length);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
SZ_DYNAMIC sz_size_t sz_utf8_case_fold(sz_cptr_t source, sz_size_t source_length, sz_ptr_t destination) {
|
|
507
|
+
return sz_dispatch_table.utf8_case_fold(source, source_length, destination);
|
|
508
|
+
}
|
|
509
|
+
|
|
437
510
|
// Provide overrides for the libc mem* functions
|
|
438
511
|
#if SZ_OVERRIDE_LIBC && !defined(__CYGWIN__)
|
|
439
512
|
|
|
@@ -526,7 +526,7 @@ SZ_DYNAMIC sz_bool_t sz_equal(sz_cptr_t a, sz_cptr_t b, sz_size_t length) {
|
|
|
526
526
|
return sz_equal_skylake(a, b, length);
|
|
527
527
|
#elif SZ_USE_HASWELL
|
|
528
528
|
return sz_equal_haswell(a, b, length);
|
|
529
|
-
#elif SZ_USE_SVE
|
|
529
|
+
#elif SZ_USE_SVE && SZ_ENFORCE_SVE_OVER_NEON
|
|
530
530
|
return sz_equal_sve(a, b, length);
|
|
531
531
|
#elif SZ_USE_NEON
|
|
532
532
|
return sz_equal_neon(a, b, length);
|
|
@@ -540,7 +540,7 @@ SZ_DYNAMIC sz_ordering_t sz_order(sz_cptr_t a, sz_size_t a_length, sz_cptr_t b,
|
|
|
540
540
|
return sz_order_skylake(a, a_length, b, b_length);
|
|
541
541
|
#elif SZ_USE_HASWELL
|
|
542
542
|
return sz_order_haswell(a, a_length, b, b_length);
|
|
543
|
-
#elif SZ_USE_SVE
|
|
543
|
+
#elif SZ_USE_SVE && SZ_ENFORCE_SVE_OVER_NEON
|
|
544
544
|
return sz_order_sve(a, a_length, b, b_length);
|
|
545
545
|
#elif SZ_USE_NEON
|
|
546
546
|
return sz_order_neon(a, a_length, b, b_length);
|
|
@@ -205,6 +205,41 @@ SZ_PUBLIC sz_cptr_t sz_find_byteset_neon(sz_cptr_t haystack, sz_size_t length, s
|
|
|
205
205
|
SZ_PUBLIC sz_cptr_t sz_rfind_byteset_neon(sz_cptr_t haystack, sz_size_t length, sz_byteset_t const *set);
|
|
206
206
|
#endif
|
|
207
207
|
|
|
208
|
+
/**
|
|
209
|
+
* @brief Finds the first occurence of a UTF-8 whitespace or punctuation character in a string.
|
|
210
|
+
*
|
|
211
|
+
* Delimiters include all of the above, plus common "punctuation" characters, "symbols", and "separators",
|
|
212
|
+
* as defined by the "Unicode UAX #29" word segmentation standard and implemented in the ICU.
|
|
213
|
+
* - around 30 ASCII characters
|
|
214
|
+
* - around 130 2-byte characters
|
|
215
|
+
* - around 4.3k 3-byte characters
|
|
216
|
+
* - around 4.1k 4-byte characters
|
|
217
|
+
*
|
|
218
|
+
* @param[in] text String to be scanned.
|
|
219
|
+
* @param[in] length Number of bytes in the string.
|
|
220
|
+
* @param[out] matched_length Number of bytes in the matched newline delimiter.
|
|
221
|
+
* @return Pointer to the first matching newline character from @p text.
|
|
222
|
+
*/
|
|
223
|
+
SZ_DYNAMIC sz_cptr_t sz_find_delimiter_utf8(sz_cptr_t text, sz_size_t length, sz_size_t *matched_length);
|
|
224
|
+
|
|
225
|
+
/** @copydoc sz_find_delimiters_utf8 */
|
|
226
|
+
SZ_PUBLIC sz_cptr_t sz_find_delimiters_utf8_serial(sz_cptr_t text, sz_size_t length, sz_size_t *matched_length);
|
|
227
|
+
|
|
228
|
+
#if SZ_USE_HASWELL
|
|
229
|
+
/** @copydoc sz_find_delimiters_utf8 */
|
|
230
|
+
SZ_PUBLIC sz_cptr_t sz_find_delimiters_utf8_haswell(sz_cptr_t text, sz_size_t length, sz_size_t *matched_length);
|
|
231
|
+
#endif
|
|
232
|
+
|
|
233
|
+
#if SZ_USE_ICE
|
|
234
|
+
/** @copydoc sz_find_delimiters_utf8 */
|
|
235
|
+
SZ_PUBLIC sz_cptr_t sz_find_delimiters_utf8_ice(sz_cptr_t text, sz_size_t length, sz_size_t *matched_length);
|
|
236
|
+
#endif
|
|
237
|
+
|
|
238
|
+
#if SZ_USE_NEON
|
|
239
|
+
/** @copydoc sz_find_delimiters_utf8 */
|
|
240
|
+
SZ_PUBLIC sz_cptr_t sz_find_delimiters_utf8_neon(sz_cptr_t text, sz_size_t length, sz_size_t *matched_length);
|
|
241
|
+
#endif
|
|
242
|
+
|
|
208
243
|
#pragma endregion // Core API
|
|
209
244
|
|
|
210
245
|
#pragma region Helper Shortcuts
|
|
@@ -905,7 +940,7 @@ SZ_PUBLIC sz_cptr_t sz_find_westmere(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
905
940
|
sz_locate_needle_anomalies_(n, n_length, &offset_first, &offset_mid, &offset_last);
|
|
906
941
|
|
|
907
942
|
// Broadcast those characters into XMM registers.
|
|
908
|
-
|
|
943
|
+
sz_u32_vec_t matches_vec;
|
|
909
944
|
sz_u128_vec_t h_first_vec, h_mid_vec, h_last_vec, n_first_vec, n_mid_vec, n_last_vec;
|
|
910
945
|
n_first_vec.xmm = _mm_set1_epi8(n[offset_first]);
|
|
911
946
|
n_mid_vec.xmm = _mm_set1_epi8(n[offset_mid]);
|
|
@@ -916,14 +951,14 @@ SZ_PUBLIC sz_cptr_t sz_find_westmere(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
916
951
|
h_first_vec.xmm = _mm_lddqu_si128((__m128i const *)(h + offset_first));
|
|
917
952
|
h_mid_vec.xmm = _mm_lddqu_si128((__m128i const *)(h + offset_mid));
|
|
918
953
|
h_last_vec.xmm = _mm_lddqu_si128((__m128i const *)(h + offset_last));
|
|
919
|
-
|
|
954
|
+
matches_vec.i32 = //
|
|
920
955
|
_mm_movemask_epi8(_mm_cmpeq_epi8(h_first_vec.xmm, n_first_vec.xmm)) &
|
|
921
956
|
_mm_movemask_epi8(_mm_cmpeq_epi8(h_mid_vec.xmm, n_mid_vec.xmm)) &
|
|
922
957
|
_mm_movemask_epi8(_mm_cmpeq_epi8(h_last_vec.xmm, n_last_vec.xmm));
|
|
923
|
-
while (
|
|
924
|
-
int potential_offset = sz_u32_ctz(
|
|
958
|
+
while (matches_vec.u32) {
|
|
959
|
+
int potential_offset = sz_u32_ctz(matches_vec.u32);
|
|
925
960
|
if (sz_equal_westmere(h + potential_offset, n, n_length)) return h + potential_offset;
|
|
926
|
-
|
|
961
|
+
matches_vec.u32 &= matches_vec.u32 - 1;
|
|
927
962
|
}
|
|
928
963
|
}
|
|
929
964
|
|
|
@@ -940,7 +975,7 @@ SZ_PUBLIC sz_cptr_t sz_rfind_westmere(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
940
975
|
sz_locate_needle_anomalies_(n, n_length, &offset_first, &offset_mid, &offset_last);
|
|
941
976
|
|
|
942
977
|
// Broadcast those characters into XMM registers.
|
|
943
|
-
|
|
978
|
+
sz_u32_vec_t matches_vec;
|
|
944
979
|
sz_u128_vec_t h_first_vec, h_mid_vec, h_last_vec, n_first_vec, n_mid_vec, n_last_vec;
|
|
945
980
|
n_first_vec.xmm = _mm_set1_epi8(n[offset_first]);
|
|
946
981
|
n_mid_vec.xmm = _mm_set1_epi8(n[offset_mid]);
|
|
@@ -953,15 +988,15 @@ SZ_PUBLIC sz_cptr_t sz_rfind_westmere(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
953
988
|
h_first_vec.xmm = _mm_lddqu_si128((__m128i const *)(h_reversed + offset_first));
|
|
954
989
|
h_mid_vec.xmm = _mm_lddqu_si128((__m128i const *)(h_reversed + offset_mid));
|
|
955
990
|
h_last_vec.xmm = _mm_lddqu_si128((__m128i const *)(h_reversed + offset_last));
|
|
956
|
-
|
|
991
|
+
matches_vec.i32 = //
|
|
957
992
|
_mm_movemask_epi8(_mm_cmpeq_epi8(h_first_vec.xmm, n_first_vec.xmm)) &
|
|
958
993
|
_mm_movemask_epi8(_mm_cmpeq_epi8(h_mid_vec.xmm, n_mid_vec.xmm)) &
|
|
959
994
|
_mm_movemask_epi8(_mm_cmpeq_epi8(h_last_vec.xmm, n_last_vec.xmm));
|
|
960
|
-
while (
|
|
961
|
-
int potential_offset = sz_u32_clz(
|
|
995
|
+
while (matches_vec.u32) {
|
|
996
|
+
int potential_offset = sz_u32_clz(matches_vec.u32) - 16;
|
|
962
997
|
if (sz_equal_westmere(h + h_length - n_length - potential_offset, n, n_length))
|
|
963
998
|
return h + h_length - n_length - potential_offset;
|
|
964
|
-
|
|
999
|
+
matches_vec.u32 &= ~(1u << (15 - potential_offset));
|
|
965
1000
|
}
|
|
966
1001
|
}
|
|
967
1002
|
|
|
@@ -1029,7 +1064,7 @@ SZ_PUBLIC sz_cptr_t sz_find_haswell(sz_cptr_t h, sz_size_t h_length, sz_cptr_t n
|
|
|
1029
1064
|
sz_locate_needle_anomalies_(n, n_length, &offset_first, &offset_mid, &offset_last);
|
|
1030
1065
|
|
|
1031
1066
|
// Broadcast those characters into YMM registers.
|
|
1032
|
-
|
|
1067
|
+
sz_u32_vec_t matches_vec;
|
|
1033
1068
|
sz_u256_vec_t h_first_vec, h_mid_vec, h_last_vec, n_first_vec, n_mid_vec, n_last_vec;
|
|
1034
1069
|
n_first_vec.ymm = _mm256_set1_epi8(n[offset_first]);
|
|
1035
1070
|
n_mid_vec.ymm = _mm256_set1_epi8(n[offset_mid]);
|
|
@@ -1040,14 +1075,14 @@ SZ_PUBLIC sz_cptr_t sz_find_haswell(sz_cptr_t h, sz_size_t h_length, sz_cptr_t n
|
|
|
1040
1075
|
h_first_vec.ymm = _mm256_lddqu_si256((__m256i const *)(h + offset_first));
|
|
1041
1076
|
h_mid_vec.ymm = _mm256_lddqu_si256((__m256i const *)(h + offset_mid));
|
|
1042
1077
|
h_last_vec.ymm = _mm256_lddqu_si256((__m256i const *)(h + offset_last));
|
|
1043
|
-
|
|
1078
|
+
matches_vec.i32 = //
|
|
1044
1079
|
_mm256_movemask_epi8(_mm256_cmpeq_epi8(h_first_vec.ymm, n_first_vec.ymm)) &
|
|
1045
1080
|
_mm256_movemask_epi8(_mm256_cmpeq_epi8(h_mid_vec.ymm, n_mid_vec.ymm)) &
|
|
1046
1081
|
_mm256_movemask_epi8(_mm256_cmpeq_epi8(h_last_vec.ymm, n_last_vec.ymm));
|
|
1047
|
-
while (
|
|
1048
|
-
int potential_offset = sz_u32_ctz(
|
|
1082
|
+
while (matches_vec.u32) {
|
|
1083
|
+
int potential_offset = sz_u32_ctz(matches_vec.u32);
|
|
1049
1084
|
if (sz_equal_haswell(h + potential_offset, n, n_length)) return h + potential_offset;
|
|
1050
|
-
|
|
1085
|
+
matches_vec.u32 &= matches_vec.u32 - 1;
|
|
1051
1086
|
}
|
|
1052
1087
|
}
|
|
1053
1088
|
|
|
@@ -1065,7 +1100,7 @@ SZ_PUBLIC sz_cptr_t sz_rfind_haswell(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
1065
1100
|
sz_locate_needle_anomalies_(n, n_length, &offset_first, &offset_mid, &offset_last);
|
|
1066
1101
|
|
|
1067
1102
|
// Broadcast those characters into YMM registers.
|
|
1068
|
-
|
|
1103
|
+
sz_u32_vec_t matches_vec;
|
|
1069
1104
|
sz_u256_vec_t h_first_vec, h_mid_vec, h_last_vec, n_first_vec, n_mid_vec, n_last_vec;
|
|
1070
1105
|
n_first_vec.ymm = _mm256_set1_epi8(n[offset_first]);
|
|
1071
1106
|
n_mid_vec.ymm = _mm256_set1_epi8(n[offset_mid]);
|
|
@@ -1078,15 +1113,15 @@ SZ_PUBLIC sz_cptr_t sz_rfind_haswell(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
1078
1113
|
h_first_vec.ymm = _mm256_lddqu_si256((__m256i const *)(h_reversed + offset_first));
|
|
1079
1114
|
h_mid_vec.ymm = _mm256_lddqu_si256((__m256i const *)(h_reversed + offset_mid));
|
|
1080
1115
|
h_last_vec.ymm = _mm256_lddqu_si256((__m256i const *)(h_reversed + offset_last));
|
|
1081
|
-
|
|
1116
|
+
matches_vec.i32 = //
|
|
1082
1117
|
_mm256_movemask_epi8(_mm256_cmpeq_epi8(h_first_vec.ymm, n_first_vec.ymm)) &
|
|
1083
1118
|
_mm256_movemask_epi8(_mm256_cmpeq_epi8(h_mid_vec.ymm, n_mid_vec.ymm)) &
|
|
1084
1119
|
_mm256_movemask_epi8(_mm256_cmpeq_epi8(h_last_vec.ymm, n_last_vec.ymm));
|
|
1085
|
-
while (
|
|
1086
|
-
int potential_offset = sz_u32_clz(
|
|
1120
|
+
while (matches_vec.u32) {
|
|
1121
|
+
int potential_offset = sz_u32_clz(matches_vec.u32);
|
|
1087
1122
|
if (sz_equal_haswell(h + h_length - n_length - potential_offset, n, n_length))
|
|
1088
1123
|
return h + h_length - n_length - potential_offset;
|
|
1089
|
-
|
|
1124
|
+
matches_vec.u32 &= ~(1u << (31 - potential_offset));
|
|
1090
1125
|
}
|
|
1091
1126
|
}
|
|
1092
1127
|
|
|
@@ -1388,9 +1423,8 @@ SZ_PUBLIC sz_cptr_t sz_rfind_skylake(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
1388
1423
|
int potential_offset = sz_u64_clz(matches);
|
|
1389
1424
|
if (n_length <= 3 || sz_equal_skylake(h + h_length - n_length - potential_offset, n, n_length))
|
|
1390
1425
|
return h + h_length - n_length - potential_offset;
|
|
1391
|
-
sz_assert_((matches & (
|
|
1392
|
-
|
|
1393
|
-
matches &= ~((sz_u64_t)1 << (63 - potential_offset));
|
|
1426
|
+
sz_assert_((matches & (1ull << (63 - potential_offset))) != 0 && "The bit must be set before we squash it");
|
|
1427
|
+
matches &= ~(1ull << (63 - potential_offset));
|
|
1394
1428
|
}
|
|
1395
1429
|
}
|
|
1396
1430
|
|
|
@@ -1409,9 +1443,8 @@ SZ_PUBLIC sz_cptr_t sz_rfind_skylake(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
1409
1443
|
int potential_offset = sz_u64_clz(matches);
|
|
1410
1444
|
if (n_length <= 3 || sz_equal_skylake(h + 64 - potential_offset - 1, n, n_length))
|
|
1411
1445
|
return h + 64 - potential_offset - 1;
|
|
1412
|
-
sz_assert_((matches & (
|
|
1413
|
-
|
|
1414
|
-
matches &= ~((sz_u64_t)1 << (63 - potential_offset));
|
|
1446
|
+
sz_assert_((matches & (1ull << (63 - potential_offset))) != 0 && "The bit must be set before we squash it");
|
|
1447
|
+
matches &= ~(1ull << (63 - potential_offset));
|
|
1415
1448
|
}
|
|
1416
1449
|
}
|
|
1417
1450
|
|
|
@@ -1584,7 +1617,7 @@ SZ_PUBLIC sz_cptr_t sz_rfind_byteset_ice(sz_cptr_t text, sz_size_t length, sz_by
|
|
|
1584
1617
|
#pragma GCC target("+simd")
|
|
1585
1618
|
#endif
|
|
1586
1619
|
|
|
1587
|
-
SZ_INTERNAL sz_u64_t
|
|
1620
|
+
SZ_INTERNAL sz_u64_t sz_find_vreinterpretq_u8_u4_(uint8x16_t vec) {
|
|
1588
1621
|
// Use `vshrn` to produce a bitmask, similar to `movemask` in SSE.
|
|
1589
1622
|
// https://community.arm.com/arm-community-blogs/b/infrastructure-solutions-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon
|
|
1590
1623
|
return vget_lane_u64(vreinterpret_u64_u8(vshrn_n_u16(vreinterpretq_u16_u8(vec), 4)), 0) & 0x8888888888888888ull;
|
|
@@ -1601,7 +1634,7 @@ SZ_PUBLIC sz_cptr_t sz_find_byte_neon(sz_cptr_t h, sz_size_t h_length, sz_cptr_t
|
|
|
1601
1634
|
// In Arm NEON we don't have a `movemask` to combine it with `ctz` and get the offset of the match.
|
|
1602
1635
|
// But assuming the `vmaxvq` is cheap, we can use it to find the first match, by blending (bitwise selecting)
|
|
1603
1636
|
// the vector with a relative offsets array.
|
|
1604
|
-
matches =
|
|
1637
|
+
matches = sz_find_vreinterpretq_u8_u4_(matches_vec.u8x16);
|
|
1605
1638
|
if (matches) return h + sz_u64_ctz(matches) / 4;
|
|
1606
1639
|
|
|
1607
1640
|
h += 16, h_length -= 16;
|
|
@@ -1618,7 +1651,7 @@ SZ_PUBLIC sz_cptr_t sz_rfind_byte_neon(sz_cptr_t h, sz_size_t h_length, sz_cptr_
|
|
|
1618
1651
|
while (h_length >= 16) {
|
|
1619
1652
|
h_vec.u8x16 = vld1q_u8((sz_u8_t const *)h + h_length - 16);
|
|
1620
1653
|
matches_vec.u8x16 = vceqq_u8(h_vec.u8x16, n_vec.u8x16);
|
|
1621
|
-
matches =
|
|
1654
|
+
matches = sz_find_vreinterpretq_u8_u4_(matches_vec.u8x16);
|
|
1622
1655
|
if (matches) return h + h_length - 1 - sz_u64_clz(matches) / 4;
|
|
1623
1656
|
h_length -= 16;
|
|
1624
1657
|
}
|
|
@@ -1643,7 +1676,7 @@ SZ_PUBLIC sz_u64_t sz_find_byteset_neon_register_( //
|
|
|
1643
1676
|
uint8x16_t matches_vec = vorrq_u8(matches_top_vec, matches_bottom_vec);
|
|
1644
1677
|
// Istead of pure `vandq_u8`, we can immediately broadcast a match presence across each 8-bit word.
|
|
1645
1678
|
matches_vec = vtstq_u8(matches_vec, byte_mask_vec);
|
|
1646
|
-
return
|
|
1679
|
+
return sz_find_vreinterpretq_u8_u4_(matches_vec);
|
|
1647
1680
|
}
|
|
1648
1681
|
|
|
1649
1682
|
SZ_PUBLIC sz_cptr_t sz_find_neon(sz_cptr_t h, sz_size_t h_length, sz_cptr_t n, sz_size_t n_length) {
|
|
@@ -1668,7 +1701,7 @@ SZ_PUBLIC sz_cptr_t sz_find_neon(sz_cptr_t h, sz_size_t h_length, sz_cptr_t n, s
|
|
|
1668
1701
|
h_last_vec.u8x16 = vld1q_u8((sz_u8_t const *)(h + 1));
|
|
1669
1702
|
matches_vec.u8x16 =
|
|
1670
1703
|
vandq_u8(vceqq_u8(h_first_vec.u8x16, n_first_vec.u8x16), vceqq_u8(h_last_vec.u8x16, n_last_vec.u8x16));
|
|
1671
|
-
matches =
|
|
1704
|
+
matches = sz_find_vreinterpretq_u8_u4_(matches_vec.u8x16);
|
|
1672
1705
|
if (matches) return h + sz_u64_ctz(matches) / 4;
|
|
1673
1706
|
}
|
|
1674
1707
|
}
|
|
@@ -1690,7 +1723,7 @@ SZ_PUBLIC sz_cptr_t sz_find_neon(sz_cptr_t h, sz_size_t h_length, sz_cptr_t n, s
|
|
|
1690
1723
|
vceqq_u8(h_first_vec.u8x16, n_first_vec.u8x16), //
|
|
1691
1724
|
vceqq_u8(h_mid_vec.u8x16, n_mid_vec.u8x16)),
|
|
1692
1725
|
vceqq_u8(h_last_vec.u8x16, n_last_vec.u8x16));
|
|
1693
|
-
matches =
|
|
1726
|
+
matches = sz_find_vreinterpretq_u8_u4_(matches_vec.u8x16);
|
|
1694
1727
|
if (matches) return h + sz_u64_ctz(matches) / 4;
|
|
1695
1728
|
}
|
|
1696
1729
|
}
|
|
@@ -1714,7 +1747,7 @@ SZ_PUBLIC sz_cptr_t sz_find_neon(sz_cptr_t h, sz_size_t h_length, sz_cptr_t n, s
|
|
|
1714
1747
|
vceqq_u8(h_first_vec.u8x16, n_first_vec.u8x16), //
|
|
1715
1748
|
vceqq_u8(h_mid_vec.u8x16, n_mid_vec.u8x16)),
|
|
1716
1749
|
vceqq_u8(h_last_vec.u8x16, n_last_vec.u8x16));
|
|
1717
|
-
matches =
|
|
1750
|
+
matches = sz_find_vreinterpretq_u8_u4_(matches_vec.u8x16);
|
|
1718
1751
|
while (matches) {
|
|
1719
1752
|
int potential_offset = sz_u64_ctz(matches) / 4;
|
|
1720
1753
|
if (sz_equal_neon(h + potential_offset, n, n_length)) return h + potential_offset;
|
|
@@ -1754,7 +1787,7 @@ SZ_PUBLIC sz_cptr_t sz_rfind_neon(sz_cptr_t h, sz_size_t h_length, sz_cptr_t n,
|
|
|
1754
1787
|
vceqq_u8(h_first_vec.u8x16, n_first_vec.u8x16), //
|
|
1755
1788
|
vceqq_u8(h_mid_vec.u8x16, n_mid_vec.u8x16)),
|
|
1756
1789
|
vceqq_u8(h_last_vec.u8x16, n_last_vec.u8x16));
|
|
1757
|
-
matches =
|
|
1790
|
+
matches = sz_find_vreinterpretq_u8_u4_(matches_vec.u8x16);
|
|
1758
1791
|
while (matches) {
|
|
1759
1792
|
int potential_offset = sz_u64_clz(matches) / 4;
|
|
1760
1793
|
if (sz_equal_neon(h + h_length - n_length - potential_offset, n, n_length))
|
|
@@ -1966,7 +1999,7 @@ SZ_DYNAMIC sz_cptr_t sz_find_byte(sz_cptr_t haystack, sz_size_t h_length, sz_cpt
|
|
|
1966
1999
|
return sz_find_byte_haswell(haystack, h_length, needle);
|
|
1967
2000
|
#elif SZ_USE_WESTMERE
|
|
1968
2001
|
return sz_find_byte_westmere(haystack, h_length, needle);
|
|
1969
|
-
#elif SZ_USE_SVE
|
|
2002
|
+
#elif SZ_USE_SVE // ? actually faster than NEON on most machines
|
|
1970
2003
|
return sz_find_byte_sve(haystack, h_length, needle);
|
|
1971
2004
|
#elif SZ_USE_NEON
|
|
1972
2005
|
return sz_find_byte_neon(haystack, h_length, needle);
|
|
@@ -1982,7 +2015,7 @@ SZ_DYNAMIC sz_cptr_t sz_rfind_byte(sz_cptr_t haystack, sz_size_t h_length, sz_cp
|
|
|
1982
2015
|
return sz_rfind_byte_haswell(haystack, h_length, needle);
|
|
1983
2016
|
#elif SZ_USE_WESTMERE
|
|
1984
2017
|
return sz_rfind_byte_westmere(haystack, h_length, needle);
|
|
1985
|
-
#elif SZ_USE_SVE
|
|
2018
|
+
#elif SZ_USE_SVE // ? actually faster than NEON on most machines
|
|
1986
2019
|
return sz_rfind_byte_sve(haystack, h_length, needle);
|
|
1987
2020
|
#elif SZ_USE_NEON
|
|
1988
2021
|
return sz_rfind_byte_neon(haystack, h_length, needle);
|
|
@@ -1998,7 +2031,7 @@ SZ_DYNAMIC sz_cptr_t sz_find(sz_cptr_t haystack, sz_size_t h_length, sz_cptr_t n
|
|
|
1998
2031
|
return sz_find_haswell(haystack, h_length, needle, n_length);
|
|
1999
2032
|
#elif SZ_USE_WESTMERE
|
|
2000
2033
|
return sz_find_westmere(haystack, h_length, needle, n_length);
|
|
2001
|
-
#elif SZ_USE_SVE
|
|
2034
|
+
#elif SZ_USE_SVE && SZ_ENFORCE_SVE_OVER_NEON
|
|
2002
2035
|
return sz_find_sve(haystack, h_length, needle, n_length);
|
|
2003
2036
|
#elif SZ_USE_NEON
|
|
2004
2037
|
return sz_find_neon(haystack, h_length, needle, n_length);
|