Repository navigation
Support for CUDA fp16 math functions (part 1) - #8605
Conversation
|
gpuci run tests |
|
@testhound thanks for the patch. I've altered the PT title so that it reflects the change is for CUDA and for fp16 types. This is so that the merged PR will appear in the change log with a more specific title. |
gmarkall
left a comment
There was a problem hiding this comment.
Thanks for the PR. I'm not sure I understand how this should work - I see that lowering is added, but no additional typing. For example, if I try compiling a call to a math function on a float16 and check the typing:
from numba import cuda, types
import math
@cuda.jit(types.void(types.float16[::1]))
def f(x):
print(math.sin(x[0]))
f.inspect_types()I see
$ python repro.py
_ZN6cudapy8__main__1fB2v1B106cw51cXTLSUwHBinCqbbgUAAGBlq82ILSCEQYkgSQBFCjFSaBZJtttTo4sahbKRjoKKiDvAVKN0AuNEDVYWGDJATUC_2bQZ12oCAA_3d_3dE5ArrayIDhLi1E1C7mutable7alignedE (array(float16, 1d, C),)
--------------------------------------------------------------------------------
# File: /home/gmarkall/numbadev/issues/8605/repro.py
# --- LINE 5 ---
@cuda.jit(types.void(types.float16[::1]))
# --- LINE 6 ---
def f(x):
# --- LINE 7 ---
# label 0
# x = arg(0, name=x) :: array(float16, 1d, C)
# $2load_global.0 = global(print: <built-in function print>) :: Function(<built-in function print>)
# del $2load_global.0
# $4load_global.1 = global(math: <module 'math' from '/home/gmarkall/mambaforge/envs/numbadev/lib/python3.10/lib-dynload/math.cpython-310-x86_64-linux-gnu.so'>) :: Module(<module 'math' from '/home/gmarkall/mambaforge/envs/numbadev/lib/python3.10/lib-dynload/math.cpython-310-x86_64-linux-gnu.so'>)
# $6load_method.2 = getattr(value=$4load_global.1, attr=sin) :: Function(<built-in function sin>)
# del $4load_global.1
# $const10.4 = const(int, 0) :: Literal[int](0)
# $12binary_subscr.5 = static_getitem(value=x, index=0, index_var=$const10.4, fn=<built-in function getitem>) :: float16
# del x
# del $const10.4
# $14call_method.6 = call $6load_method.2($12binary_subscr.5, func=$6load_method.2, args=[Var($12binary_subscr.5, repro.py:7)], kws=(), vararg=None, varkwarg=None, :: (float32,) -> float32
# del $6load_method.2
# del $12binary_subscr.5
# print($14call_method.6)
# del $14call_method.6
# $16call_function.7 = const(NoneType, None) :: none
# del $16call_function.7
# $const20.8 = const(NoneType, None) :: none
# $22return_value.9 = cast(value=$const20.8) :: none
# del $const20.8
# return $22return_value.9
print(math.sin(x[0]))
================================================================================
The argument to math.sin is typed as accepting a float32.
However, I don't think that the right way to go would be to add typing - now that the high-level API is supported in CUDA, I think it would be better to try writing these using @overload instead.
|
@gmarkall okay I understand now. As a quick test I added typing for "math.sin" in cuda/cmath.py and the IR now generates code using fp16 instead of fp32. Can you clarify why you believe it is better to use "@overload" instead of typing? I don't understand how this conflicts with the high-level API as you mentioned above. |
|
@gmarkall I added typing for all the fp16 math functions in the latest iteration. I spoke with @sklam about using "@overload" and he indicated that there is a registration issue with using "@overload" and "@infer_global". He indicated that we need to use either all "@overload" or all "@infer_global". This problem is similar to the one we had when adding typing for fp16 operators and intrinsics. We needed to use AbstractTemplate for operators and ConcreteTemplate |
|
gpuci run tests |
gmarkall
left a comment
There was a problem hiding this comment.
Thanks for the updates. This now appears to use the FP16 implementations in all cases. There are a couple of comments on the diff - in addition to those, the lowering implementations for the math module should be in numba.cuda.mathimpl, rather than numba.cuda.cudaimpl - cudaimpl is where the implementations of the functions in the numba.cuda module are.
Regarding the conversion to use overload - I was going to suggest trying to convert these functions to the overload throughout Numba so that the ConcreteTemplate / overload issue isn't a problem, but given that @stuartarchibald is refactoring a lot of the math function implementations this is probably not productive at this time. So, if the comments above and on the diff can be addressed / resolved, then I think this will be good to approve.
| @infer_global(math.exp) | ||
| @infer_global(math.fabs) | ||
| @infer_global(math.trunc) | ||
| class Math_sin(ConcreteTemplate): |
There was a problem hiding this comment.
Perhaps a more appropriate name:
| class Math_sin(ConcreteTemplate): | |
| class Math_unary_with_fp16(ConcreteTemplate): |
| def fp16_sin(x): | ||
| return cuda.fp16.hsin(x) | ||
|
|
||
| return context.compile_internal(builder, fp16_sin, sig, args, ) |
There was a problem hiding this comment.
I think this copy-pastes a type from the hdiv implementation (which should also be fixed similarly), along with all other instances:
| return context.compile_internal(builder, fp16_sin, sig, args, ) | |
| return context.compile_internal(builder, fp16_sin, sig, args) |
|
@gmarkall I addresses all your comments in this latest change. |
|
gpuci run tests |
|
@gmarkall I added implementations of math.trunc for float32 and float64. |
|
gpuci run tests |
|
gpuci run tests |
gmarkall
left a comment
There was a problem hiding this comment.
Many thanks for the patches!
This PR adds support for a subset of the python math functions for fp16. The supported subset was chosen because they map directly to fp16 math intrinsics that have been implemented already.