Skip to content

[Schedule] Support for intra-kernel data placement - #436

Open
hecmay wants to merge 19 commits into
tvmfrom
intra-kernel-placement
Open

hecmay wants to merge 19 commits into
tvmfrom
intra-kernel-placement

Conversation

@hecmay

@hecmay hecmay commented Feb 4, 2022

Copy link
Copy Markdown
Collaborator

This PR aims to enhance .systolic() and .to() primitive to better support intra-kernel data placement for systolic array generation using AutoSA backend.

.systolic() primitive is a push-button API that maps the compute kernel to a systolic array automatically (while the dataflow pattern is left to compiler's decision). .to() primitive provides more flexibility for expert designers to explore the trade-offs of different systolic dataflows.

I have successfully solved the dependency issues and installed AutoSA on our local server. In this PR, i will also add the CI/CD local testing for systolic array programs with AutoSA backend.

@hecmay hecmay changed the title [Schedule] Improve support for intra-kernel data placement [Schedule] Support for intra-kernel data placement Feb 6, 2022
@hecmay

hecmay commented Mar 6, 2022

Copy link
Copy Markdown
Collaborator Author

@zzzDavid @chhzh123 can you maybe take a quick pass on this PR? Thanks!

@chhzh123 chhzh123 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late review. I’ve looked through the code and think maybe you could add more descriptions for this PR. Seems you have added several new features besides the AutoSA backend.

  1. I notice you introduced new APIs like transpose and pack, and new passes like transform_layout and explicit_unroll, could you also describe the changes in this PR?
  2. Just a small question: You are not writing a C++ codegen for AutoSA right? All the compilation happens at the Python level (except for some transformation passes).

source $VITIS/settings64.sh
source /opt/xilinx/xrt/setup.sh
export LOCAL_CI_TEST=1
which vivado_hls

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The vivado_hls has been included in the previous paths?

Comment thread python/heterocl/autosa.py
Comment on lines +24 to +35
def indent(num):
return " " * num

def get_function_code(name, code):
pos = code.find(name)
start_pos = pos - len("inline void")
end_pos = code.find("/* Helper", pos)
return code[start_pos:end_pos]


def get_ser_size(code):
lines = code.split("\n")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure what Python formatter HeteroCL uses, but mixing one-line space and two-line space seems weird.

Comment thread python/heterocl/autosa.py
Comment on lines +117 to +119
PART = "10,16"
LAT = "2,2"
SIMD = 4

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are these magic numbers? Could you add comments or use more specific variable names here?

Comment thread python/heterocl/autosa.py
Comment on lines +126 to +129
print(f"[ INFO ] input size OC({OC}), OH({OH}), OW({OW}), IC({IC}), R({R}), C({C})")
PART = "16,13,13,1"
LAT = "2,1,2"
SIMD = "1,1,2,4"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why "16,13,13,1"? I suppose this is not a test file but a general implementation.

/*!
* Copyright (c) 2019 by Contributors
* \file adjust_buffer_binding.cc
* \file loop_partition.cc

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose you changed the header by mistake? The file name remains the same.

"inconsistent tensor joining"
self.sch.join(target, dest, self[src])

def transpose(self, tensor=None):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is one in compute_api.py. What's the difference between these two transpose?

return Y

# Note that you have to make sure AutoSA binary
# in on the PATH by running which command, otherwise HCL runtime

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"in on" typo. Better add quotation marks for which.

Comment thread python/heterocl/autosa.py
extra_flags = "--simd-info=./autosa_tests/cnn/simd_info.json "
return ST, PART, LAT, SIMD, extra_flags

def generate_systolic_array(keys, values, code, backend):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems the codegen, copying files, and generating headers are done in this function? Maybe it would be better if this function can be separated into several subfunctions or several steps like what we did in runtime.py.

@hecmay

hecmay commented Mar 7, 2022

Copy link
Copy Markdown
Collaborator Author

Sorry for the late review. I’ve looked through the code and think maybe you could add more descriptions for this PR. Seems you have added several new features besides the AutoSA backend.

  1. I notice you introduced new APIs like transpose and pack, and new passes like transform_layout and explicit_unroll, could you also describe the changes in this PR?
  2. Just a small question: You are not writing a C++ codegen for AutoSA right? All the compilation happens at the Python level (except for some transformation passes).

Thanks for pointing that out.

  1. These new APIs (e.g., packing, layout transformation) are necessary to generate a high-throughput memory subsystem for the GEMM systolic array. I will add more explanations on these new APIs.
  2. The AutoSA codegen in HCL is a mix of C++ and python rn - the HLS/OpenCL code generator (i.e., C++ part) will call a utility function (i.e., python part) that is responsible for inferring the CLI arguments and then invoking AutoSA. I can probably implement that utility function in C++, which would make the flow a bit cleaner


self.cascade_tensor = tensor
self.cascade_source_stage = None
self.sch.transpose(src, tensor, new_shape)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a question about this self.sch.transpose function: is data packing actually done by this function? It seems to me that this pack function only calculates the new shape.

if (top_arg_names_.find(var_name) != top_arg_names_.end()) {
placement_info += "[0]"; // located on off-chip memory
} else {
placement_info += "[1]"; // loacted on on-chip memory

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tiny typo

@zzzDavid zzzDavid left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a few general questions about the newly added passes:

  1. From the test case, we are wrapping a piece of imperative gemm code into a stage and calls systolic() on the stage. Do we have any checks to see if the imperative code can be mapped to AutoSA? Or AutoSA would complain if it can't map the algorithm?
  2. I want to check if my understanding is correct. For a piece of code that is targeted to AutoSA backend, we first generate C code from it, and then calls AutoSA to generate systolic array HLS code + serialization/de-serialization code, which is then wrapped into a stage. Is that correct?
  3. About the "explicit unroll" pass, is it unrolling a loop and then outline the loop body to become PEs (function calls)?
  4. What does "transform layout" do?

stmt = ir_pass.AdjustBufferBinding(stmt, arg_list)
# perform layout transformation
stmt = ir_pass.TransformLayout(stmt, arg_list)
stmt = ir_pass.AdjustBufferBinding(stmt, arg_list)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does AdjustBufferBinding do? Why is it called multiple times after each pass?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants