Thanks to visit codestin.com
Credit goes to github.com

Skip to content

DEP: deprecate np.set_numeric_ops and friends #11916

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 10, 2018

Conversation

mattip
Copy link
Member

@mattip mattip commented Sep 9, 2018

The third part of NEP 15. Deprecate np.set_numeric_ops, PyArray_SetNumericOps, PyArray_GetNumericOps.

The second part, "we should use some new, private API to set up ndarray.__add__ and friends" is still TBD.

@mattip
Copy link
Member Author

mattip commented Sep 9, 2018

Codecov failures since newly deprecated PyArray_GetNumericOps is not tested.

@mattip
Copy link
Member Author

mattip commented Sep 17, 2018

I think codecov is comparing this pr to some other base changeset. The diff is showing changes I did not make to distutils and random.

@tylerjereddy
Copy link
Contributor

Your link is for "changes," not the actual diff, which correctly shows which lines in this PR are not covered. I tend to ignore the "changes" tab, as previously discussed elsewhere.

@mattip mattip force-pushed the deprecate-set_numeric_ops branch from 53613cf to e6b3911 Compare September 21, 2018 10:15
@mattip
Copy link
Member Author

mattip commented Sep 21, 2018

rebased and deprecation test added to help code coverage

@mattip mattip closed this Sep 22, 2018
@mattip mattip reopened this Sep 22, 2018
@mattip
Copy link
Member Author

mattip commented Sep 22, 2018

Closed/reopened to restart crashed appveyor tests

@mattip
Copy link
Member Author

mattip commented Sep 22, 2018

Should squash before merging

eric-wieser
eric-wieser previously approved these changes Sep 22, 2018
@mattip mattip force-pushed the deprecate-set_numeric_ops branch from dae5b0e to 823ed3e Compare September 23, 2018 04:41
@mattip
Copy link
Member Author

mattip commented Sep 23, 2018

squashed to a single commit

@@ -1537,6 +1537,10 @@ def luf(lamdaexpr, *args, **kwargs):

Set numerical operators for array objects.

.. deprecated:: 1.16

Use :c:func:`PyUFunc_ReplaceLoopBySignature` to change ufunc behaviour.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should also suggest creating a subclass with an overloaded __array_ufunc__ here, for python-only users who were replacing operators.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads badly. Maybe

        For the general case, use :c:func:`PyUFunc_ReplaceLoopBySignature`.
        For ndarray subclasses, define the ``__array_ufunc__`` method and
        override the relevant ufunc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping.

@mattip mattip force-pushed the deprecate-set_numeric_ops branch from 823ed3e to e20fd11 Compare September 25, 2018 07:19
@eric-wieser
Copy link
Member

This closes #10141, right?

@eric-wieser
Copy link
Member

It doesn't look like you added a deprecation notice to the C api docs

@eric-wieser eric-wieser dismissed their stale review September 27, 2018 06:05

Needs a C docs change too

@mattip mattip force-pushed the deprecate-set_numeric_ops branch from e20fd11 to 11fa5ca Compare September 28, 2018 13:16
@mattip
Copy link
Member Author

mattip commented Sep 28, 2018

C API deprecation added. Also added a commit to remove mention of the deprecated set_numeric_ops which closes #10141

@mattip
Copy link
Member Author

mattip commented Oct 9, 2018

ping

@mattip mattip force-pushed the deprecate-set_numeric_ops branch from 94723cb to 0a21fa2 Compare October 12, 2018 08:18
@mattip
Copy link
Member Author

mattip commented Oct 12, 2018

rebased to fix release note merge confilicts

@mattip
Copy link
Member Author

mattip commented Oct 16, 2018

ping

@eric-wieser
Copy link
Member

I feel like we have a compile-time mechanism for deprecating C Apis?

At a guess, perhaps @charris or @njsmith would know more.

@mattip
Copy link
Member Author

mattip commented Oct 16, 2018

@eric-wieser indeed I did not increment the NPY_API_VERSION for the deprecation. Fixed.

Get dictionary showing number functions that all arrays will use
*/
NPY_NO_EXPORT PyObject *
PyArray_GetNumericOps(void)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be wrapped in

#if !defined(NPY_NO_DEPRECATED_API) || \
    (NPY_NO_DEPRECATED_API < NPY_1_16_API_VERSION)

#endif

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is only for headers, to allow access to old API macros. The C files always start with this define, which will defeat the check you suggest
#define NPY_NO_DEPRECATED_API NPY_API_VERSION. NPY_API_VERSION is hard-coded from C_API_VERSION in core/setup_common.py , see core/setup.py where the magic happens.

We don't really have a way to actually remove or disable deprecated API functions, since the convention is that the PyArray_API structure built in __multiarray_api.h by core/code_generators/generate_array_api.py from the list in core.code_generators/numpy_api.py can only grow, never shrink, to allow backward compatibility.

This is somewhat talked about in the documentation from the user's perspective and in the 'VERSIONING SUPPORT' docstring in setup_common.py, but if you think of hook where I can hang more documentation let me know.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, good point.

Can we move PyArray_GetNumericOps to a macro that hides the C api macro?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could eventually turn the warning into an exception. Not sure if I understand which "C api macro" you mean, there are so many.

At some point we could remove things from the PyArray_API structure by changing our major version, which would infer no backward API compatibility.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean this macro:

#define PyArray_GetNumericOps \
        (*(PyObject * (*)(void)) \
         PyArray_API[41])

Perhaps we should leave this as an open question, and just take this PR as it currently stands

@charris
Copy link
Member

charris commented Oct 16, 2018

Not sure that we should increment the API version, the API hash remains the same and nothing has been added or removed, nor do we remove deprecated API functions -- there are a couple. So the API hasn't changed, we just recommend that some interface functions should not be used. If we want to disable the function, I don't think we have a policy for that.

@eric-wieser
Copy link
Member

nor do we remove deprecated API functions

If that's the case, why does NPY_NO_DEPRECATED_API exist?

@mattip
Copy link
Member Author

mattip commented Oct 16, 2018

Those who wish to access PyArrayObject as per pre-1.7-NumPy can set it to NPY_1_6_API_VERSION and then PyArrayObject is exposed as a full C struct.

@charris
Copy link
Member

charris commented Oct 16, 2018

Those who wish to access PyArrayObject as per pre-1.7-NumPy

Yep, there was a move to hide the structure internals behind functions so that we would be freed up to change the structures in the future, but that is incomplete and has been stalled for some time.

@mattip
Copy link
Member Author

mattip commented Oct 16, 2018

Note PR #11175 changed the size of PyUFuncObject. Since that is a publically-facing API we incremented NPY_API_VERSION even though the hash did not change.

@charris
Copy link
Member

charris commented Oct 16, 2018

But that change is not backwards compatible, i.e., code that uses the new attributes will not run on older NumPy. Is that the case for code compiled against 1.16?

@mattip mattip added this to the 1.16.0 release milestone Oct 21, 2018
@mattip mattip force-pushed the deprecate-set_numeric_ops branch from 07e9486 to 73c5a5a Compare October 21, 2018 15:28
@mattip
Copy link
Member Author

mattip commented Oct 27, 2018

The only difference in this PR is the deprecation warning that will be emitted on 1.16 if the deprecated C functions are used. Does that not justify incrementing the NPY_API_VERSION?

@eric-wieser
Copy link
Member

Those who wish to access PyArrayObject as per pre-1.7-NumPy can set it to NPY_1_6_API_VERSION and then PyArrayObject is exposed as a full C struct.

Conversely, I think that users should be able to opt into no longer having PyArray_GetNumericOps available by defining it to NPY_1_16_API_VERSION - which would indeed require an api version increment.

@njsmith
Copy link
Member

njsmith commented Oct 27, 2018

If that's the case, why does NPY_NO_DEPRECATED_API exist?

Honestly, as far as I've ever been able to figure out, there is no good reason for it to exist.

Yep, there was a move to hide the structure internals behind functions so that we would be freed up to change the structures in the future, but that is incomplete and has been stalled for some time.

It was also done incorrectly... the internals were moved from macros/direct access to inline functions, but inline functions are just like macros: they both expose the structure internals as part of the ABI. And we never had a plan for how to actually remove the old APIs. And I'm not even sure what the point is... I don't think anything on our roadmap actually benefits from hiding the internals of PyArrayObject.

Also, I'm pretty sure that all of the C compilers we support have native support for issuing deprecation warnings, so I'm not sure why we need to invent our own system?

@eric-wieser
Copy link
Member

the internals were moved from macros/direct access to inline functions

Are you sure the inline functions aren't inline only when used within multiarray? I thought I saw something like that somewhere, but perhaps I'm imagining it.

@njsmith
Copy link
Member

njsmith commented Oct 28, 2018

I see code in ndarraytypes.h to switch them between macros and inline functions depending on NPY_NO_DEPRECATED_API, but not to convert them into actual API functions? I could be missing something...

@mattip
Copy link
Member Author

mattip commented Oct 29, 2018

The code currently uses functions in the headers which will probably be inlined to be identical to the macros.

convert them into actual API functions ...

This would incur a performance penalty since the call could no longer be inlined, and would cross a shared-object border. Whether that penalty is significant or not depends on the use case. We could adopt a policy where the first call caches a C-compatible representation of the hidden, possibly non-C-representable field, and functions like reshape or resize invalidate the cache, but as you say "I don't think anything on our roadmap actually benefits from hiding the internals of PyArrayObject"

Besides the 1.7 attribute hiding API changes, we used NPY_API_VERSION for the RESOLVEWRITEBACKIFCOPY deprecations, and now for these changes.

Also, PR #12235 fixes the definition of the NPY_1_XX_API_VERSION macros, and is waiting for review

Perhaps we could merge this, and if a change to the API versioning policy is needed open a new issue for that.

@stefanv
Copy link
Contributor

stefanv commented Nov 6, 2018

This is probably good to go? It looks fairly uncontroversial.

@mattip
Copy link
Member Author

mattip commented Nov 10, 2018

reworded documentation

@charris charris merged commit d0e2f1a into numpy:master Nov 10, 2018
@charris
Copy link
Member

charris commented Nov 10, 2018

Thanks Matti.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants