diff --git a/.github/workflows/productionize.yml b/.github/workflows/productionize.yml index c95f71ca..3e8e2db1 100644 --- a/.github/workflows/productionize.yml +++ b/.github/workflows/productionize.yml @@ -100,10 +100,11 @@ jobs: # Change `@stdlib/string-format` to `@stdlib/error-tools-fmtprodmsg` in package.json if the former is a dependency, otherwise insert it as a dependency: - name: 'Update dependencies in package.json' run: | + PKG_VERSION=$(npm view @stdlib/error-tools-fmtprodmsg version) if grep -q '"@stdlib/string-format"' package.json; then - sed -i "s/\"@stdlib\/string-format\"/\"@stdlib\/error-tools-fmtprodmsg\"/g" package.json + sed -i "s/\"@stdlib\/string-format\": \"^.*\"/\"@stdlib\/error-tools-fmtprodmsg\": \"^$PKG_VERSION\"/g" package.json else - node -e "var pkg = require( './package.json' ); pkg.dependencies[ '@stdlib/error-tools-fmtprodmsg' ] = '^0.0.x'; require( 'fs' ).writeFileSync( 'package.json', JSON.stringify( pkg, null, 2 ) );" + node -e "var pkg = require( './package.json' ); pkg.dependencies[ '@stdlib/error-tools-fmtprodmsg' ] = '^$PKG_VERSION'; require( 'fs' ).writeFileSync( 'package.json', JSON.stringify( pkg, null, 2 ) );" fi # Configure git: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b236827b..6adf06a8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -46,7 +46,7 @@ jobs: publish: # Define display name: - name: 'Publish to npm' + name: 'Publish package to npm' # Define the type of virtual host machine on which to run the job: runs-on: ubuntu-latest @@ -90,17 +90,65 @@ jobs: NEW_VERSION=$(node -p "require('./package.json').version") # Replace branch in README.md link definitions for badges with the new version: - find . -type f -name '*.md' -print0 | xargs -0 sed -Ei "s/branch[=:][^ ]+/branch=v${NEW_VERSION}/g" + find . -type f -name '*.md' -print0 | xargs -0 sed -Ei "s/branch([=:])[^ ]+/branch\1v${NEW_VERSION}/g" # Create a new commit and tag: git add package.json README.md git commit -m "Release v${NEW_VERSION}" - git tag -a "v${NEW_VERSION}" -m "Release v{NEW_VERSION}" + git tag -a "v${NEW_VERSION}" -m "Release v${NEW_VERSION}" # Push changes to GitHub: SLUG=${{ github.repository }} git push "https://$GITHUB_ACTOR:$GITHUB_TOKEN@github.com/$SLUG.git" --follow-tags + # Remove CLI: + - name: 'Remove CLI' + if: ${{ github.ref == 'refs/heads/main' }} + run: | + # Exit if the package does not have a CLI: + if ! grep -q '"bin":' package.json; then + exit 0 + fi + rm -rf ./bin/cli + rm test/test.cli.js + rm etc/cli_opts.json + rm docs/usage.txt + + # For all dependencies, check in all *.js files if they are still used; if not, remove them: + jq -r '.dependencies | keys[]' ./package.json | while read -r dep; do + dep=$(echo "$dep" | xargs) + if ! grep -q "$dep" lib/** && ! grep -q -s "$dep" manifest.json && ! grep -q -s "$dep" include.gypi; then + jq --indent 2 "del(.dependencies[\"$dep\"])" ./package.json > ./package.json.tmp + mv ./package.json.tmp ./package.json + fi + done + jq -r '.devDependencies | keys[]' ./package.json | while read -r dep; do + if [[ "$dep" != "@stdlib"* ]]; then + continue + fi + dep=$(echo "$dep" | xargs) + if ! grep -q "$dep" lib/** && ! grep -q -s "$dep" manifest.json && ! grep -q -s "$dep" include.gypi; then + jq --indent 2 "del(.devDependencies[\"$dep\"])" ./package.json > ./package.json.tmp + mv ./package.json.tmp ./package.json + fi + done + + # Remove CLI section: + find . -type f -name '*.md' -print0 | xargs -0 perl -0777 -i -pe "s/(\* \* \*\n+)?
[\s\S]+?<\!\-\- \/.cli \-\->//" + + # Remove CLI from package.json: + jq -r 'del(.bin)' package.json > package.json.tmp + mv package.json.tmp package.json + + # Add entry for CLI package to See Also section of README.md: + cliPkgName=$(jq -r '.name' package.json)-cli + escapedPkg=$(echo "$cliPkgName" | sed -e 's/\//\\\//g') + escapedPkg=$(echo "$escapedPkg" | sed -e 's/\@/\\\@/g') + find . -type f -name '*.md' -print0 | xargs -0 perl -0777 -i -pe "s/
(?:\n\n\* \* \*\n\n## See Also\n\n)?/
\n\n## See Also\n\n- [\`$escapedPkg\`][$escapedPkg]<\/span>: <\/span>CLI package for use as a command-line utility.<\/span>\n/" + + # Add link definition for CLI package to README.md: + find . -type f -name '*.md' -print0 | xargs -0 perl -0777 -i -pe "s/
/
\n\n[$escapedPkg]: https:\/\/www.npmjs.com\/package\/$escapedPkg/" + # Replace GitHub links to individual packages with npm links: - name: 'Replace all GitHub links to individual packages with npm links' run: | @@ -111,6 +159,12 @@ jobs: run: | find . -type f -name '*.md' -print0 | xargs -0 perl -0777 -i -pe "s/\`\`\`\n\nAlternatively,[^<]+<\/section>/\`\`\`\n\n<\/section>/" + # Remove unnecessary files: + - name: 'Remove unnecessary files' + run: | + rm docs/repl.txt + rm docs/types/test.ts + # Replace all stdlib GitHub dependencies with the respective npm packages: - name: 'Replace all stdlib GitHub dependencies with the respective npm packages' run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ab961777..7b714f45 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,6 +32,11 @@ on: # Run workflow on each push to the main branch: push: + # Run workflow upon completion of `publish` workflow run: + workflow_run: + workflows: ["publish"] + types: [completed] + # Workflow jobs: jobs: diff --git a/.gitignore b/.gitignore index 96412149..49b206b8 100644 --- a/.gitignore +++ b/.gitignore @@ -182,3 +182,7 @@ jsconfig.json ################ *.sublime-workspace *.sublime-project + +# Other editor files # +###################### +.idea/ diff --git a/CONTRIBUTORS b/CONTRIBUTORS index f97b6ef9..2cb9b1c5 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -9,9 +9,11 @@ Bruno Fenzl Christopher Dambamuromo Dominik Moritz Frank Kovacs +Harshita Kalani <95532771+HarshitaKalani@users.noreply.github.com> James Jithin KS Joey Reed +Jordan-Gallivan <115050475+Jordan-Gallivan@users.noreply.github.com> Joris Labie Justin Dennison Marcus diff --git a/base/lib/index.js b/base/lib/index.js index 307e06c5..72b5ce3c 100644 --- a/base/lib/index.js +++ b/base/lib/index.js @@ -328,6 +328,24 @@ setReadOnly( ns, 'ndarraylike2object', require( './../../base/ndarraylike2object */ setReadOnly( ns, 'nonsingletonDimensions', require( './../../base/nonsingleton-dimensions' ) ); +/** +* @name nullaryLoopOrder +* @memberof ns +* @readonly +* @type {Function} +* @see {@link module:@stdlib/ndarray/base/nullary-loop-interchange-order} +*/ +setReadOnly( ns, 'nullaryLoopOrder', require( './../../base/nullary-loop-interchange-order' ) ); + +/** +* @name nullaryBlockSize +* @memberof ns +* @readonly +* @type {Function} +* @see {@link module:@stdlib/ndarray/base/nullary-tiling-block-size} +*/ +setReadOnly( ns, 'nullaryBlockSize', require( './../../base/nullary-tiling-block-size' ) ); + /** * @name numel * @memberof ns diff --git a/base/nullary-loop-interchange-order/README.md b/base/nullary-loop-interchange-order/README.md new file mode 100644 index 00000000..cb4c977d --- /dev/null +++ b/base/nullary-loop-interchange-order/README.md @@ -0,0 +1,138 @@ + + +# nullaryLoopOrder + +> Reorder ndarray dimensions and associated strides for loop interchange. + + + +
+ +
+ + + + + +
+ +## Usage + +```javascript +var nullaryLoopOrder = require( '@stdlib/ndarray/base/nullary-loop-interchange-order' ); +``` + +#### nullaryLoopOrder( shape, stridesX ) + +Reorders [ndarray][@stdlib/ndarray/ctor] dimensions and associated strides for [loop interchange][loop-interchange]. + +```javascript +// Define an array shape: +var shape = [ 2, 2 ]; + +// Define array strides: +var stridesX = [ 2, 1 ]; // row-major + +// Resolve the loop interchange order: +var o = nullaryLoopOrder( shape, stridesX ); +// returns {...} +``` + +The function returns an object having the following properties: + +- **sh**: ordered dimensions. +- **sx**: array strides sorted in loop order. + +For all returned arrays, the first element corresponds to the innermost loop, and the last element corresponds to the outermost loop. + +
+ + + + + +
+ +## Notes + +- When iterating over the elements of a multi-dimensional array, accessing elements which are closer in memory can improve performance. To this end, [loop interchange][loop-interchange] is a technique used in [loop nest optimization][loop-nest-optimization] to improve locality of reference and take advantage of CPU cache. + + The purpose of this function is to order [ndarray][@stdlib/ndarray/ctor] dimensions according to the magnitude of array strides. By using the ordered dimensions and associated strides, one can construct nested loops (one for each dimension) such that the innermost loop iterates over the dimension in which array elements are closest in memory and the outermost loop iterates over the dimension in which array elements are farthest apart in memory. As a consequence, element iteration is optimized to minimized cache misses and ensure locality of reference. + +
+ + + + + +
+ +## Examples + + + +```javascript +var array = require( '@stdlib/ndarray/array' ); +var loopOrder = require( '@stdlib/ndarray/base/nullary-loop-interchange-order' ); + +// Create an ndarray: +var x = array( [ [ 1, 2 ], [ 3, 4 ] ] ); + +// Resolve loop interchange data: +var o = loopOrder( x.shape, x.strides ); +// returns {...} + +console.log( o ); +``` + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + diff --git a/base/nullary-loop-interchange-order/benchmark/benchmark.js b/base/nullary-loop-interchange-order/benchmark/benchmark.js new file mode 100644 index 00000000..4b2c5863 --- /dev/null +++ b/base/nullary-loop-interchange-order/benchmark/benchmark.js @@ -0,0 +1,81 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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 bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isArray = require( '@stdlib/assert/is-array' ); +var shape2strides = require( './../../../base/shape2strides' ); +var pkg = require( './../package.json' ).name; +var loopOrder = require( './../lib' ); + + +// MAIN // + +bench( pkg+'::row-major', function benchmark( b ) { + var strides; + var shape; + var out; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'row-major' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ i%shape.length ] *= ( randu() < 0.5 ) ? -1 : 1; + out = loopOrder( shape, strides ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isArray( out.sh ) || !isArray( out.sx ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::column-major', function benchmark( b ) { + var strides; + var shape; + var out; + var i; + + shape = [ 10, 10, 10 ]; + strides = shape2strides( shape, 'column-major' ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + strides[ i%shape.length ] *= ( randu() < 0.5 ) ? -1 : 1; + out = loopOrder( shape, strides ); + if ( typeof out !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isArray( out.sh ) || !isArray( out.sx ) ) { + b.fail( 'should return an array' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/nullary-loop-interchange-order/docs/repl.txt b/base/nullary-loop-interchange-order/docs/repl.txt new file mode 100644 index 00000000..e0ab1216 --- /dev/null +++ b/base/nullary-loop-interchange-order/docs/repl.txt @@ -0,0 +1,40 @@ + +{{alias}}( shape, stridesX ) + Reorders ndarray dimensions and associated strides for loop interchange. + + The function returns an object having the following properties: + + - sh: ordered dimensions. + - sx: array strides sorted in loop order. + + For all returned arrays, the first element corresponds to the innermost + loop, and the last element corresponds to the outermost loop. + + Parameters + ---------- + shape: ArrayLikeObject + Array dimensions. + + stridesX: ArrayLikeObject + Array strides. + + Returns + ------- + out: Object + Loop interchange data. + + out.sh: Array + Ordered dimensions. + + out.sx: Array + Array strides sorted in loop order. + + Examples + -------- + > var x = {{alias:@stdlib/ndarray/array}}( [ [ 1, 2 ], [ 3, 4 ] ] ); + > var o = {{alias}}( x.shape, x.strides ) + {...} + + See Also + -------- + diff --git a/base/nullary-loop-interchange-order/docs/types/index.d.ts b/base/nullary-loop-interchange-order/docs/types/index.d.ts new file mode 100644 index 00000000..c3b07f6c --- /dev/null +++ b/base/nullary-loop-interchange-order/docs/types/index.d.ts @@ -0,0 +1,77 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2023 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. +*/ + +// TypeScript Version: 2.0 + +/// + +import { ArrayLike } from '@stdlib/types/array'; + +/** +* Interface describing loop interchange data. +*/ +interface LoopOrderObject { + /** + * Dimensions sorted in loop order. + */ + sh: Array; + + /** + * Array strides sorted in loop order. + */ + sx: Array; +} + +/** +* Reorders ndarray dimensions and associated strides for loop interchange. +* +* ## Notes +* +* - The returned object has the following properties: +* +* - **sh**: dimensions sorted in loop order. +* - **sx**: ndarray strides sorted in loop order. +* +* - When iterating over the elements of a multi-dimensional array, accessing elements which are closer in memory can improve performance. To this end, loop interchange is a technique used in loop nest optimization to improve locality of reference and take advantage of CPU cache. +* +* The purpose of this function is to order ndarray dimensions according to the magnitude of array strides. By using the ordered dimensions and associated strides, one can construct nested loops (one for each dimension) such that the innermost loop iterates over the dimension in which array elements are closest in memory and the outermost loop iterates over the dimension in which array elements are farthest apart in memory. As a consequence, element iteration is optimized to minimized cache misses and ensure locality of reference. +* +* @param sh - array dimensions +* @param sx - array stride lengths +* @returns loop interchange data +* +* @example +* var sh = [ 2, 3, 4 ]; +* +* var sx = [ 12, 4, 1 ]; // row-major +* +* var o = nullaryLoopOrder( sh, sx ); +* // returns {...} +* +* var ssh = o.sh; +* // returns [ 4, 3, 2 ] +* +* var ssx = o.sx; +* // returns [ 1, 4, 12 ] +*/ +declare function nullaryLoopOrder( shape: ArrayLike, stridesX: ArrayLike ): LoopOrderObject; // tslint-disable-line max-line-length + + +// EXPORTS // + +export = nullaryLoopOrder; diff --git a/base/nullary-loop-interchange-order/docs/types/test.ts b/base/nullary-loop-interchange-order/docs/types/test.ts new file mode 100644 index 00000000..44dc6118 --- /dev/null +++ b/base/nullary-loop-interchange-order/docs/types/test.ts @@ -0,0 +1,60 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2023 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. +*/ + +import nullaryLoopOrder = require( './index' ); + + +// TESTS // + +// The function returns an object... +{ + const sh = [ 2, 2 ]; + const sx = [ 2, 1 ]; + nullaryLoopOrder( sh, sx ); // $ExpectType LoopOrderObject +} + +// The compiler throws an error if the function is provided a first argument which is not an array-like object of numbers... +{ + const sx = [ 2, 1 ]; + nullaryLoopOrder( true, sx ); // $ExpectError + nullaryLoopOrder( false, sx ); // $ExpectError + nullaryLoopOrder( '5', sx ); // $ExpectError + nullaryLoopOrder( 123, sx ); // $ExpectError + nullaryLoopOrder( {}, sx ); // $ExpectError + nullaryLoopOrder( ( x: number ): number => x, sx ); // $ExpectError +} + +// The compiler throws an error if the function is provided a second argument which is not an array-like object of numbers... +{ + const sh = [ 2, 2 ]; + nullaryLoopOrder( sh, true ); // $ExpectError + nullaryLoopOrder( sh, false ); // $ExpectError + nullaryLoopOrder( sh, '5' ); // $ExpectError + nullaryLoopOrder( sh, 123 ); // $ExpectError + nullaryLoopOrder( sh, {} ); // $ExpectError + nullaryLoopOrder( sh, ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided an unsupported number of arguments... +{ + const sh = [ 2, 2 ]; + const sx = [ 2, 1 ]; + nullaryLoopOrder(); // $ExpectError + nullaryLoopOrder( sh ); // $ExpectError + nullaryLoopOrder( sh, sx, [] ); // $ExpectError +} diff --git a/base/nullary-loop-interchange-order/examples/index.js b/base/nullary-loop-interchange-order/examples/index.js new file mode 100644 index 00000000..92a3ce39 --- /dev/null +++ b/base/nullary-loop-interchange-order/examples/index.js @@ -0,0 +1,31 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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'; + +var array = require( './../../../array' ); +var loopOrder = require( './../lib' ); + +// Create an ndarray: +var x = array( [ [ 1, 2 ], [ 3, 4 ] ] ); + +// Resolve loop interchange data: +var o = loopOrder( x.shape, x.strides ); +// returns {...} + +console.log( o ); diff --git a/base/nullary-loop-interchange-order/lib/index.js b/base/nullary-loop-interchange-order/lib/index.js new file mode 100644 index 00000000..93dd1c01 --- /dev/null +++ b/base/nullary-loop-interchange-order/lib/index.js @@ -0,0 +1,50 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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'; + +/** +* Reorder ndarray dimensions and associated strides for loop interchange. +* +* @module @stdlib/ndarray/base/nullary-loop-interchange-order +* +* @example +* var nullaryLoopOrder = require( '@stdlib/ndarray/base/nullary-loop-interchange-order' ); +* +* var sh = [ 2, 3, 4 ]; +* +* var sx = [ 12, 4, 1 ]; // row-major +* +* var o = nullaryLoopOrder( sh, sx ); +* // returns {...} +* +* var ssh = o.sh; +* // returns [ 4, 3, 2 ] +* +* var ssx = o.sx; +* // returns [ 1, 4, 12 ] +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/base/nullary-loop-interchange-order/lib/main.js b/base/nullary-loop-interchange-order/lib/main.js new file mode 100644 index 00000000..ebb4dab7 --- /dev/null +++ b/base/nullary-loop-interchange-order/lib/main.js @@ -0,0 +1,81 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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 zeroTo = require( '@stdlib/array/base/zero-to' ); +var copy = require( '@stdlib/array/base/copy-indexed' ); +var take = require( '@stdlib/array/base/take' ); +var sort2ins = require( './sort2ins.js' ); + + +// MAIN // + +/** +* Reorders ndarray dimensions and associated strides for loop interchange. +* +* ## Notes +* +* - The returned object has the following properties: +* +* - **sh**: dimensions sorted in loop order. +* - **sx**: ndarray strides sorted in loop order. +* +* @param {NonNegativeIntegerArray} sh - array dimensions +* @param {IntegerArray} sx - array stride lengths +* @returns {Object} loop interchange data +* +* @example +* var sh = [ 2, 3, 4 ]; +* +* var sx = [ 12, 4, 1 ]; // row-major +* +* var o = loopOrder( sh, sx ); +* // returns {...} +* +* var ssh = o.sh; +* // returns [ 4, 3, 2 ] +* +* var ssx = o.sx; +* // returns [ 1, 4, 12 ] +*/ +function loopOrder( sh, sx ) { + var idx; + + // Initialize a loop interchange index array for generating a loop order permutation: + idx = zeroTo( sh.length ); + + // Sort the array strides in increasing order (of magnitude): + sx = copy( sx ); + sort2ins( sx, idx ); + + // Permute the shape based on the sorted array strides: + sh = take( sh, idx ); + + return { + 'sh': sh, + 'sx': sx + }; +} + + +// EXPORTS // + +module.exports = loopOrder; diff --git a/base/nullary-loop-interchange-order/lib/sort2ins.js b/base/nullary-loop-interchange-order/lib/sort2ins.js new file mode 100644 index 00000000..ec9ebcf6 --- /dev/null +++ b/base/nullary-loop-interchange-order/lib/sort2ins.js @@ -0,0 +1,98 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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'; + +// MAIN // + +/** +* Simultaneously sorts two arrays based on the sort order of the first array using insertion sort. +* +* ## Notes +* +* - The first array is sorted in increasing order according to absolute value. +* - The algorithm has space complexity `O(1)` and worst case time complexity `O(N^2)`. +* - The algorithm is efficient for small arrays (typically `N <= 20``) and is particularly efficient for sorting arrays which are already substantially sorted. +* - The algorithm is **stable**, meaning that the algorithm does **not** change the order of array elements which are equal or equivalent. +* - The input arrays are sorted in-place (i.e., the input arrays are mutated). +* +* @private +* @param {Array} x - first array +* @param {Array} y - second array +* @returns {void} +* +* @example +* var x = [ -4, -2, 3, 1 ]; +* var y = [ 0, 1, 2, 3 ]; +* +* sort2ins( x, y ); +* +* console.log( x ); +* // => [ 1, -2, 3, -4 ] +* +* console.log( y ); +* // => [ 3, 1, 2, 0 ] +*/ +function sort2ins( x, y ) { + var avx; + var aux; + var ix; + var iy; + var jx; + var jy; + var vx; + var vy; + var ux; + var i; + + ix = 1; + iy = 1; + + // Sort in increasing order... + for ( i = 1; i < x.length; i++ ) { + vx = x[ ix ]; + avx = ( vx < 0 ) ? -vx : vx; + + vy = y[ iy ]; + + jx = ix - 1; + jy = iy - 1; + + // Shift all larger values to the left of the current element to the right... + while ( jx >= 0 ) { + ux = x[ jx ]; + aux = ( ux < 0 ) ? -ux : ux; + if ( aux <= avx ) { + break; + } + x[ jx+1 ] = ux; + y[ jy+1 ] = y[ jy ]; + jx -= 1; + jy -= 1; + } + x[ jx+1 ] = vx; + y[ jy+1 ] = vy; + ix += 1; + iy += 1; + } +} + + +// EXPORTS // + +module.exports = sort2ins; diff --git a/base/nullary-loop-interchange-order/package.json b/base/nullary-loop-interchange-order/package.json new file mode 100644 index 00000000..732ea99c --- /dev/null +++ b/base/nullary-loop-interchange-order/package.json @@ -0,0 +1,73 @@ +{ + "name": "@stdlib/ndarray/base/nullary-loop-interchange-order", + "version": "0.0.0", + "description": "Reorder ndarray dimensions and associated strides for loop interchange.", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "main": "./lib", + "directories": { + "benchmark": "./benchmark", + "doc": "./docs", + "example": "./examples", + "lib": "./lib", + "test": "./test" + }, + "types": "./docs/types", + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "stdtypes", + "types", + "base", + "ndarray", + "reorder", + "sort", + "loop", + "tiling", + "blocking", + "interchange", + "cache-oblivious", + "optimization", + "multidimensional", + "array", + "utilities", + "utility", + "utils", + "util" + ], + "__stdlib__": {} +} diff --git a/base/nullary-loop-interchange-order/test/test.js b/base/nullary-loop-interchange-order/test/test.js new file mode 100644 index 00000000..9a48f5ef --- /dev/null +++ b/base/nullary-loop-interchange-order/test/test.js @@ -0,0 +1,83 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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 tape = require( 'tape' ); +var isArray = require( '@stdlib/assert/is-array' ); +var loopOrder = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof loopOrder, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns loop interchange data (row-major)', function test( t ) { + var sh; + var sx; + var o; + + sh = [ 4, 2, 2 ]; + sx = [ 4, -2, 1 ]; + + o = loopOrder( sh, sx ); + + t.notEqual( o.sh, sh, 'returns new array' ); + t.strictEqual( isArray( o.sh ), true, 'returns expected value' ); + t.deepEqual( o.sh, [ 2, 2, 4 ], 'returns expected value' ); + + t.notEqual( o.sx, sx, 'returns new array' ); + t.strictEqual( isArray( o.sx ), true, 'returns expected value' ); + t.deepEqual( o.sx, [ 1, -2, 4 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'the function returns loop interchange data (column-major)', function test( t ) { + var sh; + var sx; + var o; + + sh = [ 4, 2, 2 ]; + sx = [ 1, -4, 8 ]; + + o = loopOrder( sh, sx ); + + t.notEqual( o.sh, sh, 'returns new array' ); + t.strictEqual( isArray( o.sh ), true, 'returns expected value' ); + t.deepEqual( o.sh, [ 4, 2, 2 ], 'returns expected value' ); + + t.notEqual( o.sx, sx, 'returns new array' ); + t.strictEqual( isArray( o.sx ), true, 'returns expected value' ); + t.deepEqual( o.sx, [ 1, -4, 8 ], 'returns expected value' ); + + t.end(); +}); + +tape( 'if provided empty arrays, the function returns empty arrays', function test( t ) { + var o = loopOrder( [], [] ); + t.deepEqual( o.sh, [], 'returns expected value' ); + t.deepEqual( o.sx, [], 'returns expected value' ); + t.end(); +}); diff --git a/base/nullary-tiling-block-size/README.md b/base/nullary-tiling-block-size/README.md new file mode 100644 index 00000000..d1f8d25c --- /dev/null +++ b/base/nullary-tiling-block-size/README.md @@ -0,0 +1,121 @@ + + +# nullaryBlockSize + +> Resolve a loop block size for multi-dimensional array tiled loops. + + + +
+ +
+ + + + + +
+ +## Usage + +```javascript +var nullaryBlockSize = require( '@stdlib/ndarray/base/nullary-tiling-block-size' ); +``` + +#### nullaryBlockSize( dtypeX ) + +Resolves a loop block size according to provided ndarray [dtypes][@stdlib/ndarray/dtypes] for multi-dimensional array tiled loops applying a nullary function. + +```javascript +var bsize = nullaryBlockSize( 'float64' ); +// returns +``` + +
+ + + + + +
+ +## Notes + +- The returned loop tiling block size is in units of elements. + +
+ + + + + +
+ +## Examples + + + +```javascript +var dtypes = require( '@stdlib/ndarray/dtypes' ); +var nullaryBlockSize = require( '@stdlib/ndarray/base/nullary-tiling-block-size' ); + +// Get the list of ndarray dtypes: +var dt = dtypes(); + +// Resolve the block size for each dtype... +var b; +var i; +console.log( 'block_size, xdtype' ); +for ( i = 0; i < dt.length; i++ ) { + b = nullaryBlockSize( dt[ i ] ); + console.log( '%d, %s', b, dt[ i ] ); +} +``` + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + diff --git a/base/nullary-tiling-block-size/benchmark/benchmark.js b/base/nullary-tiling-block-size/benchmark/benchmark.js new file mode 100644 index 00000000..dbd19ad3 --- /dev/null +++ b/base/nullary-tiling-block-size/benchmark/benchmark.js @@ -0,0 +1,72 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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 bench = require( '@stdlib/bench' ); +var isPositiveInteger = require( '@stdlib/assert/is-positive-integer' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var blockSize = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var dx; + var dy; + var s; + var i; + + dx = [ + 'float64', + 'float32', + 'int8', + 'uint8', + 'uint8c', + 'int16', + 'uint16', + 'int32', + 'uint32', + 'binary', + 'generic', + 'foobar' + ]; + dy = [ + 'float64', + 'generic', + 'int32', + 'int16', + 'int8' + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + s = blockSize( dx[ i%dx.length ], dy[ i%dy.length ] ); + if ( typeof s !== 'number' ) { + b.fail( 'should return a number' ); + } + } + b.toc(); + if ( !isPositiveInteger( s ) ) { + b.fail( 'should return a positive integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/nullary-tiling-block-size/docs/repl.txt b/base/nullary-tiling-block-size/docs/repl.txt new file mode 100644 index 00000000..953fb098 --- /dev/null +++ b/base/nullary-tiling-block-size/docs/repl.txt @@ -0,0 +1,24 @@ + +{{alias}}( dtypeX ) + Returns a loop block size for multi-dimensional array tiled loops. + + Parameters + ---------- + dtypeX: string + Array data type. + + Returns + ------- + out: integer + Block size. + + Examples + -------- + > var out = {{alias}}( 'float64' ) + + > out = {{alias}}( 'int32' ) + + + See Also + -------- + diff --git a/base/nullary-tiling-block-size/docs/types/index.d.ts b/base/nullary-tiling-block-size/docs/types/index.d.ts new file mode 100644 index 00000000..97e0a3eb --- /dev/null +++ b/base/nullary-tiling-block-size/docs/types/index.d.ts @@ -0,0 +1,36 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2023 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. +*/ + +// TypeScript Version: 2.0 + +/** +* Returns a loop block size for multi-dimensional array tiled loops. +* +* @param dtypeX - array data type +* @returns block size (in units of elements) +* +* @example +* var bsize = nullaryBlockSize( 'float64' ); +* // returns +*/ +declare function nullaryBlockSize( dtypeX: string ): number; + + +// EXPORTS // + +export = nullaryBlockSize; diff --git a/base/nullary-tiling-block-size/docs/types/test.ts b/base/nullary-tiling-block-size/docs/types/test.ts new file mode 100644 index 00000000..6ccacb47 --- /dev/null +++ b/base/nullary-tiling-block-size/docs/types/test.ts @@ -0,0 +1,46 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2023 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. +*/ + +import nullaryBlockSize = require( './index' ); + + +// TESTS // + +// The function returns a number... +{ + nullaryBlockSize( 'float64' ); // $ExpectType number + nullaryBlockSize( 'generic' ); // $ExpectType number +} + +// The compiler throws an error if the function is provided a first argument which is not a string... +{ + nullaryBlockSize( 123 ); // $ExpectError + nullaryBlockSize( true ); // $ExpectError + nullaryBlockSize( false ); // $ExpectError + nullaryBlockSize( null ); // $ExpectError + nullaryBlockSize( {} ); // $ExpectError + nullaryBlockSize( [] ); // $ExpectError + nullaryBlockSize( ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided an unsupported number of arguments... +{ + nullaryBlockSize(); // $ExpectError + nullaryBlockSize( 'float64', 'float64' ); // $ExpectError + nullaryBlockSize( 'float64', 'float64', 'float64' ); // $ExpectError +} diff --git a/base/nullary-tiling-block-size/examples/index.js b/base/nullary-tiling-block-size/examples/index.js new file mode 100644 index 00000000..e8d6508c --- /dev/null +++ b/base/nullary-tiling-block-size/examples/index.js @@ -0,0 +1,34 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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'; + +var dtypes = require( './../../../dtypes' ); +var nullaryBlockSize = require( './../lib' ); + +// Get the list of ndarray dtypes: +var dt = dtypes(); + +// Resolve the block size for each dtype... +var b; +var i; +console.log( 'block_size, xdtype' ); +for ( i = 0; i < dt.length; i++ ) { + b = nullaryBlockSize( dt[ i ] ); + console.log( '%d, %s', b, dt[ i ] ); +} diff --git a/base/nullary-tiling-block-size/lib/defaults.js b/base/nullary-tiling-block-size/lib/defaults.js new file mode 100644 index 00000000..b4f52ccd --- /dev/null +++ b/base/nullary-tiling-block-size/lib/defaults.js @@ -0,0 +1,34 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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'; + +// MAIN // + +var defaults = { + // Define a default block size (in bytes): + 'BLOCK_SIZE_IN_BYTES': 64|0, // 64b is a common cache line size. How applicable the common cache line size is here is debatable, given that, depending on the associated stride(s), the innermost loop may not iterate over adjacent elements. The primary goal is to have a block size in which all data within a block can always fit in (L1) cache, regardless of cache size (i.e., cache-oblivious). For reference, a common L1 cache size is 32kB per core. For best performance, block sizes should be tuned based on system hardware; however, such tuning is not readily available to us here. Without obvious better alternatives, 64b has some theoretical (and practical) underpinning, and it should be good enough for most inputs, especially for ndarrays with near contiguity. + + // Define a default block size (in elements): + 'BLOCK_SIZE_IN_ELEMENTS': 8|0 // 64 bytes / 8 bytes per element (i.e., default element size is same as a double) +}; + + +// EXPORTS // + +module.exports = defaults; diff --git a/base/nullary-tiling-block-size/lib/index.js b/base/nullary-tiling-block-size/lib/index.js new file mode 100644 index 00000000..b1647412 --- /dev/null +++ b/base/nullary-tiling-block-size/lib/index.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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'; + +/** +* Resolve a loop block size for multi-dimensional array tiled loops. +* +* @module @stdlib/ndarray/base/nullary-tiling-block-size +* +* @example +* var nullaryBlockSize = require( '@stdlib/ndarray/base/nullary-tiling-block-size' ); +* +* var bsize = nullaryBlockSize( 'float64' ); +* // returns +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/base/nullary-tiling-block-size/lib/main.js b/base/nullary-tiling-block-size/lib/main.js new file mode 100644 index 00000000..426db899 --- /dev/null +++ b/base/nullary-tiling-block-size/lib/main.js @@ -0,0 +1,50 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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 bytesPerElement = require( './../../../base/bytes-per-element' ); +var defaults = require( './defaults.js' ); + + +// MAIN // + +/** +* Returns a loop block size for multi-dimensional array tiled loops. +* +* @param {string} dtypeX - array data type +* @returns {integer} block size (in units of elements) +* +* @example +* var bsize = nullaryBlockSize( 'float64' ); +* // returns +*/ +function nullaryBlockSize( dtypeX ) { + var nbx = bytesPerElement( dtypeX ); + if ( nbx === null ) { // e.g., "generic" arrays + return defaults.BLOCK_SIZE_IN_ELEMENTS; + } + return ( defaults.BLOCK_SIZE_IN_BYTES/nbx )|0; // asm type annotation +} + + +// EXPORTS // + +module.exports = nullaryBlockSize; diff --git a/base/nullary-tiling-block-size/package.json b/base/nullary-tiling-block-size/package.json new file mode 100644 index 00000000..1fb416f7 --- /dev/null +++ b/base/nullary-tiling-block-size/package.json @@ -0,0 +1,69 @@ +{ + "name": "@stdlib/ndarray/base/nullary-tiling-block-size", + "version": "0.0.0", + "description": "Resolve a loop block size for multi-dimensional array tiled loops.", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "main": "./lib", + "directories": { + "benchmark": "./benchmark", + "doc": "./docs", + "example": "./examples", + "lib": "./lib", + "test": "./test" + }, + "types": "./docs/types", + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "stdtypes", + "types", + "base", + "ndarray", + "loop", + "tiling", + "blocking", + "cache-oblivious", + "multidimensional", + "array", + "utilities", + "utility", + "utils", + "util" + ], + "__stdlib__": {} +} diff --git a/base/nullary-tiling-block-size/test/test.js b/base/nullary-tiling-block-size/test/test.js new file mode 100644 index 00000000..3745d0d6 --- /dev/null +++ b/base/nullary-tiling-block-size/test/test.js @@ -0,0 +1,56 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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 tape = require( 'tape' ); +var isPositiveInteger = require( '@stdlib/assert/is-positive-integer' ).isPrimitive; +var dtypes = require( './../../../dtypes' ); +var nullaryBlockSize = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof nullaryBlockSize, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns a block size', function test( t ) { + var dt; + var v; + var i; + + // NOTE: we don't test for exact block size values, as we shouldn't need to make guarantees regarding the block size for any particular dtype. This function is meant to be opaque, and we want to reserve the right to silently update/change return values in the future. + + // Get the list of dtypes: + dt = dtypes(); + + for ( i = 0; i < dt.length; i++ ) { + v = nullaryBlockSize( dt[ i ] ); + t.strictEqual( isPositiveInteger( v ), true, 'returns a positive integer when provided ('+dt[ i ]+')' ); + } + + // Sanity check that the block size for dtypes with wider bit widths is smaller than for dtypes with shorter bit widths... + t.strictEqual( nullaryBlockSize( 'complex128' ) < nullaryBlockSize( 'int8' ), true, 'returns expected value' ); + t.strictEqual( nullaryBlockSize( 'float64' ) < nullaryBlockSize( 'uint8' ), true, 'returns expected value' ); + t.end(); +}); diff --git a/base/unary-loop-interchange-order/docs/types/test.ts b/base/unary-loop-interchange-order/docs/types/test.ts index 4770f8a2..62891239 100644 --- a/base/unary-loop-interchange-order/docs/types/test.ts +++ b/base/unary-loop-interchange-order/docs/types/test.ts @@ -53,7 +53,7 @@ import unaryLoopOrder = require( './index' ); unaryLoopOrder( sh, ( x: number ): number => x, sy ); // $ExpectError } -// The compiler throws an error if the function is provided a first argument which is not an array-like object of numbers... +// The compiler throws an error if the function is provided a third argument which is not an array-like object of numbers... { const sh = [ 2, 2 ]; const sx = [ 2, 1 ]; diff --git a/branches.md b/branches.md index 6c924cf4..e0366228 100644 --- a/branches.md +++ b/branches.md @@ -38,12 +38,12 @@ C -->|bundle| D[esm]; C -->|bundle| E[deno]; C -->|bundle| F[umd]; -click A href "https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/ndarray" -click B href "https://github.com/stdlib-js/ndarray/tree/main" -click C href "https://github.com/stdlib-js/ndarray/tree/production" -click D href "https://github.com/stdlib-js/ndarray/tree/esm" -click E href "https://github.com/stdlib-js/ndarray/tree/deno" -click F href "https://github.com/stdlib-js/ndarray/tree/umd" +%% click A href "https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/ndarray" +%% click B href "https://github.com/stdlib-js/ndarray/tree/main" +%% click C href "https://github.com/stdlib-js/ndarray/tree/production" +%% click D href "https://github.com/stdlib-js/ndarray/tree/esm" +%% click E href "https://github.com/stdlib-js/ndarray/tree/deno" +%% click F href "https://github.com/stdlib-js/ndarray/tree/umd" ``` [stdlib-url]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/ndarray diff --git a/package.json b/package.json index 10f01918..72bdd421 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ ], "__stdlib__": {}, "funding": { - "type": "patreon", - "url": "https://www.patreon.com/athan" + "type": "opencollective", + "url": "https://opencollective.com/stdlib" } }