362#if defined(DEAL_II_WITH_TBB) && !defined(DEAL_II_TBB_WITH_ONEAPI)
369 tbb::empty_task *root =
370 new (tbb::task::allocate_root()) tbb::empty_task;
371 root->set_ref_count(
evens + 1);
372 std::vector<partition::PartitionWork *> worker(
n_workers);
373 std::vector<partition::PartitionWork *> blocked_worker(
375 MPICommunication *worker_compr =
376 new (root->allocate_child()) MPICommunication(funct,
true);
377 worker_compr->set_ref_count(1);
378 for (
unsigned int j = 0; j <
evens; ++j)
382 worker[j] =
new (root->allocate_child())
383 partition::PartitionWork(funct, 2 * j, *
this,
false);
384 worker[j]->set_ref_count(2);
385 blocked_worker[j - 1]->dummy =
386 new (worker[j]->allocate_child()) tbb::empty_task;
387 tbb::task::spawn(*blocked_worker[j - 1]);
391 worker[j] =
new (worker_compr->allocate_child())
392 partition::PartitionWork(funct, 2 * j, *
this,
false);
393 worker[j]->set_ref_count(2);
394 MPICommunication *worker_dist =
395 new (worker[j]->allocate_child())
396 MPICommunication(funct,
false);
397 tbb::task::spawn(*worker_dist);
401 blocked_worker[j] =
new (worker[j]->allocate_child())
402 partition::PartitionWork(funct, 2 * j + 1, *
this,
true);
408 worker[
evens] =
new (worker[j]->allocate_child())
409 partition::PartitionWork(funct,
413 tbb::task::spawn(*worker[
evens]);
417 tbb::empty_task *child =
418 new (worker[j]->allocate_child()) tbb::empty_task();
419 tbb::task::spawn(*child);
424 root->wait_for_all();
425 root->destroy(*root);
441 tbb::empty_task *root =
442 new (tbb::task::allocate_root()) tbb::empty_task;
443 root->set_ref_count(
evens + 1);
448 std::vector<color::PartitionWork *> worker(
n_workers);
449 std::vector<color::PartitionWork *> blocked_worker(
451 unsigned int worker_index = 0, slice_index = 0;
452 int spawn_index_child = -2;
453 MPICommunication *worker_compr =
454 new (root->allocate_child()) MPICommunication(funct,
true);
455 worker_compr->set_ref_count(1);
456 for (
unsigned int part = 0;
461 worker[worker_index] =
462 new (worker_compr->allocate_child())
463 color::PartitionWork(funct,
468 worker[worker_index] =
new (root->allocate_child())
469 color::PartitionWork(funct,
477 worker[worker_index]->set_ref_count(1);
479 worker[worker_index] =
480 new (worker[worker_index - 1]->allocate_child())
481 color::PartitionWork(funct,
486 worker[worker_index]->set_ref_count(2);
489 blocked_worker[(part - 1) / 2]->dummy =
490 new (worker[worker_index]->allocate_child())
493 if (spawn_index_child == -1)
494 tbb::task::spawn(*blocked_worker[(part - 1) / 2]);
497 Assert(spawn_index_child >= 0,
499 tbb::task::spawn(*worker[spawn_index_child]);
501 spawn_index_child = -2;
505 MPICommunication *worker_dist =
506 new (worker[worker_index]->allocate_child())
507 MPICommunication(funct,
false);
508 tbb::task::spawn(*worker_dist);
516 blocked_worker[part / 2] =
517 new (worker[worker_index - 1]->allocate_child())
518 color::PartitionWork(funct,
525 blocked_worker[part / 2]->set_ref_count(1);
526 worker[worker_index] =
new (
527 blocked_worker[part / 2]->allocate_child())
528 color::PartitionWork(funct,
536 spawn_index_child = -1;
545 worker[worker_index]->set_ref_count(1);
548 worker[worker_index] =
549 new (worker[worker_index - 1]->allocate_child())
550 color::PartitionWork(funct,
555 spawn_index_child = worker_index;
560 tbb::empty_task *
final =
561 new (worker[worker_index - 1]->allocate_child())
563 tbb::task::spawn(*
final);
564 spawn_index_child = worker_index - 1;
570 tbb::task::spawn(*worker[spawn_index_child]);
572 root->wait_for_all();
573 root->destroy(*root);
586 tbb::empty_task *root =
587 new (tbb::task::allocate_root()) tbb::empty_task;
588 root->set_ref_count(2);
589 color::PartitionWork *worker =
590 new (root->allocate_child())
591 color::PartitionWork(funct,
color, *
this,
false);
592 tbb::empty_task::spawn(*worker);
593 root->wait_for_all();
594 root->destroy(*root);
793 const std::vector<unsigned int> &cells_with_comm,
794 const unsigned int dofs_per_cell,
795 const bool categories_are_hp,
796 const std::vector<unsigned int> &cell_vectorization_categories,
797 const bool cell_vectorization_categories_strict,
798 const std::vector<unsigned int> &parent_relation,
799 std::vector<unsigned int> &renumbering,
800 std::vector<unsigned char> &incompletely_filled_vectorization)
831 unsigned int n_categories = 1;
833 if (cell_vectorization_categories.empty() ==
false)
838 std::vector<unsigned int> used_categories_vector(
839 cell_vectorization_categories);
840 std::sort(used_categories_vector.begin(),
841 used_categories_vector.end());
842 used_categories_vector.erase(
843 std::unique(used_categories_vector.begin(),
844 used_categories_vector.end()),
845 used_categories_vector.end());
849 const unsigned int index =
850 std::lower_bound(used_categories_vector.begin(),
851 used_categories_vector.end(),
852 cell_vectorization_categories[i]) -
853 used_categories_vector.begin();
855 tight_category_map[i] =
index;
857 n_categories = used_categories_vector.size();
860 std::vector<unsigned int> temporary_numbering;
862 (n_lanes - 1) * n_categories);
863 std::vector<unsigned int> category_size;
870 bool do_advanced_reordering =
false;
871 if (cell_vectorization_categories_strict ==
true &&
874 std::vector<std::pair<unsigned int, unsigned int>> renumbered(
877 renumbered[i] = std::make_pair(tight_category_map[i], i);
878 std::sort(renumbered.begin(), renumbered.end());
883 renumbered[i + j].
first == renumbered[i].
first)
885 for (
unsigned int k = 0; k < j; ++k)
886 temporary_numbering.push_back(renumbered[i + k].second);
887 while (temporary_numbering.size() % n_lanes != 0)
895 else if (cell_vectorization_categories_strict ==
false &&
900 temporary_numbering[tight_category_map[i]] = i;
907 do_advanced_reordering =
true;
908 std::vector<std::vector<unsigned int>> renumbering_category(
911 renumbering_category[tight_category_map[i]].
push_back(i);
913 if (cell_vectorization_categories_strict ==
false && n_categories > 1)
914 for (
unsigned int j = n_categories - 1; j > 0; --j)
916 unsigned int lower_index = j - 1;
917 while ((renumbering_category[j].
size() % n_lanes) != 0u)
919 while (((renumbering_category[j].
size() % n_lanes) != 0u) &&
920 !renumbering_category[lower_index].empty())
922 renumbering_category[j].push_back(
923 renumbering_category[lower_index].back());
924 renumbering_category[lower_index].pop_back();
926 if (lower_index == 0)
937 const unsigned int n_cells_per_parent =
938 std::count(parent_relation.begin(), parent_relation.end(), 0);
939 for (
unsigned int j = 0; j < n_categories; ++j)
941 std::vector<std::pair<unsigned int, unsigned int>> grouped_cells;
942 std::vector<unsigned int> other_cells;
943 for (
const unsigned int cell : renumbering_category[j])
944 if (parent_relation.empty() ||
946 other_cells.push_back(cell);
948 grouped_cells.emplace_back(parent_relation[cell], cell);
951 std::sort(grouped_cells.begin(), grouped_cells.end());
952 std::vector<unsigned int> n_cells_per_group;
953 unsigned int length = 0;
954 for (
unsigned int i = 0; i < grouped_cells.size(); ++i, ++length)
956 grouped_cells[i].
first != grouped_cells[i - 1].
first)
958 n_cells_per_group.push_back(length);
962 n_cells_per_group.push_back(length);
967 auto group_it = grouped_cells.begin();
968 for (
const unsigned int length : n_cells_per_group)
969 if (length < n_cells_per_parent)
970 for (
unsigned int j = 0; j < length; ++j)
971 other_cells.push_back((group_it++)->second);
977 for (
unsigned int j = 0; j < length; ++j)
978 temporary_numbering.push_back((group_it++)->second);
982 std::sort(other_cells.begin(), other_cells.end());
983 temporary_numbering.insert(temporary_numbering.end(),
987 while (temporary_numbering.size() % n_lanes != 0)
990 category_size.push_back(temporary_numbering.size());
994 while (temporary_numbering.size() % n_lanes != 0)
998 std::vector<unsigned int> temporary_numbering_inverse(
n_active_cells);
999 for (
unsigned int i = 0; i < temporary_numbering.size(); ++i)
1001 temporary_numbering_inverse[temporary_numbering[i]] = i;
1002 std::vector<bool> batch_with_comm(temporary_numbering.size() / n_lanes,
1004 for (
const unsigned int cell : cells_with_comm)
1005 batch_with_comm[temporary_numbering_inverse[cell] / n_lanes] =
true;
1014 std::vector<std::array<unsigned int, 3>> batch_order;
1015 std::vector<std::array<unsigned int, 3>> batch_order_comm;
1016 for (
unsigned int i = 0; i < temporary_numbering.size(); i += n_lanes)
1018 unsigned int max_index = 0;
1019 if (do_advanced_reordering)
1020 for (
unsigned int j = 0; j < n_lanes; ++j)
1022 max_index =
std::max(temporary_numbering[i + j], max_index);
1024 const unsigned int category_hp =
1026 std::upper_bound(category_size.begin(), category_size.end(), i) -
1027 category_size.begin() :
1029 const std::array<unsigned int, 3> next{{category_hp, max_index, i}};
1030 if (batch_with_comm[i / n_lanes] || !do_advanced_reordering)
1031 batch_order_comm.emplace_back(next);
1033 batch_order.emplace_back(next);
1036 std::sort(batch_order.begin(), batch_order.end());
1037 std::sort(batch_order_comm.begin(), batch_order_comm.end());
1044 std::vector<unsigned int> blocks;
1047 if (batch_order.empty())
1048 std::swap(batch_order_comm, batch_order);
1051 blocks = {0,
static_cast<unsigned int>(batch_order.size())};
1056 const unsigned int comm_begin = batch_order.size() / 2;
1057 batch_order.insert(batch_order.begin() + comm_begin,
1058 batch_order_comm.begin(),
1059 batch_order_comm.end());
1060 const unsigned int comm_end = comm_begin + batch_order_comm.size();
1061 const unsigned int end = batch_order.size();
1062 blocks = {0, comm_begin, comm_end,
end};
1066 std::vector<std::array<unsigned int, 2>> tight_category_map_ghost;
1068 if (cell_vectorization_categories.empty() ==
false)
1072 std::set<unsigned int> used_categories;
1074 used_categories.insert(
1077 std::vector<unsigned int> used_categories_vector(
1078 used_categories.size());
1080 for (
const auto &it : used_categories)
1081 used_categories_vector[n_categories++] = it;
1083 std::vector<unsigned int> counters(n_categories, 0);
1087 const unsigned int index =
1089 used_categories_vector.begin(),
1090 used_categories_vector.end(),
1092 used_categories_vector.begin();
1094 tight_category_map_ghost.emplace_back(
1095 std::array<unsigned int, 2>{{
index, i}});
1098 if (categories_are_hp || cell_vectorization_categories_strict)
1103 for (
unsigned int i = 0; i < counters.size(); ++i)
1104 if (counters[i] % n_lanes != 0)
1105 for (
unsigned int j = counters[i] % n_lanes; j < n_lanes; ++j)
1106 tight_category_map_ghost.emplace_back(
1107 std::array<unsigned int, 2>{
1108 {i, numbers::invalid_unsigned_int}});
1110 std::sort(tight_category_map_ghost.begin(),
1111 tight_category_map_ghost.end());
1115 const unsigned int n_cell_batches = batch_order.size();
1116 const unsigned int n_ghost_batches =
1117 ((tight_category_map_ghost.empty() ? n_ghost_cells :
1118 tight_category_map_ghost.size()) +
1121 incompletely_filled_vectorization.resize(n_cell_batches +
1124 cell_partition_data.clear();
1125 cell_partition_data.resize(1, 0);
1127 renumbering.clear();
1128 renumbering.resize(n_active_cells + n_ghost_cells,
1131 unsigned int counter = 0;
1132 for (
unsigned int block = 0; block < blocks.size() - 1; ++block)
1134 const unsigned int grain_size =
1135 std::max((2048U / dofs_per_cell) / 8 * 4, 2U);
1136 for (
unsigned int k = blocks[block]; k < blocks[block + 1];
1138 cell_partition_data.push_back(
1139 std::min(k + grain_size, blocks[block + 1]));
1140 partition_row_index[block + 1] = cell_partition_data.size() - 1;
1143 for (
unsigned int k = blocks[block]; k < blocks[block + 1]; ++k)
1145 const unsigned int pos = batch_order[k][2];
1147 for (; j < n_lanes && temporary_numbering[pos + j] !=
1150 renumbering[counter++] = temporary_numbering[pos + j];
1152 incompletely_filled_vectorization[k] = j;
1158 if (tight_category_map_ghost.empty())
1160 for (
unsigned int cell = 0; cell < n_ghost_cells; ++cell)
1161 renumbering[n_active_cells + cell] = n_active_cells + cell;
1163 if ((n_ghost_cells % n_lanes) != 0u)
1164 incompletely_filled_vectorization.back() = n_ghost_cells % n_lanes;
1168 for (
unsigned int k = 0, ptr = 0; k < n_ghost_batches;
1169 ++k, ptr += n_lanes)
1174 j < n_lanes && (ptr + j < tight_category_map_ghost.size()) &&
1175 (tight_category_map_ghost[ptr + j][1] !=
1178 renumbering[counter++] =
1179 n_active_cells + tight_category_map_ghost[ptr + j][1];
1182 incompletely_filled_vectorization[n_cell_batches + k] = j;
1188 cell_partition_data.push_back(n_cell_batches + n_ghost_batches);
1189 partition_row_index.back() = cell_partition_data.size() - 1;
1193 std::vector<unsigned int> renumber_cpy(renumbering);
1194 std::sort(renumber_cpy.begin(), renumber_cpy.end());
1195 for (
unsigned int i = 0; i < renumber_cpy.size(); ++i)
1203 TaskInfo::initial_setup_blocks_tasks(
1204 const std::vector<unsigned int> &boundary_cells,
1205 std::vector<unsigned int> &renumbering,
1206 std::vector<unsigned char> &incompletely_filled_vectorization)
1208 const unsigned int n_cell_batches =
1209 (n_active_cells + vectorization_length - 1) / vectorization_length;
1210 const unsigned int n_ghost_slots =
1211 (n_ghost_cells + vectorization_length - 1) / vectorization_length;
1212 incompletely_filled_vectorization.resize(n_cell_batches + n_ghost_slots);
1213 if (n_cell_batches * vectorization_length > n_active_cells)
1214 incompletely_filled_vectorization[n_cell_batches - 1] =
1215 vectorization_length -
1216 (n_cell_batches * vectorization_length - n_active_cells);
1217 if (n_ghost_slots * vectorization_length > n_ghost_cells)
1218 incompletely_filled_vectorization[n_cell_batches + n_ghost_slots - 1] =
1219 vectorization_length -
1220 (n_ghost_slots * vectorization_length - n_ghost_cells);
1222 std::vector<unsigned int> reverse_numbering(
1224 for (
unsigned int j = 0; j < boundary_cells.size(); ++j)
1225 reverse_numbering[boundary_cells[j]] = j;
1226 unsigned int counter = boundary_cells.size();
1227 for (
unsigned int j = 0; j < n_active_cells; ++j)
1229 reverse_numbering[j] = counter++;
1234 for (
unsigned int j = n_active_cells; j < n_active_cells + n_ghost_cells;
1236 renumbering.push_back(j);
1240 cell_partition_data.clear();
1241 cell_partition_data.push_back(0);
1244 const unsigned int n_macro_boundary_cells =
1245 (boundary_cells.size() + vectorization_length - 1) /
1246 vectorization_length;
1247 cell_partition_data.push_back(
1248 (n_cell_batches - n_macro_boundary_cells) / 2);
1249 cell_partition_data.push_back(cell_partition_data[1] +
1250 n_macro_boundary_cells);
1254 cell_partition_data.push_back(n_cell_batches);
1255 cell_partition_data.push_back(cell_partition_data.back() + n_ghost_slots);
1256 partition_row_index.resize(
n_procs > 1 ? 4 : 2);
1257 partition_row_index[0] = 0;
1258 partition_row_index[1] = 1;
1261 partition_row_index[2] = 2;
1262 partition_row_index[3] = 3;
1297 TaskInfo::make_thread_graph_partition_color(
1299 std::vector<unsigned int> &renumbering,
1300 std::vector<unsigned char> &irregular_cells,
1303 const unsigned int n_cell_batches = *(cell_partition_data.end() - 2);
1304 if (n_cell_batches == 0)
1309 unsigned int partition = 0, counter = 0;
1314 make_connectivity_cells_to_blocks(irregular_cells,
1323 std::vector<unsigned int> cell_partition(n_blocks,
1328 std::vector<unsigned int> partition_list(n_blocks, 0);
1329 std::vector<unsigned int> partition_color_list(n_blocks, 0);
1332 std::vector<unsigned int> partition_size(2, 0);
1338 unsigned int cluster_size = 1;
1341 make_partitioning(connectivity,
1349 make_coloring_within_partitions_pre_blocked(connectivity,
1354 partition_color_list);
1356 partition_list = renumbering;
1362 std::vector<unsigned int> sorted_pc_list(partition_color_list);
1363 std::sort(sorted_pc_list.begin(), sorted_pc_list.end());
1364 for (
unsigned int i = 0; i < sorted_pc_list.size(); ++i)
1371 std::vector<unsigned int> block_start(n_cell_batches + 1);
1372 std::vector<unsigned char> irregular(n_cell_batches);
1374 unsigned int mcell_start = 0;
1376 for (
unsigned int block = 0; block < n_blocks; ++block)
1378 block_start[block + 1] = block_start[block];
1379 for (
unsigned int mcell = mcell_start;
1380 mcell <
std::min(mcell_start + block_size, n_cell_batches);
1383 unsigned int n_comp = (irregular_cells[mcell] > 0) ?
1384 irregular_cells[mcell] :
1385 vectorization_length;
1386 block_start[block + 1] += n_comp;
1389 mcell_start += block_size;
1392 unsigned int counter_macro = 0;
1393 unsigned int block_size_last =
1394 n_cell_batches - block_size * (n_blocks - 1);
1395 if (block_size_last == 0)
1396 block_size_last = block_size;
1398 unsigned int tick = 0;
1399 for (
unsigned int block = 0; block < n_blocks; ++block)
1401 unsigned int present_block = partition_color_list[block];
1402 for (
unsigned int cell = block_start[present_block];
1403 cell < block_start[present_block + 1];
1405 renumbering[counter++] = partition_list[cell];
1406 unsigned int this_block_size =
1407 (present_block == n_blocks - 1) ? block_size_last : block_size;
1411 if (cell_partition_data[tick] == block)
1412 cell_partition_data[tick++] = counter_macro;
1414 for (
unsigned int j = 0; j < this_block_size; ++j)
1415 irregular[counter_macro++] =
1416 irregular_cells[present_block * block_size + j];
1419 cell_partition_data.back() = counter_macro;
1421 irregular_cells.swap(irregular);
1429 std::vector<unsigned int> sorted_renumbering(renumbering);
1430 std::sort(sorted_renumbering.begin(), sorted_renumbering.end());
1431 for (
unsigned int i = 0; i < sorted_renumbering.size(); ++i)
1446 TaskInfo::make_thread_graph(
1447 const std::vector<unsigned int> &cell_active_fe_index,
1449 std::vector<unsigned int> &renumbering,
1450 std::vector<unsigned char> &irregular_cells,
1453 const unsigned int n_cell_batches = *(cell_partition_data.end() - 2);
1454 if (n_cell_batches == 0)
1462 make_connectivity_cells_to_blocks(irregular_cells,
1464 connectivity_blocks);
1466 unsigned int n_blocks = 0;
1467 if (scheme == partition_color ||
1469 n_blocks = this->n_blocks;
1471 n_blocks = n_active_cells;
1476 std::vector<unsigned int> cell_partition(n_blocks,
1482 std::vector<unsigned int> partition_list(n_blocks, 0);
1483 std::vector<unsigned int> partition_2layers_list(n_blocks, 0);
1486 std::vector<unsigned int> partition_size(2, 0);
1488 unsigned int partition = 0;
1494 unsigned int cluster_size = 1;
1495 if (scheme == partition_partition)
1496 cluster_size = block_size * vectorization_length;
1499 if (scheme == partition_color || scheme == color)
1500 make_partitioning(connectivity_blocks,
1507 make_partitioning(connectivity,
1515 if (scheme == partition_partition)
1519 make_partitioning_within_partitions_post_blocked(
1521 cell_active_fe_index,
1528 partition_2layers_list,
1531 else if (scheme == partition_color || scheme == color)
1533 make_coloring_within_partitions_pre_blocked(connectivity_blocks,
1538 partition_2layers_list);
1545 std::vector<unsigned int> sorted_pc_list(partition_2layers_list);
1546 std::sort(sorted_pc_list.begin(), sorted_pc_list.end());
1547 for (
unsigned int i = 0; i < sorted_pc_list.size(); ++i)
1553 std::vector<unsigned int> renumbering_in(n_active_cells, 0);
1554 renumbering_in.swap(renumbering);
1555 if (scheme == partition_partition)
1560 for (
unsigned int j = 0; j < renumbering.size(); ++j)
1561 renumbering[j] = renumbering_in[partition_2layers_list[j]];
1563 for (
unsigned int i = 0; i < n_ghost_cells; ++i)
1564 renumbering.push_back(i + n_active_cells);
1570 std::vector<unsigned int> block_start(n_cell_batches + 1);
1571 std::vector<unsigned char> irregular(n_cell_batches);
1573 unsigned int counter = 0;
1574 unsigned int mcell_start = 0;
1576 for (
unsigned int block = 0; block < n_blocks; ++block)
1578 block_start[block + 1] = block_start[block];
1579 for (
unsigned int mcell = mcell_start;
1580 mcell <
std::min(mcell_start + block_size, n_cell_batches);
1583 unsigned int n_comp = (irregular_cells[mcell] > 0) ?
1584 irregular_cells[mcell] :
1585 vectorization_length;
1586 block_start[block + 1] += n_comp;
1589 mcell_start += block_size;
1592 unsigned int counter_macro = 0;
1593 unsigned int block_size_last =
1594 n_cell_batches - block_size * (n_blocks - 1);
1595 if (block_size_last == 0)
1596 block_size_last = block_size;
1598 unsigned int tick = 0;
1599 for (
unsigned int block = 0; block < n_blocks; ++block)
1601 unsigned int present_block = partition_2layers_list[block];
1602 for (
unsigned int cell = block_start[present_block];
1603 cell < block_start[present_block + 1];
1605 renumbering[counter++] = renumbering_in[cell];
1606 unsigned int this_block_size =
1607 (present_block == n_blocks - 1) ? block_size_last : block_size;
1611 if (cell_partition_data[tick] == block)
1612 cell_partition_data[tick++] = counter_macro;
1614 for (
unsigned int j = 0; j < this_block_size; ++j)
1615 irregular[counter_macro++] =
1616 irregular_cells[present_block * block_size + j];
1619 cell_partition_data.back() = counter_macro;
1621 irregular_cells.swap(irregular);
1628 std::vector<unsigned int> sorted_renumbering(renumbering);
1629 std::sort(sorted_renumbering.begin(), sorted_renumbering.end());
1630 for (
unsigned int i = 0; i < sorted_renumbering.size(); ++i)
1637 update_task_info(partition);
1755 TaskInfo::make_partitioning_within_partitions_post_blocked(
1757 const std::vector<unsigned int> &cell_active_fe_index,
1758 const unsigned int partition,
1759 const unsigned int cluster_size,
1761 const std::vector<unsigned int> &cell_partition,
1762 const std::vector<unsigned int> &partition_list,
1763 const std::vector<unsigned int> &partition_size,
1764 std::vector<unsigned int> &partition_partition_list,
1765 std::vector<unsigned char> &irregular_cells)
1767 const unsigned int n_cell_batches = *(cell_partition_data.end() - 2);
1768 const unsigned int n_ghost_slots =
1769 *(cell_partition_data.end() - 1) - n_cell_batches;
1772 std::vector<unsigned int> neighbor_list;
1775 std::vector<unsigned int> neighbor_neighbor_list;
1777 std::vector<unsigned int> renumbering(n_active_cells);
1779 irregular_cells.back() = 0;
1780 irregular_cells.resize(n_active_cells + n_ghost_slots);
1782 unsigned int max_fe_index = 0;
1783 for (
const unsigned int fe_index : cell_active_fe_index)
1784 max_fe_index =
std::max(fe_index, max_fe_index);
1786 Assert(!hp_bool || cell_active_fe_index.size() == n_active_cells,
1790 unsigned int n_cell_batches_before = 0;
1796 std::vector<unsigned int> cell_partition_l2(
1798 partition_row_index.clear();
1799 partition_row_index.resize(partition + 1, 0);
1800 cell_partition_data.resize(1, 0);
1802 unsigned int counter = 0;
1803 unsigned int missing_macros;
1804 for (
unsigned int part = 0; part < partition; ++part)
1806 neighbor_neighbor_list.resize(0);
1807 neighbor_list.resize(0);
1809 unsigned int partition_l2 = 0;
1810 unsigned int start_up = partition_size[part];
1811 unsigned int partition_counter = 0;
1814 if (neighbor_list.empty())
1817 partition_counter = 0;
1818 for (
unsigned int j = start_up;
1819 j < partition_size[part + 1];
1821 if (cell_partition[partition_list[j]] == part &&
1822 cell_partition_l2[partition_list[j]] ==
1827 partition_counter = 1;
1831 cell_partition_l2[partition_list[start_up]] =
1833 neighbor_neighbor_list.push_back(
1834 partition_list[start_up]);
1835 partition_partition_list[counter++] =
1836 partition_list[start_up];
1843 partition_counter = 0;
1844 for (
const unsigned int neighbor : neighbor_list)
1846 Assert(cell_partition[neighbor] == part,
1848 Assert(cell_partition_l2[neighbor] == partition_l2 - 1,
1850 auto neighbor_it = connectivity.
begin(neighbor);
1851 const auto end_it = connectivity.
end(neighbor);
1852 for (; neighbor_it != end_it; ++neighbor_it)
1854 if (cell_partition[neighbor_it->column()] == part &&
1855 cell_partition_l2[neighbor_it->column()] ==
1858 cell_partition_l2[neighbor_it->column()] =
1860 neighbor_neighbor_list.push_back(
1861 neighbor_it->column());
1862 partition_partition_list[counter++] =
1863 neighbor_it->column();
1864 ++partition_counter;
1869 if (partition_counter > 0)
1871 int index_before = neighbor_neighbor_list.size(),
1872 index = index_before;
1877 std::vector<unsigned int> remaining_per_cell_batch(
1879 std::vector<std::vector<unsigned int>>
1880 renumbering_fe_index;
1883 if (hp_bool ==
true)
1885 renumbering_fe_index.resize(max_fe_index + 1);
1886 for (cell = counter - partition_counter;
1890 renumbering_fe_index
1891 [cell_active_fe_index.empty() ?
1893 cell_active_fe_index
1894 [partition_partition_list[cell]]]
1895 .push_back(partition_partition_list[cell]);
1898 for (
unsigned int j = 0; j < max_fe_index + 1; ++j)
1900 remaining_per_cell_batch[j] =
1901 renumbering_fe_index[j].size() %
1902 vectorization_length;
1903 if (remaining_per_cell_batch[j] != 0)
1906 ((renumbering_fe_index[j].size() +
1907 vectorization_length - 1) /
1908 vectorization_length);
1913 remaining_per_cell_batch.resize(1);
1914 remaining_per_cell_batch[0] =
1915 partition_counter % vectorization_length;
1917 partition_counter / vectorization_length;
1918 if (remaining_per_cell_batch[0] != 0)
1925 cluster_size - (missing_macros % cluster_size);
1928 while (missing_macros > 0 || filled ==
false)
1932 index = neighbor_neighbor_list.size();
1933 if (
index == index_before)
1935 if (missing_macros != 0)
1937 neighbor_neighbor_list.resize(0);
1942 index_before =
index;
1945 unsigned int additional =
1946 neighbor_neighbor_list[
index];
1957 for (; neighbor !=
end; ++neighbor)
1959 if (cell_partition[neighbor->
column()] == part &&
1960 cell_partition_l2[neighbor->
column()] ==
1963 unsigned int this_index = 0;
1964 if (hp_bool ==
true)
1966 cell_active_fe_index.empty() ?
1968 cell_active_fe_index[neighbor
1975 if (missing_macros > 0 ||
1976 remaining_per_cell_batch[this_index] > 0)
1978 cell_partition_l2[neighbor->
column()] =
1980 neighbor_neighbor_list.push_back(
1982 if (hp_bool ==
true)
1983 renumbering_fe_index[this_index]
1984 .push_back(neighbor->
column());
1985 partition_partition_list[counter] =
1988 ++partition_counter;
1989 if (remaining_per_cell_batch
1990 [this_index] == 0 &&
1993 remaining_per_cell_batch[this_index]++;
1994 if (remaining_per_cell_batch
1996 vectorization_length)
1998 remaining_per_cell_batch[this_index] =
2001 if (missing_macros == 0)
2004 for (
unsigned int fe_ind = 0;
2005 fe_ind < max_fe_index + 1;
2007 if (remaining_per_cell_batch
2017 if (hp_bool ==
true)
2022 cell = counter - partition_counter;
2023 for (
unsigned int j = 0; j < max_fe_index + 1; ++j)
2025 for (
const unsigned int jj :
2026 renumbering_fe_index[j])
2027 renumbering[cell++] = jj;
2028 if (renumbering_fe_index[j].
size() %
2029 vectorization_length !=
2031 irregular_cells[renumbering_fe_index[j].
size() /
2032 vectorization_length +
2033 n_cell_batches_before] =
2034 renumbering_fe_index[j].size() %
2035 vectorization_length;
2036 n_cell_batches_before +=
2037 (renumbering_fe_index[j].size() +
2038 vectorization_length - 1) /
2039 vectorization_length;
2040 renumbering_fe_index[j].resize(0);
2045 n_cell_batches_before +=
2046 partition_counter / vectorization_length;
2047 if (partition_counter % vectorization_length != 0)
2049 irregular_cells[n_cell_batches_before] =
2050 partition_counter % vectorization_length;
2051 ++n_cell_batches_before;
2055 cell_partition_data.push_back(n_cell_batches_before);
2058 neighbor_list = neighbor_neighbor_list;
2059 neighbor_neighbor_list.resize(0);
2061 partition_row_index[part + 1] =
2062 partition_row_index[part] + partition_l2;
2065 if (hp_bool ==
true)
2067 partition_partition_list.swap(renumbering);
2076 TaskInfo::make_coloring_within_partitions_pre_blocked(
2078 const unsigned int partition,
2079 const std::vector<unsigned int> &cell_partition,
2080 const std::vector<unsigned int> &partition_list,
2081 const std::vector<unsigned int> &partition_size,
2082 std::vector<unsigned int> &partition_color_list)
2084 const unsigned int n_cell_batches = *(cell_partition_data.end() - 2);
2085 std::vector<unsigned int> cell_color(n_blocks, n_cell_batches);
2086 std::vector<bool> color_finder;
2088 partition_row_index.resize(partition + 1);
2089 cell_partition_data.clear();
2090 unsigned int color_counter = 0, index_counter = 0;
2091 for (
unsigned int part = 0; part < partition; ++part)
2093 partition_row_index[part] = index_counter;
2094 unsigned int max_color = 0;
2095 for (
unsigned int k = partition_size[part];
2096 k < partition_size[part + 1];
2099 unsigned int cell = partition_list[k];
2100 unsigned int n_neighbors = connectivity.
row_length(cell);
2104 color_finder.resize(n_neighbors + 1);
2105 for (
unsigned int j = 0; j <= n_neighbors; ++j)
2106 color_finder[j] =
true;
2108 connectivity.
begin(cell),
2109 end = connectivity.
end(cell);
2110 for (; neighbor !=
end; ++neighbor)
2114 if (cell_partition[neighbor->
column()] == part &&
2115 cell_color[neighbor->
column()] <= n_neighbors)
2116 color_finder[cell_color[neighbor->
column()]] =
false;
2119 cell_color[cell] = 0;
2120 while (color_finder[cell_color[cell]] ==
false)
2122 if (cell_color[cell] > max_color)
2123 max_color = cell_color[cell];
2128 for (
unsigned int color = 0; color <= max_color; ++color)
2130 cell_partition_data.push_back(color_counter);
2132 for (
unsigned int k = partition_size[part];
2133 k < partition_size[part + 1];
2136 unsigned int cell = partition_list[k];
2137 if (cell_color[cell] == color)
2139 partition_color_list[color_counter++] = cell;
2144 cell_partition_data.push_back(n_blocks);
2145 partition_row_index[partition] = index_counter;
2153 const unsigned int cluster_size,
2154 std::vector<unsigned int> &cell_partition,
2155 std::vector<unsigned int> &partition_list,
2156 std::vector<unsigned int> &partition_size,
2157 unsigned int &partition)
const
2166 std::vector<unsigned int> neighbor_list;
2169 std::vector<unsigned int> neighbor_neighbor_list;
2179 unsigned int counter = 0;
2180 unsigned int start_nonboundary =
2181 cell_partition_data.size() == 5 ?
2182 vectorization_length *
2183 (cell_partition_data[2] - cell_partition_data[1]) :
2186 const unsigned int n_cell_batches = *(cell_partition_data.end() - 2);
2187 if (n_cell_batches == 0)
2189 if (scheme == color)
2190 start_nonboundary = n_cell_batches;
2191 if (scheme == partition_color ||
2193 start_nonboundary = ((start_nonboundary + block_size - 1) / block_size);
2194 unsigned int n_blocks;
2195 if (scheme == partition_color ||
2197 n_blocks = this->n_blocks;
2199 n_blocks = n_active_cells;
2201 if (start_nonboundary > n_blocks)
2202 start_nonboundary = n_blocks;
2205 unsigned int start_up = 0;
2207 unsigned int remainder = cluster_size;
2215 if (start_nonboundary > 0)
2217 for (
unsigned int cell = 0; cell < start_nonboundary; ++cell)
2219 const unsigned int cell_nn = cell;
2220 cell_partition[cell_nn] = partition;
2221 neighbor_list.push_back(cell_nn);
2222 partition_list[counter++] = cell_nn;
2223 partition_size.back()++;
2225 start_nonboundary = 0;
2226 remainder -= (start_nonboundary % cluster_size);
2227 if (remainder == cluster_size)
2234 cell_partition[start_up] = partition;
2235 neighbor_list.push_back(start_up);
2236 partition_list[counter++] = start_up;
2237 partition_size.back()++;
2240 if (remainder == cluster_size)
2243 int index_before = neighbor_list.size(),
index = index_before,
2245 while (remainder > 0)
2247 if (
index == index_stop)
2249 index = neighbor_list.size();
2250 if (
index == index_before)
2252 neighbor_list.resize(0);
2255 index_stop = index_before;
2256 index_before =
index;
2259 unsigned int additional = neighbor_list[
index];
2261 connectivity.
begin(additional),
2263 connectivity.
end(additional);
2264 for (; neighbor !=
end; ++neighbor)
2266 if (cell_partition[neighbor->
column()] ==
2269 partition_size.back()++;
2270 cell_partition[neighbor->
column()] = partition;
2271 neighbor_list.push_back(neighbor->
column());
2272 partition_list[counter++] = neighbor->
column();
2280 while (neighbor_list.size() > 0)
2285 unsigned int partition_counter = 0;
2288 partition_size.push_back(partition_size.back());
2292 for (
const unsigned int cell : neighbor_list)
2294 Assert(cell_partition[cell] == partition - 1,
2296 auto neighbor = connectivity.
begin(cell);
2297 const auto end = connectivity.
end(cell);
2298 for (; neighbor !=
end; ++neighbor)
2300 if (cell_partition[neighbor->column()] ==
2303 partition_size.back()++;
2304 cell_partition[neighbor->column()] = partition;
2308 neighbor_neighbor_list.push_back(neighbor->column());
2309 partition_list[counter++] = neighbor->column();
2310 ++partition_counter;
2314 remainder = cluster_size - (partition_counter % cluster_size);
2315 if (remainder == cluster_size)
2318 int index_before = neighbor_neighbor_list.size(),
2319 index = index_before;
2320 while (remainder > 0)
2322 if (
index == index_stop)
2324 index = neighbor_neighbor_list.size();
2325 if (
index == index_before)
2327 neighbor_neighbor_list.resize(0);
2330 index_stop = index_before;
2331 index_before =
index;
2334 unsigned int additional = neighbor_neighbor_list[
index];
2340 for (; neighbor !=
end; ++neighbor)
2342 if (cell_partition[neighbor->
column()] ==
2345 partition_size.back()++;
2346 cell_partition[neighbor->
column()] = partition;
2347 neighbor_neighbor_list.push_back(neighbor->
column());
2348 partition_list[counter++] = neighbor->
column();
2356 neighbor_list = neighbor_neighbor_list;
2357 neighbor_neighbor_list.resize(0);
2363 for (
unsigned int j = start_up; j < n_blocks; ++j)
2369 remainder = cluster_size;