00001 00026 #ifndef DES_ABSTRACT_MAIN_H_ 00027 #define DES_ABSTRACT_MAIN_H_ 00028 00029 #include <iostream> 00030 #include <string> 00031 #include <vector> 00032 #include <map> 00033 #include <utility> 00034 00035 #include <cstdio> 00036 00037 #include "Galois/Statistic.h" 00038 #include "Galois/Graphs/Graph.h" 00039 #include "Galois/Galois.h" 00040 00041 #include "Lonestar/Banner.h" 00042 #include "Lonestar/CommandLine.h" 00043 00044 #include "SimObject.h" 00045 #include "SimInit.h" 00046 00047 static const char* name = "Discrete Event Simulation"; 00048 static const char* description = "Uses Chandy-Misra's algorithm, which is unordered, to perform logic circuit simulations"; 00049 static const char* url = "discrete_event_simulation"; 00050 static const char* help = "<progname> netlistFile [NEVENTS_PER_ITER]"; 00051 00055 class DESabstractMain { 00056 public: 00057 typedef SimObject::Graph Graph; 00058 typedef SimObject::GNode GNode; 00059 00060 00061 protected: 00062 00064 Graph graph; 00065 00070 virtual bool isSerial() const = 0; 00071 00077 virtual void runLoop(const SimInit& simInit) = 0; 00078 00084 std::string getVersion() const { 00085 return (isSerial() ? "Serial" : "Galois"); 00086 } 00087 00088 public: 00094 void run(int argc, const char* argv[]) { 00095 std::vector<const char*> args = parse_command_line (argc, argv, help); 00096 00097 if (args.size () < 1 || args.size () > 2) { 00098 std::cerr << help << std::endl; 00099 abort (); 00100 } 00101 00102 printBanner(std::cout, name, description, url); 00103 00104 const char* netlistFile = args[0]; 00105 00106 if (args.size () == 2) { 00107 size_t epi = AbstractSimObject::NEVENTS_PER_ITER; 00108 std::istringstream iss (args[1]); 00109 iss >> epi; 00110 00111 assert (epi >= 0); 00112 AbstractSimObject::NEVENTS_PER_ITER = epi; 00113 00114 } 00115 00116 printf ("Processing %zd events per iteration\n", AbstractSimObject::NEVENTS_PER_ITER); 00117 00118 00119 SimInit simInit(graph, netlistFile); 00120 00121 00122 printf("circuit graph: %u nodes, %zd edges\n", graph.size(), simInit.getNumEdges()); 00123 printf("Number of initial events = %zd\n", simInit.getInitEvents().size()); 00124 00125 Galois::StatTimer t; 00126 00127 t.start (); 00128 00129 runLoop(simInit); 00130 00131 t.stop (); 00132 00133 if (!skipVerify) { 00134 verify(simInit); 00135 } 00136 00137 } 00138 00143 void verify(const SimInit& simInit) { 00144 const std::vector<SimObject*>& outputObjs = simInit.getOutputObjs(); 00145 const std::map<std::string, LogicVal>& outValues = simInit.getOutValues(); 00146 00147 int exitStatus = 0; 00148 00149 for (std::vector<SimObject*>::const_iterator i = outputObjs.begin (), ei = outputObjs.end (); i != ei; ++i) { 00150 SimObject* so = *i; 00151 00152 Output* outObj = dynamic_cast< Output* > (so); 00153 00154 assert (outObj != NULL); 00155 00156 const LogicVal& simulated = outObj->getOutputVal(); 00157 const LogicVal& expected = (outValues.find (outObj->getInputName ()))->second; 00158 00159 if (simulated != expected) { 00160 exitStatus = 1; 00161 std::cerr << "Wrong output value for " << outObj->getOutputName() 00162 << ", simulated : " << simulated << " expected : " << expected << std::endl; 00163 } 00164 } 00165 00166 if (exitStatus != 0) { 00167 std::cerr << "-----------------------------------------------------------" << std::endl; 00168 00169 for (std::vector<SimObject*>::const_iterator i = outputObjs.begin (), ei = outputObjs.end (); i != ei; ++i) { 00170 SimObject* so = *i; 00171 00172 Output* outObj = dynamic_cast< Output* > (so); 00173 assert (outObj != NULL); 00174 00175 std::cerr << outObj->toString () << std::endl; 00176 } 00177 00178 abort (); 00179 } else { 00180 std::cout << ">>> OK: Simulation verified as correct" << std::endl; 00181 } 00182 } 00183 00184 }; 00185 00186 #endif // DES_ABSTRACT_MAIN_H_