コード例 #1
0
ファイル: main.cpp プロジェクト: willmlam/aomdd
int main(int argc, char **argv) {
    cout << setprecision(15);
    cout << "====================================================" << endl;
    cout << "AOMDD-BE Compiler v0.1" << endl;
    cout << "  by William Lam, UC Irvine <*****@*****.**>" << endl;
    cout << "====================================================" << endl;
    cout << endl;

    po::options_description inputOptions("Input files");
    inputOptions.add_options()
            ("file,f", po::value<string>(), "path to problem file (UAI format) [required]")
            ("order,o", po::value<string>(), "path to elimination ordering file [required]")
            ("evid,e", po::value<string>(), "path to evidence file")
            ;
    po::options_description outputOptions("Output files");
    outputOptions.add_options()
            ("treedot,t", po::value<string>(), "path to DOT file to output generated pseudo-tree")
            ("res,r", po::value<string>(), "path to output results")
            ("dddot,d", po::value<string>(), "path to DOT file to output generated AOMDD")
            ;
    po::options_description infOptions("Inference options");
    infOptions.add_options()
            ("compile,c", "compile full AOMDD")
            ("pe", "compute P(e)")
            ("mpe", "computer MPE(e) cost")
            ("mbe", "use minibucket approximation")
            ("mbebound", po::value<unsigned long>(), "diagram size bound for minibucket")
            ("mbeibound", po::value<unsigned long>(), "i-bound for minibucket")
            ("vbe", "use standard function tables")
            ("log", "output results in log space")
            ;
    po::options_description otherOptions("Other options");
    otherOptions.add_options()
            ("computeortreesize","compute OR tree size only")
            ("cmonly","generate cm graph instead(via compilation)")
            ("chaintree", "use chain pseudo-tree structure")
            ("mlim", po::value<double>(), "Memory limit (MB) for nodes")
            ("oclim", po::value<double>(), "Memory limit (MB) for operation cache")
            ("outcompile", "Output compiled AOMDD")
            ("bespace", "Output space for standard table BE (only)")
            ("cvo", "Use Kalev Kask's variable ordering code")
            ("cvoit", po::value<int>()->default_value(10),
             "Iterations to run for cvo")
            ("cvotime", po::value<int>()->default_value(-1),
             "Time to run for cvo")
            ("help,h", "Output list of options")
            ;

    /*
    if ( !ParseCommandLine(argc, argv) ) {
        cout << "Invalid arguments given" << endl;
        cout << "Options list" << endl;
        cout << "Input files:" << endl;
        cout << "  -f <file>        path to problem file (UAI format) [required]" << endl;
        cout << "  -o <file>        path to elimination ordering file [required]" << endl;
        cout << "  -e <file>        path to evidence file" << endl;
        cout << endl;
        cout << "Output files:" << endl;
        cout << "  -t <file>        path to DOT file to output generated pseudo-tree" << endl;
        cout << "  -r <file>        path to output results" << endl;
        cout << endl;
        cout << "Inference options:" << endl;
        cout << "  -c               compile full AOMDD" << endl;
        cout << "  -pe              compute P(e)" << endl;
        cout << "  -mpe             compute MPE(e) cost" << endl;
        cout << "  -mbe             use minibucket approximation" << endl;
        cout << "  -mbebound        size bound for minibuckets" << endl;
        cout << "  -mbeibound       i-bound for minibuckets" << endl;
        cout << "  -vbe             use vanilla bucket elimination" << endl;
        cout << "  -log             output results in log space" << endl;
        cout << endl;
        cout << "Other options:" << endl;
        cout << "  -mlim            specify memory limit (MB) for nodes" << endl;
//        cout << "  -oclim           specify memory limit (MB) for operations" << endl;
        cout << "  -outcompile      output compiled AOMDD" << endl;
        cout << "  -vbespace        compute space needed by vanilla bucket elimination (only)" << endl;
        return 0;
    }
    */

    po::options_description allOptions;
    allOptions.add(inputOptions).add(outputOptions).add(infOptions).add(otherOptions);

    po::variables_map vm;
    po::store(po::parse_command_line(argc,argv,allOptions),vm);
    po::notify(vm);


    if (vm.count("help")) {
        cout << allOptions << endl;
        return 1;
    }

    if (!vm.count("file")) {
        cout << "Missing UAI file" << endl;
        cout << allOptions << endl;
        return 1;
    }

    if (vm.count("pe") && vm.count("mpe")) {
        cout << "Please choose a single query type (P(e) or MPE)" << endl;
        cout << allOptions << endl;
        return 1;
    }

    try {
        inputFile = vm["file"].as<string>();
        if (vm.count("order"))
	        orderFile = vm["order"].as<string>();
        else
            computeOrdering = true;
        if (vm.count("evid"))
            evidFile = vm["evid"].as<string>();
        if (vm.count("treedot"))
            dotFile = vm["treedot"].as<string>();
        if (vm.count("dddot"))
            ddDotFile = vm["dddot"].as<string>();
        if (vm.count("res"))
            outputResultFile = vm["res"].as<string>();
        compileMode = vm.count("compile");
        peMode = vm.count("pe");
        mpeMode = vm.count("mpe");
        vbeMode = vm.count("vbe");
        logMode = vm.count("log");
        miniBucketMode = vm.count("mbe");
        outCompile = vm.count("outcompile");
        vbeSpace = vm.count("bespace");
        useChain = vm.count("chaintree");
        computeORTreeSize = vm.count("computeortreesize");
        NodeManager::GetNodeManager()->SetCMOnly(vm.count("cmonly"));

        useCVO = vm.count("cvo");
        if (vm.count("cvoit"))
          cvo_iter = vm["cvoit"].as<int>();
        if (vm.count("cvotime"))
          cvo_time = vm["cvotime"].as<int>();

        if (vm.count("mlim"))
            MBLimit = vm["mlim"].as<double>();
        if (vm.count("oclim"))
            OCMBLimit = vm["oclim"].as<double>();
        if (vm.count("mbebound"))
            mbeSizeBound = vm["mbebound"].as<unsigned long>();
        if (vm.count("mbeibound"))
            mbeIBound = vm["mbeibound"].as<unsigned long>();
    } catch (const std::exception &e) {
        cout << allOptions << endl;
        return 0;
    }

    ofstream out;
    out << setprecision(15);

    bool outputToFile = false;
    if (outputResultFile != "") {
        out.open(outputResultFile.c_str());
        outputToFile = true;
    }


    Model m;
    cout << "Reading from input file: " << inputFile << endl;
    if (outputToFile) {
        out << "Reading from input file: " << inputFile << endl;
    }

    m.parseUAI(inputFile);
    list<int> ordering;
    if (!computeOrdering) {
	    cout << "Reading from ordering file: " << orderFile << endl;
	    if (outputToFile) {
	        out << "Reading from ordering file: " << orderFile << endl;
	    }
	    ordering = parseOrder(orderFile);
	    m.SetOrdering(ordering);
	}
    map<int, int> evidence;
    if (evidFile != "") {
        cout << "Reading from evidence file: " << evidFile << endl;
        if (outputToFile) {
            out << "Reading from evidence file: " << evidFile << endl;
        }
        evidence = parseEvidence(evidFile);
    }


    Graph g(m.GetNumVars(), m.GetScopes());
    if (computeOrdering) {
      time_t time_order_start, time_order_cur;
      double timediff = 0.0;
      time(&time_order_start);
      if (useCVO) {
        scoped_ptr<ARE::Graph> cvo_graph;
        scoped_ptr<ARE::Graph> cvo_master_graph;
        scoped_ptr<CMauiAVLTreeSimple> cvo_avl_vars2check_score;
        scoped_ptr<ARE::AdjVarMemoryDynamicManager> cvo_temp_adj_var_space;
        
        vector<vector<int> > scopes_vec;

        BOOST_FOREACH(const Scope &s, m.GetScopes()) {
          scopes_vec.push_back(vector<int>(s.GetOrdering().begin(),
                                           s.GetOrdering().end()));
        }

        vector<const vector<int>*> fn_signatures;
        BOOST_FOREACH(const vector<int> &s, scopes_vec) {
          fn_signatures.push_back(&s);
        }

        cvo_master_graph.reset(new ARE::Graph);
        cvo_master_graph->Create(m.GetNumVars(), fn_signatures);
        if (!cvo_master_graph->_IsValid)
          return false;

        cvo_avl_vars2check_score.reset(new CMauiAVLTreeSimple);
        cvo_temp_adj_var_space.reset(new ARE::AdjVarMemoryDynamicManager(
                                         ARE_TempAdjVarSpaceSize));

        cvo_master_graph->
            ComputeVariableEliminationOrder_Simple_wMinFillOnly(
                INT_MAX, false, true, 10, -1, 0.0, *cvo_avl_vars2check_score,
                *cvo_temp_adj_var_space);
        cvo_master_graph->ReAllocateEdges();
        cvo_graph.reset(new ARE::Graph);

        int w = numeric_limits<int>::max();
        int iter_count = 0;
        int remaining = cvo_iter;

        while (true) {
          if (cvo_iter > -1 && remaining == 0)
            break;

          vector<int> elim_cand;
          int new_w;
          *cvo_graph = *cvo_master_graph;
          new_w = cvo_graph->ComputeVariableEliminationOrder_Simple_wMinFillOnly(
              w, true, false, 10, -1, 0.0, *cvo_avl_vars2check_score,
              *cvo_temp_adj_var_space);
          if (new_w != 0) {
            new_w = INT_MAX;
          } else {
            new_w = cvo_graph->_VarElimOrderWidth;
            elim_cand.assign(cvo_graph->_VarElimOrder, 
                cvo_graph->_VarElimOrder + cvo_graph->_OrderLength);
          }

          if (new_w < w) {
            ordering.clear();
            ordering.assign(elim_cand.begin(), elim_cand.end());
            reverse(ordering.begin(), ordering.end());
            w = new_w;
          }
          ++iter_count, --remaining;
          time(&time_order_cur);
          timediff = difftime(time_order_cur, time_order_start);
          if (cvo_time > 0 && timediff > cvo_time) {
            break;
          }
        }
        time(&time_order_cur);
        timediff = difftime(time_order_cur, time_order_start);
        cout << endl << "Ran " << iter_count << " iterations (" << int(timediff)
          << " seconds), lowest width found: "
          << w << endl;
      }
      else {