int main(int argc, char **argv) { ConfigKeeper * cfg = ConfigKeeper::inst(); if (!cfg->processCmdLine(argc, argv)) { return 1; // exit early } cout << cfg->getNodes() << " " << cfg->getNetworks() << " "; cout << cfg->getSysPeriodSecs() << " " << cfg->getOutfileName() << endl; NetGraph ng; ng.print(); return 0; }
NetGraph::NetGraph() : _ng( ConfigKeeper::inst()->getNetworks() + ConfigKeeper::inst()->getNodes()) { ConfigKeeper * cfg = ConfigKeeper::inst(); // The general idea... // Create the proper number of networks and nodes unsigned long idx; cout << "Creating nodes and nets..." << endl; for ( idx = 0; idx < cfg->getNetworks(); idx++ ) { _nets_nodes.push_back( new Net(idx) ); } for ( ; idx < cfg->getNetworks() + cfg->getNodes(); idx++ ) { _nets_nodes.push_back( new Node(idx) ); } // Take the list of nodes and connect each one to at least one bus unsigned long nidx; cout << "Connecting nodes to nets..." << endl; if ( cfg->getNetworks() > 0 ) { for (nidx = cfg->getNetworks(); nidx < cfg->getNetworks() + cfg->getNodes(); nidx++) { cout << "Network " << nidx << ": "; // For the vertex, select a number of nets to connect to and // then make a list of them unsigned long numnets = _rnd.chooseInt(1, cfg->getMaxNetsPerNode()); cout << numnets << " nets " << endl; std::vector< long > nets = _rnd.chooseInts(0, cfg->getNetworks()-1, numnets); for ( unsigned long eidx = 0; eidx < numnets; eidx++ ) { cout << " connecting (" << nidx << "," << nets[eidx] << ")" << endl; add_edge(nidx, nets[eidx], _ng); } cout << endl; } cout << endl; } // Continue adding node/bus edges until the whole graph is connected /*std::vector<size_type> rank(num_vertices(_ng)); std::vector<NetworkVertex> parent(num_vertices(_ng)); typedef size_type* Rank; typedef NetworkVertex* Parent; disjoint_sets<Rank, Parent> ds(&rank[0], &parent[0]); initialize_incremental_components(_ng, ds); incremental_components(_ng, ds); // Make a single connected component // @todo -- come back and look at cleaning this up: // The graph structure isn't using the type system. // This will not be quite as random as it should be. // For now we'll check and warn if ( ds.count_sets() > 1) cout << "The generated network is not connected!!! (" << ds.count_sets() << " comps)" << endl; /*while ( ds.count_sets() > 1 ) { NetworkVertex vn1 = parent[ds.count_sets()-1]; NetworkVertex vn2 = parent[ds.count_sets()-2]; NetworkVertex } */ // Create a random number of tasks per processor cout << "Creating random tasks..." << endl; std::vector< double > dividers; dividers.push_back(1.0); dividers.push_back(2.0); dividers.push_back(4.0); unsigned long tidx = 0; // Counterintuitive syntax -- we're iterating over nodes for (nidx = cfg->getNetworks(); nidx < cfg->getNetworks() + cfg->getNodes(); nidx++) { unsigned long numtasks = _rnd.chooseInt(1, cfg->getMaxTasksPerNode()); cout << "Node " << nidx << ": " << numtasks << endl; for ( idx = 0; idx < numtasks; idx++ ) { Task t(tidx++, nidx); cout << "p"; t._periodSecs = cfg->getSysPeriodSecs() / _rnd.chooseFromList(dividers); cout << "w"; // Get a reasonable task exec length double res = cfg->getSysResolutionSecs(); t._wcetSecs = max( t._periodSecs * _rnd.chooseDouble(cfg->getMinTaskUtil(), cfg->getMaxTaskUtil()), res ); cout << "c"; Node * n = dynamic_cast<Node *>(_nets_nodes[nidx]); cout << "r"; t._parent = n->id; cout << "t"; n->_tasks.push_back(t); _tasks.push_back(t); cout << " added task " << t.id << " pd " << t._periodSecs << " et " << t._wcetSecs << " p " << t._parent << endl; //add_vertex(t.id, _tg); } } cout << "Creating subgraph structure..." << endl; _tg = new TaskGraph(_tasks.size()); cout << "Creating subgraphs..." << endl; for ( unsigned long bidx = 0; bidx < cfg->getNetworks(); bidx++ ) { _tg_subs.push_back(_tg->create_subgraph()); } cout << "Finished creating subgraph structure." << endl; // Iterate over the buses... typedef graph_traits<NetworkGraph> GraphTraits; property_map<NetworkGraph, vertex_index_t>::type vindex = get(vertex_index, _ng); graph_traits<NetworkGraph>::adjacency_iterator ai; graph_traits<NetworkGraph>::adjacency_iterator ai_end; cout << "Creating task dependencies..." << endl; unsigned long bidx; for ( bidx = 0; bidx < cfg->getNetworks(); bidx++ ) { // Create a random graph between the tasks visible to that bus // (it could have almost any properties we want) // Get the nodes for this bus //_tg_subs[bidx] = _tg.create_subgraph(); for ( boost::tuples::tie(ai, ai_end) = adjacent_vertices(bidx, _ng); ai != ai_end; ++ai) { // Get the tasks for this node Node * n = dynamic_cast<Node *>(_nets_nodes[vindex[*ai]]); for ( std::vector<Task>::iterator pT = n->_tasks.begin(); pT != n->_tasks.end(); pT++) { add_vertex( pT->id, _tg_subs[bidx] ); } } // Create a random graph using those tasks, and store a message length double p = cfg->getMsgProb(); graph_traits<TaskGraph>::vertex_iterator vi, vi_end; graph_traits<TaskGraph>::vertex_iterator vi2, vi2_end; for ( boost::tuples::tie(vi, vi_end) = vertices(_tg_subs[bidx]); vi != vi_end; ++vi) { for ( boost::tuples::tie(vi2, vi2_end) = vertices(_tg_subs[bidx]); vi2 != vi2_end; ++vi2 ) { if ( vi == vi2 ) continue; if ( _rnd.choose(p) ) { unsigned long msgln = _rnd.chooseInt(cfg->getMinMsgBytes(), cfg->getMaxMsgBytes()); ostringstream msgtag; msgtag << bidx << "," << vindex[*vi] << "," << vindex[*vi2]; cout << "Adding " << msgtag.str() << " with length " << msgln << endl; _tasks[vindex[*vi]]._msg_lengths[msgtag.str()] = msgln; add_edge(*vi, *vi2, _tg_subs[bidx]); } } } } cout << "Creation finished." << endl; }