MCPcopy Create free account
hub / github.com/numpy/numpy / promote_and_get_info_and_ufuncimpl

Function promote_and_get_info_and_ufuncimpl

numpy/core/src/umath/dispatching.c:729–861  ·  view source on GitHub ↗

* The main implementation to find the correct DType signature and ArrayMethod * to use for a ufunc. This function may recurse with `do_legacy_fallback` * set to False. * * If value-based promotion is necessary, this is handled ahead of time by * `promote_and_get_ufuncimpl`. */

Source from the content-addressed store, hash-verified

727 * `promote_and_get_ufuncimpl`.
728 */
729static inline PyObject *
730promote_and_get_info_and_ufuncimpl(PyUFuncObject *ufunc,
731 PyArrayObject *const ops[],
732 PyArray_DTypeMeta *signature[],
733 PyArray_DTypeMeta *op_dtypes[],
734 npy_bool allow_legacy_promotion)
735{
736 /*
737 * Fetch the dispatching info which consists of the implementation and
738 * the DType signature tuple. There are three steps:
739 *
740 * 1. Check the cache.
741 * 2. Check all registered loops/promoters to find the best match.
742 * 3. Fall back to the legacy implementation if no match was found.
743 */
744 PyObject *info = PyArrayIdentityHash_GetItem(ufunc->_dispatch_cache,
745 (PyObject **)op_dtypes);
746 if (info != NULL && PyObject_TypeCheck(
747 PyTuple_GET_ITEM(info, 1), &PyArrayMethod_Type)) {
748 /* Found the ArrayMethod and NOT a promoter: return it */
749 return info;
750 }
751
752 /*
753 * If `info == NULL`, loading from cache failed, use the full resolution
754 * in `resolve_implementation_info` (which caches its result on success).
755 */
756 if (info == NULL) {
757 if (resolve_implementation_info(ufunc,
758 op_dtypes, NPY_FALSE, &info) < 0) {
759 return NULL;
760 }
761 if (info != NULL && PyObject_TypeCheck(
762 PyTuple_GET_ITEM(info, 1), &PyArrayMethod_Type)) {
763 /*
764 * Found the ArrayMethod and NOT promoter. Before returning it
765 * add it to the cache for faster lookup in the future.
766 */
767 if (PyArrayIdentityHash_SetItem(ufunc->_dispatch_cache,
768 (PyObject **)op_dtypes, info, 0) < 0) {
769 return NULL;
770 }
771 return info;
772 }
773 }
774
775 /*
776 * At this point `info` is NULL if there is no matching loop, or it is
777 * a promoter that needs to be used/called:
778 */
779 if (info != NULL) {
780 PyObject *promoter = PyTuple_GET_ITEM(info, 1);
781
782 info = call_promoter_and_recurse(ufunc,
783 promoter, op_dtypes, signature, ops);
784 if (info == NULL && PyErr_Occurred()) {
785 return NULL;
786 }

Callers 2

Tested by

no test coverage detected