run_statistics(const mrf_graph_type& mrf) : nsamples(0), nchanges(0), loglik(0.0), min_samples(std::numeric_limits<size_t>::max()), max_samples(0){ // Compute the unnormalized log likelihood loglik = unnormalized_loglikelihood(mrf); for(vertex_id_t vid = 0; vid < mrf.num_vertices(); ++vid) { const mrf_vertex_data& vdata = mrf.vertex_data(vid); nsamples += vdata.nsamples; nchanges += vdata.nchanges; min_samples = std::min(min_samples, vdata.nsamples); max_samples = std::max(max_samples, vdata.nsamples); } // end of for loop } // end of compute run statistics
void run_jtsplash_sampler(mrf_graph_type& mrf_graph, const std::string& jtsplash_results_fn, const std::vector<double>& runtimes, const bool draw_images, const splash_settings& settings) { // size_t ncpus = core.engine().get_ncpus(); // bool affinities = // core.get_engine_options().get_cpu_affinities(); // Initialize the jtsplash sampler jt_splash_sampler jtsplash_sampler(mrf_graph, settings); double total_runtime = 0; double actual_total_runtime = 0; foreach(const double experiment_runtime, runtimes) { total_runtime += experiment_runtime; // get the experiment id size_t experiment_id = file_line_count(jtsplash_results_fn); std::cout << "Running JTSplash sampler experiment " << experiment_id << " for " << experiment_runtime << " seconds." << std::endl; std::cout << "Settings: ======================" << std::endl << "Experiment: " << experiment_id << std::endl << "runtime: " << experiment_runtime << std::endl << "treesize: " << settings.max_tree_size << std::endl << "treewidth: " << settings.max_tree_width << std::endl << "treeheight: " << settings.max_tree_height << std::endl << "factorsize: " << settings.max_factor_size << std::endl << "subthreads: " << settings.subthreads << std::endl << "priorities: " << settings.priorities << std::endl << "vanish: " << settings.vanish_updates << std::endl; graphlab::timer timer; timer.start(); // run the sampler once jtsplash_sampler.sample_seconds(experiment_runtime); double actual_experiment_runtime = timer.current_time(); std::cout << "Actual Experiment Runtime:" << actual_experiment_runtime << std::endl; actual_total_runtime += actual_experiment_runtime; std::cout << "Total Experiment Runtime (actual): " << total_runtime << "(" << actual_total_runtime << ")" << std::endl; // check mrf graph for(size_t i = 0; i < mrf_graph.num_vertices(); ++i) { ASSERT_EQ(mrf_graph.vertex_data(i).tree_info.tree_id, NULL_VID); } /// ================================================================== // Compute final statistics of the mode run_statistics stats(mrf_graph); stats.print(); // Save the beliefs save_beliefs(mrf_graph, make_filename("jtsplash_blfs_", ".tsv", experiment_id)); // // Save the current assignments save_asg(mrf_graph, make_filename("jtsplash_asg_", ".asg", experiment_id)); // Save the experiment std::ofstream fout(jtsplash_results_fn.c_str(), std::ios::app); fout.precision(8); fout << experiment_id << '\t' << total_runtime << '\t' << actual_total_runtime << '\t' << settings.ntrees << '\t' << stats.nsamples << '\t' << stats.nchanges << '\t' << stats.loglik << '\t' << stats.min_samples << '\t' << stats.max_samples << '\t' << settings.max_tree_size << '\t' << settings.max_tree_width << '\t' << settings.max_factor_size << '\t' << settings.max_tree_height << '\t' << settings.subthreads << '\t' << settings.priorities << '\t' << jtsplash_sampler.total_trees() << '\t' << jtsplash_sampler.total_collisions() << '\t' << std::endl; fout.close(); // Plot images if desired if(draw_images) draw_mrf(experiment_id, "jtsplash", mrf_graph); } // end of for loop over runtimes
/** * Extend the jtree_list data structure by eliminating the vertex. If * the jtree list can be extended then it is extended and this * function returns true. * **/ bool jtree_list:: extend(const mrf_graph_type::vertex_id_type elim_vertex, const mrf_graph_type& mrf, const size_t max_tree_width, const size_t max_factor_size) { typedef mrf_graph_type::edge_id_type edge_id_type; typedef mrf_graph_type::vertex_id_type vertex_id_type; // sanity check: The vertex to eliminate should not have already // been eliminated ASSERT_FALSE( contains(elim_vertex) ); /// ===================================================================== // Construct the elimination clique for the new vertex // 1) Fill out clique // 2) Track the corresponding factor size and treewidth // 3) Find the parent of this clique jtree_list::elim_clique clique; clique.elim_vertex = elim_vertex; // the factor must at least have the eliminated vertex size_t factor_size = std::max(mrf.vertex_data(elim_vertex).variable.size(), uint32_t(1)); foreach(const edge_id_type ineid, mrf.in_edge_ids(elim_vertex)) { const vertex_id_type vid = mrf.source(ineid); const bool is_in_jtree = contains(vid); // if the neighbor is in the set of vertices being eliminated if(is_in_jtree) { clique.vertices += vid; factor_size *= std::max(mrf.vertex_data(vid).variable.size(), uint32_t(1) ); } // if the clique ever gets too large then teminate // the + 1 is because we need to include the elim vertex if((clique.vertices.size() > max_tree_width) || (max_factor_size > 0 && factor_size > max_factor_size)) return false; } // Determine the parent of this clique ------------------------- vertex_id_type parent_id = 0; foreach(vertex_id_type vid, clique.vertices) parent_id = std::max(parent_id, elim_time_lookup(vid)); clique.parent = parent_id; /// ===================================================================== // Simulate injecting vertices in parent cliques back to when RIP is // satisfied vertex_set rip_verts = clique.vertices; for(vertex_id_t parent_vid = clique.parent; !rip_verts.empty() && parent_vid < cliques.size(); ) { const jtree_list::elim_clique& parent_clique = cliques[parent_vid]; // Remove the parent vertex rip_verts -= vertex_set(parent_clique.elim_vertex); // Construct the new vertices that would normally be stored at // this vertes const vertex_set tmp_verts = rip_verts + parent_clique.vertices; // Check that the expanded clique is still within tree width if(tmp_verts.size() > max_tree_width) return false; // If we care about the maximum factor size Compute the factor // size and fail if the factor is too large if(max_factor_size > 0) { size_t factor_size = std::max(mrf.vertex_data(parent_clique.elim_vertex).variable.size(), uint32_t(1)); foreach(vertex_id_t vid, tmp_verts) { factor_size *= std::max(mrf.vertex_data(vid).variable.size(), uint32_t(1)); } if(factor_size > max_factor_size) return false; }