Numba signatures cuda

Hello!
I am trying to understand a basic example of signatures for @vectorize targetting cuda and a some doubts appeared.

From here Types and signatures — Numba 0.52.0.dev0+274.g626b40e-py3.7-linux-x86_64.egg documentation I understand that:

  • "float64(int32, int32)" ) which specifies a function taking two 32-bit integers and returning a double-precision float.
  • Given the former information, I would expect the following signature in the code below (CUDA Ufuncs and Generalized Ufuncs — Numba 0.50.1 documentation)
    @vectorize(['float64(float32, float32, float32)'] (Output a float64 and input 3 arrays of float32)

So my questions are:

  1. Why isn´t it @vectorize(['float64(float32, float32, float32)']?
  2. To understand how to pass my signatures, how could I for instance use the nb.typeof to create my signatures? For instance if I had TWO input array having the type array(float32, 2d, C) that outputs me TWO single float64 (not an array) would the signature in this case be @vectorize(['float64,float64(float32, float32)']?

import math
from numba import vectorize, cuda
import numpy as np

@vectorize(['float32(float32, float32, float32)',
            'float64(float64, float64, float64)'],
           target='cuda')
def cu_discriminant(a, b, c):
    return math.sqrt(b ** 2 - 4 * a * c)

N = 10000
dtype = np.float32

# prepare the input
A = np.array(np.random.sample(N), dtype=dtype)
B = np.array(np.random.sample(N) + 10, dtype=dtype)
C = np.array(np.random.sample(N), dtype=dtype)

D = cu_discriminant(A, B, C)

print(D)  # print result

Many thanks!

Hello DTKx :slight_smile:

I have (very) limited knowledge about CUDA, but may I ask why you want the signature to be @vectorize(['float64(float32, float32, float32)'] ?
If your inputs are single precision and you only have a few arithmetic operations on that data, then this will limit the precision you can achieve. Casting the result into a double precision afterwards provides you with no additional information, just more memory usage.

Hello @Hannes!
Thaanks! haha yes indeed I also got really confused about that too. I thought that here the code:
@vectorize([‘float32(float32, float32, float32)’,#Input
‘float64(float64, float64, float64)’],#Output
I was thinking that somehow having 2 different type signatures float32 and float 64 was somehow related to input and output. So I assumed the one liner ‘float64(float32, float32, float32)’.
However now that you mentioned I remembered of something else I read and perhaps I was able to connect the dots, I guess that the signature actually means
@vectorize([‘float32(float32, float32, float32)’,#Accepts input 3 floats 32 and output float32
‘float64(float64, float64, float64)’],#Accepts input 3 floats 64and output float32
In other words, if my input was a float 32, it would be ok to have a one liner signature @vectorize([‘float32(float32, float32, float32)’. I have just tested and indeed it works.
Many Thanks!