Skip to content

Commit b6ee443

Browse files
aman-095kgryte
andauthored
feat: add C ndarray implementation for blas/base/caxpy
PR-URL: #3456 Ref: #2039 Co-authored-by: Athan Reines <[email protected]> Reviewed-by: Athan Reines <[email protected]> Signed-off-by: Athan Reines <[email protected]>
1 parent cf7d38a commit b6ee443

23 files changed

+3479
-1
lines changed

Diff for: lib/node_modules/@stdlib/blas/base/caxpy/README.md

+146
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,152 @@ logEach( '(%s)*(%s) + (%s) = %s', ca, cx, cyc, cy );
229229

230230
<!-- /.examples -->
231231

232+
<!-- C interface documentation. -->
233+
234+
* * *
235+
236+
<section class="c">
237+
238+
## C APIs
239+
240+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
241+
242+
<section class="intro">
243+
244+
</section>
245+
246+
<!-- /.intro -->
247+
248+
<!-- C usage documentation. -->
249+
250+
<section class="usage">
251+
252+
### Usage
253+
254+
```c
255+
#include "stdlib/blas/base/caxpy.h"
256+
```
257+
258+
#### c_caxpy( N, ca, \*CX, strideX, \*CY, strideY )
259+
260+
Scales values from `cx` by `ca` and adds the result to `cy`.
261+
262+
```c
263+
#include "stdlib/complex/float32/ctor.h"
264+
265+
float cx[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f };
266+
float cy[] = { -1.0f, -2.0f, -3.0f, -4.0f, -5.0f, -6.0f, -7.0f, -8.0f };
267+
const stdlib_complex64_t ca = stdlib_complex64( 2.0f, 2.0f );
268+
269+
c_caxpy( 4, ca, (void *)cx, 1, (void *)cy, 1 );
270+
```
271+
272+
The function accepts the following arguments:
273+
274+
- **N**: `[in] CBLAS_INT` number of indexed elements.
275+
- **ca**: `[in] stdlib_complex64_t` scalar constant.
276+
- **CX**: `[in] void*` input array.
277+
- **strideX**: `[in] CBLAS_INT` index increment for `CX`.
278+
- **CY**: `[inout] void*` output array.
279+
- **strideY**: `[in] CBLAS_INT` index increment for `CY`.
280+
281+
```c
282+
void c_caxpy( const CBLAS_INT N, const stdlib_complex64_t ca, const void *CX, const CBLAS_INT strideX, void *CY, const CBLAS_INT strideY );
283+
```
284+
285+
#### c_caxpy_ndarray( N, ca, \*CX, strideX, offsetX, \*CY, strideY, offsetY )
286+
287+
Scales values from `cx` by `ca` and adds the result to `cy` using alternative indexing semantics.
288+
289+
```c
290+
#include "stdlib/complex/float32/ctor.h"
291+
292+
float cx[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f };
293+
float cy[] = { -1.0f, -2.0f, -3.0f, -4.0f, -5.0f, -6.0f, -7.0f, -8.0f }
294+
const stdlib_complex64_t ca = stdlib_complex64( 2.0f, 2.0f );
295+
296+
c_caxpy_ndarray( 4, ca, (void *)cx, 1, 0, (void *)cy, 1, 0 );
297+
```
298+
299+
The function accepts the following arguments:
300+
301+
- **N**: `[in] CBLAS_INT` number of indexed elements.
302+
- **ca**: `[in] stdlib_complex64_t` scalar constant.
303+
- **CX**: `[in] void*` input array.
304+
- **strideX**: `[in] CBLAS_INT` index increment for `CX`.
305+
- **offsetX**: `[in] CBLAS_INT` starting index for `CX`.
306+
- **CY**: `[inout] void*` output array.
307+
- **strideY**: `[in] CBLAS_INT` index increment for `CY`.
308+
- **offsetY**: `[in] CBLAS_INT` starting index for `CY`.
309+
310+
```c
311+
void c_caxpy_ndarray( const CBLAS_INT N, const stdlib_complex64_t ca, const void *CX, const CBLAS_INT strideX, const CBLAS_INT offsetX, void *CY, const CBLAS_INT strideY, const CBLAS_INT offsetY );
312+
```
313+
314+
</section>
315+
316+
<!-- /.usage -->
317+
318+
<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
319+
320+
<section class="notes">
321+
322+
</section>
323+
324+
<!-- /.notes -->
325+
326+
<!-- C API usage examples. -->
327+
328+
<section class="examples">
329+
330+
### Examples
331+
332+
```c
333+
#include "stdlib/blas/base/caxpy.h"
334+
#include "stdlib/complex/float32/ctor.h"
335+
#include <stdio.h>
336+
337+
int main( void ) {
338+
// Create strided arrays of interleaved real and imaginary components...
339+
float cx[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f };
340+
float cy[] = { -1.0f, -2.0f, -3.0f, -4.0f, -5.0f, -6.0f, -7.0f, -8.0f };
341+
342+
// Create a complex scalar:
343+
const stdlib_complex64_t ca = stdlib_complex64( 2.0f, 2.0f );
344+
345+
// Specify the number of elements:
346+
const int N = 4;
347+
348+
// Specify strides...
349+
const int strideX = 1;
350+
const int strideY = 1;
351+
352+
// Scale values from `cx` by `ca` and adds the result to `cy`:
353+
c_caxpy( N, ca, (void *)cx, strideX, (void *)cy, strideY );
354+
355+
// Print the result:
356+
for ( int i = 0; i < N; i++ ) {
357+
printf( "cy[ %i ] = %f + %fj\n", i, cy[ i*2 ], cy[ (i*2)+1 ] );
358+
}
359+
360+
// Scales values from `cx` by `ca` and adds the result to `cy` using alternative indexing semantics:
361+
c_caxpy_ndarray( N, ca, (void *)cx, -strideX, 3, (void *)cy, -strideY, 3 );
362+
363+
// Print the result:
364+
for ( int i = 0; i < N; i++ ) {
365+
printf( "cy[ %i ] = %f + %fj\n", i, cy[ i*2 ], cy[ (i*2)+1 ] );
366+
}
367+
}
368+
```
369+
370+
</section>
371+
372+
<!-- /.examples -->
373+
374+
</section>
375+
376+
<!-- /.c -->
377+
232378
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
233379
234380
<section class="related">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2024 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MODULES //
22+
23+
var resolve = require( 'path' ).resolve;
24+
var bench = require( '@stdlib/bench' );
25+
var uniform = require( '@stdlib/random/array/uniform' );
26+
var isnanf = require( '@stdlib/math/base/assert/is-nanf' );
27+
var pow = require( '@stdlib/math/base/special/pow' );
28+
var Complex64Array = require( '@stdlib/array/complex64' );
29+
var Complex64 = require( '@stdlib/complex/float32/ctor' );
30+
var reinterpret = require( '@stdlib/strided/base/reinterpret-complex64' );
31+
var tryRequire = require( '@stdlib/utils/try-require' );
32+
var pkg = require( './../package.json' ).name;
33+
34+
35+
// VARIABLES //
36+
37+
var caxpy = tryRequire( resolve( __dirname, './../lib/caxpy.native.js' ) );
38+
var opts = {
39+
'skip': ( caxpy instanceof Error )
40+
};
41+
var options = {
42+
'dtype': 'float32'
43+
};
44+
45+
46+
// FUNCTIONS //
47+
48+
/**
49+
* Creates a benchmark function.
50+
*
51+
* @private
52+
* @param {PositiveInteger} len - array length
53+
* @returns {Function} benchmark function
54+
*/
55+
function createBenchmark( len ) {
56+
var viewY;
57+
var ca;
58+
var cx;
59+
var cy;
60+
61+
cx = new Complex64Array( uniform( len*2, -100.0, 100.0, options ) );
62+
cy = new Complex64Array( uniform( len*2, -100.0, 100.0, options ) );
63+
64+
viewY = reinterpret( cy, 0 );
65+
66+
ca = new Complex64( 1.0, 0.0 );
67+
68+
return benchmark;
69+
70+
/**
71+
* Benchmark function.
72+
*
73+
* @private
74+
* @param {Benchmark} b - benchmark instance
75+
*/
76+
function benchmark( b ) {
77+
var i;
78+
79+
b.tic();
80+
for ( i = 0; i < b.iterations; i++ ) {
81+
caxpy( cx.length, ca, cx, 1, cy, 1 );
82+
if ( isnanf( viewY[ i%(len*2) ] ) ) {
83+
b.fail( 'should not return NaN' );
84+
}
85+
}
86+
b.toc();
87+
if ( isnanf( viewY[ i%(len*2) ] ) ) {
88+
b.fail( 'should not return NaN' );
89+
}
90+
b.pass( 'benchmark finished' );
91+
b.end();
92+
}
93+
}
94+
95+
96+
// MAIN //
97+
98+
/**
99+
* Main execution sequence.
100+
*
101+
* @private
102+
*/
103+
function main() {
104+
var len;
105+
var min;
106+
var max;
107+
var f;
108+
var i;
109+
110+
min = 1; // 10^min
111+
max = 6; // 10^max
112+
113+
for ( i = min; i <= max; i++ ) {
114+
len = pow( 10, i );
115+
f = createBenchmark( len );
116+
bench( pkg+'::native:len='+len, opts, f );
117+
}
118+
}
119+
120+
main();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2024 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MODULES //
22+
23+
var resolve = require( 'path' ).resolve;
24+
var bench = require( '@stdlib/bench' );
25+
var uniform = require( '@stdlib/random/array/uniform' );
26+
var isnanf = require( '@stdlib/math/base/assert/is-nanf' );
27+
var pow = require( '@stdlib/math/base/special/pow' );
28+
var Complex64Array = require( '@stdlib/array/complex64' );
29+
var Complex64 = require( '@stdlib/complex/float32/ctor' );
30+
var reinterpret = require( '@stdlib/strided/base/reinterpret-complex64' );
31+
var tryRequire = require( '@stdlib/utils/try-require' );
32+
var pkg = require( './../package.json' ).name;
33+
34+
35+
// VARIABLES //
36+
37+
var caxpy = tryRequire( resolve( __dirname, './../lib/ndarray.native.js' ) );
38+
var opts = {
39+
'skip': ( caxpy instanceof Error )
40+
};
41+
var options = {
42+
'dtype': 'float32'
43+
};
44+
45+
46+
// FUNCTIONS //
47+
48+
/**
49+
* Creates a benchmark function.
50+
*
51+
* @private
52+
* @param {PositiveInteger} len - array length
53+
* @returns {Function} benchmark function
54+
*/
55+
function createBenchmark( len ) {
56+
var viewY;
57+
var ca;
58+
var cx;
59+
var cy;
60+
61+
cx = new Complex64Array( uniform( len*2, -100.0, 100.0, options ) );
62+
cy = new Complex64Array( uniform( len*2, -100.0, 100.0, options ) );
63+
64+
viewY = reinterpret( cy, 0 );
65+
66+
ca = new Complex64( 1.0, 0.0 );
67+
68+
return benchmark;
69+
70+
/**
71+
* Benchmark function.
72+
*
73+
* @private
74+
* @param {Benchmark} b - benchmark instance
75+
*/
76+
function benchmark( b ) {
77+
var i;
78+
79+
b.tic();
80+
for ( i = 0; i < b.iterations; i++ ) {
81+
caxpy( cx.length, ca, cx, 1, 0, cy, 1, 0 );
82+
if ( isnanf( viewY[ i%(len*2) ] ) ) {
83+
b.fail( 'should not return NaN' );
84+
}
85+
}
86+
b.toc();
87+
if ( isnanf( viewY[ i%(len*2) ] ) ) {
88+
b.fail( 'should not return NaN' );
89+
}
90+
b.pass( 'benchmark finished' );
91+
b.end();
92+
}
93+
}
94+
95+
96+
// MAIN //
97+
98+
/**
99+
* Main execution sequence.
100+
*
101+
* @private
102+
*/
103+
function main() {
104+
var len;
105+
var min;
106+
var max;
107+
var f;
108+
var i;
109+
110+
min = 1; // 10^min
111+
max = 6; // 10^max
112+
113+
for ( i = min; i <= max; i++ ) {
114+
len = pow( 10, i );
115+
f = createBenchmark( len );
116+
bench( pkg+'::native:ndarray:len='+len, opts, f );
117+
}
118+
}
119+
120+
main();

0 commit comments

Comments
 (0)