-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Add support for Xilinx FPGA board with SDAccel #1278
Conversation
6f7c8d6
to
fc8f768
Compare
@tmoreau89 @Huyuwei can you share your input on this? |
Looping @vegaluisjose in who can add his two cents. I'll try reproducing the tutorial over the next few days on F1 to make sure that this runs correctly. This looks like a promising start to having an OpenCL back-end for FPGAs. |
@seanlatias @comaniac may be interested and have something to share |
I briefly reviewed the PR and looks good to me. While I don't have comments to the runtime part, I'd like to confirm some points in kernel compilation part.
Thanks. |
Yes, exactly. I think it's the most intuitive way, but any other suggestions would be much appreciated.
From the point of view of code semantics, I guess there is no limitation; Vivado HLS could compile the generated code as far as FPGA resource is available. For optimization, there are many things we have to do, but they would be future work as you said. Thanks. |
I traced some more parts with your clarification and made the following summary of this PR:
Please correct me if I misunderstand anything. Thanks. |
Yes.
The main reason I decoupled the tutorial script is that we need to create AFI (Amazon FPGA Image) before execution on the AWS F1 instance. If we use a standalone server with Xilinx FPGAs, I think we can combine those two script into one. I confirmed I could compile and execute the vector addition code with one script for software/hardware emulation, so we can use the same code with other backend at least for testing purpose.
No, I guess the flow would be similar to other standalone servers, though I've not tested it yet. The only thing we need to change is to specify a xclbin binary instead of an awsxclbin file, I think.
Yes.
Yes. Thanks for your help for clarification! |
@comaniac I've added a tiny testcase which shows we can try SDAccel backend without decoupling scripts for emulation. |
np.testing.assert_allclose( | ||
b.asnumpy(), np.exp(a.asnumpy()), rtol=1e-5) | ||
|
||
check_device("sdaccel") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the TVM Jenkins environment has sdaccel?
If so, how did you mock the bitstream generation part?
If not, it seems to me that this test will exit at line 29 and nothing will be tested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the Jenkins environment of this community doesn't have SDAccel, so the test is not run via CI. I checked the test works on my AWS F1 instance:
$ python -m nose -vs tests/python/integration/test_ewise_fpga.py
test_ewise_fpga.test_exp ... [07:37:36] /home/centos/src/project_data/tvm/src/runtime/opencl/opencl_device_api.cc:232: Initialize OpenCL platform 'Xilinx'
[07:37:36] /home/centos/src/project_data/tvm/src/runtime/opencl/opencl_device_api.cc:259: opencl(0)='xilinx_aws-vu9p-f1_dynamic_5_0' cl_device_id=0x1ad7ef0
#include <ap_int.h>
extern "C" void myexp_kernel0( float* B, float* A) {
#pragma HLS INTERFACE m_axi port=B offset=slave bundle=gmem
#pragma HLS INTERFACE s_axilite port=B bundle=control
#pragma HLS INTERFACE m_axi port=A offset=slave bundle=gmem
#pragma HLS INTERFACE s_axilite port=A bundle=control
#pragma HLS INTERFACE s_axilite port=return bundle=control
for (int i0_inner = 0; i0_inner < 1024; ++i0_inner) {
B[i0_inner] = expf(A[i0_inner]);
}
}
****** xocc v2017.4 (64-bit)
**** SW Build 2193837 on Tue Apr 10 18:06:59 MDT 2018
** Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.
Attempting to get a license: ap_opencl
Feature available: ap_opencl
INFO: [XOCC 60-585] Compiling for software emulation target
(snip)
INFO: [XOCC 60-586] Created /tmp/tmpc5uk9a/output.xclbin
INFO: [XOCC 60-791] Total elapsed time: 0h 0m 11s
ok
----------------------------------------------------------------------
Ran 1 test in 61.040s
OK
I set the environment variable XCL_EMULATION_MODE in the python test file, so SDAccel doesn't generate a bitstream but run in software emulation mode - it works like a mock.
Let me know if I'm missing something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Could we figure out a plan to include SDAccel in Jenkins, or an alternative way to perform unit tests without SDAccel? I'm worried that it would be hard to be maintained when other contributors start adding more features.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another way is to use FPGA Developer AMI of AWS. It contains SDAccel.
@tqchen, is it possible to launch an AWS instance from Jenkins for FPGA testing purpose? Note that we don't need F1 instances for emulation. Any instance types is okay.
@tmoreau89, have you tried the tutorial? Let me know if there is anything I can help you with. :) |
I have been discussing for a while with @tmoreau89 on how to introduce SDAccel and other VHLS toolchain into test infrastructure. The main challenge here is that our current test infra was based on Docker and because we need some manual step in setting up the Xilinx toolchain, it is hard to dockerize these parts. Given the situation @comaniac suggested, we might need to look into possible solutions. |
I've added a change to create a program binary for GPU when SDAccel is not available. I think we can test the sdaccel backend in Jenkins with this change. @tqchen @tmoreau89 @comaniac Let me know your opinion. |
python/tvm/contrib/sdaccel.py
Outdated
os.environ.get("AWS_PLATFORM", "xilinx:kcu1500:dynamic")) | ||
platform = os.environ.get("XCL_PLATFORM", os.environ.get("AWS_PLATFORM")) | ||
|
||
if platform is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest showing a warning like "Failed to set up SDAccel, running on GPU instead." in case if a user really wants to run with SDAccel but just forgets to set up the environment.
python/tvm/ndarray.py
Outdated
@@ -121,6 +121,22 @@ def vpi(dev_id=0): | |||
return TVMContext(9, dev_id) | |||
|
|||
|
|||
def sdaccel(dev_id=0): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is not necessary, as from frontend's perspective, sdaccel is just opencl
src/codegen/codegen_vhls.cc
Outdated
} | ||
} | ||
|
||
void CodeGenVHLS::AddFunction(LoweredFunc f) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VLHS->VivadoHLS
src/codegen/intrin_rule_vhls.cc
Outdated
TVM_REGISTER_GLOBAL("tvm.intrin.rule.sdaccel.popcount") | ||
.set_body(DispatchExtern<Direct>); | ||
|
||
TVM_REGISTER_GLOBAL("tvm.intrin.rule.sdaccel.tvm_warp_shuffle") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think sdaccel have warp shuffle
docs/deploy/aws_fpga.md
Outdated
@@ -0,0 +1,151 @@ | |||
Deploy to AWS F1 FPGA Instance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deploy to AWS F1 -> HLS Backend Example
docs/deploy/aws_fpga.md
Outdated
Deploy to AWS F1 FPGA Instance | ||
============================== | ||
|
||
TVM supports Xilinx FPGA board with SDAccel. Here is a tutorial for how to deploy TVM to AWS F1 FPGA instance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a note saying that this is still experimental, as we cannot use to deploy an end to end neural networks.
cmake/modules/OpenCL.cmake
Outdated
@@ -13,6 +13,10 @@ if(USE_OPENCL) | |||
file(GLOB RUNTIME_OPENCL_SRCS src/runtime/opencl/*.cc) | |||
list(APPEND TVM_RUNTIME_LINKER_LIBS ${OpenCL_LIBRARIES}) | |||
list(APPEND RUNTIME_SRCS ${RUNTIME_OPENCL_SRCS}) | |||
if($ENV{XILINX_SDX}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would this conflict with runtime SDK?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When we have another SDK, we can still compile tvm and find multiple OpenCL platforms with clGetPlatformInfo(). Currently, tvm cannot handle this case but it's another problem:
https://github.com/dmlc/tvm/blob/1e66d3c/src/runtime/opencl/opencl_device_api.cc#L242
I think of sending another PR to support it.
Anyway, I'll remove this if condition since cmake can compile tvm for sdaccel in either way. It is not necessary to use headers and libraries in the Xilinx toolchain at compile time.
Thanks for all the reviews. I think the conclusion is that we want to bring this in. However, there are a few things we need to keep in mind as there are limitations in this approach.
|
@tqchen Thanks for your comments. I addressed your review comments and rebased onto the current master.
It sounds very nice! I'm looking forward to it. :) |
Thanks! this is merged |
This PR adds initial support for Xilinx FPGA boards with SDAccel. The following are included:
This PR is only preliminary implementation, but would be a good start point for FPGA supports, I think.