* This checks whether a trivial loop is ok, * making copies of scalar and one dimensional operands if that will * help. * * Returns 1 if a trivial loop is ok, 0 if it is not, and * -1 if there is an error. */
| 1101 | * -1 if there is an error. |
| 1102 | */ |
| 1103 | static int |
| 1104 | check_for_trivial_loop(PyArrayMethodObject *ufuncimpl, |
| 1105 | PyArrayObject **op, PyArray_Descr **dtypes, |
| 1106 | NPY_CASTING casting, npy_intp buffersize) |
| 1107 | { |
| 1108 | int force_cast_input = ufuncimpl->flags & _NPY_METH_FORCE_CAST_INPUTS; |
| 1109 | int i, nin = ufuncimpl->nin, nop = nin + ufuncimpl->nout; |
| 1110 | |
| 1111 | for (i = 0; i < nop; ++i) { |
| 1112 | /* |
| 1113 | * If the dtype doesn't match, or the array isn't aligned, |
| 1114 | * indicate that the trivial loop can't be done. |
| 1115 | */ |
| 1116 | if (op[i] == NULL) { |
| 1117 | continue; |
| 1118 | } |
| 1119 | int must_copy = !PyArray_ISALIGNED(op[i]); |
| 1120 | |
| 1121 | if (dtypes[i] != PyArray_DESCR(op[i])) { |
| 1122 | npy_intp view_offset; |
| 1123 | NPY_CASTING safety = PyArray_GetCastInfo( |
| 1124 | PyArray_DESCR(op[i]), dtypes[i], NULL, &view_offset); |
| 1125 | if (safety < 0 && PyErr_Occurred()) { |
| 1126 | /* A proper error during a cast check, should be rare */ |
| 1127 | return -1; |
| 1128 | } |
| 1129 | if (view_offset != 0) { |
| 1130 | /* NOTE: Could possibly implement non-zero view offsets */ |
| 1131 | must_copy = 1; |
| 1132 | } |
| 1133 | |
| 1134 | if (force_cast_input && i < nin) { |
| 1135 | /* |
| 1136 | * ArrayMethod flagged to ignore casting (logical funcs |
| 1137 | * can force cast to bool) |
| 1138 | */ |
| 1139 | } |
| 1140 | else if (PyArray_MinCastSafety(safety, casting) != casting) { |
| 1141 | return 0; /* the cast is not safe enough */ |
| 1142 | } |
| 1143 | } |
| 1144 | if (must_copy) { |
| 1145 | /* |
| 1146 | * If op[j] is a scalar or small one dimensional |
| 1147 | * array input, make a copy to keep the opportunity |
| 1148 | * for a trivial loop. Outputs are not copied here. |
| 1149 | */ |
| 1150 | if (i < nin && (PyArray_NDIM(op[i]) == 0 |
| 1151 | || (PyArray_NDIM(op[i]) == 1 |
| 1152 | && PyArray_DIM(op[i], 0) <= buffersize))) { |
| 1153 | PyArrayObject *tmp; |
| 1154 | Py_INCREF(dtypes[i]); |
| 1155 | tmp = (PyArrayObject *)PyArray_CastToType(op[i], dtypes[i], 0); |
| 1156 | if (tmp == NULL) { |
| 1157 | return -1; |
| 1158 | } |
| 1159 | Py_DECREF(op[i]); |
| 1160 | op[i] = tmp; |
no test coverage detected