Skip to content

Commit

Permalink
Output data array is managed by Hipacc
Browse files Browse the repository at this point in the history
  • Loading branch information
oreiche committed Sep 1, 2018
1 parent 94ca74a commit f64b693
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 79 deletions.
7 changes: 3 additions & 4 deletions lib/Rewrite/CreateHostStrings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,10 +304,9 @@ void CreateHostStrings::writeMemoryTransfer(HipaccImage *Img, std::string mem,
break;
case DEVICE_TO_HOST:
resultStr += "hipaccReadMemory";
if (!options.emitVivado()) {
resultStr += "<" + Img->getTypeStr() + ">(";
} else {
resultStr += "(" + mem + ", ";
resultStr += "<" + Img->getTypeStr() + ">(";
if (options.emitVivado()) {
resultStr += mem + ", ";
}
resultStr += Img->getName() + ");";
break;
Expand Down
91 changes: 25 additions & 66 deletions lib/Rewrite/Rewrite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ class Rewrite : public ASTConsumer, public RecursiveASTVisitor<Rewrite> {
bool VisitDeclStmt(DeclStmt *D);
bool VisitFunctionDecl(FunctionDecl *D);
bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
bool VisitBinaryOperator(BinaryOperator *E);
bool VisitCXXMemberCallExpr(CXXMemberCallExpr *E);
bool VisitCallExpr(CallExpr *E);

Expand Down Expand Up @@ -1918,66 +1917,6 @@ bool Rewrite::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
}


bool Rewrite::VisitBinaryOperator(BinaryOperator *E) {
if (!compilerClasses.HipaccEoP || !compilerOptions.emitVivado()) return true;

// This function is Vivado only, because we need the right-hand side.
// Convert Image assignments to a variable into a memory transfer,
// e.g. in_ptr = OUT.data();
if (E->getOpcode() == BO_Assign && isa<CXXMemberCallExpr>(E->getRHS())) {
CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(E->getRHS());

// match only .data() calls to Image instances
if (MCE->getDirectCallee()->getNameAsString() != "data") return true;

if (isa<DeclRefExpr>(MCE->getImplicitObjectArgument()->IgnoreImpCasts())) {
DeclRefExpr *DRE =
dyn_cast<DeclRefExpr>(MCE->getImplicitObjectArgument()->IgnoreImpCasts());

// check if we have an Image
if (ImgDeclMap.count(DRE->getDecl())) {
HipaccImage *Img = ImgDeclMap[DRE->getDecl()];

std::string newStr;

// get the text string for the memory transfer dst
std::string dataStr;
llvm::raw_string_ostream DS(dataStr);
E->getLHS()->printPretty(DS, 0, PrintingPolicy(CI.getLangOpts()));

// create memory transfer string
std::string stream = dataDeps->getOutputStream(DRE->getDecl());
if (!stream.empty()) {
std::string typeCast;
if (isa<VectorType>(Img->getType()
.getCanonicalType().getTypePtr())) {
const VectorType *VT = dyn_cast<VectorType>(Img->getType()
.getCanonicalType().getTypePtr());
VectorTypeInfo info = createVectorTypeInfo(VT);
typeCast = "(" + getStdIntFromBitWidth(
info.elementCount * info.elementWidth) + "*)";
}
// call entry function, which creates current output
newStr = dataDeps->printEntryCall(entryArguments, Img->getName());
// TODO: find better solution than embedding stream in mem string
stringCreator.writeMemoryTransfer(Img,
stream + ", " + typeCast + DS.str(), DEVICE_TO_HOST, newStr);
}

// rewrite Image assignment to memory transfer
// get the start location and compute the semi location.
SourceLocation startLoc = E->getLocStart();
const char *startBuf = SM.getCharacterData(startLoc);
const char *semiPtr = strchr(startBuf, ';');
TextRewriter.ReplaceText(startLoc, semiPtr-startBuf+1, newStr);
}
}
}

return true;
}


bool Rewrite::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
if (!compilerClasses.HipaccEoP)
return true;
Expand Down Expand Up @@ -2121,16 +2060,36 @@ bool Rewrite::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
// get the Image from the DRE if we have one
if (ImgDeclMap.count(DRE->getDecl())) {
// match for supported member calls
if (ME->getMemberNameInfo().getAsString() == "data" &&
!compilerOptions.emitVivado()) {
if (ME->getMemberNameInfo().getAsString() == "data") {
if (skipTransfer) {
skipTransfer = false;
return true;
}
HipaccImage *Img = ImgDeclMap[DRE->getDecl()];
// create memory transfer string
stringCreator.writeMemoryTransfer(Img, "NULL", DEVICE_TO_HOST,
newStr);

std::string mem = "NULL";

if (compilerOptions.emitVivado()) {
// replace mem by stream (empty, if not output in dependency graph)
mem = dataDeps->getOutputStream(DRE->getDecl());

if (!mem.empty()){
// call entry function, which creates current output
std::string callStr = dataDeps->printEntryCall(entryArguments,
Img->getName());

// insert entry function call in the line before
unsigned fileNum = SM.getSpellingLineNumber(E->getLocStart(), nullptr);
SourceLocation callLoc = SM.translateLineCol(mainFileID, fileNum, 1);
TextRewriter.InsertText(callLoc, callStr);
}
}

if (!mem.empty()) {
// create memory transfer string
stringCreator.writeMemoryTransfer(Img, mem, DEVICE_TO_HOST, newStr);
}

// rewrite Image assignment to memory transfer
// get the start location and compute the semi location.
SourceLocation startLoc = E->getLocStart();
Expand Down
24 changes: 15 additions & 9 deletions runtime/hipacc_vivado.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,18 @@ void hipaccWriteMemory(HipaccImage &img, hls::stream<T1> &s, T2 *host_mem) {

// Read from stream
template<typename T1, typename T2>
void hipaccReadMemory(hls::stream<T1> &s, T2 *host_mem, HipaccImage &img) {
T1 *hipaccReadMemory(hls::stream<T2> &s, HipaccImage &img) {
int width = img->width;
int height = img->height;
T1 *host_mem = (T1*)img->host;

for (size_t i=0; i<width*height; ++i) {
T1 data;
T2 data;
s >> data;
host_mem[i] = data;
host_mem[i] = (T1)data;
}

return host_mem;
}


Expand Down Expand Up @@ -161,13 +164,14 @@ void hipaccWriteMemory(HipaccImage &img, hls::stream<ap_uint<BW> > &s, T2 *host_


// Read from stream
// T1 is ap_uint<32>
// T2 is uint (representing uchar4)
template<int BW, typename T2>
void hipaccReadMemory(hls::stream<ap_uint<BW> > &s, T2 *host_mem, HipaccImage &img) {
// T1 is uint (representing uchar4)
// T2 is ap_uint<32>
template<typename T1, int BW>
T1 *hipaccReadMemory(hls::stream<ap_uint<BW> > &s, HipaccImage &img) {
int width = img->width;
int height = img->height;
int vect = BW/8/sizeof(T2);
int vect = BW/8/sizeof(T1);
T1 *host_mem = (T1*)img->host;

for (size_t y=0; y<height; ++y) {
for (size_t x=0; x<width; x+=vect) {
Expand All @@ -183,10 +187,12 @@ void hipaccReadMemory(hls::stream<ap_uint<BW> > &s, T2 *host_mem, HipaccImage &i
}
} else {
ap_uint<BW> temp = hipaccReverseBits<ap_uint<BW> >(data);
host_mem[i] = *(T2*)&temp;
host_mem[i] = *(T1*)&temp;
}
}
}

return host_mem;
}


Expand Down

0 comments on commit f64b693

Please sign in to comment.