summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
authorTouqir Sajed <touqir@ualberta.ca>2021-02-05 16:49:16 +0600
committerTouqir Sajed <touqir@ualberta.ca>2021-02-05 16:49:16 +0600
commited3d080f637e263fdcd702fb7d588433461ff243 (patch)
tree1e96b98c6ce36a4f6055f80edab22a44875a997a /numpy/core
parent2b41cbf3e46e6d16e84f0fa800500346789dba6d (diff)
parent0a1bd4ead41b1fdfb53142097b5e08555f280545 (diff)
downloadnumpy-ed3d080f637e263fdcd702fb7d588433461ff243.tar.gz
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/__init__.py4
-rw-r--r--numpy/core/_add_newdocs.py4
-rw-r--r--numpy/core/_add_newdocs_scalars.py5
-rw-r--r--numpy/core/arrayprint.py12
-rw-r--r--numpy/core/arrayprint.pyi24
-rw-r--r--numpy/core/defchararray.py182
-rw-r--r--numpy/core/einsumfunc.py8
-rw-r--r--numpy/core/fromnumeric.py43
-rw-r--r--numpy/core/fromnumeric.pyi31
-rw-r--r--numpy/core/function_base.pyi9
-rw-r--r--numpy/core/include/numpy/random/distributions.h8
-rw-r--r--numpy/core/multiarray.py6
-rw-r--r--numpy/core/numeric.py7
-rw-r--r--numpy/core/records.py17
-rw-r--r--numpy/core/setup_common.py4
-rw-r--r--numpy/core/shape_base.py2
-rw-r--r--numpy/core/shape_base.pyi4
-rw-r--r--numpy/core/src/_simd/_simd.dispatch.c.src13
-rw-r--r--numpy/core/src/common/simd/avx2/arithmetic.h37
-rw-r--r--numpy/core/src/common/simd/avx512/arithmetic.h58
-rw-r--r--numpy/core/src/common/simd/neon/arithmetic.h31
-rw-r--r--numpy/core/src/common/simd/sse/arithmetic.h35
-rw-r--r--numpy/core/src/common/simd/sse/sse.h1
-rw-r--r--numpy/core/src/common/simd/sse/utils.h19
-rw-r--r--numpy/core/src/common/simd/vsx/arithmetic.h27
-rw-r--r--numpy/core/src/multiarray/compiled_base.c4
-rw-r--r--numpy/core/src/multiarray/ctors.c19
-rw-r--r--numpy/core/src/multiarray/datetime_busday.c12
-rw-r--r--numpy/core/src/multiarray/dtypemeta.c13
-rw-r--r--numpy/core/src/multiarray/einsum_sumprod.c.src320
-rw-r--r--numpy/core/src/multiarray/mapping.c14
-rw-r--r--numpy/core/src/multiarray/methods.c2
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c2
-rw-r--r--numpy/core/src/multiarray/scalartypes.c.src10
-rw-r--r--numpy/core/src/multiarray/usertypes.c2
-rw-r--r--numpy/core/src/umath/ufunc_type_resolution.c55
-rw-r--r--numpy/core/tests/test_array_coercion.py13
-rw-r--r--numpy/core/tests/test_arrayprint.py3
-rw-r--r--numpy/core/tests/test_deprecations.py54
-rw-r--r--numpy/core/tests/test_half.py6
-rw-r--r--numpy/core/tests/test_indexing.py17
-rw-r--r--numpy/core/tests/test_nditer.py1
-rw-r--r--numpy/core/tests/test_numeric.py69
-rw-r--r--numpy/core/tests/test_regression.py4
-rw-r--r--numpy/core/tests/test_shape_base.py5
-rw-r--r--numpy/core/tests/test_simd.py21
46 files changed, 711 insertions, 526 deletions
diff --git a/numpy/core/__init__.py b/numpy/core/__init__.py
index e8d3a381b..f22c86f59 100644
--- a/numpy/core/__init__.py
+++ b/numpy/core/__init__.py
@@ -75,7 +75,7 @@ from . import fromnumeric
from .fromnumeric import *
from . import defchararray as char
from . import records as rec
-from .records import *
+from .records import record, recarray, format_parser
from .memmap import *
from .defchararray import chararray
from . import function_base
@@ -106,7 +106,7 @@ from . import _methods
__all__ = ['char', 'rec', 'memmap']
__all__ += numeric.__all__
__all__ += fromnumeric.__all__
-__all__ += rec.__all__
+__all__ += ['record', 'recarray', 'format_parser']
__all__ += ['chararray']
__all__ += function_base.__all__
__all__ += machar.__all__
diff --git a/numpy/core/_add_newdocs.py b/numpy/core/_add_newdocs.py
index 2cbfe52be..6073166a0 100644
--- a/numpy/core/_add_newdocs.py
+++ b/numpy/core/_add_newdocs.py
@@ -377,7 +377,7 @@ add_newdoc('numpy.core', 'nditer',
... while not it.finished:
... it[0] = lamdaexpr(*it[1:])
... it.iternext()
- ... return it.operands[0]
+ ... return it.operands[0]
>>> a = np.arange(5)
>>> b = np.ones(5)
@@ -821,7 +821,7 @@ add_newdoc('numpy.core.multiarray', 'array',
===== ========= ===================================================
When ``copy=False`` and a copy is made for other reasons, the result is
- the same as if ``copy=True``, with some exceptions for `A`, see the
+ the same as if ``copy=True``, with some exceptions for 'A', see the
Notes section. The default order is 'K'.
subok : bool, optional
If True, then sub-classes will be passed-through, otherwise
diff --git a/numpy/core/_add_newdocs_scalars.py b/numpy/core/_add_newdocs_scalars.py
index b9b151224..d31f0037d 100644
--- a/numpy/core/_add_newdocs_scalars.py
+++ b/numpy/core/_add_newdocs_scalars.py
@@ -6,6 +6,7 @@ platform-dependent information.
from numpy.core import dtype
from numpy.core import numerictypes as _numerictypes
from numpy.core.function_base import add_newdoc
+import platform
##############################################################################
#
@@ -49,6 +50,8 @@ possible_aliases = numeric_type_aliases([
])
+
+
def add_newdoc_for_scalar_type(obj, fixed_aliases, doc):
# note: `:field: value` is rST syntax which renders as field lists.
o = getattr(_numerictypes, obj)
@@ -56,7 +59,7 @@ def add_newdoc_for_scalar_type(obj, fixed_aliases, doc):
character_code = dtype(o).char
canonical_name_doc = "" if obj == o.__name__ else ":Canonical name: `numpy.{}`\n ".format(obj)
alias_doc = ''.join(":Alias: `numpy.{}`\n ".format(alias) for alias in fixed_aliases)
- alias_doc += ''.join(":Alias on this platform: `numpy.{}`: {}.\n ".format(alias, doc)
+ alias_doc += ''.join(":Alias on this platform ({} {}): `numpy.{}`: {}.\n ".format(platform.system(), platform.machine(), alias, doc)
for (alias_type, alias, doc) in possible_aliases if alias_type is o)
docstring = """
{doc}
diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py
index 94ec8ed34..5c1d6cb63 100644
--- a/numpy/core/arrayprint.py
+++ b/numpy/core/arrayprint.py
@@ -41,6 +41,7 @@ from .numeric import concatenate, asarray, errstate
from .numerictypes import (longlong, intc, int_, float_, complex_, bool_,
flexible)
from .overrides import array_function_dispatch, set_module
+import operator
import warnings
import contextlib
@@ -78,6 +79,7 @@ def _make_options_dict(precision=None, threshold=None, edgeitems=None,
if legacy not in [None, False, '1.13']:
warnings.warn("legacy printing option can currently only be '1.13' or "
"`False`", stacklevel=3)
+
if threshold is not None:
# forbid the bad threshold arg suggested by stack overflow, gh-12351
if not isinstance(threshold, numbers.Number):
@@ -85,6 +87,14 @@ def _make_options_dict(precision=None, threshold=None, edgeitems=None,
if np.isnan(threshold):
raise ValueError("threshold must be non-NAN, try "
"sys.maxsize for untruncated representation")
+
+ if precision is not None:
+ # forbid the bad precision arg as suggested by issue #18254
+ try:
+ options['precision'] = operator.index(precision)
+ except TypeError as e:
+ raise TypeError('precision must be an integer') from e
+
return options
@@ -538,7 +548,7 @@ def array2string(a, max_line_width=None, precision=None,
separator : str, optional
Inserted between elements.
prefix : str, optional
- suffix: str, optional
+ suffix : str, optional
The length of the prefix and suffix strings are used to respectively
align and wrap the output. An array is typically printed as::
diff --git a/numpy/core/arrayprint.pyi b/numpy/core/arrayprint.pyi
index 6aaae0320..d2a5fdef9 100644
--- a/numpy/core/arrayprint.pyi
+++ b/numpy/core/arrayprint.pyi
@@ -21,12 +21,12 @@ from numpy import (
longdouble,
clongdouble,
)
-from numpy.typing import ArrayLike, _CharLike, _FloatLike
+from numpy.typing import ArrayLike, _CharLike_co, _FloatLike_co
if sys.version_info > (3, 8):
- from typing import Literal, TypedDict
+ from typing import Literal, TypedDict, SupportsIndex
else:
- from typing_extensions import Literal, TypedDict
+ from typing_extensions import Literal, TypedDict, SupportsIndex
_FloatMode = Literal["fixed", "unique", "maxprec", "maxprec_equal"]
@@ -40,13 +40,13 @@ class _FormatDict(TypedDict, total=False):
complexfloat: Callable[[complexfloating[Any, Any]], str]
longcomplexfloat: Callable[[clongdouble], str]
void: Callable[[void], str]
- numpystr: Callable[[_CharLike], str]
+ numpystr: Callable[[_CharLike_co], str]
object: Callable[[object], str]
all: Callable[[object], str]
int_kind: Callable[[integer[Any]], str]
float_kind: Callable[[floating[Any]], str]
complex_kind: Callable[[complexfloating[Any, Any]], str]
- str_kind: Callable[[_CharLike], str]
+ str_kind: Callable[[_CharLike_co], str]
class _FormatOptions(TypedDict):
precision: int
@@ -62,7 +62,7 @@ class _FormatOptions(TypedDict):
legacy: Literal[False, "1.13"]
def set_printoptions(
- precision: Optional[int] = ...,
+ precision: Optional[SupportsIndex] = ...,
threshold: Optional[int] = ...,
edgeitems: Optional[int] = ...,
linewidth: Optional[int] = ...,
@@ -79,7 +79,7 @@ def get_printoptions() -> _FormatOptions: ...
def array2string(
a: ndarray[Any, Any],
max_line_width: Optional[int] = ...,
- precision: Optional[int] = ...,
+ precision: Optional[SupportsIndex] = ...,
suppress_small: Optional[bool] = ...,
separator: str = ...,
prefix: str = ...,
@@ -96,7 +96,7 @@ def array2string(
legacy: Optional[Literal[False, "1.13"]] = ...,
) -> str: ...
def format_float_scientific(
- x: _FloatLike,
+ x: _FloatLike_co,
precision: Optional[int] = ...,
unique: bool = ...,
trim: Literal["k", ".", "0", "-"] = ...,
@@ -105,7 +105,7 @@ def format_float_scientific(
exp_digits: Optional[int] = ...,
) -> str: ...
def format_float_positional(
- x: _FloatLike,
+ x: _FloatLike_co,
precision: Optional[int] = ...,
unique: bool = ...,
fractional: bool = ...,
@@ -117,20 +117,20 @@ def format_float_positional(
def array_repr(
arr: ndarray[Any, Any],
max_line_width: Optional[int] = ...,
- precision: Optional[int] = ...,
+ precision: Optional[SupportsIndex] = ...,
suppress_small: Optional[bool] = ...,
) -> str: ...
def array_str(
a: ndarray[Any, Any],
max_line_width: Optional[int] = ...,
- precision: Optional[int] = ...,
+ precision: Optional[SupportsIndex] = ...,
suppress_small: Optional[bool] = ...,
) -> str: ...
def set_string_function(
f: Optional[Callable[[ndarray[Any, Any]], str]], repr: bool = ...
) -> None: ...
def printoptions(
- precision: Optional[int] = ...,
+ precision: Optional[SupportsIndex] = ...,
threshold: Optional[int] = ...,
edgeitems: Optional[int] = ...,
linewidth: Optional[int] = ...,
diff --git a/numpy/core/defchararray.py b/numpy/core/defchararray.py
index 9d7b54a1a..ab1166ad2 100644
--- a/numpy/core/defchararray.py
+++ b/numpy/core/defchararray.py
@@ -273,7 +273,7 @@ def str_len(a):
out : ndarray
Output array of integers
- See also
+ See Also
--------
builtins.len
"""
@@ -368,7 +368,7 @@ def mod(a, values):
out : ndarray
Output array of str or unicode, depending on input types
- See also
+ See Also
--------
str.__mod__
@@ -398,7 +398,7 @@ def capitalize(a):
Output array of str or unicode, depending on input
types
- See also
+ See Also
--------
str.capitalize
@@ -443,7 +443,7 @@ def center(a, width, fillchar=' '):
Output array of str or unicode, depending on input
types
- See also
+ See Also
--------
str.center
@@ -485,7 +485,7 @@ def count(a, sub, start=0, end=None):
out : ndarray
Output array of ints.
- See also
+ See Also
--------
str.count
@@ -534,7 +534,7 @@ def decode(a, encoding=None, errors=None):
-------
out : ndarray
- See also
+ See Also
--------
str.decode
@@ -580,7 +580,7 @@ def encode(a, encoding=None, errors=None):
-------
out : ndarray
- See also
+ See Also
--------
str.encode
@@ -620,7 +620,7 @@ def endswith(a, suffix, start=0, end=None):
out : ndarray
Outputs an array of bools.
- See also
+ See Also
--------
str.endswith
@@ -672,7 +672,7 @@ def expandtabs(a, tabsize=8):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.expandtabs
@@ -708,7 +708,7 @@ def find(a, sub, start=0, end=None):
out : ndarray or int
Output array of ints. Returns -1 if `sub` is not found.
- See also
+ See Also
--------
str.find
@@ -737,7 +737,7 @@ def index(a, sub, start=0, end=None):
out : ndarray
Output array of ints. Returns -1 if `sub` is not found.
- See also
+ See Also
--------
find, str.find
@@ -765,7 +765,7 @@ def isalnum(a):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.isalnum
"""
@@ -791,7 +791,7 @@ def isalpha(a):
out : ndarray
Output array of bools
- See also
+ See Also
--------
str.isalpha
"""
@@ -817,7 +817,7 @@ def isdigit(a):
out : ndarray
Output array of bools
- See also
+ See Also
--------
str.isdigit
"""
@@ -844,7 +844,7 @@ def islower(a):
out : ndarray
Output array of bools
- See also
+ See Also
--------
str.islower
"""
@@ -871,7 +871,7 @@ def isspace(a):
out : ndarray
Output array of bools
- See also
+ See Also
--------
str.isspace
"""
@@ -897,7 +897,7 @@ def istitle(a):
out : ndarray
Output array of bools
- See also
+ See Also
--------
str.istitle
"""
@@ -924,7 +924,7 @@ def isupper(a):
out : ndarray
Output array of bools
- See also
+ See Also
--------
str.isupper
"""
@@ -953,7 +953,7 @@ def join(sep, seq):
out : ndarray
Output array of str or unicode, depending on input types
- See also
+ See Also
--------
str.join
"""
@@ -988,7 +988,7 @@ def ljust(a, width, fillchar=' '):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.ljust
@@ -1021,7 +1021,7 @@ def lower(a):
out : ndarray, {str, unicode}
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.lower
@@ -1066,7 +1066,7 @@ def lstrip(a, chars=None):
out : ndarray, {str, unicode}
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.lstrip
@@ -1127,7 +1127,7 @@ def partition(a, sep):
The output array will have an extra dimension with 3
elements per input element.
- See also
+ See Also
--------
str.partition
@@ -1163,7 +1163,7 @@ def replace(a, old, new, count=None):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.replace
@@ -1197,7 +1197,7 @@ def rfind(a, sub, start=0, end=None):
out : ndarray
Output array of ints. Return -1 on failure.
- See also
+ See Also
--------
str.rfind
@@ -1227,7 +1227,7 @@ def rindex(a, sub, start=0, end=None):
out : ndarray
Output array of ints.
- See also
+ See Also
--------
rfind, str.rindex
@@ -1258,7 +1258,7 @@ def rjust(a, width, fillchar=' '):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.rjust
@@ -1299,7 +1299,7 @@ def rpartition(a, sep):
type. The output array will have an extra dimension with
3 elements per input element.
- See also
+ See Also
--------
str.rpartition
@@ -1339,7 +1339,7 @@ def rsplit(a, sep=None, maxsplit=None):
out : ndarray
Array of list objects
- See also
+ See Also
--------
str.rsplit, split
@@ -1378,7 +1378,7 @@ def rstrip(a, chars=None):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.rstrip
@@ -1423,7 +1423,7 @@ def split(a, sep=None, maxsplit=None):
out : ndarray
Array of list objects
- See also
+ See Also
--------
str.split, rsplit
@@ -1459,7 +1459,7 @@ def splitlines(a, keepends=None):
out : ndarray
Array of list objects
- See also
+ See Also
--------
str.splitlines
@@ -1495,7 +1495,7 @@ def startswith(a, prefix, start=0, end=None):
out : ndarray
Array of booleans
- See also
+ See Also
--------
str.startswith
@@ -1528,7 +1528,7 @@ def strip(a, chars=None):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.strip
@@ -1569,7 +1569,7 @@ def swapcase(a):
out : ndarray, {str, unicode}
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.swapcase
@@ -1609,7 +1609,7 @@ def title(a):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.title
@@ -1654,7 +1654,7 @@ def translate(a, table, deletechars=None):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.translate
@@ -1687,7 +1687,7 @@ def upper(a):
out : ndarray, {str, unicode}
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.upper
@@ -1726,7 +1726,7 @@ def zfill(a, width):
out : ndarray, {str, unicode}
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.zfill
@@ -1760,7 +1760,7 @@ def isnumeric(a):
out : ndarray, bool
Array of booleans of same shape as `a`.
- See also
+ See Also
--------
unicode.isnumeric
@@ -1792,7 +1792,7 @@ def isdecimal(a):
out : ndarray, bool
Array of booleans identical in shape to `a`.
- See also
+ See Also
--------
unicode.isdecimal
@@ -2004,7 +2004,7 @@ class chararray(ndarray):
"""
Return (self == other) element-wise.
- See also
+ See Also
--------
equal
"""
@@ -2014,7 +2014,7 @@ class chararray(ndarray):
"""
Return (self != other) element-wise.
- See also
+ See Also
--------
not_equal
"""
@@ -2024,7 +2024,7 @@ class chararray(ndarray):
"""
Return (self >= other) element-wise.
- See also
+ See Also
--------
greater_equal
"""
@@ -2034,7 +2034,7 @@ class chararray(ndarray):
"""
Return (self <= other) element-wise.
- See also
+ See Also
--------
less_equal
"""
@@ -2044,7 +2044,7 @@ class chararray(ndarray):
"""
Return (self > other) element-wise.
- See also
+ See Also
--------
greater
"""
@@ -2054,7 +2054,7 @@ class chararray(ndarray):
"""
Return (self < other) element-wise.
- See also
+ See Also
--------
less
"""
@@ -2065,7 +2065,7 @@ class chararray(ndarray):
Return (self + other), that is string concatenation,
element-wise for a pair of array_likes of str or unicode.
- See also
+ See Also
--------
add
"""
@@ -2076,7 +2076,7 @@ class chararray(ndarray):
Return (other + self), that is string concatenation,
element-wise for a pair of array_likes of `string_` or `unicode_`.
- See also
+ See Also
--------
add
"""
@@ -2087,7 +2087,7 @@ class chararray(ndarray):
Return (self * i), that is string multiple concatenation,
element-wise.
- See also
+ See Also
--------
multiply
"""
@@ -2098,7 +2098,7 @@ class chararray(ndarray):
Return (self * i), that is string multiple concatenation,
element-wise.
- See also
+ See Also
--------
multiply
"""
@@ -2110,7 +2110,7 @@ class chararray(ndarray):
(interpolation), element-wise for a pair of array_likes of `string_`
or `unicode_`.
- See also
+ See Also
--------
mod
"""
@@ -2145,7 +2145,7 @@ class chararray(ndarray):
Return a copy of `self` with only the first character of each element
capitalized.
- See also
+ See Also
--------
char.capitalize
@@ -2157,7 +2157,7 @@ class chararray(ndarray):
Return a copy of `self` with its elements centered in a
string of length `width`.
- See also
+ See Also
--------
center
"""
@@ -2168,7 +2168,7 @@ class chararray(ndarray):
Returns an array with the number of non-overlapping occurrences of
substring `sub` in the range [`start`, `end`].
- See also
+ See Also
--------
char.count
@@ -2179,7 +2179,7 @@ class chararray(ndarray):
"""
Calls `str.decode` element-wise.
- See also
+ See Also
--------
char.decode
@@ -2190,7 +2190,7 @@ class chararray(ndarray):
"""
Calls `str.encode` element-wise.
- See also
+ See Also
--------
char.encode
@@ -2202,7 +2202,7 @@ class chararray(ndarray):
Returns a boolean array which is `True` where the string element
in `self` ends with `suffix`, otherwise `False`.
- See also
+ See Also
--------
char.endswith
@@ -2214,7 +2214,7 @@ class chararray(ndarray):
Return a copy of each string element where all tab characters are
replaced by one or more spaces.
- See also
+ See Also
--------
char.expandtabs
@@ -2226,7 +2226,7 @@ class chararray(ndarray):
For each element, return the lowest index in the string where
substring `sub` is found.
- See also
+ See Also
--------
char.find
@@ -2237,7 +2237,7 @@ class chararray(ndarray):
"""
Like `find`, but raises `ValueError` when the substring is not found.
- See also
+ See Also
--------
char.index
@@ -2250,7 +2250,7 @@ class chararray(ndarray):
are alphanumeric and there is at least one character, false
otherwise.
- See also
+ See Also
--------
char.isalnum
@@ -2263,7 +2263,7 @@ class chararray(ndarray):
are alphabetic and there is at least one character, false
otherwise.
- See also
+ See Also
--------
char.isalpha
@@ -2275,7 +2275,7 @@ class chararray(ndarray):
Returns true for each element if all characters in the string are
digits and there is at least one character, false otherwise.
- See also
+ See Also
--------
char.isdigit
@@ -2288,7 +2288,7 @@ class chararray(ndarray):
string are lowercase and there is at least one cased character,
false otherwise.
- See also
+ See Also
--------
char.islower
@@ -2301,7 +2301,7 @@ class chararray(ndarray):
characters in the string and there is at least one character,
false otherwise.
- See also
+ See Also
--------
char.isspace
@@ -2313,7 +2313,7 @@ class chararray(ndarray):
Returns true for each element if the element is a titlecased
string and there is at least one character, false otherwise.
- See also
+ See Also
--------
char.istitle
@@ -2326,7 +2326,7 @@ class chararray(ndarray):
string are uppercase and there is at least one character, false
otherwise.
- See also
+ See Also
--------
char.isupper
@@ -2338,7 +2338,7 @@ class chararray(ndarray):
Return a string which is the concatenation of the strings in the
sequence `seq`.
- See also
+ See Also
--------
char.join
@@ -2350,7 +2350,7 @@ class chararray(ndarray):
Return an array with the elements of `self` left-justified in a
string of length `width`.
- See also
+ See Also
--------
char.ljust
@@ -2362,7 +2362,7 @@ class chararray(ndarray):
Return an array with the elements of `self` converted to
lowercase.
- See also
+ See Also
--------
char.lower
@@ -2374,7 +2374,7 @@ class chararray(ndarray):
For each element in `self`, return a copy with the leading characters
removed.
- See also
+ See Also
--------
char.lstrip
@@ -2385,7 +2385,7 @@ class chararray(ndarray):
"""
Partition each element in `self` around `sep`.
- See also
+ See Also
--------
partition
"""
@@ -2396,7 +2396,7 @@ class chararray(ndarray):
For each element in `self`, return a copy of the string with all
occurrences of substring `old` replaced by `new`.
- See also
+ See Also
--------
char.replace
@@ -2409,7 +2409,7 @@ class chararray(ndarray):
where substring `sub` is found, such that `sub` is contained
within [`start`, `end`].
- See also
+ See Also
--------
char.rfind
@@ -2421,7 +2421,7 @@ class chararray(ndarray):
Like `rfind`, but raises `ValueError` when the substring `sub` is
not found.
- See also
+ See Also
--------
char.rindex
@@ -2433,7 +2433,7 @@ class chararray(ndarray):
Return an array with the elements of `self`
right-justified in a string of length `width`.
- See also
+ See Also
--------
char.rjust
@@ -2444,7 +2444,7 @@ class chararray(ndarray):
"""
Partition each element in `self` around `sep`.
- See also
+ See Also
--------
rpartition
"""
@@ -2455,7 +2455,7 @@ class chararray(ndarray):
For each element in `self`, return a list of the words in
the string, using `sep` as the delimiter string.
- See also
+ See Also
--------
char.rsplit
@@ -2467,7 +2467,7 @@ class chararray(ndarray):
For each element in `self`, return a copy with the trailing
characters removed.
- See also
+ See Also
--------
char.rstrip
@@ -2479,7 +2479,7 @@ class chararray(ndarray):
For each element in `self`, return a list of the words in the
string, using `sep` as the delimiter string.
- See also
+ See Also
--------
char.split
@@ -2491,7 +2491,7 @@ class chararray(ndarray):
For each element in `self`, return a list of the lines in the
element, breaking at line boundaries.
- See also
+ See Also
--------
char.splitlines
@@ -2503,7 +2503,7 @@ class chararray(ndarray):
Returns a boolean array which is `True` where the string element
in `self` starts with `prefix`, otherwise `False`.
- See also
+ See Also
--------
char.startswith
@@ -2515,7 +2515,7 @@ class chararray(ndarray):
For each element in `self`, return a copy with the leading and
trailing characters removed.
- See also
+ See Also
--------
char.strip
@@ -2527,7 +2527,7 @@ class chararray(ndarray):
For each element in `self`, return a copy of the string with
uppercase characters converted to lowercase and vice versa.
- See also
+ See Also
--------
char.swapcase
@@ -2540,7 +2540,7 @@ class chararray(ndarray):
string: words start with uppercase characters, all remaining cased
characters are lowercase.
- See also
+ See Also
--------
char.title
@@ -2554,7 +2554,7 @@ class chararray(ndarray):
`deletechars` are removed, and the remaining characters have
been mapped through the given translation table.
- See also
+ See Also
--------
char.translate
@@ -2566,7 +2566,7 @@ class chararray(ndarray):
Return an array with the elements of `self` converted to
uppercase.
- See also
+ See Also
--------
char.upper
@@ -2578,7 +2578,7 @@ class chararray(ndarray):
Return the numeric string left-filled with zeros in a string of
length `width`.
- See also
+ See Also
--------
char.zfill
@@ -2590,7 +2590,7 @@ class chararray(ndarray):
For each element in `self`, return True if there are only
numeric characters in the element.
- See also
+ See Also
--------
char.isnumeric
@@ -2602,7 +2602,7 @@ class chararray(ndarray):
For each element in `self`, return True if there are only
decimal characters in the element.
- See also
+ See Also
--------
char.isdecimal
diff --git a/numpy/core/einsumfunc.py b/numpy/core/einsumfunc.py
index e0942beca..18157641a 100644
--- a/numpy/core/einsumfunc.py
+++ b/numpy/core/einsumfunc.py
@@ -327,7 +327,7 @@ def _greedy_path(input_sets, output_set, idx_dict, memory_limit):
Set that represents the rhs side of the overall einsum subscript
idx_dict : dictionary
Dictionary of index sizes
- memory_limit_limit : int
+ memory_limit : int
The maximum number of elements in a temporary array
Returns
@@ -1061,14 +1061,12 @@ def einsum(*operands, out=None, optimize=False, **kwargs):
See Also
--------
einsum_path, dot, inner, outer, tensordot, linalg.multi_dot
-
- einops:
+ einops :
similar verbose interface is provided by
`einops <https://github.com/arogozhnikov/einops>`_ package to cover
additional operations: transpose, reshape/flatten, repeat/tile,
squeeze/unsqueeze and reductions.
-
- opt_einsum:
+ opt_einsum :
`opt_einsum <https://optimized-einsum.readthedocs.io/en/stable/>`_
optimizes contraction order for einsum-like expressions
in backend-agnostic manner.
diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py
index 52df1aad9..658b1aca5 100644
--- a/numpy/core/fromnumeric.py
+++ b/numpy/core/fromnumeric.py
@@ -319,34 +319,34 @@ def choose(a, choices, out=None, mode='raise'):
But this omits some subtleties. Here is a fully general summary:
- Given an "index" array (`a`) of integers and a sequence of `n` arrays
+ Given an "index" array (`a`) of integers and a sequence of ``n`` arrays
(`choices`), `a` and each choice array are first broadcast, as necessary,
to arrays of a common shape; calling these *Ba* and *Bchoices[i], i =
0,...,n-1* we have that, necessarily, ``Ba.shape == Bchoices[i].shape``
- for each `i`. Then, a new array with shape ``Ba.shape`` is created as
+ for each ``i``. Then, a new array with shape ``Ba.shape`` is created as
follows:
- * if ``mode=raise`` (the default), then, first of all, each element of
- `a` (and thus `Ba`) must be in the range `[0, n-1]`; now, suppose that
- `i` (in that range) is the value at the `(j0, j1, ..., jm)` position
- in `Ba` - then the value at the same position in the new array is the
- value in `Bchoices[i]` at that same position;
+ * if ``mode='raise'`` (the default), then, first of all, each element of
+ ``a`` (and thus ``Ba``) must be in the range ``[0, n-1]``; now, suppose
+ that ``i`` (in that range) is the value at the ``(j0, j1, ..., jm)``
+ position in ``Ba`` - then the value at the same position in the new array
+ is the value in ``Bchoices[i]`` at that same position;
- * if ``mode=wrap``, values in `a` (and thus `Ba`) may be any (signed)
+ * if ``mode='wrap'``, values in `a` (and thus `Ba`) may be any (signed)
integer; modular arithmetic is used to map integers outside the range
`[0, n-1]` back into that range; and then the new array is constructed
as above;
- * if ``mode=clip``, values in `a` (and thus `Ba`) may be any (signed)
- integer; negative integers are mapped to 0; values greater than `n-1`
- are mapped to `n-1`; and then the new array is constructed as above.
+ * if ``mode='clip'``, values in `a` (and thus ``Ba``) may be any (signed)
+ integer; negative integers are mapped to 0; values greater than ``n-1``
+ are mapped to ``n-1``; and then the new array is constructed as above.
Parameters
----------
a : int array
- This array must contain integers in `[0, n-1]`, where `n` is the number
- of choices, unless ``mode=wrap`` or ``mode=clip``, in which cases any
- integers are permissible.
+ This array must contain integers in ``[0, n-1]``, where ``n`` is the
+ number of choices, unless ``mode=wrap`` or ``mode=clip``, in which
+ cases any integers are permissible.
choices : sequence of arrays
Choice arrays. `a` and all of the choices must be broadcastable to the
same shape. If `choices` is itself an array (not recommended), then
@@ -355,12 +355,12 @@ def choose(a, choices, out=None, mode='raise'):
out : array, optional
If provided, the result will be inserted into this array. It should
be of the appropriate shape and dtype. Note that `out` is always
- buffered if `mode='raise'`; use other modes for better performance.
+ buffered if ``mode='raise'``; use other modes for better performance.
mode : {'raise' (default), 'wrap', 'clip'}, optional
- Specifies how indices outside `[0, n-1]` will be treated:
+ Specifies how indices outside ``[0, n-1]`` will be treated:
* 'raise' : an exception is raised
- * 'wrap' : value becomes value mod `n`
+ * 'wrap' : value becomes value mod ``n``
* 'clip' : values < 0 are mapped to 0, values > n-1 are mapped to n-1
Returns
@@ -1381,7 +1381,7 @@ def resize(a, new_shape):
--------
np.reshape : Reshape an array without changing the total size.
np.pad : Enlarge and pad an array.
- np.repeat: Repeat elements of an array.
+ np.repeat : Repeat elements of an array.
ndarray.resize : resize an array in-place.
Notes
@@ -2007,7 +2007,7 @@ def compress(condition, a, axis=None, out=None):
--------
take, choose, diag, diagonal, select
ndarray.compress : Equivalent method in ndarray
- extract: Equivalent method when working on 1-D arrays
+ extract : Equivalent method when working on 1-D arrays
:ref:`ufuncs-output-type`
Examples
@@ -2475,14 +2475,11 @@ def cumsum(a, axis=None, dtype=None, out=None):
result has the same size as `a`, and the same shape as `a` if
`axis` is not None or `a` is a 1-d array.
-
See Also
--------
sum : Sum array elements.
-
trapz : Integration of array values using the composite trapezoidal rule.
-
- diff : Calculate the n-th discrete difference along given axis.
+ diff : Calculate the n-th discrete difference along given axis.
Notes
-----
diff --git a/numpy/core/fromnumeric.pyi b/numpy/core/fromnumeric.pyi
index 3b147e1d7..fc7f28a59 100644
--- a/numpy/core/fromnumeric.pyi
+++ b/numpy/core/fromnumeric.pyi
@@ -23,9 +23,8 @@ from numpy.typing import (
ArrayLike,
_ShapeLike,
_Shape,
- _IntLike,
- _BoolLike,
- _NumberLike,
+ _IntLike_co,
+ _NumberLike_co,
)
if sys.version_info >= (3, 8):
@@ -98,7 +97,7 @@ def choose(
) -> _ScalarIntOrBool: ...
@overload
def choose(
- a: Union[_IntLike, _BoolLike], choices: ArrayLike, out: Optional[ndarray] = ..., mode: _ModeKind = ...
+ a: _IntLike_co, choices: ArrayLike, out: Optional[ndarray] = ..., mode: _ModeKind = ...
) -> Union[integer, bool_]: ...
@overload
def choose(
@@ -250,7 +249,7 @@ def sum(
dtype: DTypeLike = ...,
out: Optional[ndarray] = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
+ initial: _NumberLike_co = ...,
where: _ArrayLikeBool = ...,
) -> _Number: ...
@overload
@@ -260,7 +259,7 @@ def sum(
dtype: DTypeLike = ...,
out: Optional[ndarray] = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
+ initial: _NumberLike_co = ...,
where: _ArrayLikeBool = ...,
) -> Union[number, ndarray]: ...
@overload
@@ -324,7 +323,7 @@ def amax(
axis: Optional[_ShapeLike] = ...,
out: Optional[ndarray] = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
+ initial: _NumberLike_co = ...,
where: _ArrayLikeBool = ...,
) -> _Number: ...
@overload
@@ -333,7 +332,7 @@ def amax(
axis: None = ...,
out: Optional[ndarray] = ...,
keepdims: Literal[False] = ...,
- initial: _NumberLike = ...,
+ initial: _NumberLike_co = ...,
where: _ArrayLikeBool = ...,
) -> number: ...
@overload
@@ -342,7 +341,7 @@ def amax(
axis: Optional[_ShapeLike] = ...,
out: Optional[ndarray] = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
+ initial: _NumberLike_co = ...,
where: _ArrayLikeBool = ...,
) -> Union[number, ndarray]: ...
@overload
@@ -351,7 +350,7 @@ def amin(
axis: Optional[_ShapeLike] = ...,
out: Optional[ndarray] = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
+ initial: _NumberLike_co = ...,
where: _ArrayLikeBool = ...,
) -> _Number: ...
@overload
@@ -360,7 +359,7 @@ def amin(
axis: None = ...,
out: Optional[ndarray] = ...,
keepdims: Literal[False] = ...,
- initial: _NumberLike = ...,
+ initial: _NumberLike_co = ...,
where: _ArrayLikeBool = ...,
) -> number: ...
@overload
@@ -369,7 +368,7 @@ def amin(
axis: Optional[_ShapeLike] = ...,
out: Optional[ndarray] = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
+ initial: _NumberLike_co = ...,
where: _ArrayLikeBool = ...,
) -> Union[number, ndarray]: ...
@@ -387,7 +386,7 @@ def prod(
dtype: DTypeLike = ...,
out: None = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
+ initial: _NumberLike_co = ...,
where: _ArrayLikeBool = ...,
) -> _Number: ...
@overload
@@ -397,7 +396,7 @@ def prod(
dtype: DTypeLike = ...,
out: None = ...,
keepdims: Literal[False] = ...,
- initial: _NumberLike = ...,
+ initial: _NumberLike_co = ...,
where: _ArrayLikeBool = ...,
) -> number: ...
@overload
@@ -407,7 +406,7 @@ def prod(
dtype: DTypeLike = ...,
out: Optional[ndarray] = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
+ initial: _NumberLike_co = ...,
where: _ArrayLikeBool = ...,
) -> Union[number, ndarray]: ...
def cumprod(
@@ -424,7 +423,7 @@ def around(
) -> _Number: ...
@overload
def around(
- a: _NumberLike, decimals: int = ..., out: Optional[ndarray] = ...
+ a: _NumberLike_co, decimals: int = ..., out: Optional[ndarray] = ...
) -> number: ...
@overload
def around(
diff --git a/numpy/core/function_base.pyi b/numpy/core/function_base.pyi
index 1490bed4a..d4543f281 100644
--- a/numpy/core/function_base.pyi
+++ b/numpy/core/function_base.pyi
@@ -2,20 +2,17 @@ import sys
from typing import overload, Tuple, Union, Sequence, Any
from numpy import ndarray, inexact
-from numpy.typing import ArrayLike, DTypeLike, _SupportsArray, _NumberLike
+from numpy.typing import ArrayLike, DTypeLike, _SupportsArray, _NumberLike_co
if sys.version_info >= (3, 8):
from typing import SupportsIndex, Literal
else:
- from typing_extensions import Literal, Protocol
-
- class SupportsIndex(Protocol):
- def __index__(self) -> int: ...
+ from typing_extensions import SupportsIndex, Literal
# TODO: wait for support for recursive types
_ArrayLikeNested = Sequence[Sequence[Any]]
_ArrayLikeNumber = Union[
- _NumberLike, Sequence[_NumberLike], ndarray, _SupportsArray, _ArrayLikeNested
+ _NumberLike_co, Sequence[_NumberLike_co], ndarray, _SupportsArray, _ArrayLikeNested
]
@overload
def linspace(
diff --git a/numpy/core/include/numpy/random/distributions.h b/numpy/core/include/numpy/random/distributions.h
index c474c4d14..3ffacc8f9 100644
--- a/numpy/core/include/numpy/random/distributions.h
+++ b/numpy/core/include/numpy/random/distributions.h
@@ -1,6 +1,10 @@
#ifndef _RANDOMDGEN__DISTRIBUTIONS_H_
#define _RANDOMDGEN__DISTRIBUTIONS_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include "Python.h"
#include "numpy/npy_common.h"
#include <stddef.h>
@@ -197,4 +201,8 @@ static NPY_INLINE double next_double(bitgen_t *bitgen_state) {
return bitgen_state->next_double(bitgen_state->state);
}
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/numpy/core/multiarray.py b/numpy/core/multiarray.py
index 07179a627..b7277ac24 100644
--- a/numpy/core/multiarray.py
+++ b/numpy/core/multiarray.py
@@ -1441,7 +1441,7 @@ def is_busday(dates, weekmask=None, holidays=None, busdaycal=None, out=None):
See Also
--------
- busdaycalendar: An object that specifies a custom set of valid days.
+ busdaycalendar : An object that specifies a custom set of valid days.
busday_offset : Applies an offset counted in valid days.
busday_count : Counts how many valid days are in a half-open date range.
@@ -1516,7 +1516,7 @@ def busday_offset(dates, offsets, roll=None, weekmask=None, holidays=None,
See Also
--------
- busdaycalendar: An object that specifies a custom set of valid days.
+ busdaycalendar : An object that specifies a custom set of valid days.
is_busday : Returns a boolean array indicating valid days.
busday_count : Counts how many valid days are in a half-open date range.
@@ -1598,7 +1598,7 @@ def busday_count(begindates, enddates, weekmask=None, holidays=None,
See Also
--------
- busdaycalendar: An object that specifies a custom set of valid days.
+ busdaycalendar : An object that specifies a custom set of valid days.
is_busday : Returns a boolean array indicating valid days.
busday_offset : Applies an offset counted in valid days.
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py
index c95c48d71..086439656 100644
--- a/numpy/core/numeric.py
+++ b/numpy/core/numeric.py
@@ -299,7 +299,7 @@ def full(shape, fill_value, dtype=None, order='C', *, like=None):
Fill value.
dtype : data-type, optional
The desired data-type for the array The default, None, means
- `np.array(fill_value).dtype`.
+ ``np.array(fill_value).dtype``.
order : {'C', 'F'}, optional
Whether to store multidimensional data in C- or Fortran-contiguous
(row- or column-wise) order in memory.
@@ -1427,12 +1427,11 @@ def moveaxis(a, source, destination):
See Also
--------
- transpose: Permute the dimensions of an array.
- swapaxes: Interchange two axes of an array.
+ transpose : Permute the dimensions of an array.
+ swapaxes : Interchange two axes of an array.
Examples
--------
-
>>> x = np.zeros((3, 4, 5))
>>> np.moveaxis(x, 0, -1).shape
(4, 5, 3)
diff --git a/numpy/core/records.py b/numpy/core/records.py
index 00d456658..a626a0589 100644
--- a/numpy/core/records.py
+++ b/numpy/core/records.py
@@ -45,7 +45,10 @@ from numpy.core.overrides import set_module
from .arrayprint import get_printoptions
# All of the functions allow formats to be a dtype
-__all__ = ['record', 'recarray', 'format_parser']
+__all__ = [
+ 'record', 'recarray', 'format_parser',
+ 'fromarrays', 'fromrecords', 'fromstring', 'fromfile', 'array',
+]
ndarray = sb.ndarray
@@ -962,16 +965,16 @@ def array(obj, dtype=None, shape=None, offset=0, strides=None, formats=None,
Parameters
----------
- obj: any
+ obj : any
Input object. See Notes for details on how various input types are
treated.
- dtype: data-type, optional
+ dtype : data-type, optional
Valid dtype for array.
- shape: int or tuple of ints, optional
+ shape : int or tuple of ints, optional
Shape of each array.
- offset: int, optional
+ offset : int, optional
Position in the file or buffer to start reading from.
- strides: tuple of ints, optional
+ strides : tuple of ints, optional
Buffer (`buf`) is interpreted according to these strides (strides
define how many bytes each array element, row, column, etc.
occupy in memory).
@@ -979,7 +982,7 @@ def array(obj, dtype=None, shape=None, offset=0, strides=None, formats=None,
If `dtype` is ``None``, these arguments are passed to
`numpy.format_parser` to construct a dtype. See that function for
detailed documentation.
- copy: bool, optional
+ copy : bool, optional
Whether to copy the input object (True), or to use a reference instead.
This option only applies when the input is an ndarray or recarray.
Defaults to True.
diff --git a/numpy/core/setup_common.py b/numpy/core/setup_common.py
index 2d85e0718..378d93c06 100644
--- a/numpy/core/setup_common.py
+++ b/numpy/core/setup_common.py
@@ -317,8 +317,8 @@ def pyod(filename):
out : seq
list of lines of od output
- Note
- ----
+ Notes
+ -----
We only implement enough to get the necessary information for long double
representation, this is not intended as a compatible replacement for od.
"""
diff --git a/numpy/core/shape_base.py b/numpy/core/shape_base.py
index e90358ba5..89e98ab30 100644
--- a/numpy/core/shape_base.py
+++ b/numpy/core/shape_base.py
@@ -607,7 +607,7 @@ def _block_info_recursion(arrays, max_depth, result_ndim, depth=0):
The arrays to check
max_depth : list of int
The number of nested lists
- result_ndim: int
+ result_ndim : int
The number of dimensions in thefinal array.
Returns
diff --git a/numpy/core/shape_base.pyi b/numpy/core/shape_base.pyi
index b20598b1a..ec40a8814 100644
--- a/numpy/core/shape_base.pyi
+++ b/numpy/core/shape_base.pyi
@@ -7,9 +7,7 @@ from numpy.typing import ArrayLike
if sys.version_info >= (3, 8):
from typing import SupportsIndex
else:
- from typing_extensions import Protocol
- class SupportsIndex(Protocol):
- def __index__(self) -> int: ...
+ from typing_extensions import SupportsIndex
_ArrayType = TypeVar("_ArrayType", bound=ndarray)
diff --git a/numpy/core/src/_simd/_simd.dispatch.c.src b/numpy/core/src/_simd/_simd.dispatch.c.src
index af42192a9..e5b58a8d2 100644
--- a/numpy/core/src/_simd/_simd.dispatch.c.src
+++ b/numpy/core/src/_simd/_simd.dispatch.c.src
@@ -23,7 +23,8 @@
* #mul_sup = 1, 1, 1, 1, 1, 1, 0, 0, 1, 1#
* #div_sup = 0, 0, 0, 0, 0, 0, 0, 0, 1, 1#
* #fused_sup = 0, 0, 0, 0, 0, 0, 0, 0, 1, 1#
- * #sum_sup = 0, 0, 0, 0, 1, 0, 0, 0, 1, 1#
+ * #sumup_sup = 1, 0, 1, 0, 0, 0, 0, 0, 0, 0#
+ * #sum_sup = 0, 0, 0, 0, 1, 0, 1, 0, 1, 1#
* #rev64_sup = 1, 1, 1, 1, 1, 1, 0, 0, 1, 0#
* #ncont_sup = 0, 0, 0, 0, 1, 1, 1, 1, 1, 1#
* #shl_imm = 0, 0, 15, 15, 31, 31, 63, 63, 0, 0#
@@ -365,6 +366,10 @@ SIMD_IMPL_INTRIN_3(@intrin@_@sfx@, v@sfx@, v@sfx@, v@sfx@, v@sfx@)
SIMD_IMPL_INTRIN_1(sum_@sfx@, @sfx@, v@sfx@)
#endif // sum_sup
+#if @sumup_sup@
+SIMD_IMPL_INTRIN_1(sumup_@sfx@, @esfx@, v@sfx@)
+#endif // sumup_sup
+
/***************************
* Math
***************************/
@@ -452,7 +457,8 @@ static PyMethodDef simd__intrinsics_methods[] = {
* #mul_sup = 1, 1, 1, 1, 1, 1, 0, 0, 1, 1#
* #div_sup = 0, 0, 0, 0, 0, 0, 0, 0, 1, 1#
* #fused_sup = 0, 0, 0, 0, 0, 0, 0, 0, 1, 1#
- * #sum_sup = 0, 0, 0, 0, 1, 0, 0, 0, 1, 1#
+ * #sumup_sup = 1, 0, 1, 0, 0, 0, 0, 0, 0, 0#
+ * #sum_sup = 0, 0, 0, 0, 1, 0, 1, 0, 1, 1#
* #rev64_sup = 1, 1, 1, 1, 1, 1, 0, 0, 1, 0#
* #ncont_sup = 0, 0, 0, 0, 1, 1, 1, 1, 1, 1#
* #shl_imm = 0, 0, 15, 15, 31, 31, 63, 63, 0, 0#
@@ -574,6 +580,9 @@ SIMD_INTRIN_DEF(@intrin@_@sfx@)
SIMD_INTRIN_DEF(sum_@sfx@)
#endif // sum_sup
+#if @sumup_sup@
+SIMD_INTRIN_DEF(sumup_@sfx@)
+#endif // sumup_sup
/***************************
* Math
***************************/
diff --git a/numpy/core/src/common/simd/avx2/arithmetic.h b/numpy/core/src/common/simd/avx2/arithmetic.h
index 3a3a82798..4b8258759 100644
--- a/numpy/core/src/common/simd/avx2/arithmetic.h
+++ b/numpy/core/src/common/simd/avx2/arithmetic.h
@@ -5,6 +5,7 @@
#ifndef _NPY_SIMD_AVX2_ARITHMETIC_H
#define _NPY_SIMD_AVX2_ARITHMETIC_H
+#include "../sse/utils.h"
/***************************
* Addition
***************************/
@@ -117,8 +118,11 @@
}
#endif // !NPY_HAVE_FMA3
-// Horizontal add: Calculates the sum of all vector elements.
-NPY_FINLINE npy_uint32 npyv_sum_u32(__m256i a)
+/***************************
+ * Summation
+ ***************************/
+// reduce sum across vector
+NPY_FINLINE npy_uint32 npyv_sum_u32(npyv_u32 a)
{
__m256i s0 = _mm256_hadd_epi32(a, a);
s0 = _mm256_hadd_epi32(s0, s0);
@@ -127,7 +131,14 @@ NPY_FINLINE npy_uint32 npyv_sum_u32(__m256i a)
return _mm_cvtsi128_si32(s1);
}
-NPY_FINLINE float npyv_sum_f32(__m256 a)
+NPY_FINLINE npy_uint64 npyv_sum_u64(npyv_u64 a)
+{
+ __m256i two = _mm256_add_epi64(a, _mm256_shuffle_epi32(a, _MM_SHUFFLE(1, 0, 3, 2)));
+ __m128i one = _mm_add_epi64(_mm256_castsi256_si128(two), _mm256_extracti128_si256(two, 1));
+ return (npy_uint64)npyv128_cvtsi128_si64(one);
+}
+
+NPY_FINLINE float npyv_sum_f32(npyv_f32 a)
{
__m256 sum_halves = _mm256_hadd_ps(a, a);
sum_halves = _mm256_hadd_ps(sum_halves, sum_halves);
@@ -137,7 +148,7 @@ NPY_FINLINE float npyv_sum_f32(__m256 a)
return _mm_cvtss_f32(sum);
}
-NPY_FINLINE double npyv_sum_f64(__m256d a)
+NPY_FINLINE double npyv_sum_f64(npyv_f64 a)
{
__m256d sum_halves = _mm256_hadd_pd(a, a);
__m128d lo = _mm256_castpd256_pd128(sum_halves);
@@ -146,6 +157,24 @@ NPY_FINLINE double npyv_sum_f64(__m256d a)
return _mm_cvtsd_f64(sum);
}
+// expand the source vector and performs sum reduce
+NPY_FINLINE npy_uint16 npyv_sumup_u8(npyv_u8 a)
+{
+ __m256i four = _mm256_sad_epu8(a, _mm256_setzero_si256());
+ __m128i two = _mm_add_epi16(_mm256_castsi256_si128(four), _mm256_extracti128_si256(four, 1));
+ __m128i one = _mm_add_epi16(two, _mm_unpackhi_epi64(two, two));
+ return (npy_uint16)_mm_cvtsi128_si32(one);
+}
+
+NPY_FINLINE npy_uint32 npyv_sumup_u16(npyv_u16 a)
+{
+ const npyv_u16 even_mask = _mm256_set1_epi32(0x0000FFFF);
+ __m256i even = _mm256_and_si256(a, even_mask);
+ __m256i odd = _mm256_srli_epi32(a, 16);
+ __m256i eight = _mm256_add_epi32(even, odd);
+ return npyv_sum_u32(eight);
+}
+
#endif // _NPY_SIMD_AVX2_ARITHMETIC_H
diff --git a/numpy/core/src/common/simd/avx512/arithmetic.h b/numpy/core/src/common/simd/avx512/arithmetic.h
index 6f668f439..450da7ea5 100644
--- a/numpy/core/src/common/simd/avx512/arithmetic.h
+++ b/numpy/core/src/common/simd/avx512/arithmetic.h
@@ -6,7 +6,7 @@
#define _NPY_SIMD_AVX512_ARITHMETIC_H
#include "../avx2/utils.h"
-
+#include "../sse/utils.h"
/***************************
* Addition
***************************/
@@ -130,7 +130,7 @@ NPY_FINLINE __m512i npyv_mul_u8(__m512i a, __m512i b)
#define npyv_nmulsub_f64 _mm512_fnmsub_pd
/***************************
- * Reduce Sum: Calculates the sum of all vector elements.
+ * Summation: Calculates the sum of all vector elements.
* there are three ways to implement reduce sum for AVX512:
* 1- split(256) /add /split(128) /add /hadd /hadd /extract
* 2- shuff(cross) /add /shuff(cross) /add /shuff /add /shuff /add /extract
@@ -144,19 +144,29 @@ NPY_FINLINE __m512i npyv_mul_u8(__m512i a, __m512i b)
* The third one is almost the same as the second one but only works for
* intel compiler/GCC 7.1/Clang 4, we still need to support older GCC.
***************************/
-
-NPY_FINLINE npy_uint32 npyv_sum_u32(npyv_u32 a)
-{
- __m256i half = _mm256_add_epi32(npyv512_lower_si256(a), npyv512_higher_si256(a));
- __m128i quarter = _mm_add_epi32(_mm256_castsi256_si128(half), _mm256_extracti128_si256(half, 1));
- quarter = _mm_hadd_epi32(quarter, quarter);
- return _mm_cvtsi128_si32(_mm_hadd_epi32(quarter, quarter));
-}
-
+// reduce sum across vector
#ifdef NPY_HAVE_AVX512F_REDUCE
+ #define npyv_sum_u32 _mm512_reduce_add_epi32
+ #define npyv_sum_u64 _mm512_reduce_add_epi64
#define npyv_sum_f32 _mm512_reduce_add_ps
#define npyv_sum_f64 _mm512_reduce_add_pd
#else
+ NPY_FINLINE npy_uint32 npyv_sum_u32(npyv_u32 a)
+ {
+ __m256i half = _mm256_add_epi32(npyv512_lower_si256(a), npyv512_higher_si256(a));
+ __m128i quarter = _mm_add_epi32(_mm256_castsi256_si128(half), _mm256_extracti128_si256(half, 1));
+ quarter = _mm_hadd_epi32(quarter, quarter);
+ return _mm_cvtsi128_si32(_mm_hadd_epi32(quarter, quarter));
+ }
+
+ NPY_FINLINE npy_uint64 npyv_sum_u64(npyv_u64 a)
+ {
+ __m256i four = _mm256_add_epi64(npyv512_lower_si256(a), npyv512_higher_si256(a));
+ __m256i two = _mm256_add_epi64(four, _mm256_shuffle_epi32(four, _MM_SHUFFLE(1, 0, 3, 2)));
+ __m128i one = _mm_add_epi64(_mm256_castsi256_si128(two), _mm256_extracti128_si256(two, 1));
+ return (npy_uint64)npyv128_cvtsi128_si64(one);
+ }
+
NPY_FINLINE float npyv_sum_f32(npyv_f32 a)
{
__m512 h64 = _mm512_shuffle_f32x4(a, a, _MM_SHUFFLE(3, 2, 3, 2));
@@ -169,6 +179,7 @@ NPY_FINLINE npy_uint32 npyv_sum_u32(npyv_u32 a)
__m512 sum4 = _mm512_add_ps(sum8, h4);
return _mm_cvtss_f32(_mm512_castps512_ps128(sum4));
}
+
NPY_FINLINE double npyv_sum_f64(npyv_f64 a)
{
__m512d h64 = _mm512_shuffle_f64x2(a, a, _MM_SHUFFLE(3, 2, 3, 2));
@@ -181,4 +192,29 @@ NPY_FINLINE npy_uint32 npyv_sum_u32(npyv_u32 a)
}
#endif
+// expand the source vector and performs sum reduce
+NPY_FINLINE npy_uint16 npyv_sumup_u8(npyv_u8 a)
+{
+#ifdef NPY_HAVE_AVX512BW
+ __m512i eight = _mm512_sad_epu8(a, _mm512_setzero_si512());
+ __m256i four = _mm256_add_epi16(npyv512_lower_si256(eight), npyv512_higher_si256(eight));
+#else
+ __m256i lo_four = _mm256_sad_epu8(npyv512_lower_si256(a), _mm256_setzero_si256());
+ __m256i hi_four = _mm256_sad_epu8(npyv512_higher_si256(a), _mm256_setzero_si256());
+ __m256i four = _mm256_add_epi16(lo_four, hi_four);
+#endif
+ __m128i two = _mm_add_epi16(_mm256_castsi256_si128(four), _mm256_extracti128_si256(four, 1));
+ __m128i one = _mm_add_epi16(two, _mm_unpackhi_epi64(two, two));
+ return (npy_uint16)_mm_cvtsi128_si32(one);
+}
+
+NPY_FINLINE npy_uint32 npyv_sumup_u16(npyv_u16 a)
+{
+ const npyv_u16 even_mask = _mm512_set1_epi32(0x0000FFFF);
+ __m512i even = _mm512_and_si512(a, even_mask);
+ __m512i odd = _mm512_srli_epi32(a, 16);
+ __m512i ff = _mm512_add_epi32(even, odd);
+ return npyv_sum_u32(ff);
+}
+
#endif // _NPY_SIMD_AVX512_ARITHMETIC_H
diff --git a/numpy/core/src/common/simd/neon/arithmetic.h b/numpy/core/src/common/simd/neon/arithmetic.h
index 1c8bde15a..69a49f571 100644
--- a/numpy/core/src/common/simd/neon/arithmetic.h
+++ b/numpy/core/src/common/simd/neon/arithmetic.h
@@ -131,12 +131,21 @@
{ return vfmsq_f64(vnegq_f64(c), a, b); }
#endif // NPY_SIMD_F64
-// Horizontal add: Calculates the sum of all vector elements.
+/***************************
+ * Summation
+ ***************************/
+// reduce sum across vector
#if NPY_SIMD_F64
#define npyv_sum_u32 vaddvq_u32
+ #define npyv_sum_u64 vaddvq_u64
#define npyv_sum_f32 vaddvq_f32
#define npyv_sum_f64 vaddvq_f64
#else
+ NPY_FINLINE npy_uint64 npyv_sum_u64(npyv_u64 a)
+ {
+ return vget_lane_u64(vadd_u64(vget_low_u64(a), vget_high_u64(a)),0);
+ }
+
NPY_FINLINE npy_uint32 npyv_sum_u32(npyv_u32 a)
{
uint32x2_t a0 = vpadd_u32(vget_low_u32(a), vget_high_u32(a));
@@ -150,4 +159,24 @@
}
#endif
+// expand the source vector and performs sum reduce
+#if NPY_SIMD_F64
+ #define npyv_sumup_u8 vaddlvq_u8
+ #define npyv_sumup_u16 vaddlvq_u16
+#else
+ NPY_FINLINE npy_uint16 npyv_sumup_u8(npyv_u8 a)
+ {
+ uint32x4_t t0 = vpaddlq_u16(vpaddlq_u8(a));
+ uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0));
+ return vget_lane_u32(vpadd_u32(t1, t1), 0);
+ }
+
+ NPY_FINLINE npy_uint32 npyv_sumup_u16(npyv_u16 a)
+ {
+ uint32x4_t t0 = vpaddlq_u16(a);
+ uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0));
+ return vget_lane_u32(vpadd_u32(t1, t1), 0);
+ }
+#endif
+
#endif // _NPY_SIMD_NEON_ARITHMETIC_H
diff --git a/numpy/core/src/common/simd/sse/arithmetic.h b/numpy/core/src/common/simd/sse/arithmetic.h
index faf5685d9..c21b7da2d 100644
--- a/numpy/core/src/common/simd/sse/arithmetic.h
+++ b/numpy/core/src/common/simd/sse/arithmetic.h
@@ -148,16 +148,24 @@ NPY_FINLINE __m128i npyv_mul_u8(__m128i a, __m128i b)
}
#endif // !NPY_HAVE_FMA3
-// Horizontal add: Calculates the sum of all vector elements.
-
-NPY_FINLINE npy_uint32 npyv_sum_u32(__m128i a)
+/***************************
+ * Summation
+ ***************************/
+// reduce sum across vector
+NPY_FINLINE npy_uint32 npyv_sum_u32(npyv_u32 a)
{
__m128i t = _mm_add_epi32(a, _mm_srli_si128(a, 8));
t = _mm_add_epi32(t, _mm_srli_si128(t, 4));
return (unsigned)_mm_cvtsi128_si32(t);
}
-NPY_FINLINE float npyv_sum_f32(__m128 a)
+NPY_FINLINE npy_uint64 npyv_sum_u64(npyv_u64 a)
+{
+ __m128i one = _mm_add_epi64(a, _mm_unpackhi_epi64(a, a));
+ return (npy_uint64)npyv128_cvtsi128_si64(one);
+}
+
+NPY_FINLINE float npyv_sum_f32(npyv_f32 a)
{
#ifdef NPY_HAVE_SSE3
__m128 sum_halves = _mm_hadd_ps(a, a);
@@ -171,7 +179,7 @@ NPY_FINLINE float npyv_sum_f32(__m128 a)
#endif
}
-NPY_FINLINE double npyv_sum_f64(__m128d a)
+NPY_FINLINE double npyv_sum_f64(npyv_f64 a)
{
#ifdef NPY_HAVE_SSE3
return _mm_cvtsd_f64(_mm_hadd_pd(a, a));
@@ -180,6 +188,23 @@ NPY_FINLINE double npyv_sum_f64(__m128d a)
#endif
}
+// expand the source vector and performs sum reduce
+NPY_FINLINE npy_uint16 npyv_sumup_u8(npyv_u8 a)
+{
+ __m128i two = _mm_sad_epu8(a, _mm_setzero_si128());
+ __m128i one = _mm_add_epi16(two, _mm_unpackhi_epi64(two, two));
+ return (npy_uint16)_mm_cvtsi128_si32(one);
+}
+
+NPY_FINLINE npy_uint32 npyv_sumup_u16(npyv_u16 a)
+{
+ const __m128i even_mask = _mm_set1_epi32(0x0000FFFF);
+ __m128i even = _mm_and_si128(a, even_mask);
+ __m128i odd = _mm_srli_epi32(a, 16);
+ __m128i four = _mm_add_epi32(even, odd);
+ return npyv_sum_u32(four);
+}
+
#endif // _NPY_SIMD_SSE_ARITHMETIC_H
diff --git a/numpy/core/src/common/simd/sse/sse.h b/numpy/core/src/common/simd/sse/sse.h
index dc0b62f73..0bb404312 100644
--- a/numpy/core/src/common/simd/sse/sse.h
+++ b/numpy/core/src/common/simd/sse/sse.h
@@ -62,6 +62,7 @@ typedef struct { __m128d val[3]; } npyv_f64x3;
#define npyv_nlanes_f32 4
#define npyv_nlanes_f64 2
+#include "utils.h"
#include "memory.h"
#include "misc.h"
#include "reorder.h"
diff --git a/numpy/core/src/common/simd/sse/utils.h b/numpy/core/src/common/simd/sse/utils.h
new file mode 100644
index 000000000..c23def11d
--- /dev/null
+++ b/numpy/core/src/common/simd/sse/utils.h
@@ -0,0 +1,19 @@
+#ifndef NPY_SIMD
+ #error "Not a standalone header"
+#endif
+
+#ifndef _NPY_SIMD_SSE_UTILS_H
+#define _NPY_SIMD_SSE_UTILS_H
+
+#if !defined(__x86_64__) && !defined(_M_X64)
+NPY_FINLINE npy_int64 npyv128_cvtsi128_si64(__m128i a)
+{
+ npy_int64 NPY_DECL_ALIGNED(16) idx[2];
+ _mm_store_si128((__m128i *)idx, a);
+ return idx[0];
+}
+#else
+ #define npyv128_cvtsi128_si64 _mm_cvtsi128_si64
+#endif
+
+#endif // _NPY_SIMD_SSE_UTILS_H
diff --git a/numpy/core/src/common/simd/vsx/arithmetic.h b/numpy/core/src/common/simd/vsx/arithmetic.h
index 1288a52a7..7c4e32f27 100644
--- a/numpy/core/src/common/simd/vsx/arithmetic.h
+++ b/numpy/core/src/common/simd/vsx/arithmetic.h
@@ -116,7 +116,14 @@
#define npyv_nmulsub_f32 vec_nmadd // equivalent to -(a*b + c)
#define npyv_nmulsub_f64 vec_nmadd
-// Horizontal add: Calculates the sum of all vector elements.
+/***************************
+ * Summation
+ ***************************/
+// reduce sum across vector
+NPY_FINLINE npy_uint64 npyv_sum_u64(npyv_u64 a)
+{
+ return vec_extract(vec_add(a, vec_mergel(a, a)), 0);
+}
NPY_FINLINE npy_uint32 npyv_sum_u32(npyv_u32 a)
{
@@ -135,4 +142,22 @@ NPY_FINLINE double npyv_sum_f64(npyv_f64 a)
return vec_extract(a, 0) + vec_extract(a, 1);
}
+// expand the source vector and performs sum reduce
+NPY_FINLINE npy_uint16 npyv_sumup_u8(npyv_u8 a)
+{
+ const npyv_u32 zero = npyv_zero_u32();
+ npyv_u32 four = vec_sum4s(a, zero);
+ npyv_s32 one = vec_sums((npyv_s32)four, (npyv_s32)zero);
+ return (npy_uint16)vec_extract(one, 3);
+}
+
+NPY_FINLINE npy_uint32 npyv_sumup_u16(npyv_u16 a)
+{
+ const npyv_s32 zero = npyv_zero_s32();
+ npyv_u32x2 eight = npyv_expand_u32_u16(a);
+ npyv_u32 four = vec_add(eight.val[0], eight.val[1]);
+ npyv_s32 one = vec_sums((npyv_s32)four, zero);
+ return (npy_uint32)vec_extract(one, 3);
+}
+
#endif // _NPY_SIMD_VSX_ARITHMETIC_H
diff --git a/numpy/core/src/multiarray/compiled_base.c b/numpy/core/src/multiarray/compiled_base.c
index fa5d7db75..de793f87c 100644
--- a/numpy/core/src/multiarray/compiled_base.c
+++ b/numpy/core/src/multiarray/compiled_base.c
@@ -1037,7 +1037,7 @@ arr_ravel_multi_index(PyObject *self, PyObject *args, PyObject *kwds)
NpyIter *iter = NULL;
- char *kwlist[] = {"multi_index", "dims", "mode", "order", NULL};
+ static char *kwlist[] = {"multi_index", "dims", "mode", "order", NULL};
memset(op, 0, sizeof(op));
dtype[0] = NULL;
@@ -1232,7 +1232,7 @@ arr_unravel_index(PyObject *self, PyObject *args, PyObject *kwds)
int i, ret_ndim;
npy_intp ret_dims[NPY_MAXDIMS], ret_strides[NPY_MAXDIMS];
- char *kwlist[] = {"indices", "shape", "order", NULL};
+ static char *kwlist[] = {"indices", "shape", "order", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&|O&:unravel_index",
kwlist,
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c
index 58571b678..ef105ff2d 100644
--- a/numpy/core/src/multiarray/ctors.c
+++ b/numpy/core/src/multiarray/ctors.c
@@ -2124,7 +2124,16 @@ PyArray_FromInterface(PyObject *origin)
if (iface == NULL) {
if (PyErr_Occurred()) {
- return NULL;
+ if (PyErr_ExceptionMatches(PyExc_RecursionError) ||
+ PyErr_ExceptionMatches(PyExc_MemoryError)) {
+ /* RecursionError and MemoryError are considered fatal */
+ return NULL;
+ }
+ /*
+ * This probably be deprecated, but at least shapely raised
+ * a NotImplementedError expecting it to be cleared (gh-17965)
+ */
+ PyErr_Clear();
}
return Py_NotImplemented;
}
@@ -2392,7 +2401,13 @@ PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *typecode, PyObject *context)
array_meth = PyArray_LookupSpecial_OnInstance(op, "__array__");
if (array_meth == NULL) {
if (PyErr_Occurred()) {
- return NULL;
+ if (PyErr_ExceptionMatches(PyExc_RecursionError) ||
+ PyErr_ExceptionMatches(PyExc_MemoryError)) {
+ /* RecursionError and MemoryError are considered fatal */
+ return NULL;
+ }
+ /* This probably be deprecated. */
+ PyErr_Clear();
}
return Py_NotImplemented;
}
diff --git a/numpy/core/src/multiarray/datetime_busday.c b/numpy/core/src/multiarray/datetime_busday.c
index 2cf157551..f0564146d 100644
--- a/numpy/core/src/multiarray/datetime_busday.c
+++ b/numpy/core/src/multiarray/datetime_busday.c
@@ -934,8 +934,8 @@ NPY_NO_EXPORT PyObject *
array_busday_offset(PyObject *NPY_UNUSED(self),
PyObject *args, PyObject *kwds)
{
- char *kwlist[] = {"dates", "offsets", "roll",
- "weekmask", "holidays", "busdaycal", "out", NULL};
+ static char *kwlist[] = {"dates", "offsets", "roll",
+ "weekmask", "holidays", "busdaycal", "out", NULL};
PyObject *dates_in = NULL, *offsets_in = NULL, *out_in = NULL;
@@ -1065,8 +1065,8 @@ NPY_NO_EXPORT PyObject *
array_busday_count(PyObject *NPY_UNUSED(self),
PyObject *args, PyObject *kwds)
{
- char *kwlist[] = {"begindates", "enddates",
- "weekmask", "holidays", "busdaycal", "out", NULL};
+ static char *kwlist[] = {"begindates", "enddates",
+ "weekmask", "holidays", "busdaycal", "out", NULL};
PyObject *dates_begin_in = NULL, *dates_end_in = NULL, *out_in = NULL;
@@ -1210,8 +1210,8 @@ NPY_NO_EXPORT PyObject *
array_is_busday(PyObject *NPY_UNUSED(self),
PyObject *args, PyObject *kwds)
{
- char *kwlist[] = {"dates",
- "weekmask", "holidays", "busdaycal", "out", NULL};
+ static char *kwlist[] = {"dates",
+ "weekmask", "holidays", "busdaycal", "out", NULL};
PyObject *dates_in = NULL, *out_in = NULL;
diff --git a/numpy/core/src/multiarray/dtypemeta.c b/numpy/core/src/multiarray/dtypemeta.c
index 2931977c2..b2f36d794 100644
--- a/numpy/core/src/multiarray/dtypemeta.c
+++ b/numpy/core/src/multiarray/dtypemeta.c
@@ -407,6 +407,19 @@ string_unicode_common_dtype(PyArray_DTypeMeta *cls, PyArray_DTypeMeta *other)
Py_INCREF(Py_NotImplemented);
return (PyArray_DTypeMeta *)Py_NotImplemented;
}
+ if (other->type_num != NPY_STRING && other->type_num != NPY_UNICODE) {
+ /* Deprecated 2020-12-19, NumPy 1.21. */
+ if (DEPRECATE_FUTUREWARNING(
+ "Promotion of numbers and bools to strings is deprecated. "
+ "In the future, code such as `np.concatenate((['string'], [0]))` "
+ "will raise an error, while `np.asarray(['string', 0])` will "
+ "return an array with `dtype=object`. To avoid the warning "
+ "while retaining a string result use `dtype='U'` (or 'S'). "
+ "To get an array of Python objects use `dtype=object`. "
+ "(Warning added in NumPy 1.21)") < 0) {
+ return NULL;
+ }
+ }
/*
* The builtin types are ordered by complexity (aside from object) here.
* Arguably, we should not consider numbers and strings "common", but
diff --git a/numpy/core/src/multiarray/einsum_sumprod.c.src b/numpy/core/src/multiarray/einsum_sumprod.c.src
index d1b76de4e..333b8e188 100644
--- a/numpy/core/src/multiarray/einsum_sumprod.c.src
+++ b/numpy/core/src/multiarray/einsum_sumprod.c.src
@@ -20,28 +20,6 @@
#include "simd/simd.h"
#include "common.h"
-#ifdef NPY_HAVE_SSE_INTRINSICS
-#define EINSUM_USE_SSE1 1
-#else
-#define EINSUM_USE_SSE1 0
-#endif
-
-#ifdef NPY_HAVE_SSE2_INTRINSICS
-#define EINSUM_USE_SSE2 1
-#else
-#define EINSUM_USE_SSE2 0
-#endif
-
-#if EINSUM_USE_SSE1
-#include <xmmintrin.h>
-#endif
-
-#if EINSUM_USE_SSE2
-#include <emmintrin.h>
-#endif
-
-#define EINSUM_IS_SSE_ALIGNED(x) ((((npy_intp)x)&0xf) == 0)
-
// ARM/Neon don't have instructions for aligned memory access
#ifdef NPY_HAVE_NEON
#define EINSUM_IS_ALIGNED(x) 0
@@ -311,6 +289,77 @@ finish_after_unrolled_loop:
#elif @nop@ == 2 && !@complex@
+// calculate the multiply and add operation such as dataout = data*scalar+dataout
+static NPY_GCC_OPT_3 void
+@name@_sum_of_products_muladd(@type@ *data, @type@ *data_out, @temptype@ scalar, npy_intp count)
+{
+#if @NPYV_CHK@ // NPYV check for @type@
+ /* Use aligned instructions if possible */
+ const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
+ const int vstep = npyv_nlanes_@sfx@;
+ const npyv_@sfx@ v_scalar = npyv_setall_@sfx@(scalar);
+ /**begin repeat2
+ * #cond = if(is_aligned), else#
+ * #ld = loada, load#
+ * #st = storea, store#
+ */
+ @cond@ {
+ const npy_intp vstepx4 = vstep * 4;
+ for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
+ /**begin repeat3
+ * #i = 0, 1, 2, 3#
+ */
+ npyv_@sfx@ b@i@ = npyv_@ld@_@sfx@(data + vstep * @i@);
+ npyv_@sfx@ c@i@ = npyv_@ld@_@sfx@(data_out + vstep * @i@);
+ /**end repeat3**/
+ /**begin repeat3
+ * #i = 0, 1, 2, 3#
+ */
+ npyv_@sfx@ abc@i@ = npyv_muladd_@sfx@(v_scalar, b@i@, c@i@);
+ /**end repeat3**/
+ /**begin repeat3
+ * #i = 0, 1, 2, 3#
+ */
+ npyv_@st@_@sfx@(data_out + vstep * @i@, abc@i@);
+ /**end repeat3**/
+ }
+ }
+ /**end repeat2**/
+ for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
+ npyv_@sfx@ a = npyv_load_tillz_@sfx@(data, count);
+ npyv_@sfx@ b = npyv_load_tillz_@sfx@(data_out, count);
+ npyv_store_till_@sfx@(data_out, count, npyv_muladd_@sfx@(a, v_scalar, b));
+ }
+ npyv_cleanup();
+#else
+#ifndef NPY_DISABLE_OPTIMIZATION
+ for (; count >= 4; count -= 4, data += 4, data_out += 4) {
+ /**begin repeat2
+ * #i = 0, 1, 2, 3#
+ */
+ const @type@ b@i@ = @from@(data[@i@]);
+ const @type@ c@i@ = @from@(data_out[@i@]);
+ /**end repeat2**/
+ /**begin repeat2
+ * #i = 0, 1, 2, 3#
+ */
+ const @type@ abc@i@ = scalar * b@i@ + c@i@;
+ /**end repeat2**/
+ /**begin repeat2
+ * #i = 0, 1, 2, 3#
+ */
+ data_out[@i@] = @to@(abc@i@);
+ /**end repeat2**/
+ }
+#endif // !NPY_DISABLE_OPTIMIZATION
+ for (; count > 0; --count, ++data, ++data_out) {
+ const @type@ b = @from@(*data);
+ const @type@ c = @from@(*data_out);
+ *data_out = @to@(scalar * b + c);
+ }
+#endif // NPYV check for @type@
+}
+
static void
@name@_sum_of_products_contig_two(int nop, char **dataptr,
npy_intp const *NPY_UNUSED(strides), npy_intp count)
@@ -403,242 +452,23 @@ static void
@type@ *data1 = (@type@ *)dataptr[1];
@type@ *data_out = (@type@ *)dataptr[2];
-#if EINSUM_USE_SSE1 && @float32@
- __m128 a, b, value0_sse;
-#elif EINSUM_USE_SSE2 && @float64@
- __m128d a, b, value0_sse;
-#endif
-
NPY_EINSUM_DBG_PRINT1("@name@_sum_of_products_stride0_contig_outcontig_two (%d)\n",
(int)count);
-
-/* This is placed before the main loop to make small counts faster */
-finish_after_unrolled_loop:
- switch (count) {
-/**begin repeat2
- * #i = 6, 5, 4, 3, 2, 1, 0#
- */
- case @i@+1:
- data_out[@i@] = @to@(value0 *
- @from@(data1[@i@]) +
- @from@(data_out[@i@]));
-/**end repeat2**/
- case 0:
- return;
- }
-
-#if EINSUM_USE_SSE1 && @float32@
- value0_sse = _mm_set_ps1(value0);
-
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data1) && EINSUM_IS_SSE_ALIGNED(data_out)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-/**begin repeat2
- * #i = 0, 4#
- */
- a = _mm_mul_ps(value0_sse, _mm_load_ps(data1+@i@));
- b = _mm_add_ps(a, _mm_load_ps(data_out+@i@));
- _mm_store_ps(data_out+@i@, b);
-/**end repeat2**/
- data1 += 8;
- data_out += 8;
- }
-
- /* Finish off the loop */
- if (count > 0) {
- goto finish_after_unrolled_loop;
- }
- else {
- return;
- }
- }
-#elif EINSUM_USE_SSE2 && @float64@
- value0_sse = _mm_set1_pd(value0);
-
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data1) && EINSUM_IS_SSE_ALIGNED(data_out)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- a = _mm_mul_pd(value0_sse, _mm_load_pd(data1+@i@));
- b = _mm_add_pd(a, _mm_load_pd(data_out+@i@));
- _mm_store_pd(data_out+@i@, b);
-/**end repeat2**/
- data1 += 8;
- data_out += 8;
- }
-
- /* Finish off the loop */
- if (count > 0) {
- goto finish_after_unrolled_loop;
- }
- else {
- return;
- }
- }
-#endif
-
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-#if EINSUM_USE_SSE1 && @float32@
-/**begin repeat2
- * #i = 0, 4#
- */
- a = _mm_mul_ps(value0_sse, _mm_loadu_ps(data1+@i@));
- b = _mm_add_ps(a, _mm_loadu_ps(data_out+@i@));
- _mm_storeu_ps(data_out+@i@, b);
-/**end repeat2**/
-#elif EINSUM_USE_SSE2 && @float64@
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- a = _mm_mul_pd(value0_sse, _mm_loadu_pd(data1+@i@));
- b = _mm_add_pd(a, _mm_loadu_pd(data_out+@i@));
- _mm_storeu_pd(data_out+@i@, b);
-/**end repeat2**/
-#else
-/**begin repeat2
- * #i = 0, 1, 2, 3, 4, 5, 6, 7#
- */
- data_out[@i@] = @to@(value0 *
- @from@(data1[@i@]) +
- @from@(data_out[@i@]));
-/**end repeat2**/
-#endif
- data1 += 8;
- data_out += 8;
- }
-
- /* Finish off the loop */
- if (count > 0) {
- goto finish_after_unrolled_loop;
- }
+ @name@_sum_of_products_muladd(data1, data_out, value0, count);
+
}
static void
@name@_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
- @type@ *data0 = (@type@ *)dataptr[0];
@temptype@ value1 = @from@(*(@type@ *)dataptr[1]);
+ @type@ *data0 = (@type@ *)dataptr[0];
@type@ *data_out = (@type@ *)dataptr[2];
-#if EINSUM_USE_SSE1 && @float32@
- __m128 a, b, value1_sse;
-#elif EINSUM_USE_SSE2 && @float64@
- __m128d a, b, value1_sse;
-#endif
-
NPY_EINSUM_DBG_PRINT1("@name@_sum_of_products_contig_stride0_outcontig_two (%d)\n",
(int)count);
-
-/* This is placed before the main loop to make small counts faster */
-finish_after_unrolled_loop:
- switch (count) {
-/**begin repeat2
- * #i = 6, 5, 4, 3, 2, 1, 0#
- */
- case @i@+1:
- data_out[@i@] = @to@(@from@(data0[@i@])*
- value1 +
- @from@(data_out[@i@]));
-/**end repeat2**/
- case 0:
- return;
- }
-
-#if EINSUM_USE_SSE1 && @float32@
- value1_sse = _mm_set_ps1(value1);
-
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data0) && EINSUM_IS_SSE_ALIGNED(data_out)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-/**begin repeat2
- * #i = 0, 4#
- */
- a = _mm_mul_ps(_mm_load_ps(data0+@i@), value1_sse);
- b = _mm_add_ps(a, _mm_load_ps(data_out+@i@));
- _mm_store_ps(data_out+@i@, b);
-/**end repeat2**/
- data0 += 8;
- data_out += 8;
- }
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
- }
-#elif EINSUM_USE_SSE2 && @float64@
- value1_sse = _mm_set1_pd(value1);
-
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data0) && EINSUM_IS_SSE_ALIGNED(data_out)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- a = _mm_mul_pd(_mm_load_pd(data0+@i@), value1_sse);
- b = _mm_add_pd(a, _mm_load_pd(data_out+@i@));
- _mm_store_pd(data_out+@i@, b);
-/**end repeat2**/
- data0 += 8;
- data_out += 8;
- }
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
- }
-#endif
-
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-#if EINSUM_USE_SSE1 && @float32@
-/**begin repeat2
- * #i = 0, 4#
- */
- a = _mm_mul_ps(_mm_loadu_ps(data0+@i@), value1_sse);
- b = _mm_add_ps(a, _mm_loadu_ps(data_out+@i@));
- _mm_storeu_ps(data_out+@i@, b);
-/**end repeat2**/
-#elif EINSUM_USE_SSE2 && @float64@
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- a = _mm_mul_pd(_mm_loadu_pd(data0+@i@), value1_sse);
- b = _mm_add_pd(a, _mm_loadu_pd(data_out+@i@));
- _mm_storeu_pd(data_out+@i@, b);
-/**end repeat2**/
-#else
-/**begin repeat2
- * #i = 0, 1, 2, 3, 4, 5, 6, 7#
- */
- data_out[@i@] = @to@(@from@(data0[@i@])*
- value1 +
- @from@(data_out[@i@]));
-/**end repeat2**/
-#endif
- data0 += 8;
- data_out += 8;
- }
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
+ @name@_sum_of_products_muladd(data0, data_out, value1, count);
}
static NPY_GCC_OPT_3 void
diff --git a/numpy/core/src/multiarray/mapping.c b/numpy/core/src/multiarray/mapping.c
index d64962f87..8b9b67387 100644
--- a/numpy/core/src/multiarray/mapping.c
+++ b/numpy/core/src/multiarray/mapping.c
@@ -2328,7 +2328,7 @@ PyArray_MapIterNext(PyArrayMapIterObject *mit)
* @param Number of indices
* @param The array that is being iterated
*
- * @return 0 on success -1 on failure
+ * @return 0 on success -1 on failure (broadcasting or too many fancy indices)
*/
static int
mapiter_fill_info(PyArrayMapIterObject *mit, npy_index_info *indices,
@@ -2369,6 +2369,17 @@ mapiter_fill_info(PyArrayMapIterObject *mit, npy_index_info *indices,
}
}
+ /* Before contunuing, ensure that there are not too fancy indices */
+ if (indices[i].type & HAS_FANCY) {
+ if (NPY_UNLIKELY(j >= NPY_MAXDIMS)) {
+ PyErr_Format(PyExc_IndexError,
+ "too many advanced (array) indices. This probably "
+ "means you are indexing with too many booleans. "
+ "(more than %d found)", NPY_MAXDIMS);
+ return -1;
+ }
+ }
+
/* (iterating) fancy index, store the iterator */
if (indices[i].type == HAS_FANCY) {
mit->fancy_strides[j] = PyArray_STRIDE(arr, curr_dim);
@@ -2655,6 +2666,7 @@ PyArray_MapIterNew(npy_index_info *indices , int index_num, int index_type,
/* For shape reporting on error */
PyArrayObject *original_extra_op = extra_op;
+ /* NOTE: MAXARGS is the actual limit (2*NPY_MAXDIMS is index number one) */
PyArrayObject *index_arrays[NPY_MAXDIMS];
PyArray_Descr *intp_descr;
PyArray_Descr *dtypes[NPY_MAXDIMS]; /* borrowed references */
diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c
index 8bcf591a2..04ce53ed7 100644
--- a/numpy/core/src/multiarray/methods.c
+++ b/numpy/core/src/multiarray/methods.c
@@ -2289,7 +2289,7 @@ array_dot(PyArrayObject *self, PyObject *args, PyObject *kwds)
{
PyObject *a = (PyObject *)self, *b, *o = NULL;
PyArrayObject *ret;
- char* kwlist[] = {"b", "out", NULL };
+ static char* kwlist[] = {"b", "out", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:dot", kwlist, &b, &o)) {
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index dfd27a0bc..2c00c498b 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -2319,7 +2319,7 @@ array_matrixproduct(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject* kwds)
{
PyObject *v, *a, *o = NULL;
PyArrayObject *ret;
- char* kwlist[] = {"a", "b", "out", NULL };
+ static char* kwlist[] = {"a", "b", "out", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O:matrixproduct",
kwlist, &a, &v, &o)) {
diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src
index e480628e7..10f304fe7 100644
--- a/numpy/core/src/multiarray/scalartypes.c.src
+++ b/numpy/core/src/multiarray/scalartypes.c.src
@@ -2711,7 +2711,7 @@ static PyObject *
/* TODO: include type name in error message, which is not @name@ */
PyObject *obj = NULL;
- char *kwnames[] = {"", NULL}; /* positional-only */
+ static char *kwnames[] = {"", NULL}; /* positional-only */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
return NULL;
}
@@ -2799,7 +2799,7 @@ static PyObject *
object_arrtype_new(PyTypeObject *NPY_UNUSED(type), PyObject *args, PyObject *kwds)
{
PyObject *obj = Py_None;
- char *kwnames[] = {"", NULL}; /* positional-only */
+ static char *kwnames[] = {"", NULL}; /* positional-only */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:object_", kwnames, &obj)) {
return NULL;
}
@@ -2825,7 +2825,7 @@ static PyObject *
PyObject *obj = NULL, *meta_obj = NULL;
Py@Name@ScalarObject *ret;
- char *kwnames[] = {"", "", NULL}; /* positional-only */
+ static char *kwnames[] = {"", "", NULL}; /* positional-only */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwnames, &obj, &meta_obj)) {
return NULL;
}
@@ -2884,7 +2884,7 @@ bool_arrtype_new(PyTypeObject *NPY_UNUSED(type), PyObject *args, PyObject *kwds)
PyObject *obj = NULL;
PyArrayObject *arr;
- char *kwnames[] = {"", NULL}; /* positional-only */
+ static char *kwnames[] = {"", NULL}; /* positional-only */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:bool_", kwnames, &obj)) {
return NULL;
}
@@ -2995,7 +2995,7 @@ void_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
PyObject *obj, *arr;
PyObject *new = NULL;
- char *kwnames[] = {"", NULL}; /* positional-only */
+ static char *kwnames[] = {"", NULL}; /* positional-only */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:void", kwnames, &obj)) {
return NULL;
}
diff --git a/numpy/core/src/multiarray/usertypes.c b/numpy/core/src/multiarray/usertypes.c
index a1ed46f13..15d46800c 100644
--- a/numpy/core/src/multiarray/usertypes.c
+++ b/numpy/core/src/multiarray/usertypes.c
@@ -235,7 +235,7 @@ PyArray_RegisterDataType(PyArray_Descr *descr)
!PyDict_CheckExact(descr->fields)) {
PyErr_Format(PyExc_ValueError,
"Failed to register dtype for %S: Legacy user dtypes "
- "using `NPY_ITEM_IS_POINTER` or `NPY_ITEM_REFCOUNT` are"
+ "using `NPY_ITEM_IS_POINTER` or `NPY_ITEM_REFCOUNT` are "
"unsupported. It is possible to create such a dtype only "
"if it is a structured dtype with names and fields "
"hardcoded at registration time.\n"
diff --git a/numpy/core/src/umath/ufunc_type_resolution.c b/numpy/core/src/umath/ufunc_type_resolution.c
index be48be079..c46346118 100644
--- a/numpy/core/src/umath/ufunc_type_resolution.c
+++ b/numpy/core/src/umath/ufunc_type_resolution.c
@@ -111,14 +111,18 @@ raise_no_loop_found_error(
return -1;
}
for (i = 0; i < ufunc->nargs; ++i) {
- Py_INCREF(dtypes[i]);
- PyTuple_SET_ITEM(dtypes_tup, i, (PyObject *)dtypes[i]);
+ PyObject *tmp = Py_None;
+ if (dtypes[i] != NULL) {
+ tmp = (PyObject *)dtypes[i];
+ }
+ Py_INCREF(tmp);
+ PyTuple_SET_ITEM(dtypes_tup, i, tmp);
}
/* produce an error object */
exc_value = PyTuple_Pack(2, ufunc, dtypes_tup);
Py_DECREF(dtypes_tup);
- if (exc_value == NULL){
+ if (exc_value == NULL) {
return -1;
}
PyErr_SetObject(exc_type, exc_value);
@@ -329,10 +333,23 @@ PyUFunc_SimpleBinaryComparisonTypeResolver(PyUFuncObject *ufunc,
}
if (type_tup == NULL) {
- /* Input types are the result type */
- out_dtypes[0] = PyArray_ResultType(2, operands, 0, NULL);
- if (out_dtypes[0] == NULL) {
- return -1;
+ /*
+ * DEPRECATED NumPy 1.20, 2020-12.
+ * This check is required to avoid the FutureWarning that
+ * ResultType will give for number->string promotions.
+ * (We never supported flexible dtypes here.)
+ */
+ if (!PyArray_ISFLEXIBLE(operands[0]) &&
+ !PyArray_ISFLEXIBLE(operands[1])) {
+ out_dtypes[0] = PyArray_ResultType(2, operands, 0, NULL);
+ if (out_dtypes[0] == NULL) {
+ return -1;
+ }
+ }
+ else {
+ /* Not doing anything will lead to a loop no found error. */
+ out_dtypes[0] = PyArray_DESCR(operands[0]);
+ Py_INCREF(out_dtypes[0]);
}
out_dtypes[1] = out_dtypes[0];
Py_INCREF(out_dtypes[1]);
@@ -488,6 +505,30 @@ PyUFunc_SimpleUniformOperationTypeResolver(
out_dtypes[0] = ensure_dtype_nbo(PyArray_DESCR(operands[0]));
}
else {
+ int iop;
+ npy_bool has_flexible = 0;
+ npy_bool has_object = 0;
+ for (iop = 0; iop < ufunc->nin; iop++) {
+ if (PyArray_ISOBJECT(operands[iop])) {
+ has_object = 1;
+ }
+ if (PyArray_ISFLEXIBLE(operands[iop])) {
+ has_flexible = 1;
+ }
+ }
+ if (NPY_UNLIKELY(has_flexible && !has_object)) {
+ /*
+ * DEPRECATED NumPy 1.20, 2020-12.
+ * This check is required to avoid the FutureWarning that
+ * ResultType will give for number->string promotions.
+ * (We never supported flexible dtypes here.)
+ */
+ for (iop = 0; iop < ufunc->nin; iop++) {
+ out_dtypes[iop] = PyArray_DESCR(operands[iop]);
+ Py_INCREF(out_dtypes[iop]);
+ }
+ return raise_no_loop_found_error(ufunc, out_dtypes);
+ }
out_dtypes[0] = PyArray_ResultType(ufunc->nin, operands, 0, NULL);
}
if (out_dtypes[0] == NULL) {
diff --git a/numpy/core/tests/test_array_coercion.py b/numpy/core/tests/test_array_coercion.py
index 08b32dfcc..45c792ad2 100644
--- a/numpy/core/tests/test_array_coercion.py
+++ b/numpy/core/tests/test_array_coercion.py
@@ -234,6 +234,7 @@ class TestScalarDiscovery:
# Additionally to string this test also runs into a corner case
# with datetime promotion (the difference is the promotion order).
+ @pytest.mark.filterwarnings("ignore:Promotion of numbers:FutureWarning")
def test_scalar_promotion(self):
for sc1, sc2 in product(scalar_instances(), scalar_instances()):
sc1, sc2 = sc1.values[0], sc2.values[0]
@@ -702,17 +703,19 @@ class TestArrayLikes:
@pytest.mark.parametrize("attribute",
["__array_interface__", "__array__", "__array_struct__"])
- def test_bad_array_like_attributes(self, attribute):
- # Check that errors during attribute retrieval are raised unless
- # they are Attribute errors.
+ @pytest.mark.parametrize("error", [RecursionError, MemoryError])
+ def test_bad_array_like_attributes(self, attribute, error):
+ # RecursionError and MemoryError are considered fatal. All errors
+ # (except AttributeError) should probably be raised in the future,
+ # but shapely made use of it, so it will require a deprecation.
class BadInterface:
def __getattr__(self, attr):
if attr == attribute:
- raise RuntimeError
+ raise error
super().__getattr__(attr)
- with pytest.raises(RuntimeError):
+ with pytest.raises(error):
np.array(BadInterface())
@pytest.mark.parametrize("error", [RecursionError, MemoryError])
diff --git a/numpy/core/tests/test_arrayprint.py b/numpy/core/tests/test_arrayprint.py
index a2703d81b..2c5f1577d 100644
--- a/numpy/core/tests/test_arrayprint.py
+++ b/numpy/core/tests/test_arrayprint.py
@@ -923,6 +923,9 @@ class TestPrintOptions:
assert_raises(TypeError, np.set_printoptions, threshold='1')
assert_raises(TypeError, np.set_printoptions, threshold=b'1')
+ assert_raises(TypeError, np.set_printoptions, precision='1')
+ assert_raises(TypeError, np.set_printoptions, precision=1.5)
+
def test_unicode_object_array():
expected = "array(['é'], dtype=object)"
x = np.array([u'\xe9'], dtype=object)
diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py
index 5498e1cf9..459a89eaa 100644
--- a/numpy/core/tests/test_deprecations.py
+++ b/numpy/core/tests/test_deprecations.py
@@ -687,16 +687,16 @@ class TestDeprecatedGlobals(_DeprecationTestCase):
reason='module-level __getattr__ not supported')
def test_type_aliases(self):
# from builtins
- self.assert_deprecated(lambda: np.bool)
- self.assert_deprecated(lambda: np.int)
- self.assert_deprecated(lambda: np.float)
- self.assert_deprecated(lambda: np.complex)
- self.assert_deprecated(lambda: np.object)
- self.assert_deprecated(lambda: np.str)
+ self.assert_deprecated(lambda: np.bool(True))
+ self.assert_deprecated(lambda: np.int(1))
+ self.assert_deprecated(lambda: np.float(1))
+ self.assert_deprecated(lambda: np.complex(1))
+ self.assert_deprecated(lambda: np.object())
+ self.assert_deprecated(lambda: np.str('abc'))
# from np.compat
- self.assert_deprecated(lambda: np.long)
- self.assert_deprecated(lambda: np.unicode)
+ self.assert_deprecated(lambda: np.long(1))
+ self.assert_deprecated(lambda: np.unicode('abc'))
class TestMatrixInOuter(_DeprecationTestCase):
@@ -1100,3 +1100,41 @@ class TestNoseDecoratorsDeprecated(_DeprecationTestCase):
count += 1
assert_(count == 3)
self.assert_deprecated(_test_parametrize)
+
+
+class TestStringPromotion(_DeprecationTestCase):
+ # Deprecated 2020-12-19, NumPy 1.21
+ warning_cls = FutureWarning
+ message = "Promotion of numbers and bools to strings is deprecated."
+
+ @pytest.mark.parametrize("dtype", "?bhilqpBHILQPefdgFDG")
+ @pytest.mark.parametrize("string_dt", ["S", "U"])
+ def test_deprecated(self, dtype, string_dt):
+ self.assert_deprecated(lambda: np.promote_types(dtype, string_dt))
+
+ # concatenate has to be able to promote to find the result dtype:
+ arr1 = np.ones(3, dtype=dtype)
+ arr2 = np.ones(3, dtype=string_dt)
+ self.assert_deprecated(lambda: np.concatenate((arr1, arr2), axis=0))
+ self.assert_deprecated(lambda: np.concatenate((arr1, arr2), axis=None))
+
+ # coercing to an array is similar, but will fall-back to `object`
+ # (when raising the FutureWarning, this already happens)
+ self.assert_deprecated(lambda: np.array([arr1[0], arr2[0]]),
+ exceptions=())
+
+ @pytest.mark.parametrize("dtype", "?bhilqpBHILQPefdgFDG")
+ @pytest.mark.parametrize("string_dt", ["S", "U"])
+ def test_not_deprecated(self, dtype, string_dt):
+ # The ufunc type resolvers run into this, but giving a futurewarning
+ # here is unnecessary (it ends up as an error anyway), so test that
+ # no warning is given:
+ arr1 = np.ones(3, dtype=dtype)
+ arr2 = np.ones(3, dtype=string_dt)
+
+ # Adding two arrays uses result_type normally, which would fail:
+ with pytest.raises(TypeError):
+ self.assert_not_deprecated(lambda: arr1 + arr2)
+ # np.equal uses a different type resolver:
+ with pytest.raises(TypeError):
+ self.assert_not_deprecated(lambda: np.equal(arr1, arr2))
diff --git a/numpy/core/tests/test_half.py b/numpy/core/tests/test_half.py
index 1b6fd21e1..449a01d21 100644
--- a/numpy/core/tests/test_half.py
+++ b/numpy/core/tests/test_half.py
@@ -71,8 +71,10 @@ class TestHalf:
def test_half_conversion_to_string(self, string_dt):
# Currently uses S/U32 (which is sufficient for float32)
expected_dt = np.dtype(f"{string_dt}32")
- assert np.promote_types(np.float16, string_dt) == expected_dt
- assert np.promote_types(string_dt, np.float16) == expected_dt
+ with pytest.warns(FutureWarning):
+ assert np.promote_types(np.float16, string_dt) == expected_dt
+ with pytest.warns(FutureWarning):
+ assert np.promote_types(string_dt, np.float16) == expected_dt
arr = np.ones(3, dtype=np.float16).astype(string_dt)
assert arr.dtype == expected_dt
diff --git a/numpy/core/tests/test_indexing.py b/numpy/core/tests/test_indexing.py
index 667c49240..73dbc429c 100644
--- a/numpy/core/tests/test_indexing.py
+++ b/numpy/core/tests/test_indexing.py
@@ -3,6 +3,8 @@ import warnings
import functools
import operator
+import pytest
+
import numpy as np
from numpy.core._multiarray_tests import array_indexing
from itertools import product
@@ -547,6 +549,21 @@ class TestIndexing:
assert_array_equal(arr[0], np.array("asdfg", dtype="c"))
assert arr[0, 1] == b"s" # make sure not all were set to "a" for both
+ @pytest.mark.parametrize("index",
+ [True, False, np.array([0])])
+ @pytest.mark.parametrize("num", [32, 40])
+ @pytest.mark.parametrize("original_ndim", [1, 32])
+ def test_too_many_advanced_indices(self, index, num, original_ndim):
+ # These are limitations based on the number of arguments we can process.
+ # For `num=32` (and all boolean cases), the result is actually define;
+ # but the use of NpyIter (NPY_MAXARGS) limits it for technical reasons.
+ arr = np.ones((1,) * original_ndim)
+ with pytest.raises(IndexError):
+ arr[(index,) * num]
+ with pytest.raises(IndexError):
+ arr[(index,) * num] = 1.
+
+
class TestFieldIndexing:
def test_scalar_return_type(self):
# Field access on an array should return an array, even if it
diff --git a/numpy/core/tests/test_nditer.py b/numpy/core/tests/test_nditer.py
index 5e6472ae5..94f61baca 100644
--- a/numpy/core/tests/test_nditer.py
+++ b/numpy/core/tests/test_nditer.py
@@ -1365,6 +1365,7 @@ def test_iter_copy():
@pytest.mark.parametrize("dtype", np.typecodes["All"])
@pytest.mark.parametrize("loop_dtype", np.typecodes["All"])
+@pytest.mark.filterwarnings("ignore::numpy.ComplexWarning")
def test_iter_copy_casts(dtype, loop_dtype):
# Ensure the dtype is never flexible:
if loop_dtype.lower() == "m":
diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py
index 6de9e3764..cdfecc0f5 100644
--- a/numpy/core/tests/test_numeric.py
+++ b/numpy/core/tests/test_numeric.py
@@ -847,10 +847,12 @@ class TestTypes:
assert_equal(np.promote_types('<i8', '<i8'), np.dtype('i8'))
assert_equal(np.promote_types('>i8', '>i8'), np.dtype('i8'))
- assert_equal(np.promote_types('>i8', '>U16'), np.dtype('U21'))
- assert_equal(np.promote_types('<i8', '<U16'), np.dtype('U21'))
- assert_equal(np.promote_types('>U16', '>i8'), np.dtype('U21'))
- assert_equal(np.promote_types('<U16', '<i8'), np.dtype('U21'))
+ with pytest.warns(FutureWarning,
+ match="Promotion of numbers and bools to strings"):
+ assert_equal(np.promote_types('>i8', '>U16'), np.dtype('U21'))
+ assert_equal(np.promote_types('<i8', '<U16'), np.dtype('U21'))
+ assert_equal(np.promote_types('>U16', '>i8'), np.dtype('U21'))
+ assert_equal(np.promote_types('<U16', '<i8'), np.dtype('U21'))
assert_equal(np.promote_types('<S5', '<U8'), np.dtype('U8'))
assert_equal(np.promote_types('>S5', '>U8'), np.dtype('U8'))
@@ -897,32 +899,38 @@ class TestTypes:
promote_types = np.promote_types
S = string_dtype
- # Promote numeric with unsized string:
- assert_equal(promote_types('bool', S), np.dtype(S+'5'))
- assert_equal(promote_types('b', S), np.dtype(S+'4'))
- assert_equal(promote_types('u1', S), np.dtype(S+'3'))
- assert_equal(promote_types('u2', S), np.dtype(S+'5'))
- assert_equal(promote_types('u4', S), np.dtype(S+'10'))
- assert_equal(promote_types('u8', S), np.dtype(S+'20'))
- assert_equal(promote_types('i1', S), np.dtype(S+'4'))
- assert_equal(promote_types('i2', S), np.dtype(S+'6'))
- assert_equal(promote_types('i4', S), np.dtype(S+'11'))
- assert_equal(promote_types('i8', S), np.dtype(S+'21'))
- # Promote numeric with sized string:
- assert_equal(promote_types('bool', S+'1'), np.dtype(S+'5'))
- assert_equal(promote_types('bool', S+'30'), np.dtype(S+'30'))
- assert_equal(promote_types('b', S+'1'), np.dtype(S+'4'))
- assert_equal(promote_types('b', S+'30'), np.dtype(S+'30'))
- assert_equal(promote_types('u1', S+'1'), np.dtype(S+'3'))
- assert_equal(promote_types('u1', S+'30'), np.dtype(S+'30'))
- assert_equal(promote_types('u2', S+'1'), np.dtype(S+'5'))
- assert_equal(promote_types('u2', S+'30'), np.dtype(S+'30'))
- assert_equal(promote_types('u4', S+'1'), np.dtype(S+'10'))
- assert_equal(promote_types('u4', S+'30'), np.dtype(S+'30'))
- assert_equal(promote_types('u8', S+'1'), np.dtype(S+'20'))
- assert_equal(promote_types('u8', S+'30'), np.dtype(S+'30'))
- # Promote with object:
- assert_equal(promote_types('O', S+'30'), np.dtype('O'))
+
+ with pytest.warns(FutureWarning,
+ match="Promotion of numbers and bools to strings") as record:
+ # Promote numeric with unsized string:
+ assert_equal(promote_types('bool', S), np.dtype(S+'5'))
+ assert_equal(promote_types('b', S), np.dtype(S+'4'))
+ assert_equal(promote_types('u1', S), np.dtype(S+'3'))
+ assert_equal(promote_types('u2', S), np.dtype(S+'5'))
+ assert_equal(promote_types('u4', S), np.dtype(S+'10'))
+ assert_equal(promote_types('u8', S), np.dtype(S+'20'))
+ assert_equal(promote_types('i1', S), np.dtype(S+'4'))
+ assert_equal(promote_types('i2', S), np.dtype(S+'6'))
+ assert_equal(promote_types('i4', S), np.dtype(S+'11'))
+ assert_equal(promote_types('i8', S), np.dtype(S+'21'))
+ # Promote numeric with sized string:
+ assert_equal(promote_types('bool', S+'1'), np.dtype(S+'5'))
+ assert_equal(promote_types('bool', S+'30'), np.dtype(S+'30'))
+ assert_equal(promote_types('b', S+'1'), np.dtype(S+'4'))
+ assert_equal(promote_types('b', S+'30'), np.dtype(S+'30'))
+ assert_equal(promote_types('u1', S+'1'), np.dtype(S+'3'))
+ assert_equal(promote_types('u1', S+'30'), np.dtype(S+'30'))
+ assert_equal(promote_types('u2', S+'1'), np.dtype(S+'5'))
+ assert_equal(promote_types('u2', S+'30'), np.dtype(S+'30'))
+ assert_equal(promote_types('u4', S+'1'), np.dtype(S+'10'))
+ assert_equal(promote_types('u4', S+'30'), np.dtype(S+'30'))
+ assert_equal(promote_types('u8', S+'1'), np.dtype(S+'20'))
+ assert_equal(promote_types('u8', S+'30'), np.dtype(S+'30'))
+ # Promote with object:
+ assert_equal(promote_types('O', S+'30'), np.dtype('O'))
+
+ assert len(record) == 22 # each string promotion gave one warning
+
@pytest.mark.parametrize(["dtype1", "dtype2"],
[[np.dtype("V6"), np.dtype("V10")],
@@ -972,6 +980,7 @@ class TestTypes:
assert res.isnative
@pytest.mark.slow
+ @pytest.mark.filterwarnings('ignore:Promotion of numbers:FutureWarning')
@pytest.mark.parametrize(["dtype1", "dtype2"],
itertools.product(
list(np.typecodes["All"]) +
diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py
index 831e48e8b..5faa9923c 100644
--- a/numpy/core/tests/test_regression.py
+++ b/numpy/core/tests/test_regression.py
@@ -782,7 +782,9 @@ class TestRegression:
# Ticket #514
s = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
t = []
- np.hstack((t, s))
+ with pytest.warns(FutureWarning,
+ match="Promotion of numbers and bools to strings"):
+ np.hstack((t, s))
def test_arr_transpose(self):
# Ticket #516
diff --git a/numpy/core/tests/test_shape_base.py b/numpy/core/tests/test_shape_base.py
index 9922c9173..a0c72f9d0 100644
--- a/numpy/core/tests/test_shape_base.py
+++ b/numpy/core/tests/test_shape_base.py
@@ -256,7 +256,7 @@ class TestConcatenate:
r = np.concatenate((a, b), axis=None)
assert_equal(r.size, a.size + len(b))
assert_equal(r.dtype, a.dtype)
- r = np.concatenate((a, b, c), axis=None)
+ r = np.concatenate((a, b, c), axis=None, dtype="U")
d = array(['0.0', '1.0', '2.0', '3.0',
'0', '1', '2', 'x'])
assert_array_equal(r, d)
@@ -377,7 +377,8 @@ class TestConcatenate:
# Note that U0 and S0 should be deprecated eventually and changed to
# actually give the empty string result (together with `np.array`)
res = np.concatenate(arrs, axis=axis, dtype=string_dt, casting="unsafe")
- assert res.dtype == np.promote_types("d", string_dt)
+ # The actual dtype should be identical to a cast (of a double array):
+ assert res.dtype == np.array(1.).astype(string_dt).dtype
@pytest.mark.parametrize("axis", [None, 0])
def test_string_dtype_does_not_inspect(self, axis):
diff --git a/numpy/core/tests/test_simd.py b/numpy/core/tests/test_simd.py
index 23a5bb6c3..1d1a111be 100644
--- a/numpy/core/tests/test_simd.py
+++ b/numpy/core/tests/test_simd.py
@@ -736,11 +736,9 @@ class _SIMD_ALL(_Test_Utility):
def test_arithmetic_reduce_sum(self):
"""
Test reduce sum intrinics:
- npyv_sum_u32
- npyv_sum_f32
- npyv_sum_f64
+ npyv_sum_##sfx
"""
- if self.sfx not in ("u32", "f32", "f64"):
+ if self.sfx not in ("u32", "u64", "f32", "f64"):
return
# reduce sum
data = self._data()
@@ -750,6 +748,21 @@ class _SIMD_ALL(_Test_Utility):
vsum = self.sum(vdata)
assert vsum == data_sum
+ def test_arithmetic_reduce_sumup(self):
+ """
+ Test extend reduce sum intrinics:
+ npyv_sumup_##sfx
+ """
+ if self.sfx not in ("u8", "u16"):
+ return
+ rdata = (0, self.nlanes, self._int_min(), self._int_max()-self.nlanes)
+ for r in rdata:
+ data = self._data(r)
+ vdata = self.load(data)
+ data_sum = sum(data)
+ vsum = self.sumup(vdata)
+ assert vsum == data_sum
+
def test_mask_conditional(self):
"""
Conditional addition and subtraction for all supported data types.