Skip to content

Commit ae54d13

Browse files
committed
feat: add C "ndarray" API
1 parent 1d07426 commit ae54d13

File tree

9 files changed

+188
-17
lines changed

9 files changed

+188
-17
lines changed

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

Lines changed: 42 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 y[ len ];
@@ -120,6 +120,39 @@ static double benchmark( int iterations, int len ) {
120120
return elapsed;
121121
}
122122

123+
/**
124+
* Runs a benchmark.
125+
*
126+
* @param iterations number of iterations
127+
* @param len array length
128+
* @return elapsed time in seconds
129+
*/
130+
static double benchmark2( int iterations, int len ) {
131+
double elapsed;
132+
double x[ len ];
133+
double y[ len ];
134+
double t;
135+
int i;
136+
137+
for ( i = 0; i < len; i++ ) {
138+
x[ i ] = ( rand_double()*200.0 ) - 100.0;
139+
y[ i ] = ( rand_double()*200.0 ) - 100.0;
140+
}
141+
t = tic();
142+
for ( i = 0; i < iterations; i++ ) {
143+
c_daxpy_ndarray( len, 5.0, x, 1, 0, y, 1, 0 );
144+
if ( y[ 0 ] != y[ 0 ] ) {
145+
printf( "should not return NaN\n" );
146+
break;
147+
}
148+
}
149+
elapsed = tic() - t;
150+
if ( y[ 0 ] != y[ 0 ] ) {
151+
printf( "should not return NaN\n" );
152+
}
153+
return elapsed;
154+
}
155+
123156
/**
124157
* Main execution sequence.
125158
*/
@@ -142,7 +175,14 @@ int main( void ) {
142175
for ( j = 0; j < REPEATS; j++ ) {
143176
count += 1;
144177
printf( "# c::%s:len=%d\n", NAME, len );
145-
elapsed = benchmark( iter, len );
178+
elapsed = benchmark1( iter, len );
179+
print_results( iter, elapsed );
180+
printf( "ok %d benchmark finished\n", count );
181+
}
182+
for ( j = 0; j < REPEATS; j++ ) {
183+
count += 1;
184+
printf( "# c::%s:ndarray:len=%d\n", NAME, len );
185+
elapsed = benchmark2( iter, len );
146186
print_results( iter, elapsed );
147187
printf( "ok %d benchmark finished\n", count );
148188
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,12 @@ int main( void ) {
3838
for ( int i = 0; i < 8; i++ ) {
3939
printf( "y[ %i ] = %lf\n", i, y[ i ] );
4040
}
41+
42+
// Compute `a*x + y`:
43+
c_daxpy_ndarray( N, 5.0, x, strideX, 1, y, strideY, 7 );
44+
45+
// Print the result:
46+
for ( int i = 0; i < 8; i++ ) {
47+
printf( "y[ %i ] = %lf\n", i, y[ i ] );
48+
}
4149
}

lib/node_modules/@stdlib/blas/base/daxpy/include/stdlib/blas/base/daxpy.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_daxpy)( const CBLAS_INT N, const double alpha, const double *X, const CBLAS_INT strideX, double *Y, const CBLAS_INT strideY );
3838

39+
/**
40+
* Multiplies a vector `X` by a constant and adds the result to `Y` using alternative indexing semantics.
41+
*/
42+
void API_SUFFIX(c_daxpy_ndarray)( const CBLAS_INT N, const double alpha, const double *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, double *Y, const CBLAS_INT strideY, const CBLAS_INT offsetY );
43+
3944
#ifdef __cplusplus
4045
}
4146
#endif

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

Lines changed: 2 additions & 13 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( './daxpy.native.js' );
23+
var addon = require( './../src/addon.node' );
2624

2725

2826
// MAIN //
@@ -51,16 +49,7 @@ var addon = require( './daxpy.native.js' );
5149
* // y => <Float64Array>[ 6.0, 11.0, 16.0, 21.0, 26.0 ]
5250
*/
5351
function daxpy( N, alpha, x, strideX, offsetX, y, strideY, offsetY ) {
54-
var viewX;
55-
var viewY;
56-
57-
offsetX = minViewBufferIndex( N, strideX, offsetX );
58-
offsetY = minViewBufferIndex( N, strideY, offsetY );
59-
60-
viewX = offsetView( x, offsetX );
61-
viewY = offsetView( y, offsetY );
62-
63-
addon( N, alpha, viewX, strideX, viewY, strideY );
52+
addon.ndarray( N, alpha, x, strideX, offsetX, y, strideY, offsetY );
6453
return y;
6554
}
6655

lib/node_modules/@stdlib/blas/base/daxpy/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@stdlib/blas/base/daxpy",
33
"version": "0.0.0",
4-
"description": "Multiply a vector x by a constant and add the result to y.",
4+
"description": "Multiply a vector `x` by a constant and add the result to `y`.",
55
"license": "Apache-2.0",
66
"author": {
77
"name": "The Stdlib Authors",

lib/node_modules/@stdlib/blas/base/daxpy/src/addon.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,25 @@ static napi_value addon( napi_env env, napi_callback_info info ) {
4444
return NULL;
4545
}
4646

47-
STDLIB_NAPI_MODULE_EXPORT_FCN( addon )
47+
/**
48+
* Receives JavaScript callback invocation data.
49+
*
50+
* @param env environment under which the function is invoked
51+
* @param info callback data
52+
* @return Node-API value
53+
*/
54+
static napi_value addon_method( napi_env env, napi_callback_info info ) {
55+
STDLIB_NAPI_ARGV( env, info, argv, argc, 8 );
56+
STDLIB_NAPI_ARGV_INT64( env, N, argv, 0 );
57+
STDLIB_NAPI_ARGV_DOUBLE( env, alpha, argv, 1 );
58+
STDLIB_NAPI_ARGV_INT64( env, strideX, argv, 3 );
59+
STDLIB_NAPI_ARGV_INT64( env, offsetX, argv, 4 );
60+
STDLIB_NAPI_ARGV_INT64( env, strideY, argv, 6 );
61+
STDLIB_NAPI_ARGV_INT64( env, offsetY, argv, 7 );
62+
STDLIB_NAPI_ARGV_STRIDED_FLOAT64ARRAY( env, X, N, strideX, argv, 2 );
63+
STDLIB_NAPI_ARGV_STRIDED_FLOAT64ARRAY( env, Y, N, strideY, argv, 5 );
64+
API_SUFFIX(c_daxpy_ndarray)( N, alpha, X, strideX, offsetX, Y, strideY, offsetY );
65+
return NULL;
66+
}
67+
68+
STDLIB_NAPI_MODULE_EXPORT_FCN_WITH_METHOD( addon, "ndarray", addon_method )

lib/node_modules/@stdlib/blas/base/daxpy/src/daxpy.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,37 @@ void API_SUFFIX(c_daxpy)( const CBLAS_INT N, const double alpha, const double *X
8080
}
8181
return;
8282
}
83+
84+
/**
85+
* Multiplies a vector `X` by a constant and adds the result to `Y` using alternative indexing semantics.
86+
*
87+
* @param N number of indexed elements
88+
* @param alpha scalar
89+
* @param X input array
90+
* @param strideX X stride length
91+
* @param offsetX starting X index
92+
* @param Y output array
93+
* @param strideY Y stride length
94+
* @param offsetY starting Y index
95+
*/
96+
void API_SUFFIX(c_daxpy_ndarray)( const CBLAS_INT N, const double alpha, const double *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, double *Y, const CBLAS_INT strideY, const CBLAS_INT offsetY ) {
97+
CBLAS_INT ix;
98+
CBLAS_INT iy;
99+
CBLAS_INT i;
100+
101+
if ( N <= 0 ) {
102+
return;
103+
}
104+
// If `alpha` is `0`, then `y` is unchanged...
105+
if ( alpha == 0.0 ) {
106+
return;
107+
}
108+
ix = offsetX;
109+
iy = offsetY;
110+
for ( i = 0; i < N; i++ ) {
111+
Y[ iy ] += alpha * X[ ix ];
112+
ix += strideX;
113+
iy += strideY;
114+
}
115+
return;
116+
}

lib/node_modules/@stdlib/blas/base/daxpy/src/daxpy_cblas.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,40 @@
3333
void API_SUFFIX(c_daxpy)( const CBLAS_INT N, const double alpha, const double *X, const CBLAS_INT strideX, double *Y, const CBLAS_INT strideY ) {
3434
API_SUFFIX(cblas_daxpy)( N, alpha, X, strideX, Y, strideY );
3535
}
36+
37+
/**
38+
* Multiplies a vector `X` by a constant and adds the result to `Y` using alternative indexing semantics.
39+
*
40+
* @param N number of indexed elements
41+
* @param alpha scalar
42+
* @param X input array
43+
* @param strideX X stride length
44+
* @param offsetX starting X index
45+
* @param Y output array
46+
* @param strideY Y stride length
47+
* @param offsetY starting Y index
48+
*/
49+
void API_SUFFIX(c_daxpy_ndarray)( const CBLAS_INT N, const double alpha, const double *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, double *Y, const CBLAS_INT strideY, const CBLAS_INT offsetY ) {
50+
CBLAS_INT ox;
51+
CBLAS_INT oy;
52+
53+
double *x = X;
54+
double *y = Y;
55+
56+
// TODO: replace with @stdlib/strided/base/min-view-buffer-index
57+
if ( N > 0 && strideX < 0 ) {
58+
ox = offsetX + ( (N-1)*strideX ); // decrements the offset
59+
} else {
60+
ox = offsetX;
61+
}
62+
if ( N > 0 && strideY < 0 ) {
63+
oy = offsetY + ( (N-1)*strideY ); // decrements the offset
64+
} else {
65+
oy = offsetY;
66+
}
67+
// Adjust the array pointers:
68+
x += ox;
69+
y += oy;
70+
71+
API_SUFFIX(cblas_daxpy)( N, alpha, x, strideX, y, strideY );
72+
}

lib/node_modules/@stdlib/blas/base/daxpy/src/daxpy_f.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,40 @@
3333
void API_SUFFIX(c_daxpy)( const CBLAS_INT N, const double alpha, const double *X, const CBLAS_INT strideX, double *Y, const CBLAS_INT strideY ) {
3434
daxpy( &N, &alpha, X, &strideX, Y, &strideY );
3535
}
36+
37+
/**
38+
* Multiplies a vector `X` by a constant and adds the result to `Y` using alternative indexing semantics.
39+
*
40+
* @param N number of indexed elements
41+
* @param alpha scalar
42+
* @param X input array
43+
* @param strideX X stride length
44+
* @param offsetX starting X index
45+
* @param Y output array
46+
* @param strideY Y stride length
47+
* @param offsetY starting Y index
48+
*/
49+
void API_SUFFIX(c_daxpy_ndarray)( const CBLAS_INT N, const double alpha, const double *X, const CBLAS_INT strideX, const CBLAS_INT offsetX, double *Y, const CBLAS_INT strideY, const CBLAS_INT offsetY ) {
50+
CBLAS_INT ox;
51+
CBLAS_INT oy;
52+
53+
double *x = X;
54+
double *y = Y;
55+
56+
// TODO: replace with @stdlib/strided/base/min-view-buffer-index
57+
if ( N > 0 && strideX < 0 ) {
58+
ox = offsetX + ( (N-1)*strideX ); // decrements the offset
59+
} else {
60+
ox = offsetX;
61+
}
62+
if ( N > 0 && strideY < 0 ) {
63+
oy = offsetY + ( (N-1)*strideY ); // decrements the offset
64+
} else {
65+
oy = offsetY;
66+
}
67+
// Adjust the array pointers:
68+
x += ox;
69+
y += oy;
70+
71+
daxpy( &N, &alpha, x, &strideX, y, &strideY );
72+
}

0 commit comments

Comments
 (0)