diff --git a/.circleci/config.yml b/.circleci/config.yml index b35ab8506..fca9d1c8f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,7 +5,7 @@ _defaults: &defaults docker: # CircleCI maintains a library of pre-built images # documented at https://circleci.com/docs/2.0/circleci-images/ - - image: cimg/python:3.10.2 + - image: cimg/python:3.10.2-node working_directory: ~/repo jobs: @@ -21,6 +21,7 @@ jobs: command: | pip install -r doc-requirements.txt make spec + make compat - store_artifacts: path: _site/ diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index b328abc11..bc162e1c5 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -78,12 +78,20 @@ jobs: run: | pip install -r doc-requirements.txt + # Install Node.js: + - name: 'Install Node.js' + uses: actions/setup-node@v3 + with: + node-version: '16' # 'lts/*' + timeout-minutes: 5 + # Generate the documentation: - name: 'Build documentation' run: | # Turn warnings into errors and ensure .doctrees is not deployed: export SPHINXOPTS="-b html -WT --keep-going -d doctrees" make spec + make compat # Configure Git: - name: 'Configure Git' diff --git a/.gitignore b/.gitignore index d4f538406..3537c9c83 100644 --- a/.gitignore +++ b/.gitignore @@ -22,15 +22,170 @@ # SOFTWARE. #/ +# Files # +######### + + +# Directories # +############### _site/ doctrees/ -build/ -.vscode/ -node_modules/ -__pycache__/ -*.pyc spec/**/generated +dist/ + +build/ +downloads/ +reports/ tmp/ + +# Compiled source # +################### +*.com +*.class +*.dll +*.o +*.so +*.slo +*.lo +*.obj +*.dylib +*.lai +*.la +*.a +*.lib +*.ko +*.elf +*.node + +# Precompiled headers # +####################### +*.gch +*.pch + +# Executables # +############### +*.exe +*.out +*.app + +# Packages # +############ +# It is better to unpack these files and commit the raw source +# git has its own built in compression methods +*.7z +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.zip + +# Logs and databases # +###################### +*.log +*.sql +*.sqlite + +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +Icon? +ehthumbs.db +Thumbs.db +Desktop.ini + +# Temporary files # +################### +*~ + +# Node.js # +########### +/node_modules/ +pids +*.pid +*.seed + +# Typescript # +############## +*.tsbuildinfo + +# Matlab # +########## +*.asv +*.mex* + +# Fortran # +########### +*.mod + +# R # +##### +.Rhistory +.Rapp.history +.Rproj.user/ + +# Python # +########## +__pycache__/ +*.py[cod] +*$py.class *.egg-info/ *.egg -dist/ + +# TeX # +####### +*.aux +*.lof +*.log +*.lot +*.fls +*.out +*.toc +*.dvi +*-converted-to.* +*.bbl +*.bcf +*.blg +*-blx.aux +*-blx.bib +*.brf +*.run.xml +*.fdb_latexmk +*.synctex +*.synctex.gz +*.synctex.gz(busy) +*.pdfsync +*.alg +*.loa +acs-*.bib +*.thm +*.nav +*.snm +*.vrb +*.acn +*.acr +*.glg +*.glo +*.gls +*-concordance.tex +*.tikz +*-tikzDictionary +*.idx +*.ilg +*.ind +*.ist + +# Visual Studio # +################# +.vscode/ +jsconfig.json + +# Sublime Text # +################ +*.sublime-workspace +*.sublime-project diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..26c897c0a --- /dev/null +++ b/.npmrc @@ -0,0 +1,34 @@ +#/ +# @license MIT +# +# Copyright (c) 2023 Python Data APIs Consortium. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +#/ + +# Configuration for [npm][1]. +# +# [1]: https://docs.npmjs.com/files/npmrc + +# Disable the creation of a lock file: +package-lock = false +shrinkwrap = false + +# Disable automatically "saving" dependencies on install: +save = false diff --git a/Makefile b/Makefile index d23e05218..bca0607c6 100644 --- a/Makefile +++ b/Makefile @@ -25,3 +25,6 @@ spec: sphinx-build "$(SOURCEDIR)/2022.12" "$(BUILDDIR)/2022.12" $(SPHINXOPTS) cp -r "$(BUILDDIR)/2022.12" "$(BUILDDIR)/latest" sphinx-build "$(SOURCEDIR)/draft" "$(BUILDDIR)/draft" $(SPHINXOPTS) + +compat: + npm install && npm run build diff --git a/package.json b/package.json new file mode 100644 index 000000000..c87e20408 --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "private": true, + "name": "@data-apis/array-api", + "version": "0.0.0", + "license": "MIT", + "description": "Array API specification.", + "author": {}, + "contributors": [], + "main": "", + "directories": {}, + "scripts": { + "build": "npm run build:install && npm run build:compat", + "build:install": "cd ./node_modules/array-api-compat-data && npm install", + "build:compat": "npm run build:compat:draft && npm run build:compat:latest && npm run build:compat:2022 && npm run build:compat:2021", + "build:compat:init": "cd ./node_modules/array-api-compat-data && rm -rf ./build/embed && mkdir -p ./build/embed && cd ./../../", + "build:compat:draft": "npm run build:compat:init && cd ./node_modules/array-api-compat-data && node ./scripts/build_embed.js --max-version='*' && node ./scripts/build_spec.js ./../../_site/draft", + "build:compat:latest": "npm run build:compat:init && cd ./node_modules/array-api-compat-data && node ./scripts/build_embed.js --max-version='*' && node ./scripts/build_spec.js ./../../_site/latest", + "build:compat:2022": "npm run build:compat:init && cd ./node_modules/array-api-compat-data && node ./scripts/build_embed.js --max-version='2022.12' && node ./scripts/build_spec.js ./../../_site/2022.12", + "build:compat:2021": "npm run build:compat:init && cd ./node_modules/array-api-compat-data && node ./scripts/build_embed.js --max-version='2021.12' && node ./scripts/build_spec.js ./../../_site/2021.12" + }, + "homepage": "https://github.com/data-apis/array-api", + "repository": { + "type": "git", + "url": "git://github.com/data-apis/array-api.git" + }, + "bugs": { + "url": "https://github.com/data-apis/array-api/issues" + }, + "devDependencies": { + "array-api-compat-data": "git+https://github.com/data-apis/array-api-compat-data.git#main" + }, + "keywords": [] +} diff --git a/spec/_static/images/compat/cupy_logo.png b/spec/_static/images/compat/cupy_logo.png new file mode 100644 index 000000000..fcde17744 Binary files /dev/null and b/spec/_static/images/compat/cupy_logo.png differ diff --git a/spec/_static/images/compat/cupy_logo_icon.png b/spec/_static/images/compat/cupy_logo_icon.png new file mode 100644 index 000000000..ad291629f Binary files /dev/null and b/spec/_static/images/compat/cupy_logo_icon.png differ diff --git a/spec/_static/images/compat/dask_logo_icon.svg b/spec/_static/images/compat/dask_logo_icon.svg new file mode 100644 index 000000000..65413d454 --- /dev/null +++ b/spec/_static/images/compat/dask_logo_icon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/spec/_static/images/compat/deprecated.svg b/spec/_static/images/compat/deprecated.svg new file mode 100644 index 000000000..0c28832cd --- /dev/null +++ b/spec/_static/images/compat/deprecated.svg @@ -0,0 +1,3 @@ + + + diff --git a/spec/_static/images/compat/disabled.svg b/spec/_static/images/compat/disabled.svg new file mode 100644 index 000000000..d3dc186dc --- /dev/null +++ b/spec/_static/images/compat/disabled.svg @@ -0,0 +1,3 @@ + + + diff --git a/spec/_static/images/compat/jax_logo.svg b/spec/_static/images/compat/jax_logo.svg new file mode 100644 index 000000000..ef66744f4 --- /dev/null +++ b/spec/_static/images/compat/jax_logo.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spec/_static/images/compat/more.svg b/spec/_static/images/compat/more.svg new file mode 100644 index 000000000..20b647a23 --- /dev/null +++ b/spec/_static/images/compat/more.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/spec/_static/images/compat/mxnet_logo_icon.png b/spec/_static/images/compat/mxnet_logo_icon.png new file mode 100644 index 000000000..01e0ff950 Binary files /dev/null and b/spec/_static/images/compat/mxnet_logo_icon.png differ diff --git a/spec/_static/images/compat/no.svg b/spec/_static/images/compat/no.svg new file mode 100644 index 000000000..cacadcb46 --- /dev/null +++ b/spec/_static/images/compat/no.svg @@ -0,0 +1,3 @@ + + + diff --git a/spec/_static/images/compat/numpy_logo.svg b/spec/_static/images/compat/numpy_logo.svg new file mode 100644 index 000000000..e5791dc3e --- /dev/null +++ b/spec/_static/images/compat/numpy_logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/spec/_static/images/compat/numpy_logo_icon.svg b/spec/_static/images/compat/numpy_logo_icon.svg new file mode 100644 index 000000000..08b858644 --- /dev/null +++ b/spec/_static/images/compat/numpy_logo_icon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/spec/_static/images/compat/partial.svg b/spec/_static/images/compat/partial.svg new file mode 100644 index 000000000..499205c67 --- /dev/null +++ b/spec/_static/images/compat/partial.svg @@ -0,0 +1,3 @@ + + + diff --git a/spec/_static/images/compat/preview.svg b/spec/_static/images/compat/preview.svg new file mode 100644 index 000000000..fe9ab5a79 --- /dev/null +++ b/spec/_static/images/compat/preview.svg @@ -0,0 +1,2 @@ + + diff --git a/spec/_static/images/compat/pytorch_logo.svg b/spec/_static/images/compat/pytorch_logo.svg new file mode 100644 index 000000000..5e5300038 --- /dev/null +++ b/spec/_static/images/compat/pytorch_logo.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/spec/_static/images/compat/pytorch_logo_icon.svg b/spec/_static/images/compat/pytorch_logo_icon.svg new file mode 100644 index 000000000..90184c52e --- /dev/null +++ b/spec/_static/images/compat/pytorch_logo_icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/spec/_static/images/compat/tensorflow_logo_icon.svg b/spec/_static/images/compat/tensorflow_logo_icon.svg new file mode 100644 index 000000000..65a1c2a6d --- /dev/null +++ b/spec/_static/images/compat/tensorflow_logo_icon.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/spec/_static/images/compat/unknown.svg b/spec/_static/images/compat/unknown.svg new file mode 100644 index 000000000..a1add9d74 --- /dev/null +++ b/spec/_static/images/compat/unknown.svg @@ -0,0 +1,3 @@ + + + diff --git a/spec/_static/images/compat/yes.svg b/spec/_static/images/compat/yes.svg new file mode 100644 index 000000000..f75807fb5 --- /dev/null +++ b/spec/_static/images/compat/yes.svg @@ -0,0 +1,3 @@ + + + diff --git a/spec/_static/images/compat/yes_circle.svg b/spec/_static/images/compat/yes_circle.svg new file mode 100644 index 000000000..9f7d4519f --- /dev/null +++ b/spec/_static/images/compat/yes_circle.svg @@ -0,0 +1,3 @@ + + + diff --git a/spec/_static/images/compatibility_table_0.png b/spec/_static/images/compatibility_table_0.png new file mode 100644 index 000000000..820bcffbc Binary files /dev/null and b/spec/_static/images/compatibility_table_0.png differ diff --git a/spec/_static/images/compatibility_table_1.png b/spec/_static/images/compatibility_table_1.png new file mode 100644 index 000000000..5af3b5464 Binary files /dev/null and b/spec/_static/images/compatibility_table_1.png differ diff --git a/spec/_static/images/compatibility_table_2.png b/spec/_static/images/compatibility_table_2.png new file mode 100644 index 000000000..ca5f15649 Binary files /dev/null and b/spec/_static/images/compatibility_table_2.png differ diff --git a/spec/_static/images/compatibility_table_3.png b/spec/_static/images/compatibility_table_3.png new file mode 100644 index 000000000..50e4deb88 Binary files /dev/null and b/spec/_static/images/compatibility_table_3.png differ diff --git a/spec/draft/index.rst b/spec/draft/index.rst index 3e51cc68e..7a7d919c7 100644 --- a/spec/draft/index.rst +++ b/spec/draft/index.rst @@ -26,7 +26,7 @@ Contents :maxdepth: 1 usage_data - verification_test_suite + verification_and_compliance benchmark_suite .. toctree:: diff --git a/spec/draft/purpose_and_scope.md b/spec/draft/purpose_and_scope.md index eee3c7f4c..bc936178b 100644 --- a/spec/draft/purpose_and_scope.md +++ b/spec/draft/purpose_and_scope.md @@ -417,7 +417,7 @@ in this specification. Libraries which aim to provide a conforming implementation but haven't yet completed such an implementation may, and are encouraged to, provide details on the level of (non-)conformance. For details on how to do this, see -[Verification - measuring conformance](verification_test_suite.md). +[Verification and Compliance](verification_and_compliance.md). * * * diff --git a/spec/draft/verification_and_compliance.md b/spec/draft/verification_and_compliance.md new file mode 100644 index 000000000..68823410f --- /dev/null +++ b/spec/draft/verification_and_compliance.md @@ -0,0 +1,102 @@ +# Verification and Compliance + +To facilitate adoption of this specification, adopters may rely on a set of complementary tools to verify and track Array API compliance. + +For adopters wanting to implement an array library conforming to this specification, the Array API [test suite](https://github.com/data-apis/array-api-tests) will + +1. assist in measuring specification conformance and +2. serve as a reference during test-driven development. + +For downstream adopters wanting to assess compatibility across multiple array libraries, the compatibility tables embedded in the rendered API specification + +1. provide a high-level snapshot of array library compliance for each specification version, +2. indicate the level of API portability across documented array libraries, and +3. detail minimum version requirements. + +## Test suite + +### Measuring conformance + +Adopters of this specification can measure specification conformance by using the Array API test suite, which can be found at . + +The specification is the single source of truth. While the aim of the test suite is to fully cover the behavior as described in this specification, specification adopters should be aware that some aspects of the specification cannot covered by the test suite, typically because these aspects are impossible to effectively test. If the test suite appears to diverge in any way from what this specification states, the divergence should be considered a bug in the test suite. + +### Running the tests + +To run the test suite, first clone the [test suite repository](https://github.com/data-apis/array-api-tests), and install the test suite dependencies + +```bash +pip install pytest hypothesis +``` + +or + +```bash +conda install pytest hypothesis +``` + +and any array libraries that you want to test. Before running the test suite, specify the array library to be tested in one of two ways. Either set the `ARRAY_API_TESTS_MODULE` environment variable, such as + +```text +ARRAY_API_TESTS_MODULE=numpy pytest +``` + +or, alternatively, edit the `array_api_tests/_array_module.py` file and change the +line + +```py +array_module = None +``` + +to + +```py +import numpy as array_module +``` + +(replacing `numpy` with the array module namespace to be tested). + +In both cases, tests must be run with the `pytest` command. + +The test suite has only two dependencies (`pytest` and `hypothesis`) and has no array library dependencies. The test suite is designed to be standalone in order to allow vendoring. All tests run against a specified array library and that library only. + +See the [README](https://github.com/data-apis/array-api-tests/blob/master/README.md) in the test suite repository for more information about how to run the test suite and interpret test suite results. + +## Compatibility tables + +A compatibility table is a concise representation describing the level of support for a specific API across one or more array libraries. + +![Example compatibility table](../_static/images/compatibility_table_0.png) + +For a single API, the anatomy of a compatibility table is as follows: + +- The header row contains the list of array libraries for which compatibility data is tracked. +- The first row describes the level of support across the entire API. +- If an API supports keyword arguments and/or specialized behavior (e.g., support for complex number data types), each row following the first row describes the level of support for the respective keyword argument or specialized behavior. +- The first column in a row specifies the API, keyword argument, or behavior for which support is tracked. +- Each data cell following the first column describes the level of support for the respective API, keyword argument, or behavior for a specific array library. + +A data cell describes the following levels of support in order of precedence: + +- **No support**: an array library does not support a particular API, keyword argument, or behavior. For example, in the example compatibility table above, TensorFlow and JAX do not support the `asarray` API. +- **Experimental support**: an array library supports a particular API, keyword argument, or behavior (either fully or partially), but the library does so experimentally via an environment variable or in an experimental namespace or some other mechanism indicating that support is unstable and subject to possible change. For example, in the example compatibility table above, NumPy and CuPy both experimentally support the `asarray` API in a separate experimental `array_api` namespace. +- **Partial support**: an array library only partially supports a particular API, keyword argument, or behavior. +- **Full support**: an array library fully supports a particular API, keyword argument, or behavior. For example, in the example compatibility table above, PyTorch fully supports the `asarray` API beginning in PyTorch version 1.11.0. + +In addition to support level, a data cell includes the first version in which an array library provides the displayed level of support. Based on the example compatibility table above, NumPy began offering experimental support for the `asarray` API beginning in NumPy version `1.22.0`, and CuPy began offering experimental support in `10.0.0`. + +Associated with each data cell is a timeline describing the history of support for a particular API, keyword argument, or behavior for a respective library. The following compatibility table shows an expanded timeline based on the example compatibility table above. + +![Example compatibility table displaying a support timeline](../_static/images/compatibility_table_1.png) + +Upon changes to a library's support level, a data cell should update to display the updated support status and the corresponding release for which the changes are attributed. For example, suppose that NumPy support is no longer experimental starting in version `2.0.0`; however, `copy` keyword argument support is still only partially implemented. In which case, the compatibility table should update as follows: + +![Example compatibility table displaying updated support levels](../_static/images/compatibility_table_2.png) + +In the above compatibility table, NumPy has full support for `dtype` and `device` keyword arguments; however, because `copy` keyword argument support is only partially implemented, the entire `asarray` API is also only partially implemented. + +If NumPy were to add full support for the `copy` keyword argument in version `2.1.0`, the compatibility table should update as follows: + +![Example compatibility table displaying full support](../_static/images/compatibility_table_3.png) + +Once a library achieves full support for a particular API, keyword argument, or behavior, no further status updates should be necessary. \ No newline at end of file diff --git a/spec/draft/verification_test_suite.md b/spec/draft/verification_test_suite.md deleted file mode 100644 index cbe770e48..000000000 --- a/spec/draft/verification_test_suite.md +++ /dev/null @@ -1,62 +0,0 @@ -# Verification - test suite - -## Measuring conformance - -In addition to the specification documents, a test suite is being developed to -aid library developers check conformance to the spec. **NOTE: The test suite -is still a work in progress.** It can be found at -. - -It is important to note that while the aim of the array API test suite is to -cover as much of the spec as possible, there are necessarily some aspects of -the spec that are not covered by the test suite, typically because they are -impossible to effectively test. Furthermore, if the test suite appears to -diverge in any way from what the spec documents say, this should be considered -a bug in the test suite. The specification is the ground source of truth. - -## Running the tests - -To run the tests, first clone the [test suite -repo](https://github.com/data-apis/array-api-tests), and install the testing -dependencies, - - pip install pytest hypothesis - -or - - conda install pytest hypothesis - -as well as the array libraries that you want to test. To run the tests, you -need to specify the array library that is to be tested. There are two ways to -do this. One way is to set the `ARRAY_API_TESTS_MODULE` environment variable. -For example - - ARRAY_API_TESTS_MODULE=numpy pytest - -Alternatively, edit the `array_api_tests/_array_module.py` file and change the -line - -```py -array_module = None -``` - -to - -```py -import numpy as array_module -``` - -(replacing `numpy` with the array module namespace to be tested). - -In either case, the tests should be run with the `pytest` command. - -Aside from the two testing dependencies (`pytest` and `hypothesis`), the test -suite has no dependencies. In particular, it does not depend on any specific -array libraries such as NumPy. All tests are run using only the array library -that is being tested, comparing results against the behavior as defined in the -spec. The test suite is designed to be standalone so that it can easily be vendored. - -See the -[README](https://github.com/data-apis/array-api-tests/blob/master/README.md) -in the test suite repo for more information about how to run and interpret the -test suite results.