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