Skip to content

Commit 3bd3f48

Browse files
headlessNodekgryte
andauthored
feat: add C ndarray API and refactor blas/ext/base/dcusumpw
PR-URL: #2981 Co-authored-by: Athan Reines <[email protected]> Reviewed-by: Athan Reines <[email protected]> Signed-off-by: Athan Reines <[email protected]>
1 parent ca2fbd0 commit 3bd3f48

File tree

15 files changed

+313
-125
lines changed

15 files changed

+313
-125
lines changed

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

Lines changed: 135 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ The function has the following additional parameters:
115115
- **offsetX**: starting index for `x`.
116116
- **offsetY**: starting index for `y`.
117117

118-
While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying `buffer`, `offsetX` and `offsetY` parameters support indexing semantics based on a starting indices. For example, to calculate the cumulative sum of every other value in the strided input array starting from the second value and to store in the last `N` elements of the strided output array starting from the last element
118+
While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying buffer, offset parameters support indexing semantics based on starting indices. For example, to calculate the cumulative sum of every other value in the strided input array starting from the second value and to store in the last `N` elements of the strided output array starting from the last element
119119

120120
```javascript
121121
var Float64Array = require( '@stdlib/array/float64' );
@@ -149,12 +149,13 @@ dcusumpw.ndarray( 4, 0.0, x, 2, 1, y, -1, y.length-1 );
149149
<!-- eslint no-undef: "error" -->
150150

151151
```javascript
152-
var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ).factory;
153-
var filledarrayBy = require( '@stdlib/array/filled-by' );
152+
var discreteUniform = require( '@stdlib/random/array/discrete-uniform' );
154153
var Float64Array = require( '@stdlib/array/float64' );
155154
var dcusumpw = require( '@stdlib/blas/ext/base/dcusumpw' );
156155

157-
var x = filledarrayBy( 10, 'float64', discreteUniform( 0, 100 ) );
156+
var x = discreteUniform( 10, -100, 100, {
157+
'dtype': 'float64'
158+
});
158159
var y = new Float64Array( x.length );
159160

160161
console.log( x );
@@ -168,8 +169,138 @@ console.log( y );
168169

169170
<!-- /.examples -->
170171

172+
<!-- C interface documentation. -->
173+
171174
* * *
172175

176+
<section class="c">
177+
178+
## C APIs
179+
180+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
181+
182+
<section class="intro">
183+
184+
</section>
185+
186+
<!-- /.intro -->
187+
188+
<!-- C usage documentation. -->
189+
190+
<section class="usage">
191+
192+
### Usage
193+
194+
```c
195+
#include "stdlib/blas/ext/base/dcusumpw.h"
196+
```
197+
198+
#### stdlib_strided_dcusumpw( N, sum, \*X, strideX, \*Y, strideY )
199+
200+
Computes the cumulative sum of double-precision floating-point strided array elements using pairwise summation.
201+
202+
```c
203+
const double x[] = { 1.0, 2.0, 3.0, 4.0 };
204+
double y[] = { 0.0, 0.0, 0.0, 0.0 };
205+
206+
stdlib_strided_dcusumpw( 4, 0.0, x, 1, y, 1 );
207+
```
208+
209+
The function accepts the following arguments:
210+
211+
- **N**: `[in] CBLAS_INT` number of indexed elements.
212+
- **sum**: `[in] double` initial sum.
213+
- **X**: `[in] double*` input array.
214+
- **strideX**: `[in] CBLAS_INT` index increment for `X`.
215+
- **Y**: `[out] double*` output array.
216+
- **strideY**: `[in] CBLAS_INT` index increment for `Y`.
217+
218+
```c
219+
void stdlib_strided_dcusumpw( const CBLAS_INT N, const double sum, const double *X, const CBLAS_INT strideX, double *Y, const CBLAS_INT strideY );
220+
```
221+
222+
<!-- lint disable maximum-heading-length -->
223+
224+
#### stdlib_strided_dcusumpw_ndarray( N, sum, \*X, strideX, offsetX, \*Y, strideY, offsetY )
225+
226+
<!-- lint enable maximum-heading-length -->
227+
228+
Computes the cumulative sum of double-precision floating-point strided array elements using pairwise summation and alternative indexing semantics.
229+
230+
```c
231+
const double x[] = { 1.0, 2.0, 3.0, 4.0 }
232+
double y[] = { 0.0, 0.0, 0.0, 0.0 }
233+
234+
stdlib_strided_dcusumpw_ndarray( 4, 0.0, x, 1, 0, y, 1, 0 );
235+
```
236+
237+
The function accepts the following arguments:
238+
239+
- **N**: `[in] CBLAS_INT` number of indexed elements.
240+
- **sum**: `[in] double` initial sum.
241+
- **X**: `[in] double*` input array.
242+
- **strideX**: `[in] CBLAS_INT` index increment for `X`.
243+
- **offsetX**: `[in] CBLAS_INT` starting index for `X`.
244+
- **Y**: `[out] double*` output array.
245+
- **strideY**: `[in] CBLAS_INT` index increment for `Y`.
246+
- **offsetY**: `[in] CBLAS_INT` starting index for `Y`.
247+
248+
```c
249+
void stdlib_strided_dcusumpw_ndarray( const CBLAS_INT N, const double sum, const double *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, double *Y, const CBLAS_INT strideY, const CBLAS_INT offsetY );
250+
```
251+
252+
</section>
253+
254+
<!-- /.usage -->
255+
256+
<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
257+
258+
<section class="notes">
259+
260+
</section>
261+
262+
<!-- /.notes -->
263+
264+
<!-- C API usage examples. -->
265+
266+
<section class="examples">
267+
268+
### Examples
269+
270+
```c
271+
#include "stdlib/blas/ext/base/dcusumpw.h"
272+
#include <stdio.h>
273+
274+
int main( void ) {
275+
// Create strided arrays:
276+
const double x[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 };
277+
double y[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
278+
279+
// Specify the number of elements:
280+
const int N = 4;
281+
282+
// Specify stride lengths:
283+
const int strideX = 2;
284+
const int strideY = -2;
285+
286+
// Compute the cumulative sum:
287+
stdlib_strided_dcusumpw( N, 0.0, x, strideX, y, strideY );
288+
289+
// Print the result:
290+
for ( int i = 0; i < 8; i++ ) {
291+
printf( "y[ %d ] = %lf\n", i, y[ i ] );
292+
}
293+
}
294+
```
295+
296+
</section>
297+
298+
<!-- /.examples -->
299+
300+
</section>
301+
302+
<!-- /.c -->
303+
173304
<section class="references">
174305
175306
## References

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
// MODULES //
2222

2323
var bench = require( '@stdlib/bench' );
24-
var uniform = require( '@stdlib/random/base/uniform' ).factory;
25-
var filledarrayBy = require( '@stdlib/array/filled-by' );
24+
var uniform = require( '@stdlib/random/array/uniform' );
2625
var isnan = require( '@stdlib/math/base/assert/is-nan' );
2726
var pow = require( '@stdlib/math/base/special/pow' );
2827
var Float64Array = require( '@stdlib/array/float64' );
@@ -32,7 +31,9 @@ var dcusumpw = require( './../lib/dcusumpw.js' );
3231

3332
// VARIABLES //
3433

35-
var rand = uniform( -10.0, 10.0 );
34+
var options = {
35+
'dtype': 'float64'
36+
};
3637

3738

3839
// FUNCTIONS //
@@ -45,7 +46,7 @@ var rand = uniform( -10.0, 10.0 );
4546
* @returns {Function} benchmark function
4647
*/
4748
function createBenchmark( len ) {
48-
var x = filledarrayBy( len, 'float64', rand );
49+
var x = uniform( len, -100, 100, options );
4950
var y = new Float64Array( len );
5051
return benchmark;
5152

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@
2222

2323
var resolve = require( 'path' ).resolve;
2424
var bench = require( '@stdlib/bench' );
25-
var uniform = require( '@stdlib/random/base/uniform' ).factory;
26-
var filledarrayBy = require( '@stdlib/array/filled-by' );
25+
var uniform = require( '@stdlib/random/array/uniform' );
2726
var isnan = require( '@stdlib/math/base/assert/is-nan' );
2827
var pow = require( '@stdlib/math/base/special/pow' );
2928
var Float64Array = require( '@stdlib/array/float64' );
@@ -33,7 +32,9 @@ var pkg = require( './../package.json' ).name;
3332

3433
// VARIABLES //
3534

36-
var rand = uniform( -10.0, 10.0 );
35+
var options = {
36+
'dtype': 'float64'
37+
};
3738
var dcusumpw = tryRequire( resolve( __dirname, './../lib/dcusumpw.native.js' ) );
3839
var opts = {
3940
'skip': ( dcusumpw instanceof Error )
@@ -50,7 +51,7 @@ var opts = {
5051
* @returns {Function} benchmark function
5152
*/
5253
function createBenchmark( len ) {
53-
var x = filledarrayBy( len, 'float64', rand );
54+
var x = uniform( len, -100, 100, options );
5455
var y = new Float64Array( len );
5556
return benchmark;
5657

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
// MODULES //
2222

2323
var bench = require( '@stdlib/bench' );
24-
var uniform = require( '@stdlib/random/base/uniform' ).factory;
25-
var filledarrayBy = require( '@stdlib/array/filled-by' );
24+
var uniform = require( '@stdlib/random/array/uniform' );
2625
var isnan = require( '@stdlib/math/base/assert/is-nan' );
2726
var pow = require( '@stdlib/math/base/special/pow' );
2827
var Float64Array = require( '@stdlib/array/float64' );
@@ -32,7 +31,9 @@ var dcusumpw = require( './../lib/ndarray.js' );
3231

3332
// VARIABLES //
3433

35-
var rand = uniform( -10.0, 10.0 );
34+
var options = {
35+
'dtype': 'float64'
36+
};
3637

3738

3839
// FUNCTIONS //
@@ -45,7 +46,7 @@ var rand = uniform( -10.0, 10.0 );
4546
* @returns {Function} benchmark function
4647
*/
4748
function createBenchmark( len ) {
48-
var x = filledarrayBy( len, 'float64', rand );
49+
var x = uniform( len, -100, 100, options );
4950
var y = new Float64Array( len );
5051
return benchmark;
5152

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@
2222

2323
var resolve = require( 'path' ).resolve;
2424
var bench = require( '@stdlib/bench' );
25-
var uniform = require( '@stdlib/random/base/uniform' ).factory;
26-
var filledarrayBy = require( '@stdlib/array/filled-by' );
25+
var uniform = require( '@stdlib/random/array/uniform' );
2726
var isnan = require( '@stdlib/math/base/assert/is-nan' );
2827
var pow = require( '@stdlib/math/base/special/pow' );
2928
var Float64Array = require( '@stdlib/array/float64' );
@@ -33,7 +32,9 @@ var pkg = require( './../package.json' ).name;
3332

3433
// VARIABLES //
3534

36-
var rand = uniform( -10.0, 10.0 );
35+
var options = {
36+
'dtype': 'float64'
37+
};
3738
var dcusumpw = tryRequire( resolve( __dirname, './../lib/ndarray.native.js' ) );
3839
var opts = {
3940
'skip': ( dcusumpw instanceof Error )
@@ -50,7 +51,7 @@ var opts = {
5051
* @returns {Function} benchmark function
5152
*/
5253
function createBenchmark( len ) {
53-
var x = filledarrayBy( len, 'float64', rand );
54+
var x = uniform( len, -100, 100, options );
5455
var y = new Float64Array( len );
5556
return benchmark;
5657

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

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,16 @@ static double rand_double( 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;
99-
double x[ len ];
100-
double y[ len ];
99+
double *x;
100+
double *y;
101101
double t;
102102
int i;
103103

104+
x = (double *)malloc( len * sizeof(double) );
105+
y = (double *)malloc( len * sizeof(double) );
106+
104107
for ( i = 0; i < len; i++ ) {
105108
x[ i ] = ( rand_double() * 20000.0 ) - 10000.0;
106109
y[ i ] = 0.0;
@@ -118,6 +121,47 @@ static double benchmark( int iterations, int len ) {
118121
if ( y[ len-1 ] != y[ len-1 ] ) {
119122
printf( "should not return NaN\n" );
120123
}
124+
free( x );
125+
free( y );
126+
return elapsed;
127+
}
128+
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+
double *x;
139+
double *y;
140+
double t;
141+
int i;
142+
143+
x = (double *)malloc( len * sizeof(double) );
144+
y = (double *)malloc( len * sizeof(double) );
145+
146+
for ( i = 0; i < len; i++ ) {
147+
x[ i ] = ( rand_double() * 20000.0 ) - 10000.0;
148+
y[ i ] = 0.0;
149+
}
150+
t = tic();
151+
for ( i = 0; i < iterations; i++ ) {
152+
x[ 0 ] += 1.0;
153+
stdlib_strided_dcusumpw_ndarray( len, 0.0, x, 1, 0, y, 1, 0 );
154+
if ( y[ 0 ] != y[ 0 ] ) {
155+
printf( "should not return NaN\n" );
156+
break;
157+
}
158+
}
159+
elapsed = tic() - t;
160+
if ( y[ len-1 ] != y[ len-1 ] ) {
161+
printf( "should not return NaN\n" );
162+
}
163+
free( x );
164+
free( y );
121165
return elapsed;
122166
}
123167

@@ -143,7 +187,18 @@ int main( void ) {
143187
for ( j = 0; j < REPEATS; j++ ) {
144188
count += 1;
145189
printf( "# c::%s:len=%d\n", NAME, len );
146-
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 );
147202
print_results( iter, elapsed );
148203
printf( "ok %d benchmark finished\n", count );
149204
}

lib/node_modules/@stdlib/blas/ext/base/dcusumpw/docs/repl.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Computes the cumulative sum of double-precision floating-point strided array
44
elements using pairwise summation.
55

6-
The `N` and `stride` parameters determine which elements in the strided
6+
The `N` and stride parameters determine which elements in the strided
77
arrays are accessed at runtime.
88

99
Indexing is relative to the first index. To introduce an offset, use a typed
@@ -66,8 +66,8 @@
6666
elements using pairwise summation and alternative indexing semantics.
6767

6868
While typed array views mandate a view offset based on the underlying
69-
buffer, the `offset` parameter supports indexing semantics based on a
70-
starting index.
69+
buffer, offset parameters support indexing semantics based on starting
70+
indices.
7171

7272
Parameters
7373
----------

0 commit comments

Comments
 (0)