Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[API][v0.3] Introduce Struct Data Type to HeteroCL #157

Merged
merged 7 commits into from
Feb 14, 2020

Conversation

seanlatias
Copy link
Collaborator

@seanlatias seanlatias commented Feb 13, 2020

In this PR, we introduce the C-like struct to HeteroCL.

Python Interface

Users can define a HeteroCL type by using hcl.struct with a Python dictionary. The following shows an example.

ts = hcl.Struct({"fa": hcl.Int(8), "fb": hcl.Fixed(8, 2), "fc": hcl.Float()})

Note that currently, we only support single-level structs. Namely, we cannot have a struct inside another struct. Since HeteroCL does not support pointers intrinsically, we will not have pointer members or self-referential structs.

Users can print the struct simply using Python print function. The following are some examples of getting information of a struct.

print(ts)
print(ts.fa)
print(ts["fa"])

With the support of a struct, we can create tensors having struct type. For example,

A = hcl.placeholder((10,), dtype=ts)
B = hcl.compute((10,), lambda x: 0, dtype=ts)

To access the elements, we provide C-like semantics (i.e., by using .). For example,

print(A[0].fa)
print(B[0].fb)

We can also initialize a tensor with struct type by using tuples. For example,

C = hcl.compute((10,), lambda x: (B[x].fa, B[x].fb, B[x].fc), dtype=ts)

Alternatively, we can use the imperative DSL provided by HeteroCL. For example,

with hcl.Stage():
  with hcl.for_(0, 10) as i:
    C[i].fa = B[i].fa
    C[i].fb = B[i].fb
    C[i].fc = B[i].fc

More examples can be seen in the tests.

CPU Simulation (LLVM JIT)

The struct can be run with CPU simulation. This is realized by using LLVM intrinsic bitcast. Note that for bitcast to work, we need to make sure the bitwidths are the same before and after typecast. Currently, this is guaranteed by the HeteroCL compiler. Thus, users only need to consider this requirement when they want to call the intrinsic directly from Python.

The struct type is treated as "unsigned int" for all internal representation.

HLS C Code Generation

For code generation, we consider two different conditions. First, if floating-point numbers are involved, we use the C++ union. Here is an example of a generated code, where A is a floating-point tensor while B is a struct with a floating-point field.

union { float from; uint32_t to; } _converter;
_converter.from = A[i];
B[i](31, 0) = _converter.to

If floating-point is not involved, we simply use the bit-selection provided by the HLS tool. Here, A is a tensor with type ap_fixed<8, 5> while B is a struct type.

ap_uint<8> _converter;
_converter(7, 0) = A[i](7, 0);
B[i](7, 0) = _converter;

@seanlatias seanlatias changed the title [WIP][API][v0.3] Introduce Struct Data Type to HeteroCL [API][v0.3] Introduce Struct Data Type to HeteroCL Feb 14, 2020
@seanlatias seanlatias merged commit 8906f99 into cornell-zhang:v0.3 Feb 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant