forked from apache/tvm
-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Hardware][Verilator] Integrating and simulating hardware accelerator…
…s in TVM (apache#6971) * add files * update interface * update * fix comment * fix fmt * remove widget repo * remove
- Loading branch information
1 parent
abd91ba
commit 61b2a14
Showing
7 changed files
with
346 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Licensed to the Apache Software Foundation (ASF) under one | ||
# or more contributor license agreements. See the NOTICE file | ||
# distributed with this work for additional information | ||
# regarding copyright ownership. The ASF licenses this file | ||
# to you under the Apache License, Version 2.0 (the | ||
# "License"); you may not use this file except in compliance | ||
# with the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, | ||
# software distributed under the License is distributed on an | ||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
# KIND, either express or implied. See the License for the | ||
# specific language governing permissions and limitations | ||
# under the License. | ||
|
||
if(USE_VERILATOR_HW STREQUAL "ON") | ||
file(GLOB VERILATOR_RELAY_CONTRIB_SRC src/relay/backend/contrib/verilator/codegen.cc) | ||
list(APPEND COMPILER_SRCS ${VERILATOR_RELAY_CONTRIB_SRC}) | ||
list(APPEND COMPILER_SRCS ${JSON_RELAY_CONTRIB_SRC}) | ||
find_library(EXTERN_LIBRARY_VERILATOR NAMES verilator PATHS ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/hw-widgets) | ||
list(APPEND TVM_RUNTIME_LINKER_LIBS ${EXTERN_LIBRARY_VERILATOR}) | ||
file(GLOB VERILATOR_CONTRIB_SRC src/runtime/contrib/verilator/verilator_runtime.cc) | ||
list(APPEND RUNTIME_SRCS ${VERILATOR_CONTRIB_SRC}) | ||
endif() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
/*! | ||
* \file src/relay/backend/contrib/verilator/codegen.cc | ||
* \brief Implementation of Verilator codegen APIs. | ||
*/ | ||
|
||
#include <tvm/relay/attrs/nn.h> | ||
#include <tvm/relay/expr_functor.h> | ||
#include <tvm/relay/transform.h> | ||
#include <tvm/relay/type.h> | ||
#include <tvm/runtime/module.h> | ||
#include <tvm/runtime/registry.h> | ||
|
||
#include <fstream> | ||
#include <numeric> | ||
#include <sstream> | ||
|
||
#include "../../../../runtime/contrib/json/json_node.h" | ||
#include "../../utils.h" | ||
#include "../codegen_json/codegen_json.h" | ||
|
||
namespace tvm { | ||
namespace relay { | ||
namespace contrib { | ||
|
||
using namespace backend; | ||
|
||
class VerilatorJSONSerializer : public backend::contrib::JSONSerializer { | ||
using JSONGraphNode = tvm::runtime::json::JSONGraphNode; | ||
using JSONGraphNodeEntry = tvm::runtime::json::JSONGraphNodeEntry; | ||
|
||
public: | ||
VerilatorJSONSerializer(const std::string& symbol, const Expr& expr) | ||
: JSONSerializer(symbol, expr) {} | ||
|
||
std::vector<JSONGraphNodeEntry> VisitExpr_(const CallNode* cn) override { | ||
Expr expr = GetRef<Expr>(cn); | ||
std::string name; | ||
const CallNode* call = cn; | ||
if (const auto* op_node = cn->op.as<OpNode>()) { | ||
name = op_node->name; | ||
} else { | ||
LOG(FATAL) << "Verilator JSON runtime does not support calls to " << cn->op->GetTypeKey(); | ||
} | ||
|
||
std::vector<JSONGraphNodeEntry> inputs; | ||
for (const auto& arg : cn->args) { | ||
auto res = VisitExpr(arg); | ||
inputs.insert(inputs.end(), res.begin(), res.end()); | ||
} | ||
auto node = std::make_shared<JSONGraphNode>(name, /* name_ */ | ||
"kernel", /* op_type_ */ | ||
inputs, 1 /* num_outputs_ */); | ||
SetCallNodeAttribute(node, call); | ||
return AddNode(node, GetRef<Expr>(cn)); | ||
} | ||
}; | ||
|
||
/*! | ||
* \brief The external compiler/codegen tool. It takes a Relay expression/module and | ||
* compile it into a runtime module. | ||
*/ | ||
runtime::Module VerilatorCompiler(const ObjectRef& ref) { | ||
CHECK(ref->IsInstance<FunctionNode>()); | ||
auto func = Downcast<Function>(ref); | ||
auto func_name = GetExtSymbol(func); | ||
VerilatorJSONSerializer serializer(func_name, func); | ||
serializer.serialize(); | ||
std::string graph_json = serializer.GetJSON(); | ||
auto params = serializer.GetParams(); | ||
|
||
const auto* pf = runtime::Registry::Get("runtime.VerilatorJSONRuntimeCreate"); | ||
CHECK(pf != nullptr) << "Cannot find JSON runtime module to create"; | ||
auto mod = (*pf)(func_name, graph_json, params); | ||
return mod; | ||
} | ||
|
||
TVM_REGISTER_GLOBAL("relay.ext.verilator").set_body_typed(VerilatorCompiler); | ||
|
||
} // namespace contrib | ||
} // namespace relay | ||
} // namespace tvm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
/*! | ||
* \file src/runtime/contrib/verilator/verilator_device.h | ||
* \brief Use external verilator device. | ||
*/ | ||
|
||
#ifndef TVM_RUNTIME_CONTRIB_VERILATOR_VERILATOR_DEVICE_H_ | ||
#define TVM_RUNTIME_CONTRIB_VERILATOR_VERILATOR_DEVICE_H_ | ||
|
||
#include <tvm/runtime/c_runtime_api.h> | ||
|
||
namespace tvm { | ||
namespace runtime { | ||
namespace contrib { | ||
|
||
typedef void* VerilatorHandle; | ||
|
||
/* allocate Verilator object */ | ||
extern "C" TVM_DLL VerilatorHandle VerilatorAlloc(); | ||
|
||
/* deallocate Verilator object */ | ||
extern "C" TVM_DLL void VerilatorDealloc(VerilatorHandle handle); | ||
|
||
/* read Verilator register or memory */ | ||
extern "C" TVM_DLL int VerilatorRead(VerilatorHandle handle, int id, int addr); | ||
|
||
/* write Verilator register or memory */ | ||
extern "C" TVM_DLL void VerilatorWrite(VerilatorHandle handle, int id, int addr, int value); | ||
|
||
/* reset Verilator for n clock cycles */ | ||
extern "C" TVM_DLL void VerilatorReset(VerilatorHandle handle, int n); | ||
|
||
/* run Verilator for n clock cycles */ | ||
extern "C" TVM_DLL void VerilatorRun(VerilatorHandle handle, int n); | ||
|
||
} // namespace contrib | ||
} // namespace runtime | ||
} // namespace tvm | ||
#endif // TVM_RUNTIME_CONTRIB_VERILATOR_VERILATOR_DEVICE_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
/*! | ||
* \file src/runtime/contrib/verilator/verilator_kernel.h | ||
* \brief Use external verilator library kernels. | ||
*/ | ||
|
||
#ifndef TVM_RUNTIME_CONTRIB_VERILATOR_VERILATOR_KERNEL_H_ | ||
#define TVM_RUNTIME_CONTRIB_VERILATOR_VERILATOR_KERNEL_H_ | ||
|
||
#include <tvm/runtime/c_runtime_api.h> | ||
|
||
#include "verilator_device.h" | ||
|
||
namespace tvm { | ||
namespace runtime { | ||
namespace contrib { | ||
|
||
extern "C" TVM_DLL void verilator_add(VerilatorHandle handle, int* data, int* weight, int* out, | ||
int p_h_, int p_w_); | ||
|
||
} // namespace contrib | ||
} // namespace runtime | ||
} // namespace tvm | ||
#endif // TVM_RUNTIME_CONTRIB_VERILATOR_VERILATOR_KERNEL_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
/*! | ||
* \file src/runtime/contrib/verilator/verilator_runtime.cc | ||
* \brief A simple JSON runtime for Verilator. | ||
*/ | ||
|
||
#include <tvm/runtime/ndarray.h> | ||
#include <tvm/runtime/registry.h> | ||
|
||
#include <cstddef> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include "../json/json_node.h" | ||
#include "../json/json_runtime.h" | ||
#include "verilator_device.h" | ||
#include "verilator_kernel.h" | ||
|
||
namespace tvm { | ||
namespace runtime { | ||
namespace contrib { | ||
|
||
using namespace tvm::runtime; | ||
using namespace tvm::runtime::json; | ||
|
||
class VerilatorJSONRuntime : public JSONRuntimeBase { | ||
public: | ||
VerilatorJSONRuntime(const std::string& symbol_name, const std::string& graph_json, | ||
const Array<String> const_names) | ||
: JSONRuntimeBase(symbol_name, graph_json, const_names) {} | ||
|
||
const char* type_key() const { return "verilator_json"; } | ||
|
||
void Init(const Array<NDArray>& consts) override { | ||
BuildEngine(); | ||
|
||
CHECK_EQ(consts.size(), const_idx_.size()) | ||
<< "The number of input constants must match the number of required."; | ||
|
||
// Setup constants entries for weights. | ||
SetupConstants(consts); | ||
} | ||
|
||
void Run() override { | ||
std::vector<int*> in_ptr; | ||
std::vector<int*> out_ptr; | ||
for (size_t i = 0; i < input_nodes_.size(); ++i) { | ||
uint32_t eid = EntryID(input_nodes_[i], 0); | ||
int* data = static_cast<int*>(data_entry_[eid]->data); | ||
in_ptr.push_back(data); | ||
} | ||
for (size_t i = 0; i < outputs_.size(); ++i) { | ||
uint32_t eid = EntryID(outputs_[i]); | ||
int* data = static_cast<int*>(data_entry_[eid]->data); | ||
out_ptr.push_back(data); | ||
} | ||
for (size_t nid = 0; nid < nodes_.size(); ++nid) { | ||
const auto& node = nodes_[nid]; | ||
if (node.GetOpType() == "kernel") { | ||
CHECK_EQ(node.GetOpType(), "kernel"); | ||
auto op_name = node.GetOpName(); | ||
if ("add" == op_name) { | ||
auto entry = node.GetInputs()[0]; | ||
auto shape = nodes_[entry.id_].GetOpShape()[entry.index_]; | ||
verilator_add(device_, in_ptr[0], in_ptr[1], out_ptr[0], shape[0], shape[1]); | ||
} else { | ||
LOG(FATAL) << "Unsupported op: " << op_name; | ||
} | ||
} | ||
} | ||
} | ||
|
||
private: | ||
void BuildEngine() { | ||
device_ = VerilatorAlloc(); | ||
// reset for 10 cycles | ||
VerilatorReset(device_, 10); | ||
} | ||
|
||
/* The verilator handle. */ | ||
VerilatorHandle device_{nullptr}; | ||
}; | ||
|
||
runtime::Module VerilatorJSONRuntimeCreate(String symbol_name, String graph_json, | ||
const Array<String>& const_names) { | ||
auto n = make_object<VerilatorJSONRuntime>(symbol_name, graph_json, const_names); | ||
return runtime::Module(n); | ||
} | ||
|
||
TVM_REGISTER_GLOBAL("runtime.VerilatorJSONRuntimeCreate") | ||
.set_body_typed(VerilatorJSONRuntimeCreate); | ||
|
||
TVM_REGISTER_GLOBAL("runtime.module.loadbinary_verilator_json") | ||
.set_body_typed(JSONRuntimeBase::LoadFromBinary<VerilatorJSONRuntime>); | ||
|
||
} // namespace contrib | ||
} // namespace runtime | ||
} // namespace tvm |