@@ -578,6 +578,28 @@ _is_alnum_underscore(char ch)
578
578
return _is_alpha_underscore (ch ) || (ch >= '0' && ch <= '9' );
579
579
}
580
580
581
+ /*
582
+ * Convert a string into a number
583
+ */
584
+ static npy_intp
585
+ _get_size (const char * str )
586
+ {
587
+ char * stop ;
588
+ #if defined(_MSC_VER )
589
+ #define strtoll _strtoi64
590
+ #endif
591
+ npy_intp size = (npy_intp )strtoll (str , & stop , 10 );
592
+ #if defined(_MSC_VER )
593
+ #undef strtoll
594
+ #endif
595
+
596
+ if (stop == str || _is_alpha_underscore (* stop )) {
597
+ /* not a well formed number */
598
+ return -1 ;
599
+ }
600
+ return size ;
601
+ }
602
+
581
603
/*
582
604
* Return the ending position of a variable name
583
605
*/
@@ -645,10 +667,13 @@ _parse_signature(PyUFuncObject *ufunc, const char *signature)
645
667
ufunc -> core_enabled = 1 ;
646
668
ufunc -> core_num_dim_ix = 0 ;
647
669
ufunc -> core_num_dims = PyArray_malloc (sizeof (int ) * ufunc -> nargs );
648
- ufunc -> core_dim_ixs = PyArray_malloc (sizeof (int ) * len ); /* shrink this later */
649
670
ufunc -> core_offsets = PyArray_malloc (sizeof (int ) * ufunc -> nargs );
650
- if (ufunc -> core_num_dims == NULL || ufunc -> core_dim_ixs == NULL
651
- || ufunc -> core_offsets == NULL ) {
671
+ /* The next two items will be shrunk later */
672
+ ufunc -> core_dim_ixs = PyArray_malloc (sizeof (int ) * len );
673
+ ufunc -> core_dim_szs = PyArray_malloc (sizeof (npy_intp ) * len );
674
+
675
+ if (ufunc -> core_num_dims == NULL || ufunc -> core_dim_ixs == NULL ||
676
+ ufunc -> core_offsets == NULL || ufunc -> core_dim_szs == NULL ) {
652
677
PyErr_NoMemory ();
653
678
goto fail ;
654
679
}
@@ -677,8 +702,15 @@ _parse_signature(PyUFuncObject *ufunc, const char *signature)
677
702
while (signature [i ] != ')' ) {
678
703
/* loop over core dimensions */
679
704
int j = 0 ;
680
- if (!_is_alpha_underscore (signature [i ])) {
681
- parse_error = "expect dimension name" ;
705
+ npy_intp frozen_size = -1 ;
706
+ if (signature [i ] == '\0' ) {
707
+ parse_error = "unexpected end of signature string" ;
708
+ goto fail ;
709
+ }
710
+
711
+ if (!_is_alpha_underscore (signature [i ]) &&
712
+ (frozen_size = _get_size (signature + i )) < 0 ) {
713
+ parse_error = "expect dimension name or frozen size" ;
682
714
goto fail ;
683
715
}
684
716
while (j < ufunc -> core_num_dim_ix ) {
@@ -689,6 +721,7 @@ _parse_signature(PyUFuncObject *ufunc, const char *signature)
689
721
}
690
722
if (j >= ufunc -> core_num_dim_ix ) {
691
723
var_names [j ] = signature + i ;
724
+ ufunc -> core_dim_szs [j ] = frozen_size ;
692
725
ufunc -> core_num_dim_ix ++ ;
693
726
}
694
727
ufunc -> core_dim_ixs [cur_core_dim ] = j ;
@@ -733,6 +766,9 @@ _parse_signature(PyUFuncObject *ufunc, const char *signature)
733
766
}
734
767
ufunc -> core_dim_ixs = PyArray_realloc (ufunc -> core_dim_ixs ,
735
768
sizeof (int )* cur_core_dim );
769
+ // ufunc->core_dim_szs = PyArray_realloc(ufunc->core_dim_szs,
770
+ // sizeof(npy_intp)*ufunc->core_num_dim_ix);
771
+
736
772
/* check for trivial core-signature, e.g. "(),()->()" */
737
773
if (cur_core_dim == 0 ) {
738
774
ufunc -> core_enabled = 0 ;
@@ -1914,7 +1950,8 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
1914
1950
* to a core dimension, it won't be visited.
1915
1951
*/
1916
1952
for (i = 0 ; i < ufunc -> core_num_dim_ix ; ++ i ) {
1917
- core_dim_sizes [i ] = 1 ;
1953
+ npy_intp frozen_size = ufunc -> core_dim_szs [i ];
1954
+ core_dim_sizes [i ] = frozen_size == -1 ? 1 : frozen_size ;
1918
1955
}
1919
1956
for (i = 0 ; i < nop ; ++ i ) {
1920
1957
if (op [i ] != NULL ) {
@@ -1949,9 +1986,10 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
1949
1986
}
1950
1987
for (; idim < num_dims ; ++ idim ) {
1951
1988
int core_dim_index = ufunc -> core_dim_ixs [dim_offset + idim ];
1989
+ npy_intp frozen_size = ufunc -> core_dim_szs [core_dim_index ];
1952
1990
npy_intp op_dim_size =
1953
1991
PyArray_SHAPE (op [i ])[core_start_dim + idim ];
1954
- if (core_dim_sizes [core_dim_index ] == 1 ) {
1992
+ if (frozen_size == -1 && core_dim_sizes [core_dim_index ] == 1 ) {
1955
1993
core_dim_sizes [core_dim_index ] = op_dim_size ;
1956
1994
} else if ((i >= nin || op_dim_size != 1 ) &&
1957
1995
core_dim_sizes [core_dim_index ] != op_dim_size ) {
@@ -4370,6 +4408,7 @@ PyUFunc_FromFuncAndDataAndSignature(PyUFuncGenericFunction *func, void **data,
4370
4408
ufunc -> core_dim_ixs = NULL ;
4371
4409
ufunc -> core_offsets = NULL ;
4372
4410
ufunc -> core_signature = NULL ;
4411
+ ufunc -> core_dim_szs = NULL ;
4373
4412
if (signature != NULL ) {
4374
4413
if (_parse_signature (ufunc , signature ) != 0 ) {
4375
4414
Py_DECREF (ufunc );
@@ -4716,6 +4755,7 @@ ufunc_dealloc(PyUFuncObject *ufunc)
4716
4755
{
4717
4756
PyArray_free (ufunc -> core_num_dims );
4718
4757
PyArray_free (ufunc -> core_dim_ixs );
4758
+ PyArray_free (ufunc -> core_dim_szs );
4719
4759
PyArray_free (ufunc -> core_offsets );
4720
4760
PyArray_free (ufunc -> core_signature );
4721
4761
PyArray_free (ufunc -> ptr );
0 commit comments