Beispiel #1
0
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;
}