| Line | % of fetches | Source |
|---|---|---|
| 1 | /* | |
| 2 | * node_server_actions_1.cpp | |
| 3 | * | |
| 4 | * Created on: Sep 23, 2016 | |
| 5 | * Author: dmarce1 | |
| 6 | */ | |
| 7 | ||
| 8 | #include "node_server.hpp" | |
| 9 | #include "node_client.hpp" | |
| 10 | #include "diagnostics.hpp" | |
| 11 | #include "future.hpp" | |
| 12 | #include "taylor.hpp" | |
| 13 | #include "profiler.hpp" | |
| 14 | #include "options.hpp" | |
| 15 | ||
| 16 | #include <chrono> | |
| 17 | ||
| 18 | #include <hpx/include/run_as.hpp> | |
| 19 | #include <hpx/include/lcos.hpp> | |
| 20 | ||
| 21 | extern options opts; | |
| 22 | ||
| 23 | typedef node_server::load_action load_action_type; | |
| 24 | HPX_REGISTER_ACTION(load_action_type); | |
| 25 | ||
| 26 | hpx::mutex rec_size_mutex; | |
| 27 | integer rec_size = -1; | |
| 28 | ||
| 29 | void set_locality_data(real omega, space_vector pivot, integer record_size) { | |
| 30 | grid::set_omega(omega); | |
| 31 | grid::set_pivot(pivot); | |
| 32 | rec_size = record_size; | |
| 33 | } | |
| 34 | ||
| 35 | hpx::id_type make_new_node(const node_location& loc, const hpx::id_type& _parent) { | |
| 36 | return hpx::new_<node_server>(hpx::find_here(), loc, _parent, ZERO, ZERO).get(); | |
| 37 | } | |
| 38 | ||
| 39 | HPX_PLAIN_ACTION(make_new_node, make_new_node_action); | |
| 40 | HPX_PLAIN_ACTION(set_locality_data, set_locality_data_action); | |
| 41 | ||
| 42 | hpx::future<grid::output_list_type> node_client::load(integer i, const hpx::id_type& _me, | |
| 43 | bool do_o, std::string s) const { | |
| 44 | return hpx::async<typename node_server::load_action>(get_gid(), i, _me, do_o, s); | |
| 45 | } | |
| 46 | ||
| 47 | grid::output_list_type node_server::load(integer cnt, const hpx::id_type& _me, | |
| 48 | bool do_output, std::string filename) { | |
| 49 | ||
| 50 | if (rec_size == -1 && my_location.level() == 0) { | |
| 51 | ||
| 52 | real omega = 0; | |
| 53 | space_vector pivot; | |
| 54 | ||
| 55 | // run output on separate thread | |
| 56 | hpx::threads::run_as_os_thread([&]() | |
| 57 | { | |
| 58 | FILE* fp = fopen(filename.c_str(), "rb"); | |
| 59 | if (fp == NULL) { | |
| 60 | printf("Failed to open file\n"); | |
| 61 | abort(); | |
| 62 | } | |
| 63 | fseek(fp, -sizeof(integer), SEEK_END); | |
| 64 | std::size_t read_cnt = fread(&rec_size, sizeof(integer), 1, fp); | |
| 65 | fseek(fp, -4 * sizeof(real) - sizeof(integer), SEEK_END); | |
| 66 | read_cnt += fread(&omega, sizeof(real), 1, fp); | |
| 67 | for (auto& d : geo::dimension::full_set()) { | |
| 68 | read_cnt += fread(&(pivot[d]), sizeof(real), 1, fp); | |
| 69 | } | |
| 70 | fclose(fp); | |
| 71 | }).get(); | |
| 72 | ||
| 73 | auto localities = hpx::find_all_localities(); | |
| 74 | std::vector<hpx::future<void>> futs; | |
| 75 | futs.reserve(localities.size()); | |
| 76 | for (auto& locality : localities) { | |
| 77 | futs.push_back( | |
| 78 | hpx::async<set_locality_data_action>(locality, omega, pivot, rec_size)); | |
| 79 | } | |
| 80 | wait_all_and_propagate_exceptions(futs); | |
| 81 | } | |
| 82 | ||
| 83 | static auto localities = hpx::find_all_localities(); | |
| 84 | me = _me; | |
| 85 | ||
| 86 | char flag = '0'; | |
| 87 | integer total_nodes = 0; | |
| 88 | std::vector<integer> counts(NCHILD); | |
| 89 | ||
| 90 | // run output on separate thread | |
| 91 | hpx::threads::run_as_os_thread([&]() | |
| 92 | { | |
| 93 | FILE* fp = fopen(filename.c_str(), "rb"); | |
| 94 | fseek(fp, cnt * rec_size, SEEK_SET); | |
| 95 | std::size_t read_cnt = fread(&flag, sizeof(char), 1, fp); | |
| 96 | for (auto& this_cnt : counts) { | |
| 97 | read_cnt += fread(&this_cnt, sizeof(integer), 1, fp); | |
| 98 | } | |
| 99 | load_me(fp); | |
| 100 | fseek(fp, 0L, SEEK_END); | |
| 101 | total_nodes = ftell(fp) / rec_size; | |
| 102 | fclose(fp); | |
| 103 | }).get(); | |
| 104 | ||
| 105 | std::vector<hpx::future<grid::output_list_type>> futs; | |
| 106 | //printf( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1\n" ); | |
| 107 | if (flag == '1') { | |
| 108 | is_refined = true; | |
| 109 | children.resize(NCHILD); | |
| 110 | constexpr auto full_set = geo::octant::full_set(); | |
| 111 | futs.reserve(full_set.size()); | |
| 112 | for (auto& ci : full_set) { | |
| 113 | integer loc_id = ((cnt * localities.size()) / (total_nodes + 1)); | |
| 114 | children[ci] = hpx::async<make_new_node_action>(localities[loc_id], | |
| 115 | my_location.get_child(ci), me.get_gid()); | |
| 116 | futs.push_back( | |
| 117 | children[ci].load(counts[ci], children[ci].get_gid(), do_output, | |
| 118 | filename)); | |
| 119 | } | |
| 120 | } else if (flag == '0') { | |
| 121 | is_refined = false; | |
| 122 | children.clear(); | |
| 123 | } else { | |
| 124 | printf("Corrupt checkpoint file\n"); | |
| 125 | // sleep(10); | |
| 126 | hpx::this_thread::sleep_for(std::chrono::seconds(10)); | |
| 127 | abort(); | |
| 128 | } | |
| 129 | grid::output_list_type my_list; | |
| 130 | for (auto&& fut : futs) { | |
| 131 | if (do_output) { | |
| 132 | grid::merge_output_lists(my_list, fut.get()); | |
| 133 | } else { | |
| 134 | fut.get(); | |
| 135 | } | |
| 136 | } | |
| 137 | //printf( "***************************************\n" ); | |
| 138 | if (!is_refined && do_output) { | |
| 139 | my_list = grid_ptr->get_output_list(false); | |
| 140 | // grid_ptr = nullptr; | |
| 141 | } | |
| 142 | // hpx::async<inc_grids_loaded_action>(localities[0]).get(); | |
| 143 | if (my_location.level() == 0) { | |
| 144 | if (do_output) { | |
| 145 | if (hydro_on && opts.problem == DWD) { | |
| 146 | diagnostics(); | |
| 147 | } | |
| 148 | grid::output(my_list, "data.silo", current_time, | |
| 149 | get_rotation_count() / opts.output_dt, false); | |
| 150 | } | |
| 151 | printf("Loaded checkpoint file\n"); | |
| 152 | my_list = decltype(my_list)(); | |
| 153 | ||
| 154 | } | |
| 155 | return my_list; | |
| 156 | } | |
| 157 | ||
| 158 | typedef node_server::output_action output_action_type; | |
| 159 | HPX_REGISTER_ACTION(output_action_type); | |
| 160 | ||
| 161 | hpx::future<grid::output_list_type> node_client::output(std::string fname, int cycle, | |
| 162 | bool flag) const { | |
| 163 | return hpx::async<typename node_server::output_action>(get_gid(), fname, cycle, flag); | |
| 164 | } | |
| 165 | ||
| 166 | grid::output_list_type node_server::output(std::string fname, int cycle, | |
| 167 | bool analytic) const { | |
| 168 | if (is_refined) { | |
| 169 | std::vector<hpx::future<grid::output_list_type>> futs; | |
| 170 | futs.reserve(children.size()); | |
| 171 | for (auto i = children.begin(); i != children.end(); ++i) { | |
| 172 | futs.push_back(i->output(fname, cycle, analytic)); | |
| 173 | } | |
| 174 | auto i = futs.begin(); | |
| 175 | grid::output_list_type my_list = i->get(); | |
| 176 | for (++i; i != futs.end(); ++i) { | |
| 177 | grid::merge_output_lists(my_list, i->get()); | |
| 178 | } | |
| 179 | ||
| 180 | if (my_location.level() == 0) { | |
| 181 | // hpx::apply([](const grid::output_list_type& olists, const char* filename) { | |
| 182 | printf("Outputing...\n"); | |
| 183 | grid::output(my_list, fname, get_time(), cycle, analytic); | |
| 184 | printf("Done...\n"); | |
| 185 | // }, std::move(my_list), fname.c_str()); | |
| 186 | } | |
| 187 | return my_list; | |
| 188 | ||
| 189 | } else { | |
| 190 | return grid_ptr->get_output_list(analytic); | |
| 191 | } | |
| 192 | ||
| 193 | } | |
| 194 | ||
| 195 | typedef node_server::regrid_gather_action regrid_gather_action_type; | |
| 196 | HPX_REGISTER_ACTION(regrid_gather_action_type); | |
| 197 | ||
| 198 | hpx::future<integer> node_client::regrid_gather(bool rb) const { | |
| 199 | return hpx::async<typename node_server::regrid_gather_action>(get_gid(), rb); | |
| 200 | } | |
| 201 | ||
| 202 | integer node_server::regrid_gather(bool rebalance_only) { | |
| 203 | integer count = integer(1); | |
| 204 | ||
| 205 | if (is_refined) { | |
| 206 | if (!rebalance_only) { | |
| 207 | /* Turning refinement off */ | |
| 208 | if (refinement_flag == 0) { | |
| 209 | children.clear(); | |
| 210 | is_refined = false; | |
| 211 | grid_ptr->set_leaf(true); | |
| 212 | } | |
| 213 | } | |
| 214 | ||
| 215 | if (is_refined) { | |
| 216 | std::vector<hpx::future<integer>> futs; | |
| 217 | futs.reserve(children.size()); | |
| 218 | for (auto& child : children) { | |
| 219 | futs.push_back(child.regrid_gather(rebalance_only)); | |
| 220 | } | |
| 221 | auto futi = futs.begin(); | |
| 222 | for (auto& ci : geo::octant::full_set()) { | |
| 223 | auto child_cnt = futi->get(); | |
| 224 | ++futi; | |
| 225 | child_descendant_count[ci] = child_cnt; | |
| 226 | count += child_cnt; | |
| 227 | } | |
| 228 | } else { | |
| 229 | for (auto& ci : geo::octant::full_set()) { | |
| 230 | child_descendant_count[ci] = 0; | |
| 231 | } | |
| 232 | } | |
| 233 | } else if (!rebalance_only) { | |
| 234 | // if (grid_ptr->refine_me(my_location.level())) { | |
| 235 | if (refinement_flag != 0) { | |
| 236 | refinement_flag = 0; | |
| 237 | count += NCHILD; | |
| 238 | ||
| 239 | children.resize(NCHILD); | |
| 240 | std::vector<node_location> clocs(NCHILD); | |
| 241 | ||
| 242 | /* Turning refinement on*/ | |
| 243 | is_refined = true; | |
| 244 | grid_ptr->set_leaf(false); | |
| 245 | ||
| 246 | for (auto& ci : geo::octant::full_set()) { | |
| 247 | child_descendant_count[ci] = 1; | |
| 248 | children[ci] = hpx::new_<node_server>(hpx::find_here(), | |
| 249 | my_location.get_child(ci), me, current_time, rotational_time); | |
| 250 | std::array<integer, NDIM> lb = { 2 * H_BW, 2 * H_BW, 2 * H_BW }; | |
| 251 | std::array<integer, NDIM> ub; | |
| 252 | lb[XDIM] += (1 & (ci >> 0)) * (INX); | |
| 253 | lb[YDIM] += (1 & (ci >> 1)) * (INX); | |
| 254 | lb[ZDIM] += (1 & (ci >> 2)) * (INX); | |
| 255 | for (integer d = 0; d != NDIM; ++d) { | |
| 256 | ub[d] = lb[d] + (INX); | |
| 257 | } | |
| 258 | std::vector<real> outflows(NF, ZERO); | |
| 259 | if (ci == 0) { | |
| 260 | outflows = grid_ptr->get_outflows(); | |
| 261 | } | |
| 262 | if (current_time > ZERO) { | |
| 263 | children[ci].set_grid(grid_ptr->get_prolong(lb, ub), | |
| 264 | std::move(outflows)).get(); | |
| 265 | } | |
| 266 | } | |
| 267 | } | |
| 268 | } | |
| 269 | ||
| 270 | return count; | |
| 271 | } | |
| 272 | ||
| 273 | typedef node_server::regrid_scatter_action regrid_scatter_action_type; | |
| 274 | HPX_REGISTER_ACTION(regrid_scatter_action_type); | |
| 275 | ||
| 276 | hpx::future<void> node_client::regrid_scatter(integer a, integer b) const { | |
| 277 | return hpx::async<typename node_server::regrid_scatter_action>(get_gid(), a, b); | |
| 278 | } | |
| 279 | ||
| 280 | void node_server::regrid_scatter(integer a_, integer total) { | |
| 281 | refinement_flag = 0; | |
| 282 | std::vector<hpx::future<void>> futs; | |
| 283 | if (is_refined) { | |
| 284 | integer a = a_; | |
| 285 | std::vector<hpx::id_type> localities; | |
| 286 | { | |
| 287 | timings::scope ts(timings_, timings::time_find_localities); | |
| 288 | localities = hpx::find_all_localities(); | |
| 289 | } | |
| 290 | ++a; | |
| 291 | for (auto& ci : geo::octant::full_set()) { | |
| 292 | const integer loc_index = a * localities.size() / total; | |
| 293 | const auto child_loc = localities[loc_index]; | |
| 294 | a += child_descendant_count[ci]; | |
| 295 | const hpx::id_type id = children[ci].get_gid(); | |
| 296 | integer current_child_id = hpx::naming::get_locality_id_from_gid( | |
| 297 | id.get_gid()); | |
| 298 | auto current_child_loc = localities[current_child_id]; | |
| 299 | if (child_loc != current_child_loc) { | |
| 300 | children[ci] = children[ci].copy_to_locality(child_loc); | |
| 301 | } | |
| 302 | } | |
| 303 | a = a_ + 1; | |
| 304 | constexpr auto full_set = geo::octant::full_set(); | |
| 305 | futs.reserve(full_set.size()); | |
| 306 | for (auto& ci : full_set) { | |
| 307 | futs.push_back(children[ci].regrid_scatter(a, total)); | |
| 308 | a += child_descendant_count[ci]; | |
| 309 | } | |
| 310 | } | |
| 311 | clear_family(); | |
| 312 | wait_all_and_propagate_exceptions(futs); | |
| 313 | } | |
| 314 | ||
| 315 | typedef node_server::regrid_action regrid_action_type; | |
| 316 | HPX_REGISTER_ACTION(regrid_action_type); | |
| 317 | ||
| 318 | hpx::future<void> node_client::regrid(const hpx::id_type& g, bool rb) const { | |
| 319 | return hpx::async<typename node_server::regrid_action>(get_gid(), g, rb); | |
| 320 | } | |
| 321 | ||
| 322 | int node_server::regrid(const hpx::id_type& root_gid, bool rb) { | |
| 323 | timings::scope ts(timings_, timings::time_regrid); | |
| 324 | assert(grid_ptr != nullptr); | |
| 325 | printf("-----------------------------------------------\n"); | |
| 326 | if (!rb) { | |
| 327 | printf("checking for refinement\n"); | |
| 328 | check_for_refinement(); | |
| 329 | } | |
| 330 | printf("regridding\n"); | |
| 331 | integer a = regrid_gather(rb); | |
| 332 | printf("rebalancing %i nodes\n", int(a)); | |
| 333 | regrid_scatter(0, a); | |
| 334 | assert(grid_ptr != nullptr); | |
| 335 | std::vector<hpx::id_type> null_neighbors(geo::direction::count()); | |
| 336 | printf("forming tree connections\n"); | |
| 337 | form_tree(root_gid, hpx::invalid_id, null_neighbors); | |
| 338 | if (current_time > ZERO) { | |
| 339 | printf("solving gravity\n"); | |
| 340 | solve_gravity(true); | |
| 341 | } | |
| 342 | printf("regrid done\n-----------------------------------------------\n"); | |
| 343 | return a; | |
| 344 | } | |
| 345 | ||
| 346 | typedef node_server::save_action save_action_type; | |
| 347 | HPX_REGISTER_ACTION(save_action_type); | |
| 348 | ||
| 349 | integer node_client::save(integer i, std::string s) const { | |
| 350 | return hpx::async<typename node_server::save_action>(get_gid(), i, s).get(); | |
| 351 | } | |
| 352 | ||
| 353 | integer node_server::save(integer cnt, std::string filename) const { | |
| 354 | char flag = is_refined ? '1' : '0'; | |
| 355 | integer record_size = 0; | |
| 356 | ||
| 357 | // run output on separate thread | |
| 358 | hpx::threads::run_as_os_thread([&]() | |
| 359 | { | |
| 360 | FILE* fp = fopen(filename.c_str(), (cnt == 0) ? "wb" : "ab"); | |
| 361 | fwrite(&flag, sizeof(flag), 1, fp); | |
| 362 | ++cnt; | |
| 363 | // printf(" \rSaved %li sub-grids\r", (long int) cnt); | |
| 364 | integer value = cnt; | |
| 365 | std::array<integer, NCHILD> values; | |
| 366 | for (auto& ci : geo::octant::full_set()) { | |
| 367 | if (ci != 0 && is_refined) { | |
| 368 | value += child_descendant_count[ci - 1]; | |
| 369 | } | |
| 370 | values[ci] = value; | |
| 371 | fwrite(&value, sizeof(value), 1, fp); | |
| 372 | } | |
| 373 | record_size = save_me(fp) + sizeof(flag) + NCHILD * sizeof(integer); | |
| 374 | fclose(fp); | |
| 375 | }).get(); | |
| 376 | ||
| 377 | if (is_refined) { | |
| 378 | for (auto& ci : geo::octant::full_set()) { | |
| 379 | cnt = children[ci].save(cnt, filename); | |
| 380 | } | |
| 381 | } | |
| 382 | ||
| 383 | if (my_location.level() == 0) { | |
| 384 | // run output on separate thread | |
| 385 | hpx::threads::run_as_os_thread([&]() | |
| 386 | { | |
| 387 | FILE* fp = fopen(filename.c_str(), "ab"); | |
| 388 | real omega = grid::get_omega(); | |
| 389 | space_vector pivot = grid::get_pivot(); | |
| 390 | fwrite(&omega, sizeof(real), 1, fp); | |
| 391 | for (auto& d : geo::dimension::full_set()) { | |
| 392 | fwrite(&(pivot[d]), sizeof(real), 1, fp); | |
| 393 | } | |
| 394 | fwrite(&record_size, sizeof(integer), 1, fp); | |
| 395 | fclose(fp); | |
| 396 | }).get(); | |
| 397 | ||
| 398 | printf("Saved %li grids to checkpoint file\n", (long int) cnt); | |
| 399 | } | |
| 400 | ||
| 401 | return cnt; | |
| 402 | } | |
| 403 | ||
| 404 | typedef node_server::set_aunt_action set_aunt_action_type; | |
| 405 | HPX_REGISTER_ACTION(set_aunt_action_type); | |
| 406 | ||
| 407 | hpx::future<void> node_client::set_aunt(const hpx::id_type& aunt, | |
| 408 | const geo::face& f) const { | |
| 409 | return hpx::async<typename node_server::set_aunt_action>(get_gid(), aunt, f); | |
| 410 | } | |
| 411 | ||
| 412 | void node_server::set_aunt(const hpx::id_type& aunt, const geo::face& face) { | |
| 413 | aunts[face] = aunt; | |
| 414 | } | |
| 415 | ||
| 416 | typedef node_server::set_grid_action set_grid_action_type; | |
| 417 | HPX_REGISTER_ACTION(set_grid_action_type); | |
| 418 | ||
| 419 | hpx::future<void> node_client::set_grid(std::vector<real>&& g, | |
| 420 | std::vector<real>&& o) const { | |
| 421 | return hpx::async<typename node_server::set_grid_action>(get_gid(), g, o); | |
| 422 | } | |
| 423 | ||
| 424 | void node_server::set_grid(const std::vector<real>& data, std::vector<real>&& outflows) { | |
| 425 | grid_ptr->set_prolong(data, std::move(outflows)); | |
| 426 | } | |
| 427 | ||
| 428 | typedef node_server::solve_gravity_action solve_gravity_action_type; | |
| 429 | HPX_REGISTER_ACTION(solve_gravity_action_type); | |
| 430 | ||
| 431 | hpx::future<void> node_client::solve_gravity(bool ene) const { | |
| 432 | return hpx::async<typename node_server::solve_gravity_action>(get_gid(), ene); | |
| 433 | } | |
| 434 | ||
| 435 | void node_server::solve_gravity(bool ene) { | |
| 436 | if (!gravity_on) { | |
| 437 | return; | |
| 438 | } | |
| 439 | std::vector<hpx::future<void>> child_futs; | |
| 440 | child_futs.reserve(children.size()); | |
| 441 | for (auto& child : children) { | |
| 442 | child_futs.push_back(child.solve_gravity(ene)); | |
| 443 | } | |
| 444 | compute_fmm(RHO, ene); | |
| 445 | wait_all_and_propagate_exceptions(child_futs); | |
| 446 | } | |
| 447 | ||
| 448 |
Copyright (c) 2006-2012 Rogue Wave Software, Inc. All Rights Reserved.
Patents pending.