364#if defined(DEAL_II_WITH_TBB) && !defined(DEAL_II_TBB_WITH_ONEAPI)
371 tbb::empty_task *root =
372 new (tbb::task::allocate_root()) tbb::empty_task;
373 root->set_ref_count(
evens + 1);
374 std::vector<partition::PartitionWork *> worker(
n_workers);
375 std::vector<partition::PartitionWork *> blocked_worker(
379 worker_compr->set_ref_count(1);
380 for (
unsigned int j = 0; j <
evens; ++j)
384 worker[j] =
new (root->allocate_child())
386 worker[j]->set_ref_count(2);
387 blocked_worker[j - 1]->
dummy =
388 new (worker[j]->allocate_child()) tbb::empty_task;
389 tbb::task::spawn(*blocked_worker[j - 1]);
393 worker[j] =
new (worker_compr->allocate_child())
395 worker[j]->set_ref_count(2);
397 new (worker[j]->allocate_child())
399 tbb::task::spawn(*worker_dist);
403 blocked_worker[j] =
new (worker[j]->allocate_child())
410 worker[
evens] =
new (worker[j]->allocate_child())
415 tbb::task::spawn(*worker[
evens]);
419 tbb::empty_task *child =
420 new (worker[j]->allocate_child()) tbb::empty_task();
421 tbb::task::spawn(*child);
426 root->wait_for_all();
427 root->destroy(*root);
443 tbb::empty_task *root =
444 new (tbb::task::allocate_root()) tbb::empty_task;
445 root->set_ref_count(
evens + 1);
450 std::vector<color::PartitionWork *> worker(
n_workers);
451 std::vector<color::PartitionWork *> blocked_worker(
453 unsigned int worker_index = 0, slice_index = 0;
454 int spawn_index_child = -2;
457 worker_compr->set_ref_count(1);
458 for (
unsigned int part = 0;
463 worker[worker_index] =
464 new (worker_compr->allocate_child())
470 worker[worker_index] =
new (root->allocate_child())
479 worker[worker_index]->set_ref_count(1);
481 worker[worker_index] =
482 new (worker[worker_index - 1]->allocate_child())
488 worker[worker_index]->set_ref_count(2);
491 blocked_worker[(part - 1) / 2]->dummy =
492 new (worker[worker_index]->allocate_child())
495 if (spawn_index_child == -1)
496 tbb::task::spawn(*blocked_worker[(part - 1) / 2]);
499 Assert(spawn_index_child >= 0,
501 tbb::task::spawn(*worker[spawn_index_child]);
503 spawn_index_child = -2;
508 new (worker[worker_index]->allocate_child())
510 tbb::task::spawn(*worker_dist);
518 blocked_worker[part / 2] =
519 new (worker[worker_index - 1]->allocate_child())
527 blocked_worker[part / 2]->set_ref_count(1);
528 worker[worker_index] =
new (
529 blocked_worker[part / 2]->allocate_child())
538 spawn_index_child = -1;
547 worker[worker_index]->set_ref_count(1);
550 worker[worker_index] =
551 new (worker[worker_index - 1]->allocate_child())
557 spawn_index_child = worker_index;
562 tbb::empty_task *
final =
563 new (worker[worker_index - 1]->allocate_child())
565 tbb::task::spawn(*
final);
566 spawn_index_child = worker_index - 1;
572 tbb::task::spawn(*worker[spawn_index_child]);
574 root->wait_for_all();
575 root->destroy(*root);
588 tbb::empty_task *root =
589 new (tbb::task::allocate_root()) tbb::empty_task;
590 root->set_ref_count(2);
592 new (root->allocate_child())
594 tbb::empty_task::spawn(*worker);
595 root->wait_for_all();
596 root->destroy(*root);
795 const std::vector<unsigned int> &cells_with_comm,
796 const unsigned int dofs_per_cell,
797 const bool categories_are_hp,
798 const std::vector<unsigned int> &cell_vectorization_categories,
799 const bool cell_vectorization_categories_strict,
800 const std::vector<unsigned int> &parent_relation,
801 std::vector<unsigned int> &renumbering,
802 std::vector<unsigned char> &incompletely_filled_vectorization)
833 unsigned int n_categories = 1;
835 if (cell_vectorization_categories.empty() ==
false)
840 std::set<unsigned int> used_categories;
842 used_categories.insert(cell_vectorization_categories[i]);
843 std::vector<unsigned int> used_categories_vector(
844 used_categories.size());
846 for (
const auto &it : used_categories)
847 used_categories_vector[n_categories++] = it;
850 const unsigned int index =
851 std::lower_bound(used_categories_vector.begin(),
852 used_categories_vector.end(),
853 cell_vectorization_categories[i]) -
854 used_categories_vector.begin();
856 tight_category_map[i] =
index;
863 std::vector<std::vector<unsigned int>> renumbering_category(n_categories);
865 renumbering_category[tight_category_map[i]].push_back(i);
867 if (cell_vectorization_categories_strict ==
false && n_categories > 1)
868 for (
unsigned int j = n_categories - 1; j > 0; --j)
870 unsigned int lower_index = j - 1;
871 while ((renumbering_category[j].
size() % n_lanes) != 0u)
873 while (((renumbering_category[j].
size() % n_lanes) != 0u) &&
874 !renumbering_category[lower_index].empty())
876 renumbering_category[j].push_back(
877 renumbering_category[lower_index].back());
878 renumbering_category[lower_index].pop_back();
880 if (lower_index == 0)
891 std::vector<unsigned int> temporary_numbering;
893 (n_lanes - 1) * n_categories);
894 const unsigned int n_cells_per_parent =
895 std::count(parent_relation.begin(), parent_relation.end(), 0);
896 std::vector<unsigned int> category_size;
897 for (
unsigned int j = 0; j < n_categories; ++j)
899 std::vector<std::pair<unsigned int, unsigned int>> grouped_cells;
900 std::vector<unsigned int> other_cells;
901 for (
const unsigned int cell : renumbering_category[j])
902 if (parent_relation.empty() ||
904 other_cells.push_back(cell);
906 grouped_cells.emplace_back(parent_relation[cell], cell);
909 std::sort(grouped_cells.begin(), grouped_cells.end());
910 std::vector<unsigned int> n_cells_per_group;
911 unsigned int length = 0;
912 for (
unsigned int i = 0; i < grouped_cells.size(); ++i, ++length)
913 if (i > 0 && grouped_cells[i].
first != grouped_cells[i - 1].
first)
915 n_cells_per_group.push_back(length);
919 n_cells_per_group.push_back(length);
924 auto group_it = grouped_cells.begin();
925 for (
const unsigned int length : n_cells_per_group)
926 if (length < n_cells_per_parent)
927 for (
unsigned int j = 0; j < length; ++j)
928 other_cells.push_back((group_it++)->second);
934 for (
unsigned int j = 0; j < length; ++j)
935 temporary_numbering.push_back((group_it++)->second);
939 std::sort(other_cells.begin(), other_cells.end());
940 temporary_numbering.insert(temporary_numbering.end(),
944 while (temporary_numbering.size() % n_lanes != 0)
947 category_size.push_back(temporary_numbering.size());
951 std::vector<bool> batch_with_comm(temporary_numbering.size() / n_lanes,
953 std::vector<unsigned int> temporary_numbering_inverse(
n_active_cells);
954 for (
unsigned int i = 0; i < temporary_numbering.size(); ++i)
956 temporary_numbering_inverse[temporary_numbering[i]] = i;
957 for (
const unsigned int cell : cells_with_comm)
958 batch_with_comm[temporary_numbering_inverse[cell] / n_lanes] =
true;
964 std::vector<std::array<unsigned int, 3>> batch_order;
965 std::vector<std::array<unsigned int, 3>> batch_order_comm;
966 for (
unsigned int i = 0; i < temporary_numbering.size(); i += n_lanes)
968 unsigned int max_index = 0;
969 for (
unsigned int j = 0; j < n_lanes; ++j)
971 max_index =
std::max(temporary_numbering[i + j], max_index);
972 const unsigned int category_hp =
974 std::upper_bound(category_size.begin(), category_size.end(), i) -
975 category_size.begin() :
977 const std::array<unsigned int, 3> next{{category_hp, max_index, i}};
978 if (batch_with_comm[i / n_lanes])
979 batch_order_comm.emplace_back(next);
981 batch_order.emplace_back(next);
984 std::sort(batch_order.begin(), batch_order.end());
985 std::sort(batch_order_comm.begin(), batch_order_comm.end());
992 std::vector<unsigned int> blocks;
995 if (batch_order.empty())
996 std::swap(batch_order_comm, batch_order);
999 blocks = {0,
static_cast<unsigned int>(batch_order.size())};
1004 const unsigned int comm_begin = batch_order.size() / 2;
1005 batch_order.insert(batch_order.begin() + comm_begin,
1006 batch_order_comm.begin(),
1007 batch_order_comm.end());
1008 const unsigned int comm_end = comm_begin + batch_order_comm.size();
1009 const unsigned int end = batch_order.size();
1010 blocks = {0, comm_begin, comm_end, end};
1014 std::vector<std::array<unsigned int, 2>> tight_category_map_ghost;
1016 if (cell_vectorization_categories.empty() ==
false)
1020 std::set<unsigned int> used_categories;
1022 used_categories.insert(
1025 std::vector<unsigned int> used_categories_vector(
1026 used_categories.size());
1028 for (
const auto &it : used_categories)
1029 used_categories_vector[n_categories++] = it;
1031 std::vector<unsigned int> counters(n_categories, 0);
1035 const unsigned int index =
1037 used_categories_vector.begin(),
1038 used_categories_vector.end(),
1040 used_categories_vector.begin();
1042 tight_category_map_ghost.emplace_back(
1043 std::array<unsigned int, 2>{{
index, i}});
1046 if (categories_are_hp || cell_vectorization_categories_strict)
1051 for (
unsigned int i = 0; i < counters.size(); ++i)
1052 if (counters[i] % n_lanes != 0)
1053 for (
unsigned int j = counters[i] % n_lanes; j < n_lanes; ++j)
1054 tight_category_map_ghost.emplace_back(
1055 std::array<unsigned int, 2>{
1056 {i, numbers::invalid_unsigned_int}});
1058 std::sort(tight_category_map_ghost.begin(),
1059 tight_category_map_ghost.end());
1063 const unsigned int n_cell_batches = batch_order.size();
1064 const unsigned int n_ghost_batches =
1065 ((tight_category_map_ghost.empty() ? n_ghost_cells :
1066 tight_category_map_ghost.size()) +
1069 incompletely_filled_vectorization.resize(n_cell_batches +
1072 cell_partition_data.clear();
1073 cell_partition_data.resize(1, 0);
1075 renumbering.clear();
1076 renumbering.resize(n_active_cells + n_ghost_cells,
1079 unsigned int counter = 0;
1080 for (
unsigned int block = 0; block < blocks.size() - 1; ++block)
1082 const unsigned int grain_size =
1083 std::max((2048U / dofs_per_cell) / 8 * 4, 2U);
1084 for (
unsigned int k = blocks[block]; k < blocks[block + 1];
1086 cell_partition_data.push_back(
1087 std::min(k + grain_size, blocks[block + 1]));
1088 partition_row_index[block + 1] = cell_partition_data.size() - 1;
1091 for (
unsigned int k = blocks[block]; k < blocks[block + 1]; ++k)
1093 const unsigned int pos = batch_order[k][2];
1095 for (; j < n_lanes && temporary_numbering[pos + j] !=
1098 renumbering[counter++] = temporary_numbering[pos + j];
1100 incompletely_filled_vectorization[k] = j;
1106 if (tight_category_map_ghost.empty())
1108 for (
unsigned int cell = 0; cell < n_ghost_cells; ++cell)
1109 renumbering[n_active_cells + cell] = n_active_cells + cell;
1111 if ((n_ghost_cells % n_lanes) != 0u)
1112 incompletely_filled_vectorization.back() = n_ghost_cells % n_lanes;
1116 for (
unsigned int k = 0, ptr = 0; k < n_ghost_batches;
1117 ++k, ptr += n_lanes)
1122 j < n_lanes && (ptr + j < tight_category_map_ghost.size()) &&
1123 (tight_category_map_ghost[ptr + j][1] !=
1126 renumbering[counter++] =
1127 n_active_cells + tight_category_map_ghost[ptr + j][1];
1130 incompletely_filled_vectorization[n_cell_batches + k] = j;
1136 cell_partition_data.push_back(n_cell_batches + n_ghost_batches);
1137 partition_row_index.back() = cell_partition_data.size() - 1;
1141 std::vector<unsigned int> renumber_cpy(renumbering);
1142 std::sort(renumber_cpy.begin(), renumber_cpy.end());
1143 for (
unsigned int i = 0; i < renumber_cpy.size(); ++i)
1151 TaskInfo::initial_setup_blocks_tasks(
1152 const std::vector<unsigned int> &boundary_cells,
1153 std::vector<unsigned int> &renumbering,
1154 std::vector<unsigned char> &incompletely_filled_vectorization)
1156 const unsigned int n_cell_batches =
1157 (n_active_cells + vectorization_length - 1) / vectorization_length;
1158 const unsigned int n_ghost_slots =
1159 (n_ghost_cells + vectorization_length - 1) / vectorization_length;
1160 incompletely_filled_vectorization.resize(n_cell_batches + n_ghost_slots);
1161 if (n_cell_batches * vectorization_length > n_active_cells)
1162 incompletely_filled_vectorization[n_cell_batches - 1] =
1163 vectorization_length -
1164 (n_cell_batches * vectorization_length - n_active_cells);
1165 if (n_ghost_slots * vectorization_length > n_ghost_cells)
1166 incompletely_filled_vectorization[n_cell_batches + n_ghost_slots - 1] =
1167 vectorization_length -
1168 (n_ghost_slots * vectorization_length - n_ghost_cells);
1170 std::vector<unsigned int> reverse_numbering(
1172 for (
unsigned int j = 0; j < boundary_cells.size(); ++j)
1173 reverse_numbering[boundary_cells[j]] = j;
1174 unsigned int counter = boundary_cells.size();
1175 for (
unsigned int j = 0; j < n_active_cells; ++j)
1177 reverse_numbering[j] = counter++;
1182 for (
unsigned int j = n_active_cells; j < n_active_cells + n_ghost_cells;
1184 renumbering.push_back(j);
1188 cell_partition_data.clear();
1189 cell_partition_data.push_back(0);
1192 const unsigned int n_macro_boundary_cells =
1193 (boundary_cells.size() + vectorization_length - 1) /
1194 vectorization_length;
1195 cell_partition_data.push_back(
1196 (n_cell_batches - n_macro_boundary_cells) / 2);
1197 cell_partition_data.push_back(cell_partition_data[1] +
1198 n_macro_boundary_cells);
1202 cell_partition_data.push_back(n_cell_batches);
1203 cell_partition_data.push_back(cell_partition_data.back() + n_ghost_slots);
1204 partition_row_index.resize(
n_procs > 1 ? 4 : 2);
1205 partition_row_index[0] = 0;
1206 partition_row_index[1] = 1;
1209 partition_row_index[2] = 2;
1210 partition_row_index[3] = 3;
1245 TaskInfo::make_thread_graph_partition_color(
1247 std::vector<unsigned int> &renumbering,
1248 std::vector<unsigned char> &irregular_cells,
1251 const unsigned int n_cell_batches = *(cell_partition_data.end() - 2);
1252 if (n_cell_batches == 0)
1257 unsigned int partition = 0, counter = 0;
1262 make_connectivity_cells_to_blocks(irregular_cells,
1271 std::vector<unsigned int> cell_partition(n_blocks,
1276 std::vector<unsigned int> partition_list(n_blocks, 0);
1277 std::vector<unsigned int> partition_color_list(n_blocks, 0);
1280 std::vector<unsigned int> partition_size(2, 0);
1286 unsigned int cluster_size = 1;
1289 make_partitioning(connectivity,
1297 make_coloring_within_partitions_pre_blocked(connectivity,
1302 partition_color_list);
1304 partition_list = renumbering;
1310 std::vector<unsigned int> sorted_pc_list(partition_color_list);
1311 std::sort(sorted_pc_list.begin(), sorted_pc_list.end());
1312 for (
unsigned int i = 0; i < sorted_pc_list.size(); ++i)
1319 std::vector<unsigned int> block_start(n_cell_batches + 1);
1320 std::vector<unsigned char> irregular(n_cell_batches);
1322 unsigned int mcell_start = 0;
1324 for (
unsigned int block = 0; block < n_blocks; ++block)
1326 block_start[block + 1] = block_start[block];
1327 for (
unsigned int mcell = mcell_start;
1328 mcell <
std::min(mcell_start + block_size, n_cell_batches);
1331 unsigned int n_comp = (irregular_cells[mcell] > 0) ?
1332 irregular_cells[mcell] :
1333 vectorization_length;
1334 block_start[block + 1] += n_comp;
1337 mcell_start += block_size;
1340 unsigned int counter_macro = 0;
1341 unsigned int block_size_last =
1342 n_cell_batches - block_size * (n_blocks - 1);
1343 if (block_size_last == 0)
1344 block_size_last = block_size;
1346 unsigned int tick = 0;
1347 for (
unsigned int block = 0; block < n_blocks; ++block)
1349 unsigned int present_block = partition_color_list[block];
1350 for (
unsigned int cell = block_start[present_block];
1351 cell < block_start[present_block + 1];
1353 renumbering[counter++] = partition_list[cell];
1354 unsigned int this_block_size =
1355 (present_block == n_blocks - 1) ? block_size_last : block_size;
1359 if (cell_partition_data[tick] == block)
1360 cell_partition_data[tick++] = counter_macro;
1362 for (
unsigned int j = 0; j < this_block_size; ++j)
1363 irregular[counter_macro++] =
1364 irregular_cells[present_block * block_size + j];
1367 cell_partition_data.back() = counter_macro;
1369 irregular_cells.swap(irregular);
1377 std::vector<unsigned int> sorted_renumbering(renumbering);
1378 std::sort(sorted_renumbering.begin(), sorted_renumbering.end());
1379 for (
unsigned int i = 0; i < sorted_renumbering.size(); ++i)
1394 TaskInfo::make_thread_graph(
1395 const std::vector<unsigned int> &cell_active_fe_index,
1397 std::vector<unsigned int> &renumbering,
1398 std::vector<unsigned char> &irregular_cells,
1401 const unsigned int n_cell_batches = *(cell_partition_data.end() - 2);
1402 if (n_cell_batches == 0)
1410 make_connectivity_cells_to_blocks(irregular_cells,
1412 connectivity_blocks);
1414 unsigned int n_blocks = 0;
1415 if (scheme == partition_color ||
1417 n_blocks = this->n_blocks;
1419 n_blocks = n_active_cells;
1424 std::vector<unsigned int> cell_partition(n_blocks,
1430 std::vector<unsigned int> partition_list(n_blocks, 0);
1431 std::vector<unsigned int> partition_2layers_list(n_blocks, 0);
1434 std::vector<unsigned int> partition_size(2, 0);
1436 unsigned int partition = 0;
1442 unsigned int cluster_size = 1;
1443 if (scheme == partition_partition)
1444 cluster_size = block_size * vectorization_length;
1447 if (scheme == partition_color || scheme == color)
1448 make_partitioning(connectivity_blocks,
1455 make_partitioning(connectivity,
1463 if (scheme == partition_partition)
1467 make_partitioning_within_partitions_post_blocked(
1469 cell_active_fe_index,
1476 partition_2layers_list,
1479 else if (scheme == partition_color || scheme == color)
1481 make_coloring_within_partitions_pre_blocked(connectivity_blocks,
1486 partition_2layers_list);
1493 std::vector<unsigned int> sorted_pc_list(partition_2layers_list);
1494 std::sort(sorted_pc_list.begin(), sorted_pc_list.end());
1495 for (
unsigned int i = 0; i < sorted_pc_list.size(); ++i)
1501 std::vector<unsigned int> renumbering_in(n_active_cells, 0);
1502 renumbering_in.swap(renumbering);
1503 if (scheme == partition_partition)
1508 for (
unsigned int j = 0; j < renumbering.size(); ++j)
1509 renumbering[j] = renumbering_in[partition_2layers_list[j]];
1511 for (
unsigned int i = 0; i < n_ghost_cells; ++i)
1512 renumbering.push_back(i + n_active_cells);
1518 std::vector<unsigned int> block_start(n_cell_batches + 1);
1519 std::vector<unsigned char> irregular(n_cell_batches);
1521 unsigned int counter = 0;
1522 unsigned int mcell_start = 0;
1524 for (
unsigned int block = 0; block < n_blocks; ++block)
1526 block_start[block + 1] = block_start[block];
1527 for (
unsigned int mcell = mcell_start;
1528 mcell <
std::min(mcell_start + block_size, n_cell_batches);
1531 unsigned int n_comp = (irregular_cells[mcell] > 0) ?
1532 irregular_cells[mcell] :
1533 vectorization_length;
1534 block_start[block + 1] += n_comp;
1537 mcell_start += block_size;
1540 unsigned int counter_macro = 0;
1541 unsigned int block_size_last =
1542 n_cell_batches - block_size * (n_blocks - 1);
1543 if (block_size_last == 0)
1544 block_size_last = block_size;
1546 unsigned int tick = 0;
1547 for (
unsigned int block = 0; block < n_blocks; ++block)
1549 unsigned int present_block = partition_2layers_list[block];
1550 for (
unsigned int cell = block_start[present_block];
1551 cell < block_start[present_block + 1];
1553 renumbering[counter++] = renumbering_in[cell];
1554 unsigned int this_block_size =
1555 (present_block == n_blocks - 1) ? block_size_last : block_size;
1559 if (cell_partition_data[tick] == block)
1560 cell_partition_data[tick++] = counter_macro;
1562 for (
unsigned int j = 0; j < this_block_size; ++j)
1563 irregular[counter_macro++] =
1564 irregular_cells[present_block * block_size + j];
1567 cell_partition_data.back() = counter_macro;
1569 irregular_cells.swap(irregular);
1576 std::vector<unsigned int> sorted_renumbering(renumbering);
1577 std::sort(sorted_renumbering.begin(), sorted_renumbering.end());
1578 for (
unsigned int i = 0; i < sorted_renumbering.size(); ++i)
1585 update_task_info(partition);
1703 TaskInfo::make_partitioning_within_partitions_post_blocked(
1705 const std::vector<unsigned int> &cell_active_fe_index,
1706 const unsigned int partition,
1707 const unsigned int cluster_size,
1709 const std::vector<unsigned int> &cell_partition,
1710 const std::vector<unsigned int> &partition_list,
1711 const std::vector<unsigned int> &partition_size,
1712 std::vector<unsigned int> &partition_partition_list,
1713 std::vector<unsigned char> &irregular_cells)
1715 const unsigned int n_cell_batches = *(cell_partition_data.end() - 2);
1716 const unsigned int n_ghost_slots =
1717 *(cell_partition_data.end() - 1) - n_cell_batches;
1720 std::vector<unsigned int> neighbor_list;
1723 std::vector<unsigned int> neighbor_neighbor_list;
1725 std::vector<unsigned int> renumbering(n_active_cells);
1727 irregular_cells.back() = 0;
1728 irregular_cells.resize(n_active_cells + n_ghost_slots);
1730 unsigned int max_fe_index = 0;
1731 for (
const unsigned int fe_index : cell_active_fe_index)
1732 max_fe_index =
std::max(fe_index, max_fe_index);
1734 Assert(!hp_bool || cell_active_fe_index.size() == n_active_cells,
1738 unsigned int n_cell_batches_before = 0;
1744 std::vector<unsigned int> cell_partition_l2(
1746 partition_row_index.clear();
1747 partition_row_index.resize(partition + 1, 0);
1748 cell_partition_data.resize(1, 0);
1750 unsigned int counter = 0;
1751 unsigned int missing_macros;
1752 for (
unsigned int part = 0; part < partition; ++part)
1754 neighbor_neighbor_list.resize(0);
1755 neighbor_list.resize(0);
1757 unsigned int partition_l2 = 0;
1758 unsigned int start_up = partition_size[part];
1759 unsigned int partition_counter = 0;
1762 if (neighbor_list.empty())
1765 partition_counter = 0;
1766 for (
unsigned int j = start_up;
1767 j < partition_size[part + 1];
1769 if (cell_partition[partition_list[j]] == part &&
1770 cell_partition_l2[partition_list[j]] ==
1775 partition_counter = 1;
1779 cell_partition_l2[partition_list[start_up]] =
1781 neighbor_neighbor_list.push_back(
1782 partition_list[start_up]);
1783 partition_partition_list[counter++] =
1784 partition_list[start_up];
1791 partition_counter = 0;
1792 for (
const unsigned int neighbor : neighbor_list)
1794 Assert(cell_partition[neighbor] == part,
1796 Assert(cell_partition_l2[neighbor] == partition_l2 - 1,
1798 auto neighbor_it = connectivity.
begin(neighbor);
1799 const auto end_it = connectivity.
end(neighbor);
1800 for (; neighbor_it != end_it; ++neighbor_it)
1802 if (cell_partition[neighbor_it->column()] == part &&
1803 cell_partition_l2[neighbor_it->column()] ==
1806 cell_partition_l2[neighbor_it->column()] =
1808 neighbor_neighbor_list.push_back(
1809 neighbor_it->column());
1810 partition_partition_list[counter++] =
1811 neighbor_it->column();
1812 ++partition_counter;
1817 if (partition_counter > 0)
1819 int index_before = neighbor_neighbor_list.size(),
1820 index = index_before;
1825 std::vector<unsigned int> remaining_per_cell_batch(
1827 std::vector<std::vector<unsigned int>>
1828 renumbering_fe_index;
1831 if (hp_bool ==
true)
1833 renumbering_fe_index.resize(max_fe_index + 1);
1834 for (cell = counter - partition_counter;
1838 renumbering_fe_index
1839 [cell_active_fe_index.empty() ?
1841 cell_active_fe_index
1842 [partition_partition_list[cell]]]
1843 .push_back(partition_partition_list[cell]);
1846 for (
unsigned int j = 0; j < max_fe_index + 1; ++j)
1848 remaining_per_cell_batch[j] =
1849 renumbering_fe_index[j].size() %
1850 vectorization_length;
1851 if (remaining_per_cell_batch[j] != 0)
1854 ((renumbering_fe_index[j].size() +
1855 vectorization_length - 1) /
1856 vectorization_length);
1861 remaining_per_cell_batch.resize(1);
1862 remaining_per_cell_batch[0] =
1863 partition_counter % vectorization_length;
1865 partition_counter / vectorization_length;
1866 if (remaining_per_cell_batch[0] != 0)
1873 cluster_size - (missing_macros % cluster_size);
1876 while (missing_macros > 0 || filled ==
false)
1880 index = neighbor_neighbor_list.size();
1881 if (
index == index_before)
1883 if (missing_macros != 0)
1885 neighbor_neighbor_list.resize(0);
1890 index_before =
index;
1893 unsigned int additional =
1894 neighbor_neighbor_list[
index];
1905 for (; neighbor != end; ++neighbor)
1907 if (cell_partition[neighbor->
column()] == part &&
1908 cell_partition_l2[neighbor->
column()] ==
1911 unsigned int this_index = 0;
1912 if (hp_bool ==
true)
1914 cell_active_fe_index.empty() ?
1916 cell_active_fe_index[neighbor
1923 if (missing_macros > 0 ||
1924 remaining_per_cell_batch[this_index] > 0)
1926 cell_partition_l2[neighbor->
column()] =
1928 neighbor_neighbor_list.push_back(
1930 if (hp_bool ==
true)
1931 renumbering_fe_index[this_index]
1932 .push_back(neighbor->
column());
1933 partition_partition_list[counter] =
1936 ++partition_counter;
1937 if (remaining_per_cell_batch
1938 [this_index] == 0 &&
1941 remaining_per_cell_batch[this_index]++;
1942 if (remaining_per_cell_batch
1944 vectorization_length)
1946 remaining_per_cell_batch[this_index] =
1949 if (missing_macros == 0)
1952 for (
unsigned int fe_ind = 0;
1953 fe_ind < max_fe_index + 1;
1955 if (remaining_per_cell_batch
1965 if (hp_bool ==
true)
1970 cell = counter - partition_counter;
1971 for (
unsigned int j = 0; j < max_fe_index + 1; ++j)
1973 for (
const unsigned int jj :
1974 renumbering_fe_index[j])
1975 renumbering[cell++] = jj;
1976 if (renumbering_fe_index[j].
size() %
1977 vectorization_length !=
1979 irregular_cells[renumbering_fe_index[j].
size() /
1980 vectorization_length +
1981 n_cell_batches_before] =
1982 renumbering_fe_index[j].size() %
1983 vectorization_length;
1984 n_cell_batches_before +=
1985 (renumbering_fe_index[j].size() +
1986 vectorization_length - 1) /
1987 vectorization_length;
1988 renumbering_fe_index[j].resize(0);
1993 n_cell_batches_before +=
1994 partition_counter / vectorization_length;
1995 if (partition_counter % vectorization_length != 0)
1997 irregular_cells[n_cell_batches_before] =
1998 partition_counter % vectorization_length;
1999 ++n_cell_batches_before;
2003 cell_partition_data.push_back(n_cell_batches_before);
2006 neighbor_list = neighbor_neighbor_list;
2007 neighbor_neighbor_list.resize(0);
2009 partition_row_index[part + 1] =
2010 partition_row_index[part] + partition_l2;
2013 if (hp_bool ==
true)
2015 partition_partition_list.swap(renumbering);
2024 TaskInfo::make_coloring_within_partitions_pre_blocked(
2026 const unsigned int partition,
2027 const std::vector<unsigned int> &cell_partition,
2028 const std::vector<unsigned int> &partition_list,
2029 const std::vector<unsigned int> &partition_size,
2030 std::vector<unsigned int> &partition_color_list)
2032 const unsigned int n_cell_batches = *(cell_partition_data.end() - 2);
2033 std::vector<unsigned int> cell_color(n_blocks, n_cell_batches);
2034 std::vector<bool> color_finder;
2036 partition_row_index.resize(partition + 1);
2037 cell_partition_data.clear();
2038 unsigned int color_counter = 0, index_counter = 0;
2039 for (
unsigned int part = 0; part < partition; ++part)
2041 partition_row_index[part] = index_counter;
2042 unsigned int max_color = 0;
2043 for (
unsigned int k = partition_size[part];
2044 k < partition_size[part + 1];
2047 unsigned int cell = partition_list[k];
2048 unsigned int n_neighbors = connectivity.
row_length(cell);
2052 color_finder.resize(n_neighbors + 1);
2053 for (
unsigned int j = 0; j <= n_neighbors; ++j)
2054 color_finder[j] =
true;
2056 connectivity.
begin(cell),
2057 end = connectivity.
end(cell);
2058 for (; neighbor != end; ++neighbor)
2062 if (cell_partition[neighbor->
column()] == part &&
2063 cell_color[neighbor->
column()] <= n_neighbors)
2064 color_finder[cell_color[neighbor->
column()]] =
false;
2067 cell_color[cell] = 0;
2068 while (color_finder[cell_color[cell]] ==
false)
2070 if (cell_color[cell] > max_color)
2071 max_color = cell_color[cell];
2076 for (
unsigned int color = 0; color <= max_color; ++color)
2078 cell_partition_data.push_back(color_counter);
2080 for (
unsigned int k = partition_size[part];
2081 k < partition_size[part + 1];
2084 unsigned int cell = partition_list[k];
2085 if (cell_color[cell] == color)
2087 partition_color_list[color_counter++] = cell;
2092 cell_partition_data.push_back(n_blocks);
2093 partition_row_index[partition] = index_counter;
2101 const unsigned int cluster_size,
2102 std::vector<unsigned int> &cell_partition,
2103 std::vector<unsigned int> &partition_list,
2104 std::vector<unsigned int> &partition_size,
2105 unsigned int &partition)
const
2114 std::vector<unsigned int> neighbor_list;
2117 std::vector<unsigned int> neighbor_neighbor_list;
2127 unsigned int counter = 0;
2128 unsigned int start_nonboundary =
2129 cell_partition_data.size() == 5 ?
2130 vectorization_length *
2131 (cell_partition_data[2] - cell_partition_data[1]) :
2134 const unsigned int n_cell_batches = *(cell_partition_data.end() - 2);
2135 if (n_cell_batches == 0)
2137 if (scheme == color)
2138 start_nonboundary = n_cell_batches;
2139 if (scheme == partition_color ||
2141 start_nonboundary = ((start_nonboundary + block_size - 1) / block_size);
2142 unsigned int n_blocks;
2143 if (scheme == partition_color ||
2145 n_blocks = this->n_blocks;
2147 n_blocks = n_active_cells;
2149 if (start_nonboundary > n_blocks)
2150 start_nonboundary = n_blocks;
2153 unsigned int start_up = 0;
2155 unsigned int remainder = cluster_size;
2163 if (start_nonboundary > 0)
2165 for (
unsigned int cell = 0; cell < start_nonboundary; ++cell)
2167 const unsigned int cell_nn = cell;
2168 cell_partition[cell_nn] = partition;
2169 neighbor_list.push_back(cell_nn);
2170 partition_list[counter++] = cell_nn;
2171 partition_size.back()++;
2173 start_nonboundary = 0;
2174 remainder -= (start_nonboundary % cluster_size);
2175 if (remainder == cluster_size)
2182 cell_partition[start_up] = partition;
2183 neighbor_list.push_back(start_up);
2184 partition_list[counter++] = start_up;
2185 partition_size.back()++;
2188 if (remainder == cluster_size)
2191 int index_before = neighbor_list.size(),
index = index_before,
2193 while (remainder > 0)
2195 if (
index == index_stop)
2197 index = neighbor_list.size();
2198 if (
index == index_before)
2200 neighbor_list.resize(0);
2203 index_stop = index_before;
2204 index_before =
index;
2207 unsigned int additional = neighbor_list[
index];
2209 connectivity.
begin(additional),
2211 connectivity.
end(additional);
2212 for (; neighbor != end; ++neighbor)
2214 if (cell_partition[neighbor->
column()] ==
2217 partition_size.back()++;
2218 cell_partition[neighbor->
column()] = partition;
2219 neighbor_list.push_back(neighbor->
column());
2220 partition_list[counter++] = neighbor->
column();
2228 while (neighbor_list.size() > 0)
2233 unsigned int partition_counter = 0;
2236 partition_size.push_back(partition_size.back());
2240 for (
const unsigned int cell : neighbor_list)
2242 Assert(cell_partition[cell] == partition - 1,
2244 auto neighbor = connectivity.
begin(cell);
2245 const auto end = connectivity.
end(cell);
2246 for (; neighbor != end; ++neighbor)
2248 if (cell_partition[neighbor->column()] ==
2251 partition_size.back()++;
2252 cell_partition[neighbor->column()] = partition;
2256 neighbor_neighbor_list.push_back(neighbor->column());
2257 partition_list[counter++] = neighbor->column();
2258 ++partition_counter;
2262 remainder = cluster_size - (partition_counter % cluster_size);
2263 if (remainder == cluster_size)
2266 int index_before = neighbor_neighbor_list.size(),
2267 index = index_before;
2268 while (remainder > 0)
2270 if (
index == index_stop)
2272 index = neighbor_neighbor_list.size();
2273 if (
index == index_before)
2275 neighbor_neighbor_list.resize(0);
2278 index_stop = index_before;
2279 index_before =
index;
2282 unsigned int additional = neighbor_neighbor_list[
index];
2286 end = connectivity.
end(
2288 for (; neighbor != end; ++neighbor)
2290 if (cell_partition[neighbor->
column()] ==
2293 partition_size.back()++;
2294 cell_partition[neighbor->
column()] = partition;
2295 neighbor_neighbor_list.push_back(neighbor->
column());
2296 partition_list[counter++] = neighbor->
column();
2304 neighbor_list = neighbor_neighbor_list;
2305 neighbor_neighbor_list.resize(0);
2311 for (
unsigned int j = start_up; j < n_blocks; ++j)
2317 remainder = cluster_size;