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

Add initial support for Intel FPGA SDK for OpenCL (AOCL) #1474

Merged
merged 27 commits into from
Jul 31, 2018
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8a5ffdb
Support OpenCL offline compilation
oss-dev-somewhere Jul 13, 2018
8b0eef8
Merge branch 'aocl' of github.com:ktabata/tvm into aocl
oss-dev-somewhere Jul 20, 2018
120979c
AOCL emulation runs.
oss-dev-somewhere Jul 23, 2018
ca137cb
Support OpenCL offline compilation
oss-dev-somewhere Jul 13, 2018
f2257d0
AOCL emulation runs.
oss-dev-somewhere Jul 23, 2018
edd0437
tab to white spaces.
oss-dev-somewhere Jul 23, 2018
8c22538
Resolved conflicts.
oss-dev-somewhere Jul 23, 2018
aca96a5
Fixed macro error.
oss-dev-somewhere Jul 23, 2018
5016f73
Fixed submodule.
oss-dev-somewhere Jul 23, 2018
ed47e4a
Implemented AOCLWorkspace.
oss-dev-somewhere Jul 25, 2018
d51f19e
Fixed document.
oss-dev-somewhere Jul 25, 2018
2c18ee0
Fixed document.
oss-dev-somewhere Jul 25, 2018
fd3d4fa
Deleted macro.
oss-dev-somewhere Jul 25, 2018
5b578e2
Fixed file header.
oss-dev-somewhere Jul 25, 2018
66a46ea
Fixed file header.
oss-dev-somewhere Jul 25, 2018
fb80366
Deleted includes.
oss-dev-somewhere Jul 25, 2018
0030c81
Fixed OpenCL.cmake
oss-dev-somewhere Jul 25, 2018
65ad10d
Fixed platform name for AOCL.
oss-dev-somewhere Jul 25, 2018
d3ab18a
Fixed device type.
oss-dev-somewhere Jul 25, 2018
3a49eee
Fixed document.
oss-dev-somewhere Jul 25, 2018
93d8d9f
Added -mattr=emulator option.
oss-dev-somewhere Jul 25, 2018
b174098
Fixed documentation.
oss-dev-somewhere Jul 25, 2018
68569d9
Fixed documentation.
oss-dev-somewhere Jul 25, 2018
d4d435f
Fixed documentation.
oss-dev-somewhere Jul 25, 2018
9d45ead
Fixed documentation.
oss-dev-somewhere Jul 25, 2018
8ff0272
Use s5_ref for target device.
oss-dev-somewhere Jul 27, 2018
f7317b0
Added testcases.
oss-dev-somewhere Jul 28, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions cmake/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ set(USE_ROCM OFF)
# Whether enable SDAccel runtime
set(USE_SDACCEL OFF)

# Whether enable Intel FPGA SDK for OpenCL (AOCL) during compile,
#
# Possible values:
# - OFF: disbale AOCL
# - board_name: use specific board name for offline compilation
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the board name should be passed with target options (e.g. tvm.context("opencl -device=[board name]")).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to use target name option like tgt="aocl -device=de5net_a7".

set(USE_AOCL OFF)

# Whether enable OpenCL runtime
set(USE_OPENCL OFF)

Expand Down
9 changes: 9 additions & 0 deletions cmake/modules/OpenCL.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ else()
list(APPEND COMPILER_SRCS src/codegen/opt/build_sdaccel_off.cc)
endif(USE_SDACCEL)

if(USE_AOCL)
message(STATUS "Build with Intel FPGA SDK for OpenCL support")
add_definitions(-DAOCL_BOARD_NAME="${USE_AOCL}")
if(NOT USE_OPENCL)
message(STATUS "Enable OpenCL support required for Intel FPGA SDK for OpenCL")
set(USE_OPENCL ON)
endif()
endif(USE_AOCL)

if(USE_OPENCL)
find_package(OpenCL REQUIRED)
message(STATUS "Build with OpenCL support")
Expand Down
56 changes: 56 additions & 0 deletions docs/deploy/aocl_fpga.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
AOCL Backend Example
====================

TVM supports Intel FPGA SDK for OpenCL also known as AOCL. Here is a tutorial for how to use TVM with AOCL.

***Note***: This feature is still experimental. We cannot use AOCL to deploy an end to end neural networks for now. In addition, we can only use AOCL's emulation mode for now.

We use a python scripts for this tutorial.

- emu-aocl-fpga.py
```# -*- coding: utf-8 -*-
import tvm
import numpy as np

tgt_host = 'llvm'
tgt = 'opencl'

# Define a computation.
n = tvm.var('n')
a = tvm.placeholder((n,), name='a')
b = tvm.placeholder((n,), name='b')
c = tvm.compute(a.shape, lambda i: a[i] + b[i], name='c')

# Make a schedule.
s = tvm.create_schedule(c.op)
px, x = s[c].split(c.op.axis[0], nparts=1)
s[c].bind(px, tvm.thread_axis("pipeline"))

# Make a executable code.
fadd = tvm.build(s, [a, b, c], tgt, target_host=tgt_host, name='myadd')

# Run.
ctx = tvm.context(tgt, 0)
n = 1024
a = tvm.nd.array(np.random.uniform(size=n).astype(a.dtype), ctx)
b = tvm.nd.array(np.random.uniform(size=n).astype(b.dtype), ctx)
c = tvm.nd.array(np.zeros(n, dtype=c.dtype), ctx)
fadd(a, b, c)```

Setup
-----

- Install AOCL 17.1 on Ubuntu 16.04.4 LTS.
- Install FPGA device driver.
- Make ICD file.
- Make FCD file.
- Setup TVM with AOCL and OpenCL enabled.

Emulation
---------

- Set environment variable.
```export CL_CONTEXT_EMULATOR_DEVICE_INTELFPGA=1```

- Run software emulation
```python emu-aocl-fpga.py```
8 changes: 8 additions & 0 deletions src/runtime/opencl/opencl_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,11 @@ class OpenCLWorkspace : public DeviceAPI {
void Init(const std::string& type_key, const std::string& device_type,
const std::string& platform_name = "");
virtual void Init() {
#ifndef AOCL_BOARD_NAME
Init("opencl", "gpu");
#else
Init("opencl", "accelerator");
#endif
Copy link
Contributor

Choose a reason for hiding this comment

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

Implement AOCLWorkspace as a subclass of OpenCLWorkspace so that it can coexist with other OpenCL platforms.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Introduced AOCLWorkspace.

}
// Check whether the context is OpenCL or not.
virtual bool IsOpenCLDevice(TVMContext ctx) {
Expand Down Expand Up @@ -284,6 +288,10 @@ class OpenCLModuleNode : public ModuleNode {
std::unordered_map<std::string, KTRefEntry> kid_map_;
// kernels build so far.
std::vector<cl_kernel> kernels_;

#ifdef AOCL_BOARD_NAME
void OfflineCompile(cl::OpenCLWorkspace* w, cl::OpenCLThreadEntry* t);
#endif
};

} // namespace runtime
Expand Down
4 changes: 4 additions & 0 deletions src/runtime/opencl/opencl_device_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,11 @@ std::vector<cl_device_id> GetDeviceIDs(
cl_device_type dtype = CL_DEVICE_TYPE_ALL;
if (device_type == "cpu") dtype = CL_DEVICE_TYPE_CPU;
if (device_type == "gpu") dtype = CL_DEVICE_TYPE_GPU;
#ifndef AOCL_BOARD_NAME
if (device_type == "accelerator") dtype = CL_DEVICE_TYPE_ACCELERATOR;
#else
if (device_type == "accelerator") dtype = CL_DEVICE_TYPE_DEFAULT;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do you want to use CL_DEVICE_TYPE_DEFAULT here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Deleted this code and now works with device_type == "accelerator".

#endif
cl_uint ret_size;
cl_int code = clGetDeviceIDs(pid, dtype, 0, nullptr, &ret_size);
std::vector<cl_device_id> ret;
Expand Down
54 changes: 54 additions & 0 deletions src/runtime/opencl/opencl_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <tvm/runtime/registry.h>
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <unordered_map>
#include "./opencl_common.h"
#include "./opencl_module.h"
Expand Down Expand Up @@ -185,11 +187,15 @@ cl_kernel OpenCLModuleNode::InstallKernel(cl::OpenCLWorkspace* w,
// create program
if (fmt_ == "cl") {
if (program_ == nullptr) {
#ifndef AOCL_BOARD_NAME
const char* s = data_.c_str();
size_t len = data_.length();
cl_int err;
program_ = clCreateProgramWithSource(w->context, 1, &s, &len, &err);
OPENCL_CHECK_ERROR(err);
#else
OfflineCompile(w, t);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be moved to codegen since compiling OpenCL codes for FPGAs takes very long time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Offline compilation was moved to codegen. See also BuildAOCL().

#endif
}
} else if (fmt_ == "xclbin" || fmt_ == "awsxclbin") {
const unsigned char* s = (const unsigned char *)data_.c_str();
Expand Down Expand Up @@ -227,6 +233,54 @@ cl_kernel OpenCLModuleNode::InstallKernel(cl::OpenCLWorkspace* w,
return kernel;
}

#ifdef AOCL_BOARD_NAME
void OpenCLModuleNode::OfflineCompile(cl::OpenCLWorkspace* w,
cl::OpenCLThreadEntry* t) {
// Write a .cl file.
std::ofstream ofs("aocltmp.cl");
if (!ofs) {
LOG(FATAL) << "Can't create OpenCL temporary file.";
}
ofs << data_.c_str();
if (!ofs) {
LOG(FATAL) << "Can't write to OpenCL temporary file.";
}
ofs.close();

// Compile the .cl file.
std::string cmd = "aoc aocltmp.cl -march=emulator -board=";
cmd += AOCL_BOARD_NAME;
if (system(cmd.c_str()) != 0) {
LOG(FATAL) << "OpenCL offline compilation error.";
}

// Read .aocx file
std::ifstream ifs("aocltmp.aocx", std::ios::in | std::ios::binary);
if (!ifs) {
LOG(FATAL) << "Can't open aocltmp.aocx file.";
}
ifs.seekg(0, std::fstream::end);
const size_t len = ifs.tellg();
char *buf = new char[len];
ifs.clear();
ifs.seekg(0, std::fstream::beg);
ifs.read(buf, len);
if (!ifs) {
LOG(FATAL) << "Can't read aocltmp.aocx file.";
}

// Create program from aocx.
cl_int err;
int device_id = t->context.device_id;
cl_device_id dev = w->devices[device_id];
const unsigned char* s = (const unsigned char *)buf;
program_ = clCreateProgramWithBinary(w->context, 1, &dev, &len, &s, NULL, &err);
OPENCL_CHECK_ERROR(err);

delete[] buf;
}
#endif

Module OpenCLModuleCreate(
std::string data,
std::string fmt,
Expand Down