Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

[API TESTS] Standardization and add more array api tests #20725

Merged
merged 43 commits into from
Nov 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
ab24c24
[API] Standardize and add more array api tests
barry-jin Nov 4, 2021
2ba1bbd
Merge remote-tracking branch 'upstream/master' into array-api-tests
barry-jin Nov 4, 2021
27dbc99
fix lint
barry-jin Nov 4, 2021
3a59e69
fix build
barry-jin Nov 4, 2021
9e80789
fix lint
barry-jin Nov 4, 2021
0de4201
fix
barry-jin Nov 4, 2021
4e20e9c
fix build
barry-jin Nov 4, 2021
19d501e
fix lint
barry-jin Nov 4, 2021
f6bc4d1
update
barry-jin Nov 4, 2021
9dfe283
fix
barry-jin Nov 4, 2021
c02603e
fix lint
barry-jin Nov 4, 2021
46d696b
fix
barry-jin Nov 5, 2021
7a89f56
update remainder
barry-jin Nov 5, 2021
270e60d
fix lint
barry-jin Nov 5, 2021
fe9813b
switch to no tvmop
barry-jin Nov 5, 2021
291896e
fix tests
barry-jin Nov 5, 2021
92332f4
fix elemwise binary
barry-jin Nov 6, 2021
3a11d15
update asarray
barry-jin Nov 8, 2021
599fdcf
Revert "update asarray"
barry-jin Nov 8, 2021
ac811b2
fix precision
barry-jin Nov 8, 2021
77388ef
fix precision
barry-jin Nov 8, 2021
ba4ccd5
fix
barry-jin Nov 9, 2021
3deb673
fix floating point exception
barry-jin Nov 9, 2021
780f5ae
fix floor_divide
barry-jin Nov 9, 2021
c176ec2
fix dtype_from_number
barry-jin Nov 9, 2021
a4cabe5
fix asarray
barry-jin Nov 10, 2021
05dc28b
fix asarray docstring
barry-jin Nov 10, 2021
6b77e38
merge data type functions
barry-jin Nov 10, 2021
9c79023
add un-func standard tests
barry-jin Nov 10, 2021
2e87451
support multiple dtypes in gpu copy
barry-jin Nov 10, 2021
5d88d75
add type_result tests
barry-jin Nov 10, 2021
bcb88e3
add binary tests
barry-jin Nov 10, 2021
53397b2
Merge remote-tracking branch 'upstream/master' into array-api-tests
barry-jin Nov 10, 2021
a2e221d
fix lint
barry-jin Nov 10, 2021
b1de51b
update
barry-jin Nov 11, 2021
f6ff8c3
update rtol, atol
barry-jin Nov 11, 2021
811cd63
update rtc types
barry-jin Nov 11, 2021
6e248ff
fix floor,ceil,trunc
barry-jin Nov 11, 2021
ce1af6d
update rtc type promotion
barry-jin Nov 16, 2021
5fa0297
update tests
barry-jin Nov 16, 2021
7d77e07
update mod
barry-jin Nov 17, 2021
811e409
Merge remote-tracking branch 'upstream/master' into array-api-tests
barry-jin Nov 17, 2021
5944c4b
fix lint
barry-jin Nov 17, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/os_x_staticbuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,35 @@ jobs:
python3 -m pytest -n 4 --durations=50 --verbose tests/python/unittest/ -k 'not test_operator and not (test_subgraph or test_custom_op or test_external_op or test_recordimage_dataset_with_data_loader_multiworker or test_multi_worker or test_multi_worker_shape or test_multi_worker_forked_data_loader or test_multi_worker_dataloader_release_pool)' -m 'not serial'
MXNET_ENGINE_TYPE=NaiveEngine python3 -m pytest -n 4 --durations=50 --verbose tests/python/unittest/ -k 'test_operator and not (test_subgraph or test_custom_op or test_external_op or test_recordimage_dataset_with_data_loader_multiworker or test_multi_worker or test_multi_worker_shape or test_multi_worker_forked_data_loader or test_multi_worker_dataloader_release_pool)' -m 'not serial'
python3 -m pytest --durations=50 --verbose tests/python/unittest/ -k 'not (test_subgraph or test_custom_op or test_external_op or test_recordimage_dataset_with_data_loader_multiworker or test_multi_worker or test_multi_worker_shape or test_multi_worker_forked_data_loader or test_multi_worker_dataloader_release_pool)' -m 'serial'

- name: Test Array API
env:
MXNET_ENFORCE_CYTHON: 0
run: |
cd ..
git clone https://github.com/data-apis/array-api-tests.git
cd array-api-tests
git checkout c1dba80a196a03f880d2e0a998a272fb3867b720
export ARRAY_API_TESTS_MODULE=mxnet.numpy pytest
export DMLC_LOG_STACK_TRACE_DEPTH=100
python3 -m pytest --reruns 3 --durations=50 --verbose array_api_tests/test_creation_functions.py
python3 -m pytest --reruns 3 --durations=50 --verbose array_api_tests/test_indexing.py
python3 -m pytest --reruns 3 --durations=50 --verbose array_api_tests/test_constants.py
python3 -m pytest --reruns 3 --durations=50 --verbose array_api_tests/test_elementwise_functions.py
python3 -m pytest --reruns 3 --durations=50 --verbose array_api_tests/test_broadcasting.py
python3 -m pytest --reruns 3 --durations=50 --verbose \
array_api_tests/test_type_promotion.py::test_elementwise_function_two_arg_bool_type_promotion
python3 -m pytest --reruns 3 --durations=50 --verbose \
array_api_tests/test_type_promotion.py::test_elementwise_function_two_arg_promoted_type_promotion
python3 -m pytest --reruns 3 --durations=50 --verbose \
array_api_tests/test_type_promotion.py::test_elementwise_function_one_arg_bool
python3 -m pytest --reruns 3 --durations=50 --verbose \
array_api_tests/test_type_promotion.py::test_elementwise_function_one_arg_type_promotion
python3 -m pytest --reruns 3 --durations=50 --verbose \
array_api_tests/test_type_promotion.py::test_operator_one_arg_type_promotion
python3 -m pytest --reruns 3 --durations=50 --verbose \
array_api_tests/test_type_promotion.py::test_operator_two_arg_bool_promotion
python3 -m pytest --reruns 3 --durations=50 --verbose \
array_api_tests/test_type_promotion.py::test_operator_two_arg_promoted_promotion
python3 -m pytest --reruns 3 --durations=50 --verbose \
array_api_tests/test_type_promotion.py::test_operator_inplace_two_arg_promoted_promotion
1 change: 1 addition & 0 deletions ci/docker/install/requirements
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pytest-env==0.6.2
pytest-cov==2.10.1
pytest-xdist==2.1.0
pytest-timeout==1.4.2
pytest-rerunfailures==10.2
flaky==3.7.0
setuptools==49.6.0 # https://github.com/pypa/setuptools/issues/2352
wheel
Expand Down
23 changes: 20 additions & 3 deletions ci/docker/runtime_functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -872,10 +872,27 @@ unittest_array_api_standardization() {
# when cython is enabled
export MXNET_ENABLE_CYTHON=0
export DMLC_LOG_STACK_TRACE_DEPTH=100
python3 -m pytest --durations=50 --cov-report xml:tests_api.xml --verbose \
python3 -m pytest --reruns 3 --durations=50 --cov-report xml:tests_api.xml --verbose array_api_tests/test_creation_functions.py
python3 -m pytest --reruns 3 --durations=50 --cov-report xml:tests_api.xml --verbose array_api_tests/test_indexing.py
python3 -m pytest --reruns 3 --durations=50 --cov-report xml:tests_api.xml --verbose array_api_tests/test_elementwise_functions.py
python3 -m pytest --reruns 3 --durations=50 --cov-report xml:tests_api.xml --verbose array_api_tests/test_constants.py
python3 -m pytest --reruns 3 --durations=50 --cov-report xml:tests_api.xml --verbose array_api_tests/test_broadcasting.py
python3 -m pytest --reruns 3 --durations=50 --cov-report xml:tests_api.xml --verbose \
array_api_tests/test_type_promotion.py::test_elementwise_function_two_arg_bool_type_promotion
python3 -m pytest --durations=50 --cov-report xml:tests_api.xml --verbose array_api_tests/test_creation_functions.py
python3 -m pytest --durations=50 --cov-report xml:tests_api.xml --verbose array_api_tests/test_indexing.py
python3 -m pytest --reruns 3 --durations=50 --cov-report xml:tests_api.xml --verbose \
array_api_tests/test_type_promotion.py::test_elementwise_function_two_arg_promoted_type_promotion
python3 -m pytest --reruns 3 --durations=50 --cov-report xml:tests_api.xml --verbose \
array_api_tests/test_type_promotion.py::test_elementwise_function_one_arg_bool
python3 -m pytest --reruns 3 --durations=50 --cov-report xml:tests_api.xml --verbose \
array_api_tests/test_type_promotion.py::test_elementwise_function_one_arg_type_promotion
python3 -m pytest --reruns 3 --durations=50 --cov-report xml:tests_api.xml --verbose \
array_api_tests/test_type_promotion.py::test_operator_one_arg_type_promotion
python3 -m pytest --reruns 3 --durations=50 --cov-report xml:tests_api.xml --verbose \
array_api_tests/test_type_promotion.py::test_operator_two_arg_bool_promotion
python3 -m pytest --reruns 3 --durations=50 --cov-report xml:tests_api.xml --verbose \
array_api_tests/test_type_promotion.py::test_operator_two_arg_promoted_promotion
python3 -m pytest --reruns 3 --durations=50 --cov-report xml:tests_api.xml --verbose \
array_api_tests/test_type_promotion.py::test_operator_inplace_two_arg_promoted_promotion
popd
}

Expand Down
2 changes: 1 addition & 1 deletion ci/jenkins/Jenkins_steps.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ def test_unix_python3_array_api(lib_name) {
return ['Python3: Array-API': {
node(NODE_LINUX_CPU) {
ws('workspace/ut-python3-cpu') {
utils.unpack_and_init(lib_name, mx_lib, true)
utils.unpack_and_init(lib_name, mx_lib, false)
python3_ut_array_api('ubuntu_cpu')
utils.publish_test_coverage()
}
Expand Down
3 changes: 2 additions & 1 deletion ci/jenkins/Jenkinsfile_unix_cpu
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ core_logic: {
utils.parallel_stage('Tests', [
custom_steps.test_unix_python3_cpu('cpu'),
custom_steps.test_unix_python3_onnx_cpu('cpu'),
custom_steps.test_unix_python3_array_api('cpu'),
// TVMOP has issue with NAN, see https://github.com/apache/incubator-mxnet/issues/20729
custom_steps.test_unix_python3_array_api('cpu_openblas_no_tvm_op'),
custom_steps.test_unix_python3_mkl_cpu('cpu_mkl'),
custom_steps.test_unix_python3_onednn_cpu('onednn_cpu'),
custom_steps.test_unix_python3_onednn_mkl_cpu('onednn_mkl_cpu'),
Expand Down
6 changes: 6 additions & 0 deletions python/mxnet/ndarray/numpy/_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -3757,6 +3757,8 @@ def ceil(x, out=None, **kwargs):
>>> a
array(4.)
"""
if isinstance(x, NDArray) and _np.issubdtype(x.dtype, _np.integer):
return x
return _pure_unary_func_helper(x, _api_internal.ceil, _np.ceil, out=out, **kwargs)


Expand Down Expand Up @@ -3796,6 +3798,8 @@ def floor(x, out=None, **kwargs):
>>> a
array(3.)
"""
if isinstance(x, NDArray) and _np.issubdtype(x.dtype, _np.integer):
return x
return _pure_unary_func_helper(x, _api_internal.floor, _np.floor, out=out, **kwargs)


Expand Down Expand Up @@ -3941,6 +3945,8 @@ def trunc(x, out=None, **kwargs):
>>> np.trunc(a)
array([-1., -1., -0., 0., 1., 1., 2.])
"""
if isinstance(x, NDArray) and _np.issubdtype(x.dtype, _np.integer):
return x
return _pure_unary_func_helper(x, _api_internal.trunc, _np.trunc, out=out, **kwargs)


Expand Down
1 change: 1 addition & 0 deletions python/mxnet/numpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from .function_base import * # pylint: disable=wildcard-import
from .stride_tricks import * # pylint: disable=wildcard-import
from .set_functions import * # pylint: disable=wildcard-import
from .type_functions import * # pylint: disable=wildcard-import
from .io import * # pylint: disable=wildcard-import
from .arrayprint import * # pylint: disable=wildcard-import

Expand Down
1 change: 0 additions & 1 deletion python/mxnet/numpy/fallback.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@
'pv',
'rate',
'real',
'result_type',
'roots',
'searchsorted',
'select',
Expand Down
60 changes: 39 additions & 21 deletions python/mxnet/numpy/multiarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,8 @@ def _get_np_boolean_indexing(self, key, ndim, shape):
remaining_dims = shape[key_ndim:]
data = _reshape_view(self, -1, *remaining_dims)
key = _reshape_view(key, -1)
if data.size == 0 and key.size == 0:
return data
return _reshape_view(_npi.boolean_mask(data, key), -1, *remaining_dims)

def _set_np_boolean_indexing(self, key, value):
Expand Down Expand Up @@ -13285,34 +13287,50 @@ def asarray(obj, dtype=None, device=None, copy=None):

Examples
--------
>>> a = np.arange(4).reshape(2,2)
>>> a
array([[0, 1],
[2, 3]])
>>> np.diagonal(a)
array([0, 3])
>>> np.diagonal(a, 1)
array([1])
>>> np.asarray([1, 2, 3])
array([1., 2., 3.])

>>> a = np.arange(8).reshape(2,2,2)
>>>a
array([[[0, 1],
[2, 3]],
[[4, 5],
[6, 7]]])
>>> np.diagonal(a, 0, 0, 1)
array([[0, 6],
[1, 7]])
>>> np.asarray([[1, 2], [3, 4]], dtype=np.int32)
array([[1, 2],
[3, 4]], dtype=int32)

>>> np.asarray([1.2], device=mx.gpu())
array([1.2], device=gpu(0))
"""
if isinstance(obj, numeric_types):
dtype = dtype_from_number(obj) if dtype is None else dtype
obj = _np.asarray(obj, dtype=dtype)
elif isinstance(obj, _np.ndarray):
dtype = obj.dtype if dtype is None else dtype
if is_np_default_dtype():
dtype = obj.dtype if dtype is None else dtype
else:
dtype = _np.float32 if dtype is None or obj.dtype is _np.float64 else dtype
elif isinstance(obj, ndarray):
dtype = obj.dtype if dtype is None else dtype
array = _as_mx_np_array(obj, device=device, zero_copy=copy)
return array.astype(dtype)
if dtype is not None:
obj = obj.astype(dtype, copy=copy)
if device is not None:
obj = obj.to_device(device)
return obj
elif hasattr(obj, '__dlpack__'):
return from_dlpack(obj)
else:
if dtype is None:
default_dtype = _np.float64 if is_np_default_dtype() else _np.float32
dtype = obj.dtype if hasattr(obj, "dtype") else default_dtype
try:
obj = _np.array(obj, dtype=dtype)
except Exception as e:
# printing out the error raised by official NumPy's array function
# for transparency on users' side
raise TypeError('{}'.format(str(e)))
if device is None:
device = current_device()
ret = empty(obj.shape, dtype=dtype, device=device)
if len(obj.shape) == 0:
ret[()] = obj
else:
ret[:] = obj
return ret


# pylint: disable=redefined-outer-name
Expand Down
163 changes: 163 additions & 0 deletions python/mxnet/numpy/type_functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.

"""Type functions for the numpy module."""

from typing import NamedTuple

import numpy as onp
from .multiarray import ndarray
from .utils import _type_promotion_table


__all__ = ['can_cast', 'finfo', 'iinfo', 'result_type']

class finfo_obj(NamedTuple):
bits: int
eps: float
max: float
min: float
smallest_normal: float


class iinfo_obj(NamedTuple):
bits: int
max: int
min: int


def can_cast(from_, to):
"""
Returns True if cast between data types can occur according to
the casting rule. If from is a scalar or array scalar,
also returns True if the scalar value can be cast without
overflow or truncation to an integer.
Parameters
----------
from_ : dtype, ndarray or scalar
Data type, scalar, or array to cast from.
to : dtype
Data type to cast to.
Returns
-------
out : bool
True if cast can occur according to the casting rule.
"""
if isinstance(from_, ndarray):
from_ = from_.asnumpy()
return onp.can_cast(from_, to)


def finfo(dtype):
"""
Machine limits for floating-point data types.
Notes
-----
`finfo` is a standard API in
https://data-apis.org/array-api/latest/API_specification/data_type_functions.html#finfo-type
instead of an official NumPy operator.
Parameters
----------
dtype : ndarray, float or dtype
Kind of floating point data-type about which to get information.
Returns
-------
out : finfo object
an object having the following attributes:
- bits : int
number of bits occupied by the floating-point data type.
- eps : float
difference between 1.0 and the next smallest representable floating-point
number larger than 1.0 according to the IEEE-754 standard.
- max : float
largest representable number.
- min : float
smallest representable number.
- smallest_normal : float
smallest positive floating-point number with full precision.
"""
f_info = onp.finfo(dtype)
return finfo_obj(f_info.bits, float(f_info.eps),
float(f_info.max), float(f_info.min), float(f_info.tiny))


def iinfo(dtype):
"""
Machine limits for floating-point data types.
Notes
-----
`iinfo` is a standard API in
https://data-apis.org/array-api/latest/API_specification/data_type_functions.html#iinfo-type
instead of an official NumPy operator.
Parameters
----------
dtype : ndarray, integer or dtype
The kind of integer data type to get information about.
Returns
-------
out : iinfo object
an object having the following attributes:
- bits : int
number of bits occupied by the type
- max : int
largest representable number.
- min : int
smallest representable number.
"""
i_info = onp.iinfo(dtype)
return iinfo_obj(i_info.bits, i_info.max, i_info.min)


def _get_dtype(array_or_dtype):
"""Utility function for result_type"""
if isinstance(array_or_dtype, (ndarray, onp.ndarray)):
return array_or_dtype.dtype
elif isinstance(array_or_dtype, onp.dtype):
return array_or_dtype
else:
raise ValueError("Inputs of result_type must be ndarrays or dtypes")


def result_type(*arrays_and_dtypes):
"""
Returns the dtype that results from applying the type promotion rules to the arguments.
Notes
-----
`result_type` is a standard API in
https://data-apis.org/array-api/latest/API_specification/data_type_functions.html#result-type-arrays-and-dtypes
instead of an official NumPy operator.
Parameters
----------
arrays_and_dtypes : mixed ndarrays and dtypes
an arbitrary number of input arrays and/or dtypes.
Returns
-------
out : dtype
the dtype resulting from an operation involving the input arrays and dtypes.
"""
if len(arrays_and_dtypes) > 0:
ret = _get_dtype(arrays_and_dtypes[0])
for d in arrays_and_dtypes[1:]:
dd = _get_dtype(d)
if (ret, dd) in _type_promotion_table:
ret = _type_promotion_table[ret, dd]
elif (dd, ret) in _type_promotion_table:
ret = _type_promotion_table[dd, ret]
else:
raise TypeError("Unknown type promotion between {} and {}".format(ret, dd))
return ret
raise ValueError("at least one array or dtype is required")
Loading