Skip to content

Commit b16259c

Browse files
authored
feat: add C ndarray implementation for blas/base/dscal
PR-URL: #2915 Ref: #2039 Reviewed-by: Athan Reines <[email protected]>
1 parent 226a6d8 commit b16259c

File tree

18 files changed

+331
-138
lines changed

18 files changed

+331
-138
lines changed

lib/node_modules/@stdlib/blas/base/dscal/README.md

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ dscal( 3, 5.0, x1, 2 );
7777
// x0 => <Float64Array>[ 1.0, -10.0, 3.0, -20.0, 5.0, -30.0 ]
7878
```
7979

80-
If either `N` or `stride` is less than or equal to `0`, the function returns `x` unchanged.
80+
If `N` is less than or equal to `0`, the function returns `x` unchanged.
8181

8282
#### dscal.ndarray( N, alpha, x, stride, offset )
8383

@@ -193,6 +193,28 @@ The function accepts the following arguments:
193193
void c_dscal( const CBLAS_INT N, const double alpha, double *X, const CBLAS_INT stride );
194194
```
195195

196+
#### c_dscal_ndarray( N, alpha, \*X, stride, offset )
197+
198+
Multiplies each element of a double-precision floating-point vector by a constant using alternative indexing semantics.
199+
200+
```c
201+
double x[] = { 1.0, 2.0, 3.0, 4.0 };
202+
203+
c_dscal_ndarray( 4, 5.0, x, 1, 0 );
204+
```
205+
206+
The function accepts the following arguments:
207+
208+
- **N**: `[in] CBLAS_INT` number of indexed elements.
209+
- **alpha**: `[in] double` scalar constant.
210+
- **X**: `[inout] double*` input array.
211+
- **stride**: `[in] CBLAS_INT` index increment for `X`.
212+
- **offset**: `[in] CBLAS_INT` starting index for `X`.
213+
214+
```c
215+
void c_dscal_ndarray( const CBLAS_INT N, const double alpha, double *X, const CBLAS_INT stride, const CBLAS_INT offset );
216+
```
217+
196218
</section>
197219

198220
<!-- /.usage -->
@@ -223,10 +245,18 @@ int main( void ) {
223245
const int N = 8;
224246

225247
// Specify a stride:
226-
const int strideX = 1;
248+
const int stride = 1;
249+
250+
// Scale the vector:
251+
c_dscal( N, 5.0, x, stride );
252+
253+
// Print the result:
254+
for ( int i = 0; i < 8; i++ ) {
255+
printf( "x[ %i ] = %lf\n", i, x[ i ] );
256+
}
227257

228258
// Scale the vector:
229-
c_dscal( N, 5.0, x, strideX );
259+
c_dscal_ndarray( N, 5.0, x, -stride, N-1 );
230260

231261
// Print the result:
232262
for ( int i = 0; i < 8; i++ ) {

lib/node_modules/@stdlib/blas/base/dscal/benchmark/c/benchmark.length.c

Lines changed: 40 additions & 2 deletions
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 t;
@@ -118,6 +118,37 @@ static double benchmark( int iterations, int len ) {
118118
return elapsed;
119119
}
120120

121+
/**
122+
* Runs a benchmark.
123+
*
124+
* @param iterations number of iterations
125+
* @param len array length
126+
* @return elapsed time in seconds
127+
*/
128+
static double benchmark2( int iterations, int len ) {
129+
double elapsed;
130+
double x[ len ];
131+
double t;
132+
int i;
133+
134+
for ( i = 0; i < len; i++ ) {
135+
x[ i ] = ( rand_double()*200.0 ) - 100.0;
136+
}
137+
t = tic();
138+
for ( i = 0; i < iterations; i++ ) {
139+
c_dscal_ndarray( len, 5.0, x, 1, 0 );
140+
if ( x[ 0 ] != x[ 0 ] ) {
141+
printf( "should not return NaN\n" );
142+
break;
143+
}
144+
}
145+
elapsed = tic() - t;
146+
if ( x[ 0 ] != x[ 0 ] ) {
147+
printf( "should not return NaN\n" );
148+
}
149+
return elapsed;
150+
}
151+
121152
/**
122153
* Main execution sequence.
123154
*/
@@ -140,7 +171,14 @@ int main( void ) {
140171
for ( j = 0; j < REPEATS; j++ ) {
141172
count += 1;
142173
printf( "# c::%s:len=%d\n", NAME, len );
143-
elapsed = benchmark( iter, len );
174+
elapsed = benchmark1( iter, len );
175+
print_results( iter, elapsed );
176+
printf( "ok %d benchmark finished\n", count );
177+
}
178+
for ( j = 0; j < REPEATS; j++ ) {
179+
count += 1;
180+
printf( "# c::%s:ndarray:len=%d\n", NAME, len );
181+
elapsed = benchmark2( iter, len );
144182
print_results( iter, elapsed );
145183
printf( "ok %d benchmark finished\n", count );
146184
}

lib/node_modules/@stdlib/blas/base/dscal/docs/repl.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
Indexing is relative to the first index. To introduce an offset, use typed
1010
array views.
1111

12-
If `N <= 0` or `stride <= 0`, the function returns `x` unchanged.
12+
If `N <= 0` the function returns `x` unchanged.
1313

1414
Parameters
1515
----------

lib/node_modules/@stdlib/blas/base/dscal/docs/types/index.d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ interface Routine {
2828
* @param N - number of indexed elements
2929
* @param alpha - constant
3030
* @param x - input array
31-
* @param stride - stride length
31+
* @param stride - index increment
3232
* @returns input array
3333
*
3434
* @example
@@ -47,7 +47,7 @@ interface Routine {
4747
* @param N - number of indexed elements
4848
* @param alpha - constant
4949
* @param x - input array
50-
* @param stride - stride length
50+
* @param stride - index increment
5151
* @param offset - starting index
5252
* @returns input array
5353
*
@@ -68,7 +68,7 @@ interface Routine {
6868
* @param N - number of indexed elements
6969
* @param alpha - constant
7070
* @param x - input array
71-
* @param stride - stride length
71+
* @param stride - index increment
7272
* @returns input array
7373
*
7474
* @example

lib/node_modules/@stdlib/blas/base/dscal/examples/c/example.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,12 @@ int main( void ) {
3636
for ( int i = 0; i < 8; i++ ) {
3737
printf( "x[ %i ] = %lf\n", i, x[ i ] );
3838
}
39+
40+
// Scale the vector:
41+
c_dscal_ndarray( N, 5.0, x, -strideX, N-1 );
42+
43+
// Print the result:
44+
for ( int i = 0; i < 8; i++ ) {
45+
printf( "x[ %i ] = %lf\n", i, x[ i ] );
46+
}
3947
}

lib/node_modules/@stdlib/blas/base/dscal/include/stdlib/blas/base/dscal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ extern "C" {
3636
*/
3737
void API_SUFFIX(c_dscal)( const CBLAS_INT N, const double alpha, double *X, const CBLAS_INT stride );
3838

39+
/**
40+
* Multiplies each element of a double-precision floating-point vector by a constant using alternative indexing semantics.
41+
*/
42+
void API_SUFFIX(c_dscal_ndarray)( const CBLAS_INT N, const double alpha, double *X, const CBLAS_INT stride, const CBLAS_INT offset );
43+
3944
#ifdef __cplusplus
4045
}
4146
#endif

lib/node_modules/@stdlib/blas/base/dscal/lib/dscal.js

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@
1818

1919
'use strict';
2020

21-
// VARIABLES //
21+
// MODULES //
2222

23-
var M = 5;
23+
var stride2offset = require( '@stdlib/strided/base/stride2offset' );
24+
var ndarray = require( './ndarray.js' );
2425

2526

2627
// MAIN //
@@ -31,7 +32,7 @@ var M = 5;
3132
* @param {PositiveInteger} N - number of indexed elements
3233
* @param {number} alpha - scalar
3334
* @param {Float64Array} x - input array
34-
* @param {PositiveInteger} stride - index increment
35+
* @param {integer} stride - index increment
3536
* @returns {Float64Array} input array
3637
*
3738
* @example
@@ -43,39 +44,8 @@ var M = 5;
4344
* // x => <Float64Array>[ -10.0, 5.0, 15.0, -25.0, 20.0, 0.0, -5.0, -15.0 ]
4445
*/
4546
function dscal( N, alpha, x, stride ) {
46-
var i;
47-
var m;
48-
49-
if ( N <= 0 || stride <= 0 || alpha === 1.0 ) {
50-
return x;
51-
}
52-
// Use loop unrolling if the stride is equal to `1`...
53-
if ( stride === 1 ) {
54-
m = N % M;
55-
56-
// If we have a remainder, run a clean-up loop...
57-
if ( m > 0 ) {
58-
for ( i = 0; i < m; i++ ) {
59-
x[ i ] *= alpha;
60-
}
61-
}
62-
if ( N < M ) {
63-
return x;
64-
}
65-
for ( i = m; i < N; i += M ) {
66-
x[ i ] *= alpha;
67-
x[ i+1 ] *= alpha;
68-
x[ i+2 ] *= alpha;
69-
x[ i+3 ] *= alpha;
70-
x[ i+4 ] *= alpha;
71-
}
72-
return x;
73-
}
74-
N *= stride;
75-
for ( i = 0; i < N; i += stride ) {
76-
x[ i ] *= alpha;
77-
}
78-
return x;
47+
var ox = stride2offset( N, stride );
48+
return ndarray( N, alpha, x, stride, ox );
7949
}
8050

8151

lib/node_modules/@stdlib/blas/base/dscal/lib/dscal.native.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ var addon = require( './../src/addon.node' );
3131
* @param {PositiveInteger} N - number of indexed elements
3232
* @param {number} alpha - scalar
3333
* @param {Float64Array} x - input array
34-
* @param {PositiveInteger} stride - index increment
34+
* @param {integer} stride - index increment
3535
* @returns {Float64Array} input array
3636
*
3737
* @example

lib/node_modules/@stdlib/blas/base/dscal/lib/ndarray.native.js

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@
2020

2121
// MODULES //
2222

23-
var minViewBufferIndex = require( '@stdlib/strided/base/min-view-buffer-index' );
24-
var offsetView = require( '@stdlib/strided/base/offset-view' );
25-
var addon = require( './dscal.native.js' );
23+
var addon = require( './../src/addon.node' );
2624

2725

2826
// MAIN //
@@ -46,13 +44,7 @@ var addon = require( './dscal.native.js' );
4644
* // x => <Float64Array>[ 1.0, -2.0, 3.0, -20.0, 25.0, -30.0 ]
4745
*/
4846
function dscal( N, alpha, x, stride, offset ) {
49-
var view;
50-
offset = minViewBufferIndex( N, stride, offset );
51-
if ( stride < 0 ) {
52-
stride *= -1;
53-
}
54-
view = offsetView( x, offset );
55-
addon( N, alpha, view, stride );
47+
addon.ndarray( N, alpha, x, stride, offset );
5648
return x;
5749
}
5850

0 commit comments

Comments
 (0)