为什么不能将按位 & 与 numba 和 uint64 一起使用?

问题描述 投票:0回答:2

我有以下 MWE:

import numba as nb

@nb.njit(nb.uint64(nb.uint64))
def popcount(x): 
      b=0
      while(x > 0):
          x &= x - 1   
          b+=1
      return b


print(popcount(43))

它失败了:

numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
No implementation of function Function(<built-in function iand>) found for signature:
 
 >>> iand(float64, float64)
 
There are 8 candidate implementations:
  - Of which 4 did not match due to:
  Overload of function 'iand': File: <numerous>: Line N/A.
    With argument(s): '(float64, float64)':
   No match.
  - Of which 2 did not match due to:
  Operator Overload in function 'iand': File: unknown: Line unknown.
    With argument(s): '(float64, float64)':
   No match for registered cases:
    * (bool, bool) -> bool
    * (int64, int64) -> int64
    * (int64, uint64) -> int64
    * (uint64, int64) -> int64
    * (uint64, uint64) -> uint64
  - Of which 2 did not match due to:
  Overload in function 'gen_operator_impl.<locals>._ol_set_operator': File: numba/cpython/setobj.py: Line 1508.
    With argument(s): '(float64, float64)':
   Rejected as the implementation raised a specific error:
     TypingError: All arguments must be Sets, got (float64, float64)
  raised from /home/user/python/mypython3.10/lib/python3.10/site-packages/numba/cpython/setobj.py:108

During: typing of intrinsic-call at /home/user/python/popcount.py (7)

File "popcount.py", line 7:
def popcount(x): 
    <source elided>
      while(x > 0):
          x &= x - 1   
          ^

为此使用 uint64 有什么问题吗?


即使我使用,代码也会失败并显示相同的消息:

print(popcount(nb.uint64(43))
python numba
2个回答
2
投票

这就是 NumPy uint64 的尴尬之处。根据 NumPy dtype 规则,标准 Python

int
被处理为带符号的
numpy.int_
dtype。没有足够大的整数数据类型可以容纳 uint64 数据类型和有符号数据类型的所有值,因此在混合 uint64/int 运算中,NumPy 将两个操作数都转换为 float64

您不能将

&
与浮点数据类型一起使用,并且 Numba 遵循此处的 NumPy 规则,因此会出现错误。


0
投票

要编译代码,您可以显式转换为

np.uint64()
类型:

import numba as nb


@nb.njit(nb.uint64(nb.uint64))
def popcount(x):
    b = 0
    while x > 0:
        x &= nb.uint64(x - 1)
        b += 1
    return b


print(popcount(43))

打印:

4
© www.soinside.com 2019 - 2024. All rights reserved.