diff --git a/lib/node_modules/@stdlib/blas/base/dgemm/lib/base.js b/lib/node_modules/@stdlib/blas/base/dgemm/lib/base.js index 51b6b0e22662..06ba57f6af3c 100644 --- a/lib/node_modules/@stdlib/blas/base/dgemm/lib/base.js +++ b/lib/node_modules/@stdlib/blas/base/dgemm/lib/base.js @@ -418,7 +418,7 @@ function dgemm( transA, transB, M, N, K, alpha, A, strideA1, strideA2, offsetA, C = scal( M, N, beta, C, strideC1, strideC2, offsetC ); } // Check whether we can early return... - if ( alpha === 0.0 ) { + if ( alpha === 0.0 || K === 0 ) { return C; } // Determine the memory layouts of `A` and `B`... diff --git a/lib/node_modules/@stdlib/blas/base/dgemm/test/test.dgemm.js b/lib/node_modules/@stdlib/blas/base/dgemm/test/test.dgemm.js index 5a4af7e7a4b4..140c74a4f9de 100644 --- a/lib/node_modules/@stdlib/blas/base/dgemm/test/test.dgemm.js +++ b/lib/node_modules/@stdlib/blas/base/dgemm/test/test.dgemm.js @@ -26,6 +26,8 @@ var tape = require( 'tape' ); var Float64Array = require( '@stdlib/array/float64' ); var dscal = require( '@stdlib/blas/base/dscal' ); var resolveEnum = require( '@stdlib/blas/base/transpose-operation-resolve-enum' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); +var NINF = require( '@stdlib/constants/float64/ninf' ); var dgemm = require( './../lib/dgemm.js' ); @@ -878,3 +880,61 @@ tape( 'the function supports `conjugate-transpose`, which is equivalent to `tran t.deepEqual( out, expected, 'returns expected value' ); t.end(); }); + +tape( 'if `K` is `0`, the function returns the third input matrix scaled by `β`, regardless of the value of `α` and the memory layout', function test( t ) { + var expected; + var alphas; + var out; + var c; + var i; + + alphas = [ NaN, PINF, NINF, 2.0 ]; + expected = new Float64Array( [ 0.5, 1.0, 1.5, 2.0 ] ); + + for ( i = 0; i < alphas.length; i++ ) { + c = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + out = dgemm( 'row-major', 'no-transpose', 'no-transpose', 2, 2, 0, alphas[ i ], new Float64Array( 0 ), 1, new Float64Array( 0 ), 2, 0.5, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + + c = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + out = dgemm( 'row-major', 'no-transpose', 'transpose', 2, 2, 0, alphas[ i ], new Float64Array( 0 ), 1, new Float64Array( 0 ), 1, 0.5, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + + c = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + out = dgemm( 'column-major', 'transpose', 'no-transpose', 2, 2, 0, alphas[ i ], new Float64Array( 0 ), 2, new Float64Array( 0 ), 2, 0.5, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + } + t.end(); +}); + +tape( 'if `K` is `0` and `β` is `0`, the function returns the third input matrix filled with zeros, regardless of the value of `α` and the memory layout', function test( t ) { + var expected; + var alphas; + var out; + var c; + var i; + + alphas = [ NaN, PINF, NINF, 2.0 ]; + expected = new Float64Array( [ 0.0, 0.0, 0.0, 0.0 ] ); + + for ( i = 0; i < alphas.length; i++ ) { + c = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + out = dgemm( 'row-major', 'no-transpose', 'no-transpose', 2, 2, 0, alphas[ i ], new Float64Array( 0 ), 1, new Float64Array( 0 ), 2, 0.0, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + + c = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + out = dgemm( 'row-major', 'no-transpose', 'transpose', 2, 2, 0, alphas[ i ], new Float64Array( 0 ), 1, new Float64Array( 0 ), 1, 0.0, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + + c = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + out = dgemm( 'column-major', 'transpose', 'no-transpose', 2, 2, 0, alphas[ i ], new Float64Array( 0 ), 2, new Float64Array( 0 ), 2, 0.0, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + } + t.end(); +}); diff --git a/lib/node_modules/@stdlib/blas/base/ggemm/lib/accessors.js b/lib/node_modules/@stdlib/blas/base/ggemm/lib/accessors.js index 172796782aca..80ed992c5a44 100644 --- a/lib/node_modules/@stdlib/blas/base/ggemm/lib/accessors.js +++ b/lib/node_modules/@stdlib/blas/base/ggemm/lib/accessors.js @@ -497,7 +497,7 @@ function ggemm( transA, transB, M, N, K, alpha, A, strideA1, strideA2, offsetA, C = scal( M, N, beta, C, strideC1, strideC2, offsetC ); } // Check whether we can early return... - if ( alpha === 0.0 ) { + if ( alpha === 0.0 || K === 0 ) { return C; } // Determine the memory layouts of `A` and `B`... diff --git a/lib/node_modules/@stdlib/blas/base/ggemm/lib/base.js b/lib/node_modules/@stdlib/blas/base/ggemm/lib/base.js index 45fa0c58f519..ca6d134adf13 100644 --- a/lib/node_modules/@stdlib/blas/base/ggemm/lib/base.js +++ b/lib/node_modules/@stdlib/blas/base/ggemm/lib/base.js @@ -416,7 +416,7 @@ function ggemm( transA, transB, M, N, K, alpha, A, strideA1, strideA2, offsetA, C = scal( M, N, beta, C, strideC1, strideC2, offsetC ); } // Check whether we can early return... - if ( alpha === 0.0 ) { + if ( alpha === 0.0 || K === 0 ) { return C; } // Determine the memory layouts of `A` and `B`... diff --git a/lib/node_modules/@stdlib/blas/base/ggemm/test/test.main.js b/lib/node_modules/@stdlib/blas/base/ggemm/test/test.main.js index cfc3d97b7ab3..b83c4aed5f82 100644 --- a/lib/node_modules/@stdlib/blas/base/ggemm/test/test.main.js +++ b/lib/node_modules/@stdlib/blas/base/ggemm/test/test.main.js @@ -28,6 +28,8 @@ var gfill = require( '@stdlib/blas/ext/base/gfill' ); var toAccessorArray = require( '@stdlib/array/base/to-accessor-array' ); var copy = require( '@stdlib/array/base/copy' ); var resolveEnum = require( '@stdlib/blas/base/transpose-operation-resolve-enum' ); +var PINF = require( '@stdlib/constants/float64/pinf' ); +var NINF = require( '@stdlib/constants/float64/ninf' ); var ggemm = require( './../lib/main.js' ); @@ -1591,3 +1593,127 @@ tape( 'the function supports `conjugate-transpose`, which is equivalent to `tran t.deepEqual( out, expected, 'returns expected value' ); t.end(); }); + +tape( 'if `K` is `0`, the function returns the third input matrix scaled by `β`, regardless of the value of `α` and the memory layout', function test( t ) { + var expected; + var alphas; + var out; + var c; + var i; + + alphas = [ NaN, PINF, NINF, 2.0 ]; + expected = [ 0.5, 1.0, 1.5, 2.0 ]; + + for ( i = 0; i < alphas.length; i++ ) { + c = [ 1.0, 2.0, 3.0, 4.0 ]; + out = ggemm( 'row-major', 'no-transpose', 'no-transpose', 2, 2, 0, alphas[ i ], [], 1, [], 2, 0.5, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + + c = [ 1.0, 2.0, 3.0, 4.0 ]; + out = ggemm( 'row-major', 'no-transpose', 'transpose', 2, 2, 0, alphas[ i ], [], 1, [], 1, 0.5, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + + c = [ 1.0, 2.0, 3.0, 4.0 ]; + out = ggemm( 'column-major', 'transpose', 'no-transpose', 2, 2, 0, alphas[ i ], [], 2, [], 2, 0.5, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + } + t.end(); +}); + +tape( 'if `K` is `0` and `β` is `0`, the function returns the third input matrix filled with zeros, regardless of the value of `α` and the memory layout', function test( t ) { + var expected; + var alphas; + var out; + var c; + var i; + + alphas = [ NaN, PINF, NINF, 2.0 ]; + expected = [ 0.0, 0.0, 0.0, 0.0 ]; + + for ( i = 0; i < alphas.length; i++ ) { + c = [ 1.0, 2.0, 3.0, 4.0 ]; + out = ggemm( 'row-major', 'no-transpose', 'no-transpose', 2, 2, 0, alphas[ i ], [], 1, [], 2, 0.0, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + + c = [ 1.0, 2.0, 3.0, 4.0 ]; + out = ggemm( 'row-major', 'no-transpose', 'transpose', 2, 2, 0, alphas[ i ], [], 1, [], 1, 0.0, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + + c = [ 1.0, 2.0, 3.0, 4.0 ]; + out = ggemm( 'column-major', 'transpose', 'no-transpose', 2, 2, 0, alphas[ i ], [], 2, [], 2, 0.0, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + } + t.end(); +}); + +tape( 'if `K` is `0`, the function returns the third input matrix scaled by `β`, regardless of the value of `α` and the memory layout (accessors)', function test( t ) { + var expected; + var alphas; + var cbuf; + var out; + var c; + var i; + + alphas = [ NaN, PINF, NINF, 2.0 ]; + expected = [ 0.5, 1.0, 1.5, 2.0 ]; + + for ( i = 0; i < alphas.length; i++ ) { + cbuf = [ 1.0, 2.0, 3.0, 4.0 ]; + c = toAccessorArray( cbuf ); + out = ggemm( 'row-major', 'no-transpose', 'no-transpose', 2, 2, 0, alphas[ i ], toAccessorArray( [] ), 1, toAccessorArray( [] ), 2, 0.5, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( cbuf, expected, 'returns expected value' ); + + cbuf = [ 1.0, 2.0, 3.0, 4.0 ]; + c = toAccessorArray( cbuf ); + out = ggemm( 'row-major', 'no-transpose', 'transpose', 2, 2, 0, alphas[ i ], toAccessorArray( [] ), 1, toAccessorArray( [] ), 1, 0.5, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( cbuf, expected, 'returns expected value' ); + + cbuf = [ 1.0, 2.0, 3.0, 4.0 ]; + c = toAccessorArray( cbuf ); + out = ggemm( 'column-major', 'transpose', 'no-transpose', 2, 2, 0, alphas[ i ], toAccessorArray( [] ), 2, toAccessorArray( [] ), 2, 0.5, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( cbuf, expected, 'returns expected value' ); + } + t.end(); +}); + +tape( 'if `K` is `0` and `β` is `0`, the function returns the third input matrix filled with zeros, regardless of the value of `α` and the memory layout (accessors)', function test( t ) { + var expected; + var alphas; + var cbuf; + var out; + var c; + var i; + + alphas = [ NaN, PINF, NINF, 2.0 ]; + expected = [ 0.0, 0.0, 0.0, 0.0 ]; + + for ( i = 0; i < alphas.length; i++ ) { + cbuf = [ 1.0, 2.0, 3.0, 4.0 ]; + c = toAccessorArray( cbuf ); + out = ggemm( 'row-major', 'no-transpose', 'no-transpose', 2, 2, 0, alphas[ i ], toAccessorArray( [] ), 1, toAccessorArray( [] ), 2, 0.0, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( cbuf, expected, 'returns expected value' ); + + cbuf = [ 1.0, 2.0, 3.0, 4.0 ]; + c = toAccessorArray( cbuf ); + out = ggemm( 'row-major', 'no-transpose', 'transpose', 2, 2, 0, alphas[ i ], toAccessorArray( [] ), 1, toAccessorArray( [] ), 1, 0.0, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( cbuf, expected, 'returns expected value' ); + + cbuf = [ 1.0, 2.0, 3.0, 4.0 ]; + c = toAccessorArray( cbuf ); + out = ggemm( 'column-major', 'transpose', 'no-transpose', 2, 2, 0, alphas[ i ], toAccessorArray( [] ), 2, toAccessorArray( [] ), 2, 0.0, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( cbuf, expected, 'returns expected value' ); + } + t.end(); +}); diff --git a/lib/node_modules/@stdlib/blas/base/sgemm/lib/base.js b/lib/node_modules/@stdlib/blas/base/sgemm/lib/base.js index f26fc5d2aae2..3e67dc9c60f6 100644 --- a/lib/node_modules/@stdlib/blas/base/sgemm/lib/base.js +++ b/lib/node_modules/@stdlib/blas/base/sgemm/lib/base.js @@ -419,7 +419,7 @@ function sgemm( transA, transB, M, N, K, alpha, A, strideA1, strideA2, offsetA, C = scal( M, N, beta, C, strideC1, strideC2, offsetC ); } // Check whether we can early return... - if ( alpha === 0.0 ) { + if ( alpha === 0.0 || K === 0 ) { return C; } // Determine the memory layouts of `A` and `B`... diff --git a/lib/node_modules/@stdlib/blas/base/sgemm/test/test.sgemm.js b/lib/node_modules/@stdlib/blas/base/sgemm/test/test.sgemm.js index e3d502056c0b..4e54b8fbf5d7 100644 --- a/lib/node_modules/@stdlib/blas/base/sgemm/test/test.sgemm.js +++ b/lib/node_modules/@stdlib/blas/base/sgemm/test/test.sgemm.js @@ -26,6 +26,8 @@ var tape = require( 'tape' ); var Float32Array = require( '@stdlib/array/float32' ); var sscal = require( '@stdlib/blas/base/sscal' ); var resolveEnum = require( '@stdlib/blas/base/transpose-operation-resolve-enum' ); +var PINF = require( '@stdlib/constants/float32/pinf' ); +var NINF = require( '@stdlib/constants/float32/ninf' ); var sgemm = require( './../lib/sgemm.js' ); @@ -878,3 +880,61 @@ tape( 'the function supports `conjugate-transpose`, which is equivalent to `tran t.deepEqual( out, expected, 'returns expected value' ); t.end(); }); + +tape( 'if `K` is `0`, the function returns the third input matrix scaled by `β`, regardless of the value of `α` and the memory layout', function test( t ) { + var expected; + var alphas; + var out; + var c; + var i; + + alphas = [ NaN, PINF, NINF, 2.0 ]; + expected = new Float32Array( [ 0.5, 1.0, 1.5, 2.0 ] ); + + for ( i = 0; i < alphas.length; i++ ) { + c = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + out = sgemm( 'row-major', 'no-transpose', 'no-transpose', 2, 2, 0, alphas[ i ], new Float32Array( 0 ), 1, new Float32Array( 0 ), 2, 0.5, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + + c = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + out = sgemm( 'row-major', 'no-transpose', 'transpose', 2, 2, 0, alphas[ i ], new Float32Array( 0 ), 1, new Float32Array( 0 ), 1, 0.5, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + + c = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + out = sgemm( 'column-major', 'transpose', 'no-transpose', 2, 2, 0, alphas[ i ], new Float32Array( 0 ), 2, new Float32Array( 0 ), 2, 0.5, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + } + t.end(); +}); + +tape( 'if `K` is `0` and `β` is `0`, the function returns the third input matrix filled with zeros, regardless of the value of `α` and the memory layout', function test( t ) { + var expected; + var alphas; + var out; + var c; + var i; + + alphas = [ NaN, PINF, NINF, 2.0 ]; + expected = new Float32Array( [ 0.0, 0.0, 0.0, 0.0 ] ); + + for ( i = 0; i < alphas.length; i++ ) { + c = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + out = sgemm( 'row-major', 'no-transpose', 'no-transpose', 2, 2, 0, alphas[ i ], new Float32Array( 0 ), 1, new Float32Array( 0 ), 2, 0.0, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + + c = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + out = sgemm( 'row-major', 'no-transpose', 'transpose', 2, 2, 0, alphas[ i ], new Float32Array( 0 ), 1, new Float32Array( 0 ), 1, 0.0, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + + c = new Float32Array( [ 1.0, 2.0, 3.0, 4.0 ] ); + out = sgemm( 'column-major', 'transpose', 'no-transpose', 2, 2, 0, alphas[ i ], new Float32Array( 0 ), 2, new Float32Array( 0 ), 2, 0.0, c, 2 ); + t.strictEqual( out, c, 'returns expected value' ); + t.deepEqual( out, expected, 'returns expected value' ); + } + t.end(); +});