Skip to content

Commit 62a5c3a

Browse files
headlessNodekgryte
andauthored
feat: add C ndarray API and refactor blas/ext/base/dcusumkbn
PR-URL: #2951 Co-authored-by: Athan Reines <kgryte@gmail.com> Reviewed-by: Athan Reines <kgryte@gmail.com> Signed-off-by: Athan Reines <kgryte@gmail.com>
1 parent 7b02c16 commit 62a5c3a

File tree

16 files changed

+368
-178
lines changed

16 files changed

+368
-178
lines changed

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

+135-4
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, 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
119119

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

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

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

159160
console.log( x );
@@ -167,8 +168,138 @@ console.log( y );
167168

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

171+
<!-- C interface documentation. -->
172+
170173
* * *
171174

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

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

+5-4
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 dcusumkbn = require( './../lib/dcusumkbn.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/dcusumkbn/benchmark/benchmark.native.js

+5-4
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 dcusumkbn = tryRequire( resolve( __dirname, './../lib/dcusumkbn.native.js' ) );
3839
var opts = {
3940
'skip': ( dcusumkbn 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/dcusumkbn/benchmark/benchmark.ndarray.js

+5-4
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 dcusumkbn = 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/dcusumkbn/benchmark/benchmark.ndarray.native.js

+5-4
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 dcusumkbn = tryRequire( resolve( __dirname, './../lib/ndarray.native.js' ) );
3839
var opts = {
3940
'skip': ( dcusumkbn 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/dcusumkbn/benchmark/c/benchmark.length.c

+47-2
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ 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;
9999
double x[ len ];
100100
double y[ len ];
@@ -121,6 +121,40 @@ static double benchmark( int iterations, int len ) {
121121
return elapsed;
122122
}
123123

124+
/**
125+
* Runs a benchmark.
126+
*
127+
* @param iterations number of iterations
128+
* @param len array length
129+
* @return elapsed time in seconds
130+
*/
131+
static double benchmark2( int iterations, int len ) {
132+
double elapsed;
133+
double x[ len ];
134+
double y[ len ];
135+
double t;
136+
int i;
137+
138+
for ( i = 0; i < len; i++ ) {
139+
x[ i ] = ( rand_double() * 20000.0 ) - 10000.0;
140+
y[ i ] = 0.0;
141+
}
142+
t = tic();
143+
for ( i = 0; i < iterations; i++ ) {
144+
x[ 0 ] += 1.0;
145+
stdlib_strided_dcusumkbn_ndarray( len, 0.0, x, 1, 0, y, 1, 0 );
146+
if ( y[ 0 ] != y[ 0 ] ) {
147+
printf( "should not return NaN\n" );
148+
break;
149+
}
150+
}
151+
elapsed = tic() - t;
152+
if ( y[ len-1 ] != y[ len-1 ] ) {
153+
printf( "should not return NaN\n" );
154+
}
155+
return elapsed;
156+
}
157+
124158
/**
125159
* Main execution sequence.
126160
*/
@@ -143,7 +177,18 @@ int main( void ) {
143177
for ( j = 0; j < REPEATS; j++ ) {
144178
count += 1;
145179
printf( "# c::%s:len=%d\n", NAME, len );
146-
elapsed = benchmark( iter, len );
180+
elapsed = benchmark1( iter, len );
181+
print_results( iter, elapsed );
182+
printf( "ok %d benchmark finished\n", count );
183+
}
184+
}
185+
for ( i = MIN; i <= MAX; i++ ) {
186+
len = pow( 10, i );
187+
iter = ITERATIONS / pow( 10, i-1 );
188+
for ( j = 0; j < REPEATS; j++ ) {
189+
count += 1;
190+
printf( "# c::%s:ndarray:len=%d\n", NAME, len );
191+
elapsed = benchmark2( iter, len );
147192
print_results( iter, elapsed );
148193
printf( "ok %d benchmark finished\n", count );
149194
}

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

+2-2
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 an improved Kahan–Babuška algorithm.
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
@@ -67,7 +67,7 @@
6767
semantics.
6868

6969
While typed array views mandate a view offset based on the underlying
70-
buffer, the `offset` parameter supports indexing semantics based on a
70+
buffer, the offset parameter supports indexing semantics based on a
7171
starting index.
7272

7373
Parameters

lib/node_modules/@stdlib/blas/ext/base/dcusumkbn/examples/c/example.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,17 @@ int main( void ) {
2727
double y[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
2828

2929
// Specify the number of elements:
30-
const int64_t N = 4;
30+
const int N = 4;
3131

3232
// Specify stride lengths:
33-
const int64_t strideX = 2;
34-
const int64_t strideY = -2;
33+
const int strideX = 2;
34+
const int strideY = -2;
3535

3636
// Compute the cumulative sum:
3737
stdlib_strided_dcusumkbn( N, 0.0, x, strideX, y, strideY );
3838

3939
// Print the result:
40-
for ( int64_t i = 0; i < 8; i++ ) {
40+
for ( int i = 0; i < 8; i++ ) {
4141
printf( "y[ %"PRId64" ] = %lf\n", i, y[ i ] );
4242
}
4343
}

0 commit comments

Comments
 (0)