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_