SRDAGGraph* result_Test0_1(PiSDFGraph* pisdf, Stack* stack){ SRDAGGraph* srdag = CREATE(stack, SRDAGGraph)(stack); PiSDFGraph* topPisdf = pisdf->getBody(0)->getSubGraph(); SRDAGVertex* vxC = srdag->addVertex(topPisdf->getConfig(0)); SRDAGVertex* vxA = srdag->addVertex(topPisdf->getBody(0)); SRDAGVertex* vxB0 = srdag->addVertex(topPisdf->getBody(1)); SRDAGVertex* vxB1 = srdag->addVertex(topPisdf->getBody(1)); SRDAGVertex* vxCheck = srdag->addVertex(topPisdf->getBody(2)); SRDAGVertex* vxF = srdag->addFork(2); SRDAGVertex* vxJ = srdag->addJoin(2); vxB0->addInParam(0, 1); vxB1->addInParam(0, 1); vxCheck->addInParam(0, 1); srdag->addEdge( vxA, 0, vxF, 0, 2); srdag->addEdge( vxF, 0, vxB0, 0, 1); srdag->addEdge( vxF, 1, vxB1, 0, 1); srdag->addEdge( vxB0, 0, vxJ, 0, 1); srdag->addEdge( vxB1, 0, vxJ, 1, 1); srdag->addEdge( vxJ, 0, vxCheck, 0, 2); return srdag; }
void SRDAGVertex::updateState(){ if(state_ == SRDAG_NEXEC){ /* Check Input Edges */ for (int i = 0; i < getNConnectedInEdge(); i++){ SRDAGVertex* predecessor = getInEdge(i)->getSrc(); if(!predecessor || predecessor->isHierarchical()){ state_ = SRDAG_NEXEC; return; } if(predecessor->state_ == SRDAG_NEXEC){ predecessor->updateState(); if(predecessor->state_ == SRDAG_NEXEC){ state_ = SRDAG_NEXEC; return; } } } state_ = SRDAG_EXEC; } }
SRDAGGraph* result_Test0_2(PiSDFGraph* pisdf, Stack* stack){ SRDAGGraph* srdag = CREATE(stack, SRDAGGraph)(stack); PiSDFGraph* topPisdf = pisdf->getBody(0)->getSubGraph(); SRDAGVertex* vxC = srdag->addVertex(topPisdf->getConfig(0)); SRDAGVertex* vxA = srdag->addVertex(topPisdf->getBody(0)); SRDAGVertex* vxB = srdag->addVertex(topPisdf->getBody(1)); SRDAGVertex* vxCheck = srdag->addVertex(topPisdf->getBody(2)); vxB->addInParam(0, 2); vxCheck->addInParam(0, 2); srdag->addEdge( vxA, 0, vxB, 0, 2); srdag->addEdge( vxB, 0, vxCheck, 0, 2); return srdag; }
static int reduceInitEnd(SRDAGGraph* topDag){ for(int i=0; i<topDag->getNVertex(); i++){ SRDAGVertex* init = topDag->getVertex(i); if(init && init->getState() == SRDAG_EXEC && init->getType() == SRDAG_INIT){ SRDAGVertex* end = init->getOutEdge(0)->getSnk(); if(end && end->getState() == SRDAG_EXEC && end->getType() == SRDAG_END){ SRDAGEdge* edge = init->getOutEdge(0); edge->disconnectSrc(); edge->disconnectSnk(); topDag->delEdge(edge); topDag->delVertex(end); topDag->delVertex(init); return 1; } } } return 0; }
bool SRDAGGraph::check(){ bool result = true; /* Check vertices */ for (int i=0; i<vertices_.getN(); i++){ SRDAGVertex* vertex = vertices_[i]; int j; // Check input edges for(j=0; j<vertex->getNConnectedInEdge(); j++){ const SRDAGEdge* edge = vertex->getInEdge(j); if(vertex->getType() == SRDAG_JOIN && edge == NULL){ printf("Warning V%d Input%d: not connected\n", vertex->getId(), j); }else if(edge == NULL){ printf("Error V%d Input%d: not connected\n", vertex->getId(), j); result = false; }else if(edge->getSnk() != vertex){ printf("Error V%d E%d: connection mismatch\n", vertex->getId(), edge->getId()); result = false; } } // Check output edges for(j=0; j<vertex->getNConnectedOutEdge(); j++){ const SRDAGEdge* edge = vertex->getOutEdge(j); if(vertex->getType() == SRDAG_FORK && edge == NULL){ printf("Warning V%d Output%d: not connected\n", vertex->getId(), j); }else if(edge == NULL){ printf("Error V%d Output%d: not connected\n", vertex->getId(), j); result = false; }else if(edge->getSrc() != vertex){ printf("Error V%d E%d: connection mismatch\n", vertex->getId(), edge->getId()); result = false; } } } /* Check edges */ return result; }
/** Print Fct */ void SRDAGGraph::print(const char *path){ if(!check()) printf("Errors in the SRDAG Graph\n"); int maxId = -1; int file = Platform::get()->fopen(path); if(file == -1){ printf("cannot open %s\n", path); return; } // Writing header Platform::get()->fprintf(file, "digraph csdag {\n"); Platform::get()->fprintf(file, "\tnode [color=\"#433D63\"];\n"); Platform::get()->fprintf(file, "\tedge [color=\"#9262B6\" arrowhead=\"empty\"];\n"); Platform::get()->fprintf(file, "\trankdir=LR;\n\n"); // Drawing vertices. Platform::get()->fprintf(file, "\t# Vertices\n"); for (int i=0; i<vertices_.getN(); i++){ char name[100]; SRDAGVertex* vertex = vertices_[i]; vertex->toString(name, 100); Platform::get()->fprintf(file, "\t%d [shape=ellipse,label=\"%d\\n%s (%d)\n%s", vertex->getId(), vertex->getId(), name, vertex->getFctId(), stateStrings[vertex->getState()]); Platform::get()->fprintf(file, "\",color="); switch (vertex->getState()){ case SRDAG_EXEC: Platform::get()->fprintf(file, "blue"); break; case SRDAG_RUN: Platform::get()->fprintf(file, "gray"); break; case SRDAG_NEXEC: if(vertex->isHierarchical()) Platform::get()->fprintf(file, "red"); else Platform::get()->fprintf(file, "black"); break; } Platform::get()->fprintf(file, "];\n"); maxId = std::max(vertex->getId(),maxId); } // Drawing edges. Platform::get()->fprintf(file, "\t# Edges\n"); for (int i=0; i<edges_.getN(); i++) { SRDAGEdge* edge = edges_[i]; int snkIx, srcIx; if(edge->getSrc()) srcIx = edge->getSrc()->getId(); else{ maxId++; Platform::get()->fprintf(file, "\t%d [shape=point];\n", maxId); srcIx = maxId; } if(edge->getSnk()) snkIx = edge->getSnk()->getId(); else{ maxId++; Platform::get()->fprintf(file, "\t%d [shape=point];\n", maxId); snkIx = maxId; } // switch(mode){ // case DataRates: Platform::get()->fprintf(file, "\t%d->%d [label=\"%d (ID%d)\n%#x (ix %d : %d tokens)\",taillabel=\"%d\",headlabel=\"%d\"];\n", srcIx, snkIx, edge->getRate(), edge->getId(), edge->getAlloc(), edge->getAllocIx(), edge->getNToken(), edge->getSrcPortIx(), edge->getSnkPortIx()); // break; // case Allocation: // Platform::get()->fprintf(file, "\t%d->%d [label=\"%d: %#x (%#x)\"];\n", // srcIx, snkIx, // edge->fifo.id, // edge->fifo.add, // edge->fifo.size); // break; // } } Platform::get()->fprintf(file, "}\n"); Platform::get()->fclose(file); }
static int reduceForkFork(SRDAGGraph* topDag){ for(int i=0; i<topDag->getNVertex(); i++){ SRDAGVertex* secFork = topDag->getVertex(i); if(secFork && secFork->getType() == SRDAG_FORK){ SRDAGVertex* firFork = secFork->getInEdge(0)->getSrc(); if(firFork && firFork->getState() == SRDAG_EXEC && firFork->getType() == SRDAG_FORK){ int nbToAdd = secFork->getNConnectedOutEdge(); int ixToAdd = secFork->getInEdge(0)->getSrcPortIx(); int nbTotEdges = firFork->getNConnectedOutEdge()+nbToAdd-1; // Shift edges after for(int k=nbTotEdges-1; k>ixToAdd+nbToAdd-1; k--){ SRDAGEdge* edge = firFork->getOutEdge(k-nbToAdd+1); edge->disconnectSrc(); edge->connectSrc(firFork, k); } SRDAGEdge* delEdge = firFork->getOutEdge(ixToAdd); delEdge->disconnectSrc(); topDag->delEdge(delEdge); // Add edges for(int k=0; k<nbToAdd; k++){ SRDAGEdge* edge = secFork->getOutEdge(k); edge->disconnectSrc(); edge->connectSrc(firFork, k+ixToAdd); } topDag->delVertex(secFork); return 1; } } } return 0; }
static int reduceJoinFork(SRDAGGraph* topDag){ for(int i=0; i<topDag->getNVertex(); i++){ SRDAGVertex* join = topDag->getVertex(i); if(join && join->getType() == SRDAG_JOIN && join->getState() != SRDAG_RUN){ SRDAGVertex* fork = join->getOutEdge(0)->getSnk(); if(fork && fork->getType() == SRDAG_FORK && fork->getState() != SRDAG_RUN){ int totalNbTokens = 0; int totProd = 0; int sourceIndex=0, sinkIndex=0; #define MAX_SRDAG_INPUT_EDGES 1000 SRDAGVertex* sources[MAX_SRDAG_INPUT_EDGES]; int sourceProds[MAX_SRDAG_INPUT_EDGES]; int sourcePortIx[MAX_SRDAG_INPUT_EDGES]; bool sourceExplode[MAX_SRDAG_INPUT_EDGES]; int nbSourceRepetitions = join->getNConnectedInEdge(); topDag->delEdge(join->getOutEdge(0)); for(int k=0; k<nbSourceRepetitions; k++){ SRDAGEdge *edge = join->getInEdge(k); sources[k] = edge->getSrc(); sourceProds[k] = edge->getRate(); sourcePortIx[k] = edge->getSrcPortIx(); topDag->delEdge(edge); totalNbTokens += sourceProds[k]; sourceExplode[k] = false; } topDag->delVertex(join); SRDAGVertex* sinks[MAX_SRDAG_INPUT_EDGES]; int sinkCons[MAX_SRDAG_INPUT_EDGES]; int sinkPortIx[MAX_SRDAG_INPUT_EDGES]; int nbSinkRepetitions = fork->getNConnectedOutEdge(); bool sinkImplode[MAX_SRDAG_INPUT_EDGES]; for(int k=0; k<nbSinkRepetitions; k++){ SRDAGEdge *edge = fork->getOutEdge(k); sinks[k] = edge->getSnk(); sinkCons[k] = edge->getRate(); sinkPortIx[k] = edge->getSnkPortIx(); topDag->delEdge(edge); sinkImplode[k] = false; } topDag->delVertex(fork); int curProd = sourceProds[0]; int curCons = sinkCons[0]; while (totProd < totalNbTokens) { // Production/consumption rate for the current source/target. int rest = (curProd > curCons) ? curCons:curProd; /* * Adding explode/implode vertices if required. */ if (rest < curProd && !sourceExplode[sourceIndex]){ // Adding an explode vertex. SRDAGVertex *fork_vertex = topDag->addFork(MAX_IO_EDGES); // Replacing the source vertex by the explode vertex in the array of sources. SRDAGVertex *origin_vertex = sources[sourceIndex]; sources[sourceIndex] = fork_vertex; sourceExplode[sourceIndex] = true; // Adding an edge between the source and the explode. topDag->addEdge( origin_vertex, sourcePortIx[sourceIndex], fork_vertex, 0, sourceProds[sourceIndex]); } if (rest < curCons && !sinkImplode[sinkIndex]){ // Adding an implode vertex. SRDAGVertex *join_vertex = topDag->addJoin(MAX_IO_EDGES); // Replacing the sink vertex by the implode vertex in the array of sources. SRDAGVertex *origin_vertex = sinks[sinkIndex];// // Adding vxs sinks[sinkIndex] = join_vertex; sinkImplode[sinkIndex] = true; // Adding an edge between the implode and the sink. topDag->addEdge( join_vertex, 0, origin_vertex, sinkPortIx[sinkIndex], sinkCons[sinkIndex]); } //Creating the new edge between normal vertices or between a normal and an explode/implode one. int sourcePortId, sinkPortId; if(sourceExplode[sourceIndex]){ sourcePortId = sources[sourceIndex]->getNConnectedOutEdge(); }else{ sourcePortId = sourcePortIx[sourceIndex]; } if(sinkImplode[sinkIndex]) sinkPortId = sinks[sinkIndex]->getNConnectedInEdge(); else sinkPortId = sinkPortIx[sinkIndex]; topDag->addEdge( sources[sourceIndex], sourcePortId, sinks[sinkIndex], sinkPortId, rest); // Update the totProd for the current edge (totProd is used in the condition of the While loop) totProd += rest; curCons -= rest; curProd -= rest; if(curProd == 0){ curProd += sourceProds[++sourceIndex]; } if(curCons == 0){ curCons += sinkCons[++sinkIndex]; } } if(sourceIndex != nbSourceRepetitions){ /* Check Unhandled vertices */ /* Shift on Fork */ for(int i=sourceIndex; i<nbSourceRepetitions; i++){ if(sources[i]->getType() == SRDAG_FORK){ SRDAGVertex* rem_fork = sources[i]; for(int j=0; j<rem_fork->getNConnectedOutEdge(); j++){ if(rem_fork->getOutEdge(j) == 0){ for(int k=j+1; k<rem_fork->getNOutEdge(); k++){ SRDAGEdge *edge = rem_fork->getOutEdge(k); if(edge){ edge->disconnectSrc(); edge->connectSrc(rem_fork, k-1); } } } } }else{ throw "A non-End vertex have a cons of 0\n"; } } } if(sinkIndex != nbSinkRepetitions){ /* Check Unhandled vertices */ for(int i=sinkIndex; i<nbSinkRepetitions; i++){ if(sinks[i]->getType() == SRDAG_END){ topDag->delVertex(sinks[i]); }else{ throw "A non-End vertex have a cons of 0\n"; } } } return 1; } } } return 0; }
static int removeJoin(SRDAGGraph* topDag){ bool result = false; for(int i=0; i<topDag->getNVertex(); i++){ SRDAGVertex* join = topDag->getVertex(i); if(join && join->getState() == SRDAG_EXEC && join->getType() == SRDAG_JOIN){ if(join->getNConnectedInEdge() == 1 && join->getInEdge(0)->getSrc()){ SRDAGEdge* inEdge = join->getInEdge(0); SRDAGVertex* nextVertex = join->getOutEdge(0)->getSnk(); int edgeIx = join->getOutEdge(0)->getSnkPortIx(); SRDAGEdge* delEdge = join->getOutEdge(0); delEdge->disconnectSrc(); if(delEdge->getSnk()){ delEdge->disconnectSnk(); } topDag->delEdge(delEdge); inEdge->disconnectSnk(); if(nextVertex) inEdge->connectSnk(nextVertex, edgeIx); topDag->delVertex(join); return true; }else if(join->getNConnectedInEdge() == 0){ SRDAGVertex* end = topDag->addEnd(); SRDAGEdge* edge = join->getInEdge(0); edge->disconnectSnk(); edge->connectSnk(end, 0); topDag->delVertex(join); return true; } if(result) return true; } } return result; }
static int removeFork(SRDAGGraph* topDag){ bool result = false; for(int i=0; i<topDag->getNVertex(); i++){ SRDAGVertex* fork = topDag->getVertex(i); if(fork && fork->getState() == SRDAG_EXEC && fork->getType() == SRDAG_FORK){ for(int j=0; j<fork->getNConnectedOutEdge(); j++){ SRDAGEdge* delEdge = fork->getOutEdge(j); SRDAGVertex* nextVertex = delEdge->getSnk(); if(nextVertex && delEdge->getRate() == 0){ switch (nextVertex->getType()) { case SRDAG_END:{ int nbOutput = fork->getNConnectedOutEdge(); delEdge->disconnectSrc(); delEdge->disconnectSnk(); topDag->delEdge(delEdge); topDag->delVertex(nextVertex); for(int k=j+1; k<nbOutput; k++){ SRDAGEdge *edge = fork->getOutEdge(k); edge->disconnectSrc(); edge->connectSrc(fork, k-1); } result = true; break;} case SRDAG_JOIN:{ int forkNOut = fork->getNConnectedOutEdge(); int joinPortIx = delEdge->getSnkPortIx(); int joinNIn = nextVertex->getNConnectedInEdge(); delEdge->disconnectSrc(); delEdge->disconnectSnk(); topDag->delEdge(delEdge); /* Shift on Fork */ for(int k=j+1; k<forkNOut; k++){ SRDAGEdge *edge = fork->getOutEdge(k); edge->disconnectSrc(); edge->connectSrc(fork, k-1); } /* Shift on Join */ for(int k=joinPortIx+1; k<joinNIn; k++){ SRDAGEdge *edge = nextVertex->getInEdge(k); edge->disconnectSnk(); edge->connectSnk(nextVertex, k-1); } break;} default: break; } } } if(fork->getNConnectedOutEdge() == 1 && fork->getOutEdge(0)->getSnk()){ SRDAGEdge* inEdge = fork->getInEdge(0); SRDAGVertex* nextVertex = fork->getOutEdge(0)->getSnk(); int edgeIx = fork->getOutEdge(0)->getSnkPortIx(); SRDAGEdge* delEdge = fork->getOutEdge(0); delEdge->disconnectSrc(); delEdge->disconnectSnk(); topDag->delEdge(delEdge); inEdge->disconnectSnk(); inEdge->connectSnk(nextVertex, edgeIx); topDag->delVertex(fork); return true; }else if(fork->getNConnectedOutEdge() == 0){ SRDAGVertex* end = topDag->addEnd(); SRDAGEdge* edge = fork->getInEdge(0); edge->disconnectSnk(); edge->connectSnk(end, 0); topDag->delVertex(fork); return true; } if(result) return true; } } return result; }
static int removeBr(SRDAGGraph* topDag){ bool result = false; for(int i=0; i<topDag->getNVertex(); i++){ SRDAGVertex* br = topDag->getVertex(i); if(br && br->getState() == SRDAG_EXEC && br->getType() == SRDAG_BROADCAST){ for(int j=0; j<br->getNConnectedOutEdge(); j++){ SRDAGEdge* delEdge = br->getOutEdge(j); SRDAGVertex* endVertex = delEdge->getSnk(); if(endVertex && endVertex->getType() == SRDAG_END){ int nbOutput = br->getNConnectedOutEdge(); delEdge->disconnectSrc(); delEdge->disconnectSnk(); topDag->delEdge(delEdge); topDag->delVertex(endVertex); for(int k=j+1; k<nbOutput; k++){ SRDAGEdge *edge = br->getOutEdge(k); edge->disconnectSrc(); edge->connectSrc(br, k-1); } result = true; } } if(br->getNConnectedOutEdge() == 1 && br->getOutEdge(0)->getSnk()){ SRDAGEdge* inEdge = br->getInEdge(0); SRDAGVertex* nextVertex = br->getOutEdge(0)->getSnk(); int edgeIx = br->getOutEdge(0)->getSnkPortIx(); SRDAGEdge* delEdge = br->getOutEdge(0); delEdge->disconnectSrc(); delEdge->disconnectSnk(); topDag->delEdge(delEdge); inEdge->disconnectSnk(); inEdge->connectSnk(nextVertex, edgeIx); topDag->delVertex(br); return true; }else if(br->getNConnectedOutEdge() == 0){ SRDAGVertex* end = topDag->addEnd(); SRDAGEdge* edge = br->getInEdge(0); edge->disconnectSnk(); edge->connectSnk(end, 0); topDag->delVertex(br); return true; } if(result) return true; } } return result; }
static int reduceBrBr(SRDAGGraph* topDag){ for(int i=0; i<topDag->getNVertex(); i++){ SRDAGVertex* secBr = topDag->getVertex(i); if(secBr && secBr->getType() == SRDAG_BROADCAST){ SRDAGVertex* firBr = secBr->getInEdge(0)->getSrc(); if(firBr && firBr->getState() == SRDAG_EXEC && firBr->getType() == SRDAG_BROADCAST){ int nbToAdd = secBr->getNConnectedOutEdge(); int ixToAdd = secBr->getInEdge(0)->getSrcPortIx(); SRDAGEdge* delEdge = firBr->getOutEdge(ixToAdd); delEdge->disconnectSrc(); topDag->delEdge(delEdge); /* Add first edge where the previous one was */ { SRDAGEdge* edge = secBr->getOutEdge(0); edge->disconnectSrc(); edge->connectSrc(firBr, ixToAdd); } /* Add others at the end of the firBr */ ixToAdd = firBr->getNConnectedOutEdge(); for(int k=1; k<nbToAdd; k++){ SRDAGEdge* edge = secBr->getOutEdge(k); edge->disconnectSrc(); edge->connectSrc(firBr, k-1+ixToAdd); } topDag->delVertex(secBr); return 1; } } } return 0; }