• Kirill Smelkov's avatar
    *: It is not safe to use multiply.reduce() - it overflows · 73926487
    Kirill Smelkov authored
    e.g.
    
        In [1]: multiply.reduce((1<<30, 1<<30, 1<<30))
        Out[1]: 0
    
    instead of
    
        In [2]: (1<<30) * (1<<30) * (1<<30)
        Out[2]: 1237940039285380274899124224
    
        In [3]: 1<<90
        Out[3]: 1237940039285380274899124224
    
    also multiply.reduce returns int64, instead of python int:
    
        In [4]: type( multiply.reduce([1,2,3]) )
        Out[4]: numpy.int64
    
    which also leads to overflow-related problems if we further compute with
    this value and other integers and results exceeds int64 - it becomes
    float:
    
        In [5]: idx0_stop = 18446744073709551615
    
        In [6]: stride0   = numpy.int64(1)
    
        In [7]: byte0_stop = idx0_stop * stride0
    
        In [8]: byte0_stop
        Out[8]: 1.8446744073709552e+19
    
    and then it becomes a real problem for BigArray.__getitem__()
    
        wendelin.core/bigarray/__init__.py:326: RuntimeWarning: overflow encountered in long_scalars
          page0_min  = min(byte0_start, byte0_stop+byte0_stride) // pagesize # TODO -> fileh.pagesize
    
    and then
    
        >           vma0 = self._fileh.mmap(page0_min, page0_max-page0_min+1)
        E           TypeError: integer argument expected, got float
    
    ~~~~
    
    So just avoid multiple.reduce() and do our own mul() properly the same
    way sum() is builtin into python, and we avoid overflow-related
    problems.
    73926487
test_basic.py 11.9 KB