@@ -188,63 +188,60 @@ TENSOR_SCALAR_DISPATCH(less_equal_scalar, x <= ab ? 1.0 : 0.0)
188188 * that the optimizer can vectorize the elementwise mapping instead of being
189189 * blocked by an indirect call. */
190190
191- #define TENSOR_COL_DISPATCH_BODY (op ) \
192- tensor_double_view v_a; \
193- zend_long m = 0; \
194- double * owned_b = NULL; \
195- const double * vb = NULL; \
196- \
197- if (UNEXPECTED(!tensor_view_resolve_arg(a, &v_a) || \
198- !tensor_view_doubles(b, &vb, &m, &owned_b))) { \
199- return; \
200- } \
201- \
202- zend_long total = v_a.len; \
203- zend_long nHat = zephir_get_intval(n_zval); \
204- \
205- if (UNEXPECTED(nHat < 1)) { \
206- zephir_throw_exception_string(spl_ce_LengthException, \
207- SL("Matrix and vector dimensions must agree.")); \
208- if (owned_b != NULL) { efree(owned_b); } \
209- return; \
210- } \
211- \
212- zval c; \
213- \
191+ #define TENSOR_COL_DISPATCH_BODY (op ) \
192+ tensor_double_view v_a, v_b; \
193+ \
194+ if (UNEXPECTED(!tensor_view_resolve_arg(a, &v_a) || \
195+ !tensor_view_resolve_arg(b, &v_b))) { \
196+ return; \
197+ } \
198+ \
199+ zend_long m = v_b.len; \
200+ zend_long total = v_a.len; \
201+ zend_long nHat = zephir_get_intval(n_zval); \
202+ \
203+ if (UNEXPECTED(nHat < 1)) { \
204+ zephir_throw_exception_string(spl_ce_LengthException, \
205+ SL("Matrix and vector dimensions must agree.")); \
206+ return; \
207+ } \
208+ \
209+ zval c; \
210+ \
214211 if (UNEXPECTED(tensor_tensorbuffer_create(return_value, total, &c) == FAILURE)) { \
215- if (owned_b != NULL) { efree(owned_b); } \
216- return; \
217- } \
218- \
219- double * restrict vc = zephir_buffer_doubles(&c); \
220- \
221- zend_long i, j; \
222- \
223- if (v_a.contiguous) { \
224- const double * restrict va = v_a.base + v_a.offset; \
225- \
226- for (i = 0; i < m; ++i) { \
227- for (j = 0; j < nHat; ++j) { \
228- double x = va[i * nHat + j]; \
229- double y = vb[i]; \
230- vc[i * nHat + j] = op; \
231- } \
232- } \
233- } else { \
234- tensor_view_reader ra; \
235- tensor_view_reader_init(&ra, &v_a); \
236- \
237- for (i = 0; i < m; ++i) { \
238- for (j = 0; j < nHat; ++j) { \
239- double x = tensor_view_reader_value(&ra); \
240- double y = vb[i]; \
241- vc[i * nHat + j] = op; \
242- tensor_view_reader_advance(&ra); \
243- } \
244- } \
245- } \
246- \
247- if (owned_b != NULL) { efree(owned_b); } \
212+ return; \
213+ } \
214+ \
215+ double * restrict vc = zephir_buffer_doubles(&c); \
216+ \
217+ zend_long i, j; \
218+ \
219+ if (v_a.contiguous) { \
220+ const double * restrict va = v_a.base + v_a.offset; \
221+ \
222+ for (i = 0; i < m; ++i) { \
223+ double y = tensor_double_view_get(&v_b, i); \
224+ \
225+ for (j = 0; j < nHat; ++j) { \
226+ double x = va[i * nHat + j]; \
227+ vc[i * nHat + j] = op; \
228+ } \
229+ } \
230+ } else { \
231+ tensor_view_reader ra; \
232+ tensor_view_reader_init(&ra, &v_a); \
233+ \
234+ for (i = 0; i < m; ++i) { \
235+ double y = tensor_double_view_get(&v_b, i); \
236+ \
237+ for (j = 0; j < nHat; ++j) { \
238+ double x = tensor_view_reader_value(&ra); \
239+ vc[i * nHat + j] = op; \
240+ tensor_view_reader_advance(&ra); \
241+ } \
242+ } \
243+ } \
244+ \
248245 zval_ptr_dtor(&c);
249246
250247#define TENSOR_COL_DISPATCH (name , op ) \
@@ -295,65 +292,71 @@ TENSOR_COL_DISPATCH(less_equal_col_reverse, y <= x ? 1.0 : 0.0)
295292 * can vectorize the elementwise mapping instead of being blocked by an
296293 * indirect call. */
297294
298- #define TENSOR_ROW_DISPATCH_BODY (op ) \
299- tensor_double_view v_a; \
300- zend_long nb = 0; \
301- double * owned_b = NULL; \
302- const double * vb = NULL; \
303- \
304- if (UNEXPECTED(!tensor_view_resolve_arg(a, &v_a) || \
305- !tensor_view_doubles(b, &vb, &nb, &owned_b))) { \
306- return; \
307- } \
308- \
309- zend_long total = v_a.len; \
310- zend_long nHat = zephir_get_intval(n_zval); \
311- \
312- if (UNEXPECTED(nHat < 1 || total < nHat)) { \
313- zephir_throw_exception_string(spl_ce_LengthException, \
314- SL("Matrix and vector dimensions must agree.")); \
315- if (owned_b != NULL) { efree(owned_b); } \
316- return; \
317- } \
318- \
319- zend_long m = total / nHat; \
320- \
321- zval c; \
322- \
295+ #define TENSOR_ROW_DISPATCH_BODY (op ) \
296+ tensor_double_view v_a, v_b; \
297+ \
298+ if (UNEXPECTED(!tensor_view_resolve_arg(a, &v_a) || \
299+ !tensor_view_resolve_arg(b, &v_b))) { \
300+ return; \
301+ } \
302+ \
303+ zend_long total = v_a.len; \
304+ zend_long nHat = zephir_get_intval(n_zval); \
305+ \
306+ if (UNEXPECTED(nHat < 1 || total < nHat)) { \
307+ zephir_throw_exception_string(spl_ce_LengthException, \
308+ SL("Matrix and vector dimensions must agree.")); \
309+ return; \
310+ } \
311+ \
312+ zend_long m = total / nHat; \
313+ \
314+ zval c; \
315+ \
323316 if (UNEXPECTED(tensor_tensorbuffer_create(return_value, total, &c) == FAILURE)) { \
324- if (owned_b != NULL) { efree(owned_b); } \
325- return; \
326- } \
327- \
328- double * restrict vc = zephir_buffer_doubles(&c); \
329- \
330- zend_long i, j; \
331- \
332- if (v_a.contiguous) { \
333- const double * restrict va = v_a.base + v_a.offset; \
334- \
335- for (i = 0; i < m; ++i) { \
336- for (j = 0; j < nHat; ++j) { \
337- double x = va[i * nHat + j]; \
338- double y = vb[j]; \
339- vc[i * nHat + j] = op; \
340- } \
341- } \
342- } else { \
343- tensor_view_reader ra; \
344- tensor_view_reader_init(&ra, &v_a); \
345- \
346- for (i = 0; i < m; ++i) { \
347- for (j = 0; j < nHat; ++j) { \
348- double x = tensor_view_reader_value(&ra); \
349- double y = vb[j]; \
350- vc[i * nHat + j] = op; \
351- tensor_view_reader_advance(&ra); \
352- } \
353- } \
354- } \
355- \
356- if (owned_b != NULL) { efree(owned_b); } \
317+ return; \
318+ } \
319+ \
320+ double * restrict vc = zephir_buffer_doubles(&c); \
321+ \
322+ zend_long i, j; \
323+ \
324+ if (v_a.contiguous) { \
325+ const double * restrict va = v_a.base + v_a.offset; \
326+ \
327+ if (v_b.contiguous) { \
328+ const double * vb = v_b.base + v_b.offset; \
329+ \
330+ for (i = 0; i < m; ++i) { \
331+ for (j = 0; j < nHat; ++j) { \
332+ double x = va[i * nHat + j]; \
333+ double y = vb[j]; \
334+ vc[i * nHat + j] = op; \
335+ } \
336+ } \
337+ } else { \
338+ for (i = 0; i < m; ++i) { \
339+ for (j = 0; j < nHat; ++j) { \
340+ double x = va[i * nHat + j]; \
341+ double y = tensor_double_view_get(&v_b, j); \
342+ vc[i * nHat + j] = op; \
343+ } \
344+ } \
345+ } \
346+ } else { \
347+ tensor_view_reader ra; \
348+ tensor_view_reader_init(&ra, &v_a); \
349+ \
350+ for (i = 0; i < m; ++i) { \
351+ for (j = 0; j < nHat; ++j) { \
352+ double x = tensor_view_reader_value(&ra); \
353+ double y = tensor_double_view_get(&v_b, j); \
354+ vc[i * nHat + j] = op; \
355+ tensor_view_reader_advance(&ra); \
356+ } \
357+ } \
358+ } \
359+ \
357360 zval_ptr_dtor(&c);
358361
359362#define TENSOR_ROW_DISPATCH (name , op ) \
0 commit comments