[EmitHLSCpp] some basic classes; hlsld-translate entry; add testcase
This commit is contained in:
parent
b35338e68e
commit
01baa10c97
|
@ -0,0 +1,2 @@
|
|||
BasedOnStyle: LLVM
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
|
@ -34,7 +34,6 @@ set(HLSLD_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
|||
set(HLSLD_BINARY_DIR ${CMAKE_BINARY_DIR}/bin)
|
||||
set(HLSLD_TOOLS_DIR ${CMAKE_BINARY_DIR}/bin)
|
||||
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${MLIR_CMAKE_DIR}")
|
||||
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
|
||||
include(TableGen)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# HLS Large Design Project (HLSLD)
|
||||
|
||||
## High Level Description of Project
|
||||
This project aims to create a framework that ultimately converts an algorithm written in a high level language into an efficient hardware implementation. Out of all of the existing deep learning compiler related projects, TVM and MLIR present existing tools that we can leverage in our proposed framework. With multiple levels of intermediate representations (IRs), MLIR appears to be the ideal tool for exploring ways to optimize the eventual design at various levels of abstraction (e.g. various levels of parallelism). Our framework will be based on MLIR, but it will incorporate a frontend for Sitao's powerful domain specific language (DSL) and a backend for high level synthesis (HLS) C/C++ code. However, the key contribution will be our parametrization and optimization of a tremendously large design space. So far, we are familiarizing ourselves with the existing MLIR flow using a toy example (simple neural network for MNIST digit classification) and figure out how to do this parametrization and optimization.
|
||||
|
||||
## Quick Start
|
||||
|
@ -16,6 +15,6 @@ cmake --build . --target check-hlsld
|
|||
|
||||
## References
|
||||
1. [MLIR Documents](https://mlir.llvm.org)
|
||||
2. [github mlir-npcomp](https://github.com/llvm/mlir-npcomp)
|
||||
3. [github circt](https://github.com/llvm/circt)
|
||||
4. [github onnx-mlir](https://github.com/onnx/onnx-mlir)
|
||||
2. [mlir-npcomp github](https://github.com/llvm/mlir-npcomp)
|
||||
3. [circt github](https://github.com/llvm/circt)
|
||||
4. [onnx-mlir github](https://github.com/onnx/onnx-mlir)
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
//===------------------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef HLSLD_EMIT_HLSCPP_H
|
||||
#define HLSLD_EMIT_HLSCPP_H
|
||||
|
||||
namespace hlsld {
|
||||
void registerHLSCppEmitterTranslation();
|
||||
} // namespace hlsld
|
||||
|
||||
#endif // HLSLD_EMIT_HLSCPP_H
|
||||
|
|
|
@ -1,3 +1,122 @@
|
|||
//===------------------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "EmitHLSCpp.h"
|
||||
#include "mlir/IR/Function.h"
|
||||
#include "mlir/IR/Module.h"
|
||||
#include "mlir/IR/StandardTypes.h"
|
||||
#include "mlir/Translation.h"
|
||||
#include "llvm/ADT/StringSet.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace mlir;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Utilities
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
/// This class maintains the mutable state that cross-cuts and is shared by the
|
||||
/// various emitters.
|
||||
class HLSCppEmitterState {
|
||||
public:
|
||||
explicit HLSCppEmitterState(raw_ostream &os) : os(os) {}
|
||||
|
||||
/// The stream to emit to.
|
||||
raw_ostream &os;
|
||||
|
||||
bool encounteredError = false;
|
||||
unsigned currentIndent = 0;
|
||||
|
||||
private:
|
||||
HLSCppEmitterState(const HLSCppEmitterState &) = delete;
|
||||
void operator=(const HLSCppEmitterState &) = delete;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
/// This is the base class for all of the HLSCpp Emitter components.
|
||||
class HLSCppEmitterBase {
|
||||
public:
|
||||
explicit HLSCppEmitterBase(HLSCppEmitterState &state)
|
||||
: state(state), os(state.os) {}
|
||||
|
||||
InFlightDiagnostic emitError(Operation *op, const Twine &message) {
|
||||
state.encounteredError = true;
|
||||
return op->emitError(message);
|
||||
}
|
||||
|
||||
InFlightDiagnostic emitOpError(Operation *op, const Twine &message) {
|
||||
state.encounteredError = true;
|
||||
return op->emitOpError(message);
|
||||
}
|
||||
|
||||
raw_ostream &indent() { return os.indent(state.currentIndent); }
|
||||
|
||||
void addIndent() { state.currentIndent += 2; }
|
||||
void reduceIndent() { state.currentIndent -= 2; }
|
||||
|
||||
// All of the mutable state we are maintaining.
|
||||
HLSCppEmitterState &state;
|
||||
|
||||
/// The stream to emit to.
|
||||
raw_ostream &os;
|
||||
|
||||
private:
|
||||
HLSCppEmitterBase(const HLSCppEmitterBase &) = delete;
|
||||
void operator=(const HLSCppEmitterBase &) = delete;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// FuncEmitter
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
class FuncEmitter : public HLSCppEmitterBase {
|
||||
public:
|
||||
explicit FuncEmitter(HLSCppEmitterState &state) : HLSCppEmitterBase(state) {}
|
||||
|
||||
void emitFunc(FuncOp func);
|
||||
};
|
||||
} // namespace
|
||||
|
||||
void FuncEmitter::emitFunc(FuncOp func) { os << "new function\n"; };
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// HLSCppEmitter
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
class HLSCppEmitter : public HLSCppEmitterBase {
|
||||
public:
|
||||
explicit HLSCppEmitter(HLSCppEmitterState &state)
|
||||
: HLSCppEmitterBase(state) {}
|
||||
|
||||
void emitMLIRModule(ModuleOp module);
|
||||
};
|
||||
} // namespace
|
||||
|
||||
void HLSCppEmitter::emitMLIRModule(ModuleOp module) {
|
||||
for (auto &op : *module.getBody()) {
|
||||
if (auto func = dyn_cast<FuncOp>(op))
|
||||
FuncEmitter(state).emitFunc(func);
|
||||
else if (!isa<ModuleTerminatorOp>(op))
|
||||
op.emitError("unknown operation");
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// hlsld-translate Entry
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static LogicalResult emitHLSCpp(ModuleOp module, llvm::raw_ostream &os) {
|
||||
HLSCppEmitterState state(os);
|
||||
HLSCppEmitter(state).emitMLIRModule(module);
|
||||
return failure(state.encounteredError);
|
||||
}
|
||||
|
||||
void hlsld::registerHLSCppEmitterTranslation() {
|
||||
static TranslateFromMLIRRegistration toHLSCpp("emit-hlscpp", emitHLSCpp);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// RUN: hlsld-translate %s | FileCheck %s
|
||||
// RUN: hlsld-translate -emit-hlscpp %s | FileCheck %s
|
||||
|
||||
// CHECK: new function
|
||||
func @test_standard() {
|
||||
|
||||
}
|
|
@ -38,11 +38,12 @@ static llvm::cl::opt<bool> verifyDiagnostics(
|
|||
"expected-* lines on the corresponding line"),
|
||||
llvm::cl::init(false));
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int main(int argc, char **argv) {
|
||||
mlir::registerAllDialects();
|
||||
mlir::registerAllTranslations();
|
||||
|
||||
hlsld::registerHLSCppEmitterTranslation();
|
||||
|
||||
llvm::InitLLVM y(argc, argv);
|
||||
|
||||
// Add flags for all the registered translations.
|
||||
|
@ -55,15 +56,13 @@ int main(int argc, char **argv)
|
|||
|
||||
std::string errorMessage;
|
||||
auto input = mlir::openInputFile(inputFilename, &errorMessage);
|
||||
if (!input)
|
||||
{
|
||||
if (!input) {
|
||||
llvm::errs() << errorMessage << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto output = mlir::openOutputFile(outputFilename, &errorMessage);
|
||||
if (!output)
|
||||
{
|
||||
if (!output) {
|
||||
llvm::errs() << errorMessage << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
@ -77,8 +76,7 @@ int main(int argc, char **argv)
|
|||
llvm::SourceMgr sourceMgr;
|
||||
sourceMgr.AddNewSourceBuffer(std::move(ownedBuffer), llvm::SMLoc());
|
||||
|
||||
if (!verifyDiagnostics)
|
||||
{
|
||||
if (!verifyDiagnostics) {
|
||||
mlir::SourceMgrDiagnosticHandler sourceMgrHandler(sourceMgr, &context);
|
||||
return (*translationRequested)(sourceMgr, os, &context);
|
||||
}
|
||||
|
@ -92,14 +90,11 @@ int main(int argc, char **argv)
|
|||
return sourceMgrHandler.verify();
|
||||
};
|
||||
|
||||
if (splitInputFile)
|
||||
{
|
||||
if (splitInputFile) {
|
||||
if (failed(mlir::splitAndProcessBuffer(std::move(input), processBuffer,
|
||||
output->os())))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (failed(processBuffer(std::move(input), output->os())))
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue