cornell-zhang / heterocl

HeteroCL: A Multi-Paradigm Programming Infrastructure for Software-Defined Heterogeneous Computing
https://cornell-zhang.github.io/heterocl/
Apache License 2.0
322 stars 92 forks source link

[Backend][LLVM] Runtime support for any bitwidth integer numpy input #493

Open zzzDavid opened 1 year ago

zzzDavid commented 1 year ago

Summary

Up until this PR, the top function input/output argument type has been set to 64-bit integer type (for integer type args), and type casting is done inside the function body. This was due to the fact that numpy has only 8, 16, 32, 64-bit integer types.

This PR extends hcl.Array and LLVM runtime to support arbitrary bitwidth input arguments from numpy array.

Methods

Byte-as-field numpy array

To store arbitrary width integer data as numpy arrays, we use struct-type numpy arrays, with each byte as a field. Therefore, each integer scalar is represented as a struct of bytes, and the bytes are contiguous in the memory.

Arbitrary data representation

When input data is wider than 64-bit, it cannot be represented as a numpy scalar type. Instead, we use multidimensional lists of integers in Python to represent input tensors, because Python integers can have arbitrary bitwidth.

MLIR arbitrary bitwidth integer alignment

When passing data from numpy to an MLIR's ExecutionEngine as input arguments, we are creating C Struct from numpy ndarrays with the ctypes module in Python. Through a series of experiments, I found that the required alignment of such C Struct is not byte-level, instead, it depends on the integer bitwidth: Integer type bitwidth (bit) alignment(bit)
(0, 8] 8
(8, 16] 16
(16, 32] 32
(32, 64] 64
(64, 128] 128
(128, 256] 256
(256, 512] 512

Changes

Limitations

zzzDavid commented 1 year ago

ExecutionEngine randomly produces wrong results for bitwidth 513-1024, I'm still debugging this issue. Will update you once it's solved.