[EmitHLSCpp] some basic classes; hlsld-translate entry; add testcase

This commit is contained in:
Hanchen Ye 2020-08-26 23:23:22 -05:00
parent b35338e68e
commit 01baa10c97
7 changed files with 143 additions and 19 deletions

2
.clang-format Normal file
View File

@ -0,0 +1,2 @@
BasedOnStyle: LLVM
AlwaysBreakTemplateDeclarations: Yes

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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);
}

View File

@ -1,5 +1,6 @@
// RUN: hlsld-translate %s | FileCheck %s
// RUN: hlsld-translate -emit-hlscpp %s | FileCheck %s
// CHECK: new function
func @test_standard() {
}

View File

@ -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;
}