Skip to content

Commit

Permalink
feat: add C ndarray implementation for blas/base/caxpy
Browse files Browse the repository at this point in the history
PR-URL: #3456
Ref: #2039
Co-authored-by: Athan Reines <kgryte@gmail.com>
Reviewed-by: Athan Reines <kgryte@gmail.com> 
Signed-off-by: Athan Reines <kgryte@gmail.com>
  • Loading branch information
aman-095 and kgryte authored Dec 12, 2024
1 parent cf7d38a commit b6ee443
Show file tree
Hide file tree
Showing 23 changed files with 3,479 additions and 1 deletion.
146 changes: 146 additions & 0 deletions lib/node_modules/@stdlib/blas/base/caxpy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,152 @@ logEach( '(%s)*(%s) + (%s) = %s', ca, cx, cyc, cy );

<!-- /.examples -->

<!-- C interface documentation. -->

* * *

<section class="c">

## C APIs

<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->

<section class="intro">

</section>

<!-- /.intro -->

<!-- C usage documentation. -->

<section class="usage">

### Usage

```c
#include "stdlib/blas/base/caxpy.h"
```

#### c_caxpy( N, ca, \*CX, strideX, \*CY, strideY )

Scales values from `cx` by `ca` and adds the result to `cy`.

```c
#include "stdlib/complex/float32/ctor.h"

float cx[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f };
float cy[] = { -1.0f, -2.0f, -3.0f, -4.0f, -5.0f, -6.0f, -7.0f, -8.0f };
const stdlib_complex64_t ca = stdlib_complex64( 2.0f, 2.0f );

c_caxpy( 4, ca, (void *)cx, 1, (void *)cy, 1 );
```
The function accepts the following arguments:
- **N**: `[in] CBLAS_INT` number of indexed elements.
- **ca**: `[in] stdlib_complex64_t` scalar constant.
- **CX**: `[in] void*` input array.
- **strideX**: `[in] CBLAS_INT` index increment for `CX`.
- **CY**: `[inout] void*` output array.
- **strideY**: `[in] CBLAS_INT` index increment for `CY`.
```c
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 );
```

#### c_caxpy_ndarray( N, ca, \*CX, strideX, offsetX, \*CY, strideY, offsetY )

Scales values from `cx` by `ca` and adds the result to `cy` using alternative indexing semantics.

```c
#include "stdlib/complex/float32/ctor.h"

float cx[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f };
float cy[] = { -1.0f, -2.0f, -3.0f, -4.0f, -5.0f, -6.0f, -7.0f, -8.0f }
const stdlib_complex64_t ca = stdlib_complex64( 2.0f, 2.0f );

c_caxpy_ndarray( 4, ca, (void *)cx, 1, 0, (void *)cy, 1, 0 );
```
The function accepts the following arguments:
- **N**: `[in] CBLAS_INT` number of indexed elements.
- **ca**: `[in] stdlib_complex64_t` scalar constant.
- **CX**: `[in] void*` input array.
- **strideX**: `[in] CBLAS_INT` index increment for `CX`.
- **offsetX**: `[in] CBLAS_INT` starting index for `CX`.
- **CY**: `[inout] void*` output array.
- **strideY**: `[in] CBLAS_INT` index increment for `CY`.
- **offsetY**: `[in] CBLAS_INT` starting index for `CY`.
```c
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 );
```

</section>

<!-- /.usage -->

<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->

<section class="notes">

</section>

<!-- /.notes -->

<!-- C API usage examples. -->

<section class="examples">

### Examples

```c
#include "stdlib/blas/base/caxpy.h"
#include "stdlib/complex/float32/ctor.h"
#include <stdio.h>

int main( void ) {
// Create strided arrays of interleaved real and imaginary components...
float cx[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f };
float cy[] = { -1.0f, -2.0f, -3.0f, -4.0f, -5.0f, -6.0f, -7.0f, -8.0f };

// Create a complex scalar:
const stdlib_complex64_t ca = stdlib_complex64( 2.0f, 2.0f );

// Specify the number of elements:
const int N = 4;

// Specify strides...
const int strideX = 1;
const int strideY = 1;

// Scale values from `cx` by `ca` and adds the result to `cy`:
c_caxpy( N, ca, (void *)cx, strideX, (void *)cy, strideY );

// Print the result:
for ( int i = 0; i < N; i++ ) {
printf( "cy[ %i ] = %f + %fj\n", i, cy[ i*2 ], cy[ (i*2)+1 ] );
}

// Scales values from `cx` by `ca` and adds the result to `cy` using alternative indexing semantics:
c_caxpy_ndarray( N, ca, (void *)cx, -strideX, 3, (void *)cy, -strideY, 3 );

// Print the result:
for ( int i = 0; i < N; i++ ) {
printf( "cy[ %i ] = %f + %fj\n", i, cy[ i*2 ], cy[ (i*2)+1 ] );
}
}
```
</section>
<!-- /.examples -->
</section>
<!-- /.c -->
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
<section class="related">
Expand Down
120 changes: 120 additions & 0 deletions lib/node_modules/@stdlib/blas/base/caxpy/benchmark/benchmark.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/**
* @license Apache-2.0
*
* Copyright (c) 2024 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

// MODULES //

var resolve = require( 'path' ).resolve;
var bench = require( '@stdlib/bench' );
var uniform = require( '@stdlib/random/array/uniform' );
var isnanf = require( '@stdlib/math/base/assert/is-nanf' );
var pow = require( '@stdlib/math/base/special/pow' );
var Complex64Array = require( '@stdlib/array/complex64' );
var Complex64 = require( '@stdlib/complex/float32/ctor' );
var reinterpret = require( '@stdlib/strided/base/reinterpret-complex64' );
var tryRequire = require( '@stdlib/utils/try-require' );
var pkg = require( './../package.json' ).name;


// VARIABLES //

var caxpy = tryRequire( resolve( __dirname, './../lib/caxpy.native.js' ) );
var opts = {
'skip': ( caxpy instanceof Error )
};
var options = {
'dtype': 'float32'
};


// FUNCTIONS //

/**
* Creates a benchmark function.
*
* @private
* @param {PositiveInteger} len - array length
* @returns {Function} benchmark function
*/
function createBenchmark( len ) {
var viewY;
var ca;
var cx;
var cy;

cx = new Complex64Array( uniform( len*2, -100.0, 100.0, options ) );
cy = new Complex64Array( uniform( len*2, -100.0, 100.0, options ) );

viewY = reinterpret( cy, 0 );

ca = new Complex64( 1.0, 0.0 );

return benchmark;

/**
* Benchmark function.
*
* @private
* @param {Benchmark} b - benchmark instance
*/
function benchmark( b ) {
var i;

b.tic();
for ( i = 0; i < b.iterations; i++ ) {
caxpy( cx.length, ca, cx, 1, cy, 1 );
if ( isnanf( viewY[ i%(len*2) ] ) ) {
b.fail( 'should not return NaN' );
}
}
b.toc();
if ( isnanf( viewY[ i%(len*2) ] ) ) {
b.fail( 'should not return NaN' );
}
b.pass( 'benchmark finished' );
b.end();
}
}


// MAIN //

/**
* Main execution sequence.
*
* @private
*/
function main() {
var len;
var min;
var max;
var f;
var i;

min = 1; // 10^min
max = 6; // 10^max

for ( i = min; i <= max; i++ ) {
len = pow( 10, i );
f = createBenchmark( len );
bench( pkg+'::native:len='+len, opts, f );
}
}

main();
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/**
* @license Apache-2.0
*
* Copyright (c) 2024 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

// MODULES //

var resolve = require( 'path' ).resolve;
var bench = require( '@stdlib/bench' );
var uniform = require( '@stdlib/random/array/uniform' );
var isnanf = require( '@stdlib/math/base/assert/is-nanf' );
var pow = require( '@stdlib/math/base/special/pow' );
var Complex64Array = require( '@stdlib/array/complex64' );
var Complex64 = require( '@stdlib/complex/float32/ctor' );
var reinterpret = require( '@stdlib/strided/base/reinterpret-complex64' );
var tryRequire = require( '@stdlib/utils/try-require' );
var pkg = require( './../package.json' ).name;


// VARIABLES //

var caxpy = tryRequire( resolve( __dirname, './../lib/ndarray.native.js' ) );
var opts = {
'skip': ( caxpy instanceof Error )
};
var options = {
'dtype': 'float32'
};


// FUNCTIONS //

/**
* Creates a benchmark function.
*
* @private
* @param {PositiveInteger} len - array length
* @returns {Function} benchmark function
*/
function createBenchmark( len ) {
var viewY;
var ca;
var cx;
var cy;

cx = new Complex64Array( uniform( len*2, -100.0, 100.0, options ) );
cy = new Complex64Array( uniform( len*2, -100.0, 100.0, options ) );

viewY = reinterpret( cy, 0 );

ca = new Complex64( 1.0, 0.0 );

return benchmark;

/**
* Benchmark function.
*
* @private
* @param {Benchmark} b - benchmark instance
*/
function benchmark( b ) {
var i;

b.tic();
for ( i = 0; i < b.iterations; i++ ) {
caxpy( cx.length, ca, cx, 1, 0, cy, 1, 0 );
if ( isnanf( viewY[ i%(len*2) ] ) ) {
b.fail( 'should not return NaN' );
}
}
b.toc();
if ( isnanf( viewY[ i%(len*2) ] ) ) {
b.fail( 'should not return NaN' );
}
b.pass( 'benchmark finished' );
b.end();
}
}


// MAIN //

/**
* Main execution sequence.
*
* @private
*/
function main() {
var len;
var min;
var max;
var f;
var i;

min = 1; // 10^min
max = 6; // 10^max

for ( i = min; i <= max; i++ ) {
len = pow( 10, i );
f = createBenchmark( len );
bench( pkg+'::native:ndarray:len='+len, opts, f );
}
}

main();
Loading

1 comment on commit b6ee443

@stdlib-bot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage Report

Package Statements Branches Functions Lines
blas/base/caxpy $\color{red}429/431$
$\color{green}+99.54\%$
$\color{red}17/18$
$\color{green}+94.44\%$
$\color{green}4/4$
$\color{green}+100.00\%$
$\color{red}429/431$
$\color{green}+99.54\%$
blas/base/daxpy $\color{green}420/420$
$\color{green}+100.00\%$
$\color{green}30/30$
$\color{green}+100.00\%$
$\color{green}4/4$
$\color{green}+100.00\%$
$\color{green}420/420$
$\color{green}+100.00\%$

The above coverage report was generated for the changes in this push.

Please sign in to comment.