Skip to content

Commit a341f85

Browse files
authored
feat: add C ndarray API and refactor blas/ext/base/dsnannsumors
PR-URL: #3086 Reviewed-by: Philipp Burckhardt <[email protected]>
1 parent af8d471 commit a341f85

File tree

21 files changed

+466
-196
lines changed

21 files changed

+466
-196
lines changed

lib/node_modules/@stdlib/blas/ext/base/dsnannsumors/README.md

Lines changed: 131 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ The function has the following parameters:
5555

5656
- **N**: number of indexed elements.
5757
- **x**: input [`Float32Array`][@stdlib/array/float32].
58-
- **strideX**: index increment for `x`.
58+
- **strideX**: stride length for `x`.
5959
- **out**: output [`Float64Array`][@stdlib/array/float64] whose first element is the sum and whose second element is the number of non-NaN elements.
60-
- **strideOut**: index increment for `out`.
60+
- **strideOut**: stride length for `out`.
6161

62-
The `N` and stride parameters determine which elements are accessed at runtime. For example, to compute the sum of every other element in `x`,
62+
The `N` and stride parameters determine which elements are accessed at runtime. For example, to compute the sum of every other element:
6363

6464
```javascript
6565
var Float32Array = require( '@stdlib/array/float32' );
@@ -92,7 +92,7 @@ var v = dsnannsumors( 4, x1, 2, out1, 1 );
9292

9393
#### dsnannsumors.ndarray( N, x, strideX, offsetX, out, strideOut, offsetOut )
9494

95-
Computes the sum of single-precision floating-point strided array elements, ignoring `NaN` values and using ordinary recursive summation with extended accumulation and alternative indexing semantics.
95+
Computes the sum of single-precision floating-point strided array elements, ignoring `NaN` values and using ordinary recursive summation with extended accumulation and alternative indexing semantics and returning an extended precision result.
9696

9797
```javascript
9898
var Float32Array = require( '@stdlib/array/float32' );
@@ -110,7 +110,7 @@ The function has the following additional parameters:
110110
- **offsetX**: starting index for `x`.
111111
- **offsetOut**: starting index for `out`.
112112

113-
While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying `buffer`, the `offset` parameter supports indexing semantics based on a starting index. For example, to calculate the sum of every other value in `x` starting from the second value
113+
While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying buffer, the offset parameters support indexing semantics based on starting indices. For example, to calculate the sum of every other element starting from the second element:
114114

115115
```javascript
116116
var Float32Array = require( '@stdlib/array/float32' );
@@ -171,6 +171,132 @@ console.log( out );
171171

172172
<!-- /.examples -->
173173

174+
<!-- C interface documentation. -->
175+
176+
* * *
177+
178+
<section class="c">
179+
180+
## C APIs
181+
182+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
183+
184+
<section class="intro">
185+
186+
</section>
187+
188+
<!-- /.intro -->
189+
190+
<!-- C usage documentation. -->
191+
192+
<section class="usage">
193+
194+
### Usage
195+
196+
```c
197+
#include "stdlib/blas/ext/base/dsnannsumors.h"
198+
```
199+
200+
#### stdlib_strided_dsnannsumors( N, \*X, strideX, \*n )
201+
202+
Computes the sum of single-precision floating-point strided array elements, ignoring `NaN` values, using ordinary recursive summation with extended accumulation, and returning an extended precision result.
203+
204+
```c
205+
const float x[] = { 1.0f, -2.0f, 0.0/0.0, 2.0f };
206+
CBLAS_INT n = 0;
207+
208+
double v = stdlib_strided_dsnannsumors( 4, x, 1, &n );
209+
// returns 1.0
210+
```
211+
212+
The function accepts the following arguments:
213+
214+
- **N**: `[in] CBLAS_INT` number of indexed elements.
215+
- **X**: `[in] float*` input array.
216+
- **strideX**: `[in] CBLAS_INT` stride length for `X`.
217+
- **n**: `[out] CBLAS_INT*` number of non-NaN elements.
218+
219+
```c
220+
double stdlib_strided_dsnannsumors( const CBLAS_INT N, const float *X, const CBLAS_INT strideX, CBLAS_INT *n );
221+
```
222+
223+
#### stdlib_strided_dsnannsumors_ndarray( N, \*X, strideX, offsetX, \*n )
224+
225+
Computes the sum of single-precision floating-point strided array elements, ignoring `NaN` values and using ordinary recursive summation with extended accumulation and alternative indexing semantics and returning an extended precision result.
226+
227+
```c
228+
const float x[] = { 1.0f, -2.0f, 0.0/0.0, 2.0f };
229+
CBLAS_INT n = 0;
230+
231+
double v = stdlib_strided_dsnannsumors_ndarray( 4, x, 1, 0, &n );
232+
// returns 1.0
233+
```
234+
235+
The function accepts the following arguments:
236+
237+
- **N**: `[in] CBLAS_INT` number of indexed elements.
238+
- **X**: `[in] float*` input array.
239+
- **strideX**: `[in] CBLAS_INT` stride length for `X`.
240+
- **offsetX**: `[in] CBLAS_INT` starting index for `X`.
241+
- **n**: `[out] CBLAS_INT*` number of non-NaN elements.
242+
243+
```c
244+
double stdlib_strided_dsnannsumors_ndarray( const CBLAS_INT N, const float *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, CBLAS_INT *n );
245+
```
246+
247+
</section>
248+
249+
<!-- /.usage -->
250+
251+
<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
252+
253+
<section class="notes">
254+
255+
</section>
256+
257+
<!-- /.notes -->
258+
259+
<!-- C API usage examples. -->
260+
261+
<section class="examples">
262+
263+
### Examples
264+
265+
```c
266+
#include "stdlib/blas/ext/base/dsnannsumors.h"
267+
#include "stdlib/blas/base/shared.h"
268+
#include <stdio.h>
269+
270+
int main( void ) {
271+
// Create a strided array:
272+
const float x[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 0.0/0.0, 0.0/0.0 };
273+
274+
// Specify the number of elements:
275+
const int N = 5;
276+
277+
// Specify the stride length:
278+
const int strideX = 2;
279+
280+
// Initialize a variable for storing the number of non-NaN elements:
281+
CBLAS_INT n = 0;
282+
283+
// Compute the sum:
284+
double v = stdlib_strided_dsnannsumors( N, x, strideX, &n );
285+
286+
// Print the result:
287+
printf( "sum: %lf\n", v );
288+
printf( "n: %"CBLAS_IFMT"\n", n );
289+
}
290+
```
291+
292+
</section>
293+
294+
<!-- /.examples -->
295+
296+
</section>
297+
298+
<!-- /.c -->
299+
174300
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
175301
176302
<section class="related">

lib/node_modules/@stdlib/blas/ext/base/dsnannsumors/benchmark/benchmark.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ var dsnannsumors = require( './../lib/dsnannsumors.js' );
3333

3434
// FUNCTIONS //
3535

36+
/**
37+
* Returns a random number.
38+
*
39+
* @private
40+
* @returns {number} random number
41+
*/
42+
function rand() {
43+
if ( bernoulli( 0.2 ) ) {
44+
return NaN;
45+
}
46+
return uniform( -10.0, 10.0 );
47+
}
48+
3649
/**
3750
* Creates a benchmark function.
3851
*
@@ -48,13 +61,6 @@ function createBenchmark( len ) {
4861
out = new Float64Array( 2 );
4962
return benchmark;
5063

51-
function rand() {
52-
if ( bernoulli( 0.2 ) ) {
53-
return NaN;
54-
}
55-
return uniform( -10.0, 10.0 );
56-
}
57-
5864
function benchmark( b ) {
5965
var i;
6066

lib/node_modules/@stdlib/blas/ext/base/dsnannsumors/benchmark/benchmark.native.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,19 @@ var opts = {
4242

4343
// FUNCTIONS //
4444

45+
/**
46+
* Returns a random number.
47+
*
48+
* @private
49+
* @returns {number} random number
50+
*/
51+
function rand() {
52+
if ( bernoulli( 0.2 ) ) {
53+
return NaN;
54+
}
55+
return uniform( -10.0, 10.0 );
56+
}
57+
4558
/**
4659
* Creates a benchmark function.
4760
*
@@ -57,13 +70,6 @@ function createBenchmark( len ) {
5770
out = new Float64Array( 2 );
5871
return benchmark;
5972

60-
function rand() {
61-
if ( bernoulli( 0.2 ) ) {
62-
return NaN;
63-
}
64-
return uniform( -10.0, 10.0 );
65-
}
66-
6773
function benchmark( b ) {
6874
var i;
6975

lib/node_modules/@stdlib/blas/ext/base/dsnannsumors/benchmark/benchmark.ndarray.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ var dsnannsumors = require( './../lib/ndarray.js' );
3333

3434
// FUNCTIONS //
3535

36+
/**
37+
* Returns a random number.
38+
*
39+
* @private
40+
* @returns {number} random number
41+
*/
42+
function rand() {
43+
if ( bernoulli( 0.2 ) ) {
44+
return NaN;
45+
}
46+
return uniform( -10.0, 10.0 );
47+
}
48+
3649
/**
3750
* Creates a benchmark function.
3851
*
@@ -48,13 +61,6 @@ function createBenchmark( len ) {
4861
out = new Float64Array( 2 );
4962
return benchmark;
5063

51-
function rand() {
52-
if ( bernoulli( 0.2 ) ) {
53-
return NaN;
54-
}
55-
return uniform( -10.0, 10.0 );
56-
}
57-
5864
function benchmark( b ) {
5965
var i;
6066

lib/node_modules/@stdlib/blas/ext/base/dsnannsumors/benchmark/benchmark.ndarray.native.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,19 @@ var opts = {
4242

4343
// FUNCTIONS //
4444

45+
/**
46+
* Returns a random number.
47+
*
48+
* @private
49+
* @returns {number} random number
50+
*/
51+
function rand() {
52+
if ( bernoulli( 0.2 ) ) {
53+
return NaN;
54+
}
55+
return uniform( -10.0, 10.0 );
56+
}
57+
4558
/**
4659
* Creates a benchmark function.
4760
*
@@ -57,13 +70,6 @@ function createBenchmark( len ) {
5770
out = new Float64Array( 2 );
5871
return benchmark;
5972

60-
function rand() {
61-
if ( bernoulli( 0.2 ) ) {
62-
return NaN;
63-
}
64-
return uniform( -10.0, 10.0 );
65-
}
66-
6773
function benchmark( b ) {
6874
var i;
6975

lib/node_modules/@stdlib/blas/ext/base/dsnannsumors/benchmark/c/benchmark.length.c

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ static float rand_float( void ) {
9494
* @param len array length
9595
* @return elapsed time in seconds
9696
*/
97-
static double benchmark( int iterations, int len ) {
97+
static double benchmark1( int iterations, int len ) {
9898
double elapsed;
9999
float x[ len ];
100100
int64_t n;
@@ -126,6 +126,45 @@ static double benchmark( int iterations, int len ) {
126126
return elapsed;
127127
}
128128

129+
/**
130+
* Runs a benchmark.
131+
*
132+
* @param iterations number of iterations
133+
* @param len array length
134+
* @return elapsed time in seconds
135+
*/
136+
static double benchmark2( int iterations, int len ) {
137+
double elapsed;
138+
float x[ len ];
139+
int64_t n;
140+
double v;
141+
double t;
142+
int i;
143+
144+
for ( i = 0; i < len; i++ ) {
145+
if ( rand_float() < 0.2f ) {
146+
x[ i ] = 0.0f / 0.0f; // NaN
147+
} else {
148+
x[ i ] = ( rand_float() * 20000.0f ) - 10000.0f;
149+
}
150+
}
151+
v = 0.0;
152+
n = 0;
153+
t = tic();
154+
for ( i = 0; i < iterations; i++ ) {
155+
v = stdlib_strided_dsnannsumors_ndarray( len, x, 1, 0, &n );
156+
if ( v != v || n < 0 ) {
157+
printf( "should not return NaN\n" );
158+
break;
159+
}
160+
}
161+
elapsed = tic() - t;
162+
if ( v != v || n < 0 ) {
163+
printf( "should not return NaN\n" );
164+
}
165+
return elapsed;
166+
}
167+
129168
/**
130169
* Main execution sequence.
131170
*/
@@ -148,7 +187,18 @@ int main( void ) {
148187
for ( j = 0; j < REPEATS; j++ ) {
149188
count += 1;
150189
printf( "# c::%s:len=%d\n", NAME, len );
151-
elapsed = benchmark( iter, len );
190+
elapsed = benchmark1( iter, len );
191+
print_results( iter, elapsed );
192+
printf( "ok %d benchmark finished\n", count );
193+
}
194+
}
195+
for ( i = MIN; i <= MAX; i++ ) {
196+
len = pow( 10, i );
197+
iter = ITERATIONS / pow( 10, i-1 );
198+
for ( j = 0; j < REPEATS; j++ ) {
199+
count += 1;
200+
printf( "# c::%s:ndarray:len=%d\n", NAME, len );
201+
elapsed = benchmark2( iter, len );
152202
print_results( iter, elapsed );
153203
printf( "ok %d benchmark finished\n", count );
154204
}

0 commit comments

Comments
 (0)