-1

According to numba 0.51.2 documentation, CUDA Python supports several math functions. However, it doesn't work in the following kernel function:

@cuda.jit
def find_angle(angles):
    i, j = cuda.grid(2)
    if i < angles.shape[0] and j < angles.shape[1]:
        angles[i][j] = math.atan2(j, i)

The output:

numba.core.errors.LoweringError: Failed in nopython mode pipeline (step: nopython mode backend)
No definition for lowering <built-in function atan2>(int64, int64) -> float64

Am I using the function incorrectly?

Spencer Cain
  • 63
  • 1
  • 10
  • Well `arctan2` isn't in the list of supported functions on the page you link. Your text description of support is also not what I find when I look at that page. I don't see that "most" `math` functions are supported, I see that a list of supported functions is provided. If you look on the `numba` tag here on SO, you'll find examples of `math` usage, such as [here](https://stackoverflow.com/questions/53745701/numba-cuda-does-not-produce-correct-result-with-gpu-reduction-needed/53748514#53748514). – Robert Crovella Feb 20 '21 at 17:34
  • @RobertCrovella I wrote the question in the middle of debugging both the `math` and `numpy` errors and confused the situation a bit. To clear up the question, I directed the question to supported `math` functions, specifically `math.atan(y, x)`. The link provides the functions supported. – Spencer Cain Feb 20 '21 at 18:06

1 Answers1

3

The hint to the source of the problem is here:

No definition for lowering <built-in function atan2>(int64, int64) -> float64

The arguments returned by cuda.grid() (i.e. i, j which you are passing to atan2) are integer values because they are related to indexing.

numba can't find a version of atan2 that it can use that takes two integer arguments and returns a floating-point value:

float64 = atan2(int64, int64)

One possible solution is to convert your atan2 input arguments to match the type that numba seems to want to return from that function, which is evidently float64:

from numba import cuda, float64
import numpy
import math


@cuda.jit
def find_angle(angles):
    i, j = cuda.grid(2)
    if i < angles.shape[0] and j < angles.shape[1]:
        angles[i][j] = math.atan2(float64(j), float64(i))

block_x = 32
block_y = 32
block = (block_x, block_y)
x = 256
y = 256
grid = (x//block_x, y//block_y) # not for arbitrary x and y

angles = numpy.ones((x, y), numpy.float64)
find_angle[grid, block](angles)
Robert Crovella
  • 143,785
  • 11
  • 213
  • 257