// Step 1944: PipelineGraph // // t1: addStage and stageCount // t2: addEdge; successors and predecessors // t3: topologicalOrder on linear chain // t4: hasCycle detects cycle; acyclic returns false // t5: sourceStages and sinkStages #include "PipelineGraph.h" #include #include namespace ws = whetstone; static int p=0,f=0; #define T(n) { std::cout<<" "<<#n<<"... "; } #define P() { std::cout<<"PASS\n"; ++p; } #define F(m) { std::cout<<"FAIL: "<b"); auto sc = g.successors("b"); C(sc.size()==1 && sc[0]=="c", "b->c"); auto pb = g.predecessors("b"); C(pb.size()==1 && pb[0]=="a", "b pred a"); C(g.predecessors("a").empty(), "a no pred"); C(g.successors("c").empty(), "c no succ"); P(); } void t3(){ T(topologicalOrder_linear_chain); ws::PipelineGraph g; g.addEdge("ingest","normalize"); g.addEdge("normalize","fanout"); g.addEdge("fanout","transform"); g.addEdge("transform","serialize"); auto order = g.topologicalOrder(); C(order.size() == 5, "five stages in order"); // ingest must come before normalize, etc. auto pos = [&](const std::string& s){ return std::find(order.begin(),order.end(),s) - order.begin(); }; C(pos("ingest") < pos("normalize"), "ingest before normalize"); C(pos("normalize") < pos("fanout"), "normalize before fanout"); C(pos("fanout") < pos("transform"), "fanout before transform"); C(pos("transform") < pos("serialize"), "transform before serialize"); P(); } void t4(){ T(hasCycle_detection); ws::PipelineGraph acyclic; acyclic.addEdge("a","b"); acyclic.addEdge("b","c"); C(!acyclic.hasCycle(), "acyclic has no cycle"); ws::PipelineGraph cyclic; cyclic.addEdge("a","b"); cyclic.addEdge("b","c"); cyclic.addEdge("c","a"); C(cyclic.hasCycle(), "cycle detected"); C(cyclic.topologicalOrder().empty(), "topo empty on cycle"); P(); } void t5(){ T(sourceStages_and_sinkStages); ws::PipelineGraph g; g.addEdge("ingest","normalize"); g.addEdge("normalize","serialize"); auto src = g.sourceStages(); C(src.size()==1 && src[0]=="ingest", "ingest is source"); auto sink = g.sinkStages(); C(sink.size()==1 && sink[0]=="serialize","serialize is sink"); // diamond: two sources, one sink ws::PipelineGraph d; d.addEdge("a","c"); d.addEdge("b","c"); C(d.sourceStages().size()==2, "diamond: two sources"); C(d.sinkStages().size()==1, "diamond: one sink"); P(); } int main(){ std::cout << "Step 1944: PipelineGraph\n"; t1(); t2(); t3(); t4(); t5(); std::cout << "\n" << p << "/" << (p+f) << " passed\n"; return f > 0 ? 1 : 0; }