| 545 | |
| 546 | template <unsigned sum_items_num, template <typename, typename Enable = void> class OBJECT_BUFFER> |
| 547 | plato::sparse_state_t<behaviour_state_t<sum_items_num>, plato::empty_t> load_behaviour_graph_from_cache( |
| 548 | OBJECT_BUFFER<plato::vertex_unit_t<behaviour_state_content_t<sum_items_num>>>&& behaviour_cache, |
| 549 | plato::graph_info_t& behaviour_graph_info, OBJECT_BUFFER<degree_unit>&& behaviour_degree_cache) { |
| 550 | auto& cluster_info = plato::cluster_info_t::get_instance(); |
| 551 | |
| 552 | plato::stop_watch_t watch; |
| 553 | watch.mark("t0"); |
| 554 | watch.mark("t1"); |
| 555 | |
| 556 | constexpr size_t mem_size = sizeof(plato::vid_t) * (size_t(std::numeric_limits<plato::vid_t>::max()) + 1); |
| 557 | std::unique_ptr<plato::vid_t, plato::mmap_deleter> out_degree( |
| 558 | (plato::vid_t*)mmap(nullptr, mem_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0), |
| 559 | plato::mmap_deleter{mem_size}); |
| 560 | CHECK(MAP_FAILED != out_degree.get()) |
| 561 | << boost::format("WARNING: mmap failed, err code: %d, err msg: %s") % errno % strerror(errno); |
| 562 | |
| 563 | size_t local_degree_sum = 0; |
| 564 | plato::vid_t local_vertices = 0; |
| 565 | plato::vid_t max_vid = 0; |
| 566 | |
| 567 | behaviour_degree_cache.reset_traversal(); |
| 568 | #pragma omp parallel reduction(+:local_degree_sum) reduction(+:local_vertices) reduction(max:max_vid) |
| 569 | { |
| 570 | size_t chunk_size = 1; |
| 571 | while (behaviour_degree_cache.next_chunk([&] (size_t, degree_unit* v) { |
| 572 | out_degree.get()[v->vid_] = v->degree_; |
| 573 | local_degree_sum += v->degree_; |
| 574 | local_vertices++; |
| 575 | max_vid = std::max(max_vid, v->vid_); |
| 576 | }, &chunk_size)) {} |
| 577 | } |
| 578 | |
| 579 | size_t degree_sum = 0; |
| 580 | MPI_Allreduce(MPI_IN_PLACE, &max_vid, 1, plato::get_mpi_data_type<plato::vid_t>(), MPI_MAX, MPI_COMM_WORLD); |
| 581 | MPI_Allreduce(&local_degree_sum, °ree_sum, 1, plato::get_mpi_data_type<size_t>(), MPI_SUM, MPI_COMM_WORLD); |
| 582 | CHECK(behaviour_graph_info.edges_ == degree_sum); |
| 583 | CHECK(behaviour_graph_info.max_v_i_ == max_vid); |
| 584 | |
| 585 | plato::sparse_state_t<behaviour_state_t<sum_items_num>, plato::empty_t> behaviour(local_vertices * 1.2, std::make_shared<plato::empty_t>()); |
| 586 | |
| 587 | { |
| 588 | watch.mark("t1"); |
| 589 | |
| 590 | behaviour_mmap_p.reset( |
| 591 | mmap(nullptr, sizeof(behaviour_state_t<sum_items_num>) * local_degree_sum, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0), |
| 592 | plato::mmap_deleter{sizeof(behaviour_state_t<sum_items_num>) * local_degree_sum}); |
| 593 | CHECK(MAP_FAILED != behaviour_mmap_p.get()) |
| 594 | << boost::format("WARNING: mmap failed, err code: %d, err msg: %s") % errno % strerror(errno) << " local_degree_sum: " << local_degree_sum; |
| 595 | |
| 596 | behaviour.unlock(); |
| 597 | auto lock_defer = plato::defer([&]{ behaviour.lock(); }); |
| 598 | |
| 599 | size_t adjs_num = 0; |
| 600 | #pragma omp parallel for |
| 601 | for (plato::vid_t v_i = 0; v_i <= max_vid; ++v_i) { |
| 602 | plato::vid_t degree = *(out_degree.get() + v_i); |
| 603 | if (degree) { |
| 604 | behaviour.upsert( |
nothing calls this directly
no test coverage detected