diff --git a/lib/node_modules/@stdlib/bench/README.md b/lib/node_modules/@stdlib/bench/README.md
index d2ef2dc837ba..35a1b5747f8a 100644
--- a/lib/node_modules/@stdlib/bench/README.md
+++ b/lib/node_modules/@stdlib/bench/README.md
@@ -64,6 +64,390 @@ This function is an alias for [@stdlib/bench/harness][@stdlib/bench/harness].
+
+
+* * *
+
+
+
+## C APIs
+
+
+
+
+
+The C harness is a header-only library of macros and `static inline` helpers which emit the same [Test Anything Protocol][tap] (TAP) output as hand-written stdlib C benchmarks, so that a benchmark file contains only the code being measured.
+
+
+
+
+
+
+
+
+
+### Usage
+
+```c
+#include "stdlib/bench.h"
+```
+
+#### BENCHMARK_NAME
+
+Benchmark name. The macro is **not** defined by the header. The build tooling defines it from the enclosing package name (e.g., `-DBENCHMARK_NAME="@stdlib/math/base/special/abs"`), and a benchmark file should define a fallback:
+
+```c
+#ifndef BENCHMARK_NAME
+#define BENCHMARK_NAME "abs"
+#endif
+```
+
+#### STDLIB_BENCH { ... }
+
+Macro for defining the main execution sequence. The macro expands to a generated `main` function which seeds the C standard library pseudorandom number generator, prints the TAP version, runs the block (as the body of a static function `stdlib_bench_main`), and prints the TAP summary.
+
+```c
+STDLIB_BENCH {
+ STDLIB_BENCH_PREAMBLE( 3, 1000000 ) {
+ STDLIB_BENCH_PRINT_NAME();
+ STDLIB_RUN_BENCHMARK( benchmark );
+ }
+}
+```
+
+#### STDLIB_BENCH_PREAMBLE( repeats, iterations ) { ... }
+
+Macro for running a block `repeats` times with a fixed number of iterations. Within the block, benchmark functions defined via `STDLIB_BENCHMARK` should be run via `STDLIB_RUN_BENCHMARK`.
+
+```c
+STDLIB_BENCH_PREAMBLE( 3, 1000000 ) {
+ STDLIB_BENCH_PRINT_NAME();
+ STDLIB_RUN_BENCHMARK( benchmark );
+}
+```
+
+#### STDLIB_BENCH_LENGTH_PREAMBLE( repeats, iterations, min, max ) { ... }
+
+Macro for running a block `repeats` times for each array length `10^min`, `10^(min+1)`, ..., `10^max`. Within the block, `len` is defined and equal to the current array length, and benchmark functions defined via `STDLIB_LENGTH_BENCHMARK` should be run via `STDLIB_RUN_LENGTH_BENCHMARK`. The number of iterations for a given length is `iterations / 10^(exponent-1)`.
+
+```c
+STDLIB_BENCH_LENGTH_PREAMBLE( 3, 10000000, 1, 6 ) {
+ STDLIB_BENCH_PRINT_NAME_FORMAT( "len=%d", len );
+ STDLIB_RUN_LENGTH_BENCHMARK( benchmark );
+}
+```
+
+#### STDLIB_BENCH_PRINT_NAME()
+
+Macro for printing a benchmark name (`# c::`).
+
+```c
+STDLIB_BENCH_PRINT_NAME();
+```
+
+#### STDLIB_BENCH_PRINT_NAME_FORMAT( fmt, ... )
+
+Macro for printing a benchmark name with a formatted suffix (`# c:::`). At least one format argument must be provided.
+
+```c
+STDLIB_BENCH_PRINT_NAME_FORMAT( "len=%d", len );
+```
+
+#### STDLIB_RUN_BENCHMARK( fn )
+
+Macro for running a benchmark function defined via `STDLIB_BENCHMARK` and printing its results. Must be used within a `STDLIB_BENCH_PREAMBLE` block.
+
+```c
+STDLIB_RUN_BENCHMARK( benchmark );
+```
+
+#### STDLIB_RUN_LENGTH_BENCHMARK( fn )
+
+Macro for running a length-based benchmark function defined via `STDLIB_LENGTH_BENCHMARK` and printing its results. Must be used within a `STDLIB_BENCH_LENGTH_PREAMBLE` block.
+
+```c
+STDLIB_RUN_LENGTH_BENCHMARK( benchmark );
+```
+
+#### STDLIB_BENCHMARK( fn ) { ... }
+
+Macro for defining a benchmark function. Within the block, `iterations` is defined. The block must contain `STDLIB_BENCHMARK_LOOP_PREAMBLE`, `STDLIB_BENCHMARK_LOOP_EPILOGUE`, and `STDLIB_BENCHMARK_EPILOGUE`, in that order.
+
+```c
+STDLIB_BENCHMARK( benchmark ) {
+ double y = 0.0;
+
+ STDLIB_BENCHMARK_LOOP_PREAMBLE {
+ y = sqrt( stdlib_bench_random_uniform( 0.0, 100.0 ) );
+ if ( y != y ) {
+ printf( "should not return NaN\n" );
+ break;
+ }
+ }
+ STDLIB_BENCHMARK_LOOP_EPILOGUE;
+ if ( y != y ) {
+ printf( "should not return NaN\n" );
+ }
+ STDLIB_BENCHMARK_EPILOGUE;
+}
+```
+
+#### STDLIB_LENGTH_BENCHMARK( fn ) { ... }
+
+Macro for defining a length-based benchmark function. Within the block, `iterations` and `len` (array length) are defined. The block must contain `STDLIB_BENCHMARK_LOOP_PREAMBLE`, `STDLIB_BENCHMARK_LOOP_EPILOGUE`, and `STDLIB_BENCHMARK_EPILOGUE`, in that order.
+
+```c
+STDLIB_LENGTH_BENCHMARK( benchmark ) {
+ double y = 0.0;
+
+ STDLIB_BENCHMARK_MALLOC_ARRAY_FLOAT64( x, len );
+ STDLIB_BENCHMARK_FILL_ARRAY( x, len, stdlib_bench_random_uniform( -100.0, 100.0 ) );
+
+ STDLIB_BENCHMARK_LOOP_PREAMBLE {
+ y = x[ i%len ];
+ if ( y != y ) {
+ printf( "should not return NaN\n" );
+ break;
+ }
+ }
+ STDLIB_BENCHMARK_LOOP_EPILOGUE;
+ if ( y != y ) {
+ printf( "should not return NaN\n" );
+ }
+ STDLIB_BENCHMARK_FREE( x );
+ STDLIB_BENCHMARK_EPILOGUE;
+}
+```
+
+#### STDLIB_BENCHMARK_LOOP_PREAMBLE { ... }
+
+Macro for starting a benchmark timer and beginning the benchmark loop. Within the block, `i` is defined and equal to the current iteration.
+
+#### STDLIB_BENCHMARK_LOOP_EPILOGUE
+
+Macro for stopping a benchmark timer. Teardown code (e.g., freeing arrays) should follow this macro.
+
+#### STDLIB_BENCHMARK_EPILOGUE
+
+Macro for returning the elapsed time from a benchmark function.
+
+#### STDLIB_BENCHMARK_MALLOC_ARRAY( type, x, n )
+
+Macro for declaring a pointer `x` and allocating an array of `n` elements of type `type`.
+
+```c
+STDLIB_BENCHMARK_MALLOC_ARRAY( double, x, 100 );
+```
+
+#### STDLIB_BENCHMARK_MALLOC_ARRAY_FLOAT64( x, n )
+
+Macro for declaring a pointer `x` and allocating a double-precision floating-point array of `n` elements.
+
+```c
+STDLIB_BENCHMARK_MALLOC_ARRAY_FLOAT64( x, 100 );
+```
+
+#### STDLIB_BENCHMARK_MALLOC_ARRAY_FLOAT32( x, n )
+
+Macro for declaring a pointer `x` and allocating a single-precision floating-point array of `n` elements.
+
+```c
+STDLIB_BENCHMARK_MALLOC_ARRAY_FLOAT32( x, 100 );
+```
+
+#### STDLIB_BENCHMARK_FILL_STRIDED_ARRAY( x, n, stride, value )
+
+Macro for filling `n` indexed elements of a strided array with a value. The value expression is evaluated once per indexed element. Following stdlib strided array conventions, a negative stride fills the array starting from the last indexed element.
+
+```c
+STDLIB_BENCHMARK_FILL_STRIDED_ARRAY( x, 50, 2, stdlib_bench_random_uniform( -10.0, 10.0 ) );
+```
+
+#### STDLIB_BENCHMARK_FILL_ARRAY( x, n, value )
+
+Macro for filling an array with a value. The value expression is evaluated once per element.
+
+```c
+STDLIB_BENCHMARK_FILL_ARRAY( x, 100, stdlib_bench_random_uniform( -10.0, 10.0 ) );
+```
+
+#### STDLIB_BENCHMARK_FREE( x )
+
+Macro for freeing an array allocated via `STDLIB_BENCHMARK_MALLOC_ARRAY*`.
+
+```c
+STDLIB_BENCHMARK_FREE( x );
+```
+
+#### stdlib_bench_print_version()
+
+Prints the TAP version.
+
+```c
+stdlib_bench_print_version();
+```
+
+```c
+void stdlib_bench_print_version( void );
+```
+
+#### stdlib_bench_print_summary( total, passing )
+
+Prints the TAP summary.
+
+```c
+stdlib_bench_print_summary( 3, 3 );
+```
+
+The function accepts the following arguments:
+
+- **total**: `[in] int` total number of tests.
+- **passing**: `[in] int` total number of passing tests.
+
+```c
+void stdlib_bench_print_summary( const int total, const int passing );
+```
+
+#### stdlib_bench_print_results( iterations, elapsed )
+
+Prints benchmark results.
+
+```c
+stdlib_bench_print_results( 1000000, 0.5 );
+```
+
+The function accepts the following arguments:
+
+- **iterations**: `[in] int` number of iterations.
+- **elapsed**: `[in] double` elapsed time in seconds.
+
+```c
+void stdlib_bench_print_results( const int iterations, const double elapsed );
+```
+
+#### stdlib_bench_tic()
+
+Returns a clock time.
+
+```c
+double t = stdlib_bench_tic();
+```
+
+```c
+double stdlib_bench_tic( void );
+```
+
+#### stdlib_bench_rand_float64()
+
+Generates a random double-precision floating-point number on the interval `[0,1)`.
+
+```c
+double r = stdlib_bench_rand_float64();
+```
+
+```c
+double stdlib_bench_rand_float64( void );
+```
+
+#### stdlib_bench_rand_float32()
+
+Generates a random single-precision floating-point number on the interval `[0,1)`.
+
+```c
+float r = stdlib_bench_rand_float32();
+```
+
+```c
+float stdlib_bench_rand_float32( void );
+```
+
+#### stdlib_bench_random_uniform( min, max )
+
+Generates a random double-precision floating-point number drawn from a uniform distribution on the interval `[min,max)`.
+
+```c
+double r = stdlib_bench_random_uniform( -10.0, 10.0 );
+```
+
+The function accepts the following arguments:
+
+- **min**: `[in] double` minimum value (inclusive).
+- **max**: `[in] double` maximum value (exclusive).
+
+```c
+double stdlib_bench_random_uniform( const double min, const double max );
+```
+
+
+
+
+
+
+
+
+
+### Notes
+
+- The harness exposes the following identifiers to benchmark code: `iterations` (within benchmark functions), `i` (within benchmark loops), and `len` (within `STDLIB_BENCH_LENGTH_PREAMBLE` blocks and length-based benchmark functions). Every other identifier introduced by the harness is prefixed with `stdlib_bench_` (functions and variables) or `STDLIB_BENCH_` / `STDLIB_BENCHMARK_` (macros), with `STDLIB_RUN_BENCHMARK` and `STDLIB_RUN_LENGTH_BENCHMARK` as the exceptions (their names follow the JavaScript harness's `bench()`/`benchmark()` pairing).
+- `STDLIB_BENCH` must appear after every benchmark function it runs, as `STDLIB_RUN_BENCHMARK` and `STDLIB_RUN_LENGTH_BENCHMARK` call the function directly.
+- The header depends only on the C standard library.
+- The `stdlib_bench_print_*` and `stdlib_bench_tic` helpers are invoked by the harness macros; benchmark code does not normally call them directly.
+
+
+
+
+
+
+
+
+
+### Examples
+
+```c
+#include "stdlib/bench.h"
+#include
+#include
+
+#ifndef BENCHMARK_NAME
+#define BENCHMARK_NAME "sqrt"
+#endif
+
+#define ITERATIONS 1000000
+#define REPEATS 3
+
+STDLIB_BENCHMARK( benchmark ) {
+ double y = 0.0;
+
+ STDLIB_BENCHMARK_LOOP_PREAMBLE {
+ y = sqrt( stdlib_bench_random_uniform( 0.0, 100.0 ) );
+ if ( y != y ) {
+ printf( "should not return NaN\n" );
+ break;
+ }
+ }
+ STDLIB_BENCHMARK_LOOP_EPILOGUE;
+ if ( y != y ) {
+ printf( "should not return NaN\n" );
+ }
+ STDLIB_BENCHMARK_EPILOGUE;
+}
+
+STDLIB_BENCH {
+ STDLIB_BENCH_PREAMBLE( REPEATS, ITERATIONS ) {
+ STDLIB_BENCH_PRINT_NAME();
+ STDLIB_RUN_BENCHMARK( benchmark );
+ }
+}
+```
+
+
+
+
+
+
+
+
+
@@ -92,6 +476,8 @@ This function is an alias for [@stdlib/bench/harness][@stdlib/bench/harness].
[@stdlib/bench/harness]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/bench/harness
+[tap]: https://testanything.org/
+
[@stdlib/utils/timeit]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/utils/timeit
diff --git a/lib/node_modules/@stdlib/bench/examples/c/Makefile b/lib/node_modules/@stdlib/bench/examples/c/Makefile
new file mode 100644
index 000000000000..c8f8e9a1517b
--- /dev/null
+++ b/lib/node_modules/@stdlib/bench/examples/c/Makefile
@@ -0,0 +1,146 @@
+#/
+# @license Apache-2.0
+#
+# Copyright (c) 2026 The Stdlib Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#/
+
+# VARIABLES #
+
+ifndef VERBOSE
+ QUIET := @
+else
+ QUIET :=
+endif
+
+# Determine the OS ([1][1], [2][2]).
+#
+# [1]: https://en.wikipedia.org/wiki/Uname#Examples
+# [2]: http://stackoverflow.com/a/27776822/2225624
+OS ?= $(shell uname)
+ifneq (, $(findstring MINGW,$(OS)))
+ OS := WINNT
+else
+ifneq (, $(findstring MSYS,$(OS)))
+ OS := WINNT
+else
+ifneq (, $(findstring CYGWIN,$(OS)))
+ OS := WINNT
+else
+ifneq (, $(findstring Windows_NT,$(OS)))
+ OS := WINNT
+endif
+endif
+endif
+endif
+
+# Define the program used for compiling C source files:
+ifdef C_COMPILER
+ CC := $(C_COMPILER)
+else
+ CC := gcc
+endif
+
+# Define the command-line options when compiling C files:
+CFLAGS ?= \
+ -std=c99 \
+ -O3 \
+ -Wall \
+ -pedantic
+
+# Determine whether to generate position independent code ([1][1], [2][2]).
+#
+# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options
+# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option
+ifeq ($(OS), WINNT)
+ fPIC ?=
+else
+ fPIC ?= -fPIC
+endif
+
+# List of includes (e.g., `-I /foo/bar -I /beep/boop/include`):
+INCLUDE ?=
+
+# List of source files:
+SOURCE_FILES ?=
+
+# List of libraries (e.g., `-lopenblas -lpthread`):
+LIBRARIES ?=
+
+# List of library paths (e.g., `-L /foo/bar -L /beep/boop`):
+LIBPATH ?=
+
+# List of C targets:
+c_targets := example.out
+
+
+# RULES #
+
+#/
+# Compiles source files.
+#
+# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`)
+# @param {string} [CFLAGS] - C compiler options
+# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`)
+# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`)
+# @param {string} [SOURCE_FILES] - list of source files
+# @param {string} [LIBPATH] - list of library paths (e.g., `-L /foo/bar -L /beep/boop`)
+# @param {string} [LIBRARIES] - list of libraries (e.g., `-lopenblas -lpthread`)
+#
+# @example
+# make
+#
+# @example
+# make all
+#/
+all: $(c_targets)
+
+.PHONY: all
+
+#/
+# Compiles C source files.
+#
+# @private
+# @param {string} CC - C compiler (e.g., `gcc`)
+# @param {string} CFLAGS - C compiler options
+# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`)
+# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`)
+# @param {string} SOURCE_FILES - list of source files
+# @param {string} LIBPATH - list of library paths (e.g., `-L /foo/bar`)
+# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`)
+#/
+$(c_targets): %.out: %.c
+ $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES)
+
+#/
+# Runs compiled examples.
+#
+# @example
+# make run
+#/
+run: $(c_targets)
+ $(QUIET) ./$<
+
+.PHONY: run
+
+#/
+# Removes generated files.
+#
+# @example
+# make clean
+#/
+clean:
+ $(QUIET) -rm -f *.o *.out
+
+.PHONY: clean
diff --git a/lib/node_modules/@stdlib/bench/examples/c/example.c b/lib/node_modules/@stdlib/bench/examples/c/example.c
new file mode 100644
index 000000000000..20a3523ffa29
--- /dev/null
+++ b/lib/node_modules/@stdlib/bench/examples/c/example.c
@@ -0,0 +1,61 @@
+/**
+* @license Apache-2.0
+*
+* Copyright (c) 2026 The Stdlib Authors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "stdlib/bench.h"
+#include
+#include
+
+#ifndef BENCHMARK_NAME
+#define BENCHMARK_NAME "sqrt"
+#endif
+
+#define ITERATIONS 1000000
+#define REPEATS 3
+
+/**
+* Runs a benchmark.
+*
+* @param iterations number of iterations
+* @return elapsed time in seconds
+*/
+STDLIB_BENCHMARK( benchmark ) {
+ double y = 0.0;
+
+ STDLIB_BENCHMARK_LOOP_PREAMBLE {
+ y = sqrt( stdlib_bench_random_uniform( 0.0, 100.0 ) );
+ if ( y != y ) {
+ printf( "should not return NaN\n" );
+ break;
+ }
+ }
+ STDLIB_BENCHMARK_LOOP_EPILOGUE;
+ if ( y != y ) {
+ printf( "should not return NaN\n" );
+ }
+ STDLIB_BENCHMARK_EPILOGUE;
+}
+
+/**
+* Main execution sequence.
+*/
+STDLIB_BENCH {
+ STDLIB_BENCH_PREAMBLE( REPEATS, ITERATIONS ) {
+ STDLIB_BENCH_PRINT_NAME();
+ STDLIB_RUN_BENCHMARK( benchmark );
+ }
+}
diff --git a/lib/node_modules/@stdlib/bench/include/stdlib/bench.h b/lib/node_modules/@stdlib/bench/include/stdlib/bench.h
new file mode 100644
index 000000000000..d84763e3c3cf
--- /dev/null
+++ b/lib/node_modules/@stdlib/bench/include/stdlib/bench.h
@@ -0,0 +1,525 @@
+/**
+* @license Apache-2.0
+*
+* Copyright (c) 2026 The Stdlib Authors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/**
+* Benchmark harness for C benchmarks.
+*
+* ## Notes
+*
+* - The harness exposes the following identifiers to benchmark code: `iterations` (within benchmark functions), `i` (within benchmark loops), and `len` (within `STDLIB_BENCH_LENGTH_PREAMBLE` blocks and length-based benchmark functions). Every other identifier introduced by the harness is prefixed with `stdlib_bench_` (functions and variables) or `STDLIB_BENCH_` / `STDLIB_BENCHMARK_` (macros), with `STDLIB_RUN_BENCHMARK` and `STDLIB_RUN_LENGTH_BENCHMARK` as the exceptions (their names follow the JavaScript harness's `bench()`/`benchmark()` pairing).
+* - `BENCHMARK_NAME` must be defined as a string literal before any `STDLIB_BENCH_PRINT_NAME*` macro is used. The build tooling defines it from the enclosing package name (e.g., `-DBENCHMARK_NAME="@stdlib/math/base/special/abs"`). A benchmark file should provide a fallback:
+*
+* ```c
+* #ifndef BENCHMARK_NAME
+* #define BENCHMARK_NAME "abs"
+* #endif
+* ```
+*
+* - Output follows the Test Anything Protocol (TAP) version 13 and matches the output of hand-written stdlib C benchmarks.
+* - `STDLIB_BENCH` must appear after every benchmark function it runs, as `STDLIB_RUN_BENCHMARK` and `STDLIB_RUN_LENGTH_BENCHMARK` call the function directly.
+*
+* ## Examples
+*
+* ```c
+* #include "stdlib/bench.h"
+* #include
+* #include
+*
+* #ifndef BENCHMARK_NAME
+* #define BENCHMARK_NAME "sqrt"
+* #endif
+*
+* STDLIB_BENCHMARK( benchmark ) {
+* double y = 0.0;
+*
+* STDLIB_BENCHMARK_LOOP_PREAMBLE {
+* y = sqrt( stdlib_bench_random_uniform( 0.0, 100.0 ) );
+* if ( y != y ) {
+* printf( "should not return NaN\n" );
+* break;
+* }
+* }
+* STDLIB_BENCHMARK_LOOP_EPILOGUE;
+* if ( y != y ) {
+* printf( "should not return NaN\n" );
+* }
+* STDLIB_BENCHMARK_EPILOGUE;
+* }
+*
+* STDLIB_BENCH {
+* STDLIB_BENCH_PREAMBLE( 3, 1000000 ) {
+* STDLIB_BENCH_PRINT_NAME();
+* STDLIB_RUN_BENCHMARK( benchmark );
+* }
+* }
+* ```
+*/
+#ifndef STDLIB_BENCH_H
+#define STDLIB_BENCH_H
+
+#include
+#include
+#include
+#include
+#include
+
+/**
+* Prints the TAP version.
+*/
+static inline void stdlib_bench_print_version( void ) {
+ printf( "TAP version 13\n" );
+}
+
+/**
+* Prints the TAP summary.
+*
+* @param total total number of tests
+* @param passing total number of passing tests
+*/
+static inline void stdlib_bench_print_summary( const int total, const int passing ) {
+ printf( "#\n" );
+ printf( "1..%d\n", total ); // TAP plan
+ printf( "# total %d\n", total );
+ printf( "# pass %d\n", passing );
+ printf( "#\n" );
+ printf( "# ok\n" );
+}
+
+/**
+* Prints benchmark results.
+*
+* @param iterations number of iterations
+* @param elapsed elapsed time in seconds
+*/
+static inline void stdlib_bench_print_results( const int iterations, const double elapsed ) {
+ double rate = (double)iterations / elapsed;
+ printf( " ---\n" );
+ printf( " iterations: %d\n", iterations );
+ printf( " elapsed: %0.9f\n", elapsed );
+ printf( " rate: %0.9f\n", rate );
+ printf( " ...\n" );
+}
+
+/**
+* Returns a clock time.
+*
+* @return clock time
+*/
+static inline double stdlib_bench_tic( void ) {
+ struct timeval now;
+ gettimeofday( &now, NULL );
+ return (double)now.tv_sec + (double)now.tv_usec/1.0e6;
+}
+
+/**
+* Generates a random double-precision floating-point number on the interval [0,1).
+*
+* @return random number
+*/
+static inline double stdlib_bench_rand_float64( void ) {
+ int r = rand();
+ return (double)r / ( (double)RAND_MAX + 1.0 );
+}
+
+/**
+* Generates a random single-precision floating-point number on the interval [0,1).
+*
+* @return random number
+*/
+static inline float stdlib_bench_rand_float32( void ) {
+ int r = rand();
+ return (float)r / ( (float)RAND_MAX + 1.0f );
+}
+
+/**
+* Generates a random double-precision floating-point number drawn from a uniform distribution on the interval [min,max).
+*
+* @param min minimum value (inclusive)
+* @param max maximum value (exclusive)
+* @return random number
+*/
+static inline double stdlib_bench_random_uniform( const double min, const double max ) {
+ return min + ( stdlib_bench_rand_float64() * ( max - min ) );
+}
+
+/**
+* Macro for defining the main execution sequence.
+*
+* ## Notes
+*
+* - The macro must be immediately followed by a block (`{ ... }`) containing one or more `STDLIB_BENCH_PREAMBLE` or `STDLIB_BENCH_LENGTH_PREAMBLE` loops.
+* - The macro expands to (1) a forward declaration of a static function `stdlib_bench_main`, (2) a `main` function which seeds the C standard library pseudorandom number generator, prints the TAP version, calls `stdlib_bench_main`, and prints the TAP summary, and (3) the signature of `stdlib_bench_main`. The block following the macro is thus the body of `stdlib_bench_main`. For example,
+*
+* ```c
+* STDLIB_BENCH {
+* // ...
+* }
+* ```
+*
+* expands to
+*
+* ```c
+* static void stdlib_bench_main( void );
+* static int stdlib_bench_count = 0;
+* int main( void ) {
+* srand( time( NULL ) );
+* stdlib_bench_print_version();
+* stdlib_bench_main();
+* stdlib_bench_print_summary( stdlib_bench_count, stdlib_bench_count );
+* return 0;
+* }
+* static void stdlib_bench_main( void ) {
+* // ...
+* }
+* ```
+*
+* @example
+* STDLIB_BENCH {
+* STDLIB_BENCH_PREAMBLE( 3, 1000000 ) {
+* STDLIB_BENCH_PRINT_NAME();
+* STDLIB_RUN_BENCHMARK( benchmark );
+* }
+* }
+*/
+#define STDLIB_BENCH \
+ static void stdlib_bench_main( void ); \
+ static int stdlib_bench_count = 0; \
+ int main( void ) { \
+ srand( time( NULL ) ); \
+ stdlib_bench_print_version(); \
+ stdlib_bench_main(); \
+ stdlib_bench_print_summary( stdlib_bench_count, stdlib_bench_count ); \
+ return 0; \
+ } \
+ static void stdlib_bench_main( void )
+
+/**
+* Macro for running a block `repeats` times with a fixed number of iterations.
+*
+* ## Notes
+*
+* - The macro must be immediately followed by a block (`{ ... }`).
+* - Within the block, benchmark functions defined via `STDLIB_BENCHMARK` should be run via `STDLIB_RUN_BENCHMARK`.
+*
+* @param repeats number of repeats
+* @param iterations number of iterations
+*
+* @example
+* STDLIB_BENCH_PREAMBLE( 3, 1000000 ) {
+* STDLIB_BENCH_PRINT_NAME();
+* STDLIB_RUN_BENCHMARK( benchmark );
+* }
+*/
+#define STDLIB_BENCH_PREAMBLE( repeats, iterations ) \
+ for ( int stdlib_bench_iter = (iterations), stdlib_bench_r = 0; stdlib_bench_r < (repeats); stdlib_bench_r++ )
+
+/**
+* Macro for running a block `repeats` times for each array length `10^min`, `10^(min+1)`, ..., `10^max`.
+*
+* ## Notes
+*
+* - The macro must be immediately followed by a block (`{ ... }`).
+* - Within the block, `len` is defined and equal to the current array length.
+* - Within the block, benchmark functions defined via `STDLIB_LENGTH_BENCHMARK` should be run via `STDLIB_RUN_LENGTH_BENCHMARK`.
+* - The number of iterations for a given length is `iterations / 10^(exponent-1)`.
+*
+* @param repeats number of repeats
+* @param iterations number of iterations for the smallest array length
+* @param min minimum exponent
+* @param max maximum exponent
+*
+* @example
+* STDLIB_BENCH_LENGTH_PREAMBLE( 3, 10000000, 1, 6 ) {
+* STDLIB_BENCH_PRINT_NAME_FORMAT( "len=%d", len );
+* STDLIB_RUN_LENGTH_BENCHMARK( benchmark );
+* }
+*/
+#define STDLIB_BENCH_LENGTH_PREAMBLE( repeats, iterations, min, max ) \
+ for ( int stdlib_bench_exp = (min); stdlib_bench_exp <= (max); stdlib_bench_exp++ ) \
+ for ( int len = (int)pow( 10, stdlib_bench_exp ), stdlib_bench_iter = (int)( (iterations) / pow( 10, stdlib_bench_exp-1 ) ), stdlib_bench_r = 0; stdlib_bench_r < (repeats); stdlib_bench_r++ )
+
+/**
+* Macro for printing a benchmark name.
+*
+* ## Notes
+*
+* - Requires `BENCHMARK_NAME` to be defined as a string literal.
+*
+* @example
+* STDLIB_BENCH_PRINT_NAME();
+* // => # c::
+*/
+#define STDLIB_BENCH_PRINT_NAME() \
+ printf( "# c::%s\n", BENCHMARK_NAME )
+
+/**
+* Macro for printing a benchmark name with a formatted suffix.
+*
+* ## Notes
+*
+* - Requires `BENCHMARK_NAME` to be defined as a string literal.
+* - At least one format argument must be provided.
+*
+* @param fmt `printf` format string for the suffix
+* @param ... format arguments
+*
+* @example
+* STDLIB_BENCH_PRINT_NAME_FORMAT( "len=%d", len );
+* // => # c:::len=100
+*/
+#define STDLIB_BENCH_PRINT_NAME_FORMAT( fmt, ... ) \
+ printf( "# c::%s:" fmt "\n", BENCHMARK_NAME, __VA_ARGS__ )
+
+/**
+* Macro for running a benchmark function defined via `STDLIB_BENCHMARK` and printing its results.
+*
+* ## Notes
+*
+* - Must be used within a `STDLIB_BENCH_PREAMBLE` block.
+*
+* @param fn benchmark function defined via `STDLIB_BENCHMARK`
+*
+* @example
+* STDLIB_RUN_BENCHMARK( benchmark );
+*/
+#define STDLIB_RUN_BENCHMARK( fn ) \
+ do { \
+ double stdlib_bench_el; \
+ stdlib_bench_count += 1; \
+ stdlib_bench_el = fn( stdlib_bench_iter ); \
+ stdlib_bench_print_results( stdlib_bench_iter, stdlib_bench_el ); \
+ printf( "ok %d benchmark finished\n", stdlib_bench_count ); \
+ } while ( 0 )
+
+/**
+* Macro for running a benchmark function defined via `STDLIB_LENGTH_BENCHMARK` and printing its results.
+*
+* ## Notes
+*
+* - Must be used within a `STDLIB_BENCH_LENGTH_PREAMBLE` block.
+*
+* @param fn benchmark function defined via `STDLIB_LENGTH_BENCHMARK`
+*
+* @example
+* STDLIB_RUN_LENGTH_BENCHMARK( benchmark );
+*/
+#define STDLIB_RUN_LENGTH_BENCHMARK( fn ) \
+ do { \
+ double stdlib_bench_el; \
+ stdlib_bench_count += 1; \
+ stdlib_bench_el = fn( stdlib_bench_iter, len ); \
+ stdlib_bench_print_results( stdlib_bench_iter, stdlib_bench_el ); \
+ printf( "ok %d benchmark finished\n", stdlib_bench_count ); \
+ } while ( 0 )
+
+/**
+* Macro for defining a benchmark function.
+*
+* ## Notes
+*
+* - The macro must be immediately followed by a block (`{ ... }`).
+* - Within the block, `iterations` (number of iterations) is defined.
+* - The block must contain `STDLIB_BENCHMARK_LOOP_PREAMBLE`, `STDLIB_BENCHMARK_LOOP_EPILOGUE`, and `STDLIB_BENCHMARK_EPILOGUE`, in that order.
+*
+* @param fn function name
+*
+* @example
+* STDLIB_BENCHMARK( benchmark ) {
+* double y = 0.0;
+*
+* STDLIB_BENCHMARK_LOOP_PREAMBLE {
+* y = sqrt( stdlib_bench_random_uniform( 0.0, 100.0 ) );
+* if ( y != y ) {
+* printf( "should not return NaN\n" );
+* break;
+* }
+* }
+* STDLIB_BENCHMARK_LOOP_EPILOGUE;
+* if ( y != y ) {
+* printf( "should not return NaN\n" );
+* }
+* STDLIB_BENCHMARK_EPILOGUE;
+* }
+*/
+#define STDLIB_BENCHMARK( fn ) \
+ static double fn( int iterations )
+
+/**
+* Macro for defining a length-based benchmark function.
+*
+* ## Notes
+*
+* - The macro must be immediately followed by a block (`{ ... }`).
+* - Within the block, `iterations` (number of iterations) and `len` (array length) are defined.
+* - The block must contain `STDLIB_BENCHMARK_LOOP_PREAMBLE`, `STDLIB_BENCHMARK_LOOP_EPILOGUE`, and `STDLIB_BENCHMARK_EPILOGUE`, in that order.
+*
+* @param fn function name
+*
+* @example
+* STDLIB_LENGTH_BENCHMARK( benchmark ) {
+* double y = 0.0;
+*
+* STDLIB_BENCHMARK_MALLOC_ARRAY_FLOAT64( x, len );
+* STDLIB_BENCHMARK_FILL_ARRAY( x, len, stdlib_bench_random_uniform( -100.0, 100.0 ) );
+*
+* STDLIB_BENCHMARK_LOOP_PREAMBLE {
+* y = x[ i%len ];
+* if ( y != y ) {
+* printf( "should not return NaN\n" );
+* break;
+* }
+* }
+* STDLIB_BENCHMARK_LOOP_EPILOGUE;
+* if ( y != y ) {
+* printf( "should not return NaN\n" );
+* }
+* STDLIB_BENCHMARK_FREE( x );
+* STDLIB_BENCHMARK_EPILOGUE;
+* }
+*/
+#define STDLIB_LENGTH_BENCHMARK( fn ) \
+ static double fn( int iterations, int len )
+
+/**
+* Macro for starting a benchmark timer and beginning the benchmark loop.
+*
+* ## Notes
+*
+* - The macro must be immediately followed by a block (`{ ... }`).
+* - Within the block, `i` is defined and equal to the current iteration.
+*
+* @example
+* STDLIB_BENCHMARK_LOOP_PREAMBLE {
+* y = sqrt( stdlib_bench_random_uniform( 0.0, 100.0 ) );
+* }
+*/
+#define STDLIB_BENCHMARK_LOOP_PREAMBLE \
+ double stdlib_bench_elapsed = 0.0; \
+ double stdlib_bench_t = stdlib_bench_tic(); \
+ for ( int i = 0; i < iterations; i++ )
+
+/**
+* Macro for stopping a benchmark timer.
+*
+* @example
+* STDLIB_BENCHMARK_LOOP_EPILOGUE;
+*/
+#define STDLIB_BENCHMARK_LOOP_EPILOGUE \
+ stdlib_bench_elapsed = stdlib_bench_tic() - stdlib_bench_t
+
+/**
+* Macro for returning the elapsed time from a benchmark function.
+*
+* @example
+* STDLIB_BENCHMARK_EPILOGUE;
+*/
+#define STDLIB_BENCHMARK_EPILOGUE \
+ return stdlib_bench_elapsed
+
+/**
+* Macro for declaring a pointer and allocating an array.
+*
+* @param type element type
+* @param x variable name
+* @param n number of elements
+*
+* @example
+* STDLIB_BENCHMARK_MALLOC_ARRAY( double, x, 100 );
+*/
+#define STDLIB_BENCHMARK_MALLOC_ARRAY( type, x, n ) \
+ type *x = (type *)malloc( (size_t)(n) * sizeof( type ) )
+
+/**
+* Macro for declaring a pointer and allocating a double-precision floating-point array.
+*
+* @param x variable name
+* @param n number of elements
+*
+* @example
+* STDLIB_BENCHMARK_MALLOC_ARRAY_FLOAT64( x, 100 );
+*/
+#define STDLIB_BENCHMARK_MALLOC_ARRAY_FLOAT64( x, n ) \
+ STDLIB_BENCHMARK_MALLOC_ARRAY( double, x, n )
+
+/**
+* Macro for declaring a pointer and allocating a single-precision floating-point array.
+*
+* @param x variable name
+* @param n number of elements
+*
+* @example
+* STDLIB_BENCHMARK_MALLOC_ARRAY_FLOAT32( x, 100 );
+*/
+#define STDLIB_BENCHMARK_MALLOC_ARRAY_FLOAT32( x, n ) \
+ STDLIB_BENCHMARK_MALLOC_ARRAY( float, x, n )
+
+/**
+* Macro for filling a strided array with a value.
+*
+* ## Notes
+*
+* - Following stdlib strided array conventions, a negative stride fills the array starting from the last indexed element (i.e., the first indexed element is at index `(1-n)*stride`).
+*
+* @param x array
+* @param n number of indexed elements
+* @param stride stride length
+* @param value fill value (evaluated once per indexed element)
+*
+* @example
+* STDLIB_BENCHMARK_FILL_STRIDED_ARRAY( x, 50, 2, 0.0 );
+*
+* @example
+* STDLIB_BENCHMARK_FILL_STRIDED_ARRAY( x, 50, 2, stdlib_bench_random_uniform( -10.0, 10.0 ) );
+*/
+#define STDLIB_BENCHMARK_FILL_STRIDED_ARRAY( x, n, stride, value ) \
+ do { \
+ int stdlib_bench_ix = ( (stride) < 0 ) ? ( 1-(n) ) * (stride) : 0; \
+ for ( int stdlib_bench_k = 0; stdlib_bench_k < (n); stdlib_bench_k++ ) { \
+ (x)[ stdlib_bench_ix ] = (value); \
+ stdlib_bench_ix += (stride); \
+ } \
+ } while ( 0 )
+
+/**
+* Macro for filling an array with a value.
+*
+* @param x array
+* @param n number of elements
+* @param value fill value (evaluated once per element)
+*
+* @example
+* STDLIB_BENCHMARK_FILL_ARRAY( x, 100, 0.0 );
+*
+* @example
+* STDLIB_BENCHMARK_FILL_ARRAY( x, 100, stdlib_bench_random_uniform( -10.0, 10.0 ) );
+*/
+#define STDLIB_BENCHMARK_FILL_ARRAY( x, n, value ) \
+ STDLIB_BENCHMARK_FILL_STRIDED_ARRAY( x, n, 1, value )
+
+/**
+* Macro for freeing an array allocated via `STDLIB_BENCHMARK_MALLOC_ARRAY*`.
+*
+* @param x array
+*
+* @example
+* STDLIB_BENCHMARK_FREE( x );
+*/
+#define STDLIB_BENCHMARK_FREE( x ) \
+ free( x )
+
+#endif // !STDLIB_BENCH_H
diff --git a/lib/node_modules/@stdlib/bench/manifest.json b/lib/node_modules/@stdlib/bench/manifest.json
new file mode 100644
index 000000000000..844d692f6439
--- /dev/null
+++ b/lib/node_modules/@stdlib/bench/manifest.json
@@ -0,0 +1,36 @@
+{
+ "options": {},
+ "fields": [
+ {
+ "field": "src",
+ "resolve": true,
+ "relative": true
+ },
+ {
+ "field": "include",
+ "resolve": true,
+ "relative": true
+ },
+ {
+ "field": "libraries",
+ "resolve": false,
+ "relative": false
+ },
+ {
+ "field": "libpath",
+ "resolve": true,
+ "relative": false
+ }
+ ],
+ "confs": [
+ {
+ "src": [],
+ "include": [
+ "./include"
+ ],
+ "libraries": [],
+ "libpath": [],
+ "dependencies": []
+ }
+ ]
+}
diff --git a/lib/node_modules/@stdlib/bench/package.json b/lib/node_modules/@stdlib/bench/package.json
index 8d2db36b4d2b..855173d7aac9 100644
--- a/lib/node_modules/@stdlib/bench/package.json
+++ b/lib/node_modules/@stdlib/bench/package.json
@@ -20,6 +20,7 @@
"directories": {
"doc": "./docs",
"example": "./examples",
+ "include": "./include",
"lib": "./lib",
"test": "./test"
},
diff --git a/lib/node_modules/@stdlib/blas/ext/base/zindex-of-truthy/benchmark/c/Makefile b/lib/node_modules/@stdlib/blas/ext/base/zindex-of-truthy/benchmark/c/Makefile
index 0756dc7da20a..32329d7629b6 100644
--- a/lib/node_modules/@stdlib/blas/ext/base/zindex-of-truthy/benchmark/c/Makefile
+++ b/lib/node_modules/@stdlib/blas/ext/base/zindex-of-truthy/benchmark/c/Makefile
@@ -81,6 +81,16 @@ LIBRARIES ?=
# List of library paths (e.g., `-L /foo/bar -L /beep/boop`):
LIBPATH ?=
+# Benchmark name (typically resolved by the build tooling and used to define `BENCHMARK_NAME`):
+BENCHMARK_NAME ?=
+
+# Compiler definitions:
+ifdef BENCHMARK_NAME
+ DEFINES := -DBENCHMARK_NAME='"$(BENCHMARK_NAME)"'
+else
+ DEFINES :=
+endif
+
# List of C targets:
c_targets := benchmark.length.out
@@ -92,6 +102,7 @@ c_targets := benchmark.length.out
#
# @param {string} [C_COMPILER] - C compiler (e.g., `gcc`)
# @param {string} [CFLAGS] - C compiler options
+# @param {string} [BENCHMARK_NAME] - benchmark name (e.g., `@stdlib/math/base/special/abs`)
# @param {(string|void)} [fPIC] - compiler flag determining whether to generate position independent code (e.g., `-fPIC`)
# @param {string} [INCLUDE] - list of includes (e.g., `-I /foo/bar -I /beep/boop/include`)
# @param {string} [SOURCE_FILES] - list of source files
@@ -114,6 +125,7 @@ all: $(c_targets)
# @private
# @param {string} CC - C compiler (e.g., `gcc`)
# @param {string} CFLAGS - C compiler options
+# @param {(string|void)} DEFINES - compiler definitions (e.g., `-DBENCHMARK_NAME='"@stdlib/math/base/special/abs"'`)
# @param {(string|void)} fPIC - compiler flag determining whether to generate position independent code (e.g., `-fPIC`)
# @param {string} INCLUDE - list of includes (e.g., `-I /foo/bar`)
# @param {string} SOURCE_FILES - list of source files
@@ -121,7 +133,7 @@ all: $(c_targets)
# @param {string} LIBRARIES - list of libraries (e.g., `-lopenblas`)
#/
$(c_targets): %.out: %.c
- $(QUIET) $(CC) $(CFLAGS) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES)
+ $(QUIET) $(CC) $(CFLAGS) $(DEFINES) $(fPIC) $(INCLUDE) -o $@ $(SOURCE_FILES) $< $(LIBPATH) -lm $(LIBRARIES)
#/
# Runs compiled benchmarks.
diff --git a/lib/node_modules/@stdlib/blas/ext/base/zindex-of-truthy/benchmark/c/benchmark.length.c b/lib/node_modules/@stdlib/blas/ext/base/zindex-of-truthy/benchmark/c/benchmark.length.c
index faa1ac640b8c..64bbc21bbac8 100644
--- a/lib/node_modules/@stdlib/blas/ext/base/zindex-of-truthy/benchmark/c/benchmark.length.c
+++ b/lib/node_modules/@stdlib/blas/ext/base/zindex-of-truthy/benchmark/c/benchmark.length.c
@@ -18,76 +18,18 @@
#include "stdlib/blas/ext/base/zindex_of_truthy.h"
#include "stdlib/complex/float64/ctor.h"
-#include
+#include "stdlib/bench.h"
#include
-#include
-#include
-#include
-#define NAME "zindex_of_truthy"
+#ifndef BENCHMARK_NAME
+#define BENCHMARK_NAME "zindex_of_truthy"
+#endif
+
#define ITERATIONS 10000000
#define REPEATS 3
#define MIN 1
#define MAX 6
-/**
-* Prints the TAP version.
-*/
-static void print_version( void ) {
- printf( "TAP version 13\n" );
-}
-
-/**
-* Prints the TAP summary.
-*
-* @param total total number of tests
-* @param passing total number of passing tests
-*/
-static void print_summary( int total, int passing ) {
- printf( "#\n" );
- printf( "1..%d\n", total ); // TAP plan
- printf( "# total %d\n", total );
- printf( "# pass %d\n", passing );
- printf( "#\n" );
- printf( "# ok\n" );
-}
-
-/**
-* Prints benchmarks results.
-*
-* @param iterations number of iterations
-* @param elapsed elapsed time in seconds
-*/
-static void print_results( int iterations, double elapsed ) {
- double rate = (double)iterations / elapsed;
- printf( " ---\n" );
- printf( " iterations: %d\n", iterations );
- printf( " elapsed: %0.9f\n", elapsed );
- printf( " rate: %0.9f\n", rate );
- printf( " ...\n" );
-}
-
-/**
-* Returns a clock time.
-*
-* @return clock time
-*/
-static double tic( void ) {
- struct timeval now;
- gettimeofday( &now, NULL );
- return (double)now.tv_sec + (double)now.tv_usec/1.0e6;
-}
-
-/**
-* Generates a random number on the interval [0,1).
-*
-* @return random number
-*/
-static double rand_double( void ) {
- int r = rand();
- return (double)r / ( (double)RAND_MAX + 1.0 );
-}
-
/**
* Runs a benchmark.
*
@@ -95,21 +37,14 @@ static double rand_double( void ) {
* @param len array length
* @return elapsed time in seconds
*/
-static double benchmark1( int iterations, int len ) {
- double elapsed;
- double *x;
- double t;
- int idx;
- int i;
+STDLIB_LENGTH_BENCHMARK( benchmark1 ) {
+ int idx = -1;
- x = (double *)malloc( (size_t)( len*2 ) * sizeof( double ) );
- for ( i = 0; i < len*2; i++ ) {
- x[ i ] = 0.0;
- }
+ STDLIB_BENCHMARK_MALLOC_ARRAY_FLOAT64( x, len*2 );
+ STDLIB_BENCHMARK_FILL_ARRAY( x, len*2, 0.0 );
x[ (len*2)-1 ] = 1.0;
- idx = -1;
- t = tic();
- for ( i = 0; i < iterations; i++ ) {
+
+ STDLIB_BENCHMARK_LOOP_PREAMBLE {
x[ (len*2)-4 ] = (double)( i % 4 );
idx = stdlib_strided_zindex_of_truthy( len, (const stdlib_complex128_t *)x, 1 );
if ( idx < 0 ) {
@@ -117,12 +52,12 @@ static double benchmark1( int iterations, int len ) {
break;
}
}
- elapsed = tic() - t;
+ STDLIB_BENCHMARK_LOOP_EPILOGUE;
if ( idx < 0 ) {
printf( "unexpected result\n" );
}
- free( x );
- return elapsed;
+ STDLIB_BENCHMARK_FREE( x );
+ STDLIB_BENCHMARK_EPILOGUE;
}
/**
@@ -132,21 +67,14 @@ static double benchmark1( int iterations, int len ) {
* @param len array length
* @return elapsed time in seconds
*/
-static double benchmark2( int iterations, int len ) {
- double elapsed;
- double *x;
- double t;
- int idx;
- int i;
+STDLIB_LENGTH_BENCHMARK( benchmark2 ) {
+ int idx = -1;
- x = (double *)malloc( (size_t)( len*2 ) * sizeof( double ) );
- for ( i = 0; i < len*2; i++ ) {
- x[ i ] = 0.0;
- }
+ STDLIB_BENCHMARK_MALLOC_ARRAY_FLOAT64( x, len*2 );
+ STDLIB_BENCHMARK_FILL_ARRAY( x, len*2, 0.0 );
x[ (len*2)-1 ] = 1.0;
- idx = -1;
- t = tic();
- for ( i = 0; i < iterations; i++ ) {
+
+ STDLIB_BENCHMARK_LOOP_PREAMBLE {
x[ (len*2)-4 ] = (double)( i % 4 );
idx = stdlib_strided_zindex_of_truthy_ndarray( len, (const stdlib_complex128_t *)x, 1, 0 );
if ( idx < 0 ) {
@@ -154,47 +82,24 @@ static double benchmark2( int iterations, int len ) {
break;
}
}
- elapsed = tic() - t;
+ STDLIB_BENCHMARK_LOOP_EPILOGUE;
if ( idx < 0 ) {
printf( "unexpected result\n" );
}
- free( x );
- return elapsed;
+ STDLIB_BENCHMARK_FREE( x );
+ STDLIB_BENCHMARK_EPILOGUE;
}
/**
* Main execution sequence.
*/
-int main( void ) {
- double elapsed;
- int count;
- int iter;
- int len;
- int i;
- int j;
-
- // Use the current time to seed the random number generator:
- srand( time( NULL ) );
-
- print_version();
- count = 0;
- for ( i = MIN; i <= MAX; i++ ) {
- len = pow( 10, i );
- iter = ITERATIONS / pow( 10, i-1 );
- for ( j = 0; j < REPEATS; j++ ) {
- count += 1;
- printf( "# c::%s:len=%d\n", NAME, len );
- elapsed = benchmark1( iter, len );
- print_results( iter, elapsed );
- printf( "ok %d benchmark finished\n", count );
- }
- for ( j = 0; j < REPEATS; j++ ) {
- count += 1;
- printf( "# c::%s:ndarray:len=%d\n", NAME, len );
- elapsed = benchmark2( iter, len );
- print_results( iter, elapsed );
- printf( "ok %d benchmark finished\n", count );
- }
+STDLIB_BENCH {
+ STDLIB_BENCH_LENGTH_PREAMBLE( REPEATS, ITERATIONS, MIN, MAX ) {
+ STDLIB_BENCH_PRINT_NAME_FORMAT( "len=%d", len );
+ STDLIB_RUN_LENGTH_BENCHMARK( benchmark1 );
+ }
+ STDLIB_BENCH_LENGTH_PREAMBLE( REPEATS, ITERATIONS, MIN, MAX ) {
+ STDLIB_BENCH_PRINT_NAME_FORMAT( "ndarray:len=%d", len );
+ STDLIB_RUN_LENGTH_BENCHMARK( benchmark2 );
}
- print_summary( count, count );
}
diff --git a/lib/node_modules/@stdlib/blas/ext/base/zindex-of-truthy/manifest.json b/lib/node_modules/@stdlib/blas/ext/base/zindex-of-truthy/manifest.json
index 42014225e8b2..2ae7b18b92f7 100644
--- a/lib/node_modules/@stdlib/blas/ext/base/zindex-of-truthy/manifest.json
+++ b/lib/node_modules/@stdlib/blas/ext/base/zindex-of-truthy/manifest.json
@@ -65,7 +65,8 @@
"@stdlib/complex/float64/real",
"@stdlib/complex/float64/imag",
"@stdlib/math/base/assert/is-nan",
- "@stdlib/strided/base/stride2offset"
+ "@stdlib/strided/base/stride2offset",
+ "@stdlib/bench"
]
},
{
diff --git a/tools/scripts/compile_c_benchmark b/tools/scripts/compile_c_benchmark
index 13ade48240db..553c195abe94 100755
--- a/tools/scripts/compile_c_benchmark
+++ b/tools/scripts/compile_c_benchmark
@@ -35,12 +35,15 @@
# BLAS_DIR BLAS library path (if custom).
# CEPHES Cephes mathematical library path.
# CEPHES_SRC List of Cephes source files.
+# BENCHMARK_NAME Benchmark name. Default: enclosing package name.
# INCLUDE Includes (e.g., `-I /foo/bar -I /a/b`).
# SOURCE_FILES Source file list.
# LIBRARIES Linked libraries (e.g., `-lopenblas -lpthreads`).
# LIBPATH Library paths (e.g., `-L /foo/bar -L /a/b`).
#
+# shellcheck disable=SC2181,SC2153
+
# VARIABLES #
@@ -84,6 +87,9 @@ cephes="${CEPHES}"
# List of Cephes source files:
cephes_src="${CEPHES_SRC}"
+# Define the benchmark name:
+benchmark_name="${BENCHMARK_NAME}"
+
# Define a list of `include` directories (e.g., `-I /foo/bar -I /beep/boop/include`):
include="${INCLUDE}"
@@ -141,6 +147,22 @@ resolve_pkg_path() {
echo "${pkg_path}"
}
+# Resolves a package name.
+#
+# $1 - package path
+resolve_pkg_name() {
+ local pkg_name
+ local script
+
+ # Generate the script for resolving a package name:
+ script='"'"var path = require('path'); console.log(require(path.join('$1','package.json')).name);"'"'
+
+ # Resolve package name:
+ pkg_name=$(eval NODE_PATH="${node_path}" "${node_cmd}" -e "${script}")
+
+ echo "${pkg_name}"
+}
+
# Resolves a package `manifest.json`.
#
# $1 - package path
@@ -262,8 +284,9 @@ resolve_libpaths() {
# Compiles benchmark.
#
# $1 - source directory
+# $2 - package name
compile() {
- cd "$1" && C_COMPILER="${c_compiler}" INCLUDE="${include}" SOURCE_FILES="${source_files}" LIBRARIES="${libraries}" LIBPATH="${libpath}" CEPHES="${cephes}" CEPHES_SRC="${cephes_src}" make 2>&1
+ cd "$1" && C_COMPILER="${c_compiler}" INCLUDE="${include}" SOURCE_FILES="${source_files}" LIBRARIES="${libraries}" LIBPATH="${libpath}" CEPHES="${cephes}" CEPHES_SRC="${cephes_src}" BENCHMARK_NAME="$2" make 2>&1
if [[ "$?" -ne 0 ]]; then
echo 'Error when attempting to compile benchmark.' >&2
return 1
@@ -278,7 +301,6 @@ compile() {
# Main execution sequence.
main() {
local pkg_path
- local manifest
local src_dir
echo 'Resolving package path...' >&2
@@ -288,8 +310,17 @@ main() {
fi
echo "Package path: ${pkg_path}" >&2
+ if [[ -z "${benchmark_name}" ]]; then
+ echo 'Resolving benchmark name...' >&2
+ benchmark_name=$(resolve_pkg_name "${pkg_path}")
+ if [[ "$?" -ne 0 ]]; then
+ on_error 1
+ fi
+ echo "Benchmark name: ${benchmark_name}" >&2
+ fi
+
echo 'Resolving package manifest...' >&2
- manifest=$(resolve_pkg_manifest "${pkg_path}")
+ resolve_pkg_manifest "${pkg_path}"
if [[ "$?" -eq 0 ]]; then
echo 'Successfully resolved package manifest.' >&2
if [[ -z "${include}" ]]; then
@@ -325,7 +356,7 @@ main() {
fi
echo 'Compiling benchmark...' >&2
src_dir=$(dirname "${file_path}")
- compile "${src_dir}"
+ compile "${src_dir}" "${benchmark_name}"
if [[ "$?" -ne 0 ]]; then
on_error 1
fi