@@ -339,28 +339,6 @@ _is_alnum_underscore(char ch)
339
339
return _is_alpha_underscore (ch ) || (ch >= '0' && ch <= '9' );
340
340
}
341
341
342
- /*
343
- * Convert a string into a number
344
- */
345
- static npy_intp
346
- _get_size (const char * str )
347
- {
348
- char * stop ;
349
- #if defined(_MSC_VER )
350
- #define strtoll _strtoi64
351
- #endif
352
- npy_intp size = (npy_intp )strtoll (str , & stop , 10 );
353
- #if defined(_MSC_VER )
354
- #undef strtoll
355
- #endif
356
-
357
- if (stop == str || _is_alpha_underscore (* stop )) {
358
- /* not a well formed number */
359
- return -1 ;
360
- }
361
- return size ;
362
- }
363
-
364
342
/*
365
343
* Return the ending position of a variable name
366
344
*/
@@ -470,15 +448,13 @@ _parse_signature(PyUFuncObject *ufunc, const char *signature)
470
448
while (signature [i ] != ')' ) {
471
449
/* loop over core dimensions */
472
450
int j = 0 ;
473
- npy_intp frozen_size = -1 ;
474
451
if (signature [i ] == '\0' ) {
475
452
parse_error = "unexpected end of signature string" ;
476
453
goto fail ;
477
454
}
478
455
479
- if (!_is_alpha_underscore (signature [i ]) &&
480
- (frozen_size = _get_size (signature + i )) < 0 ) {
481
- parse_error = "expect dimension name or non-zero frozen size" ;
456
+ if (!_is_alpha_underscore (signature [i ])) {
457
+ parse_error = "expect dimension name" ;
482
458
goto fail ;
483
459
}
484
460
while (j < ufunc -> core_num_dim_ix ) {
@@ -2140,26 +2116,14 @@ _get_coredim_sizes(PyUFuncObject *ufunc, PyArrayObject **op,
2140
2116
int core_start_dim = PyArray_NDIM (op [i ]) - num_dims ;
2141
2117
int dim_delta = 0 ;
2142
2118
2143
- /* Check if operands have enough dimensions */
2144
- if (core_start_dim < 0 ) {
2145
- PyErr_Format (PyExc_ValueError ,
2146
- "%s: %s operand %d does not have enough "
2147
- "dimensions (has %d, gufunc core with "
2148
- "signature %s requires %d)" ,
2149
- ufunc_get_name_cstr (ufunc ), i < nin ? "Input" : "Output" ,
2150
- i < nin ? i : i - nin , PyArray_NDIM (op [i ]),
2151
- ufunc -> core_signature , num_dims );
2152
- return -1 ;
2153
- }
2154
-
2155
2119
/*
2156
2120
* Make sure every core dimension exactly matches all other core
2157
2121
* dimensions with the same label.
2158
2122
*/
2159
2123
for (idim = 0 ; idim < ufunc -> core_num_dims [i ]; ++ idim ) {
2160
2124
int core_dim_index = ufunc -> core_dim_ixs [dim_offset + idim ];
2161
2125
npy_intp op_dim_size ;
2162
- if (flexible_activated [core_dim_index ] > 0 ) {
2126
+ if (flexible_activated [core_dim_index ] == 1 ) {
2163
2127
op_dim_size = 0 ;
2164
2128
dim_delta ++ ;
2165
2129
}
@@ -2172,7 +2136,7 @@ _get_coredim_sizes(PyUFuncObject *ufunc, PyArrayObject **op,
2172
2136
}
2173
2137
else if (op_dim_size != core_dim_sizes [core_dim_index ]) {
2174
2138
PyErr_Format (PyExc_ValueError ,
2175
- "1 %s: %s operand %d has a mismatch in its "
2139
+ "%s: %s operand %d has a mismatch in its "
2176
2140
"core dimension %d, with gufunc "
2177
2141
"signature %s (size %zd is different "
2178
2142
"from %zd)" ,
@@ -2382,12 +2346,13 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
2382
2346
* (Just checks core; broadcast dimensions are tested by the iterator.)
2383
2347
*/
2384
2348
for (i = 0 ; i < nop ; i ++ ) {
2385
- /* TODO: store _n_required after parsing, ahead-of-time */
2349
+ /* TODO: store n_required after parsing, ahead-of-time */
2386
2350
int n_required = ufunc -> core_num_dims [i ];
2387
2351
if (n_required > 0 ) {
2388
2352
/* can be less if dim is flexible */
2389
- for (j = ufunc -> core_offsets [i ];
2390
- j < ufunc -> core_offsets [i ] + core_num_dims [i ]; j ++ ) {
2353
+ int core_offset = ufunc -> core_offsets [i ];
2354
+ int core_num_dim = core_num_dims [i ];
2355
+ for (j = core_offset ; j < core_offset + core_num_dim ; j ++ ) {
2391
2356
int dim_index = ufunc -> core_dim_ixs [j ];
2392
2357
n_required -= ufunc -> core_dim_flexible [dim_index ];
2393
2358
}
@@ -2434,51 +2399,52 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
2434
2399
}
2435
2400
}
2436
2401
else {
2402
+ int core_offset = ufunc -> core_offsets [i ];
2403
+ int core_num_dim = core_num_dims [i ];
2437
2404
/* never use more than the signature requires */
2438
- n_dims_used [i ] = core_num_dims [ i ] ;
2405
+ n_dims_used [i ] = core_num_dim ;
2439
2406
/* make sure any flexible dimensions are used in the same way */
2440
- for (j = ufunc -> core_offsets [i ];
2441
- j < ufunc -> core_offsets [i ] + core_num_dims [i ];
2442
- j ++ ) {
2443
- if (j <= ufunc -> core_num_dim_ix ) {
2444
- int dim_index = ufunc -> core_dim_ixs [j ];
2445
- if (flexible_activated [dim_index ] < 0 ) {
2446
- flexible_activated [dim_index ] = 0 ;
2447
- }
2448
- else if (flexible_activated [dim_index ] == 1 ) {
2449
- PyErr_Format (PyExc_ValueError ,
2450
- "%s: %s operand %d with flexible dimension "
2451
- "index %d signature %s previouosly marked "
2452
- "flexible but now is not" ,
2453
- ufunc_get_name_cstr (ufunc ),
2454
- i < nin ? "Input" : "Output" ,
2455
- i < nin ? i : i - nin , dim_index ,
2456
- ufunc -> core_signature );
2457
- goto fail ;
2458
- }
2459
- }
2407
+ for (j = core_offset ; j < core_offset + core_num_dim ; j ++ ) {
2408
+ if (j < ufunc -> core_num_dim_ix ) {
2409
+ int dim_index = ufunc -> core_dim_ixs [j ];
2410
+ if (flexible_activated [dim_index ] < 0 ) {
2411
+ flexible_activated [dim_index ] = 0 ;
2412
+ }
2413
+ else if (flexible_activated [dim_index ] == 1 ) {
2414
+ PyErr_Format (PyExc_ValueError ,
2415
+ "%s: %s operand %d with flexible dimension "
2416
+ "index %d signature %s previouosly marked "
2417
+ "flexible but now is not" ,
2418
+ ufunc_get_name_cstr (ufunc ),
2419
+ i < nin ? "Input" : "Output" ,
2420
+ i < nin ? i : i - nin , dim_index ,
2421
+ ufunc -> core_signature );
2422
+ goto fail ;
2423
+ }
2424
+ }
2460
2425
}
2461
2426
}
2462
2427
}
2463
2428
else {
2464
- /* NULL output provided . Use flexible_used to determine ndims_used */
2429
+ /* NULL output. Use flexible_activated to determine ndims_used. */
2465
2430
n_dims_used [i ] = core_num_dims [i ];
2466
- for (j = ufunc -> core_offsets [i ];
2467
- j < ufunc -> core_offsets [i ] + core_num_dims [i ]; j ++ ) {
2468
- if (j <= ufunc -> core_num_dim_ix ) {
2469
- int dim_index = ufunc -> core_dim_ixs [j ];
2470
- if (flexible_activated [dim_index ] < 0 ) {
2471
- PyErr_Format (PyExc_ValueError ,
2472
- "%s: %s operand %d with flexible dimension index "
2473
- " %d signature %s cannot be uniquely determined" ,
2474
- ufunc_get_name_cstr (ufunc ),
2475
- i < nin ? "Input" : "Output" ,
2476
- i < nin ? i : i - nin , dim_index ,
2477
- ufunc -> core_signature );
2478
- goto fail ;
2479
- }
2480
- n_dims_used [i ] -= flexible_activated [dim_index ];
2481
- }
2431
+ int core_offset = ufunc -> core_offsets [i ];
2432
+ int core_num_dim = core_num_dims [i ];
2433
+ for (j = core_offset ; j < core_offset + core_num_dim ; j ++ ) {
2434
+ if (j < ufunc -> core_num_dim_ix ) {
2435
+ int dim_index = ufunc -> core_dim_ixs [j ];
2436
+ if (flexible_activated [dim_index ] < 0 ) {
2437
+ PyErr_Format (PyExc_ValueError ,
2438
+ "%s: %s operand %d with flexible dimension index "
2439
+ " %d signature %s cannot be uniquely determined" ,
2440
+ ufunc_get_name_cstr (ufunc ),
2441
+ i < nin ? "Input" : "Output" ,
2442
+ i < nin ? i : i - nin , dim_index ,
2443
+ ufunc -> core_signature );
2444
+ goto fail ;
2445
+ }
2446
+ n_dims_used [i ] -= flexible_activated [dim_index ];
2447
+ }
2482
2448
}
2483
2449
}
2484
2450
}
@@ -2580,7 +2546,7 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
2580
2546
if (i >= nin ) {
2581
2547
int dim_offset = ufunc -> core_offsets [i ];
2582
2548
int num_dims = core_num_dims [i ];
2583
- int has_flexible = 0 ;
2549
+ int num_flexible = 0 ;
2584
2550
/*
2585
2551
* Fill in 'iter_shape' and 'op_axes' for the core dimensions
2586
2552
* of this output. Here, we have to be careful: if keepdims
@@ -2595,12 +2561,12 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
2595
2561
int core_index = ufunc -> core_dim_ixs [dim_offset + idim ];
2596
2562
if (flexible_activated [core_index ]) {
2597
2563
/* skip it */
2598
- has_flexible ++ ;
2564
+ num_flexible ++ ;
2599
2565
continue ;
2600
2566
}
2601
2567
iter_shape [j ] = core_dim_sizes [core_index ];
2602
2568
}
2603
- op_axes_arrays [i ][j ] = REMAP_AXIS (i , n + idim - has_flexible );
2569
+ op_axes_arrays [i ][j ] = REMAP_AXIS (i , n + idim - num_flexible );
2604
2570
++ j ;
2605
2571
}
2606
2572
}
@@ -4852,6 +4818,7 @@ PyUFunc_FromFuncAndDataAndSignature(PyUFuncGenericFunction *func, void **data,
4852
4818
ufunc -> core_dim_ixs = NULL ;
4853
4819
ufunc -> core_offsets = NULL ;
4854
4820
ufunc -> core_signature = NULL ;
4821
+ ufunc -> core_dim_flexible = NULL ;
4855
4822
if (signature != NULL ) {
4856
4823
if (_parse_signature (ufunc , signature ) != 0 ) {
4857
4824
Py_DECREF (ufunc );
@@ -5200,6 +5167,7 @@ ufunc_dealloc(PyUFuncObject *ufunc)
5200
5167
PyArray_free (ufunc -> core_dim_ixs );
5201
5168
PyArray_free (ufunc -> core_offsets );
5202
5169
PyArray_free (ufunc -> core_signature );
5170
+ PyArray_free (ufunc -> core_dim_flexible );
5203
5171
PyArray_free (ufunc -> ptr );
5204
5172
PyArray_free (ufunc -> op_flags );
5205
5173
Py_XDECREF (ufunc -> userloops );
0 commit comments