10 #include <polysolve/Utils.hpp>
13 #pragma GCC diagnostic push
14 #pragma GCC diagnostic ignored "-Wredundant-decls"
16 #include <tbb/parallel_for.h>
18 #pragma GCC diagnostic pop
36 std::vector<simplex::Simplex> simplices;
48 logger().debug(
"Executing on {} simplices", simplices.size());
49 std::vector<std::pair<int64_t, double>> order;
56 std::shuffle(simplices.begin(), simplices.end(), gen);
58 order.reserve(simplices.size());
59 for (int64_t i = 0; i < simplices.size(); ++i) {
60 order.emplace_back(i, op.
priority(simplices[i]));
63 std::stable_sort(order.begin(), order.end(), [](
const auto& s_a,
const auto& s_b) {
64 return s_a.second < s_b.second;
73 size_t total_simplices = simplices.size();
76 for (
const auto& s : simplices) {
77 log(res, total_simplices);
85 for (
const auto& o : order) {
86 log(res, total_simplices);
87 auto mods = op(simplices[o.first]);
114 std::vector<simplex::Simplex> simplices;
121 int64_t success = -1;
122 std::vector<std::pair<int64_t, double>> order;
124 for (
const auto& t : tups) {
125 flag_accessor.scalar_attribute(t) = char(1);
133 POLYSOLVE_SCOPED_STOPWATCH(
134 "Collecting primitives",
139 const auto n_primitives = tups.size();
144 [&](
const Tuple& t) { return flag_accessor.scalar_attribute(t) == char(0); }),
146 for (
const auto& t : tups) {
147 flag_accessor.scalar_attribute(t) = char(0);
150 logger().debug(
"Processing {}/{}", tups.size(), n_primitives);
163 std::shuffle(simplices.begin(), simplices.end(), gen);
166 order.reserve(simplices.size());
167 for (int64_t i = 0; i < simplices.size(); ++i) {
168 order.emplace_back(i, op.
priority(simplices[i]));
171 std::stable_sort(order.begin(), order.end(), [](
const auto& s_a,
const auto& s_b) {
172 return s_a.second < s_b.second;
178 size_t total_simplices = order.size();
179 POLYSOLVE_SCOPED_STOPWATCH(
180 "Executing operation",
185 for (
const auto& s : simplices) {
186 log(internal_stats, total_simplices);
196 for (
const auto& o : order) {
197 log(internal_stats, total_simplices);
198 auto mods = op(simplices[o.first]);
201 internal_stats.
fail();
210 res += internal_stats;
214 }
while (success > 0);
227 if (used_neighbor_coloring.size() == 0)
return 0;
229 std::sort(used_neighbor_coloring.begin(), used_neighbor_coloring.end());
232 for (
const auto c : used_neighbor_coloring) {
248 std::vector<std::vector<simplex::Simplex>> colored_simplices;
256 int64_t color_max = -1;
268 tbb::blocked_range<int64_t>(0, tups.size()),
269 [&](tbb::blocked_range<int64_t> r) {
270 for (int64_t i = r.begin(); i < r.end(); ++i) {
271 color_accessor.scalar_attribute(tups[i]) = -1;
276 std::vector<int64_t> used_colors;
277 for (
const auto& v : tups) {
280 for (
const auto& v_one_ring :
283 int64_t color = color_accessor.const_scalar_attribute(v_one_ring.tuple());
285 used_colors.push_back(color);
289 color_accessor.scalar_attribute(v) = c;
290 color_max = std::max(color_max, c);
293 if (c + 1 > colored_simplices.size()) {
300 logger().info(
"Have {} colors among {} vertices", colored_simplices.size(), tups.size());
305 for (
const auto& v : tups) {
306 auto current_color = color_accessor.const_scalar_attribute(v);
307 if (current_color == -1) {
308 std::cout <<
"vertex not assigned color!!!" << std::endl;
311 for (
const auto& v_one_ring :
315 color_accessor.const_scalar_attribute(v_one_ring.tuple())) {
316 std::cout <<
"adjacent vertices have same color!!!" << std::endl;
323 logger().debug(
"Executing on {} simplices", tups.size());
326 POLYSOLVE_SCOPED_STOPWATCH(
"Sorting", res.sorting_time,
logger());
333 POLYSOLVE_SCOPED_STOPWATCH(
"Executing operation", res.executing_time,
logger());
335 std::atomic_int suc_cnt = 0;
336 std::atomic_int fail_cnt = 0;
338 for (int64_t i = 0; i < colored_simplices.size(); ++i) {
340 tbb::blocked_range<int64_t>(0, colored_simplices[i].size()),
341 [&](tbb::blocked_range<int64_t> r) {
342 for (int64_t k = r.begin(); k < r.end(); ++k) {
343 auto mods = op(colored_simplices[i][k]);
362 res.m_num_op_success = suc_cnt;
363 res.m_num_op_fail = fail_cnt;
377 void Scheduler::log(
size_t total)
383 if (m_update_frequency) {
384 const size_t freq = m_update_frequency.value();
386 if (count % freq == 0) {
393 void Scheduler::set_update_frequency(std::optional<size_t>&& freq)
395 m_update_frequency = std::move(freq);
399 void SchedulerStats::print_update_log(
size_t total, spdlog::level::level_enum level)
const
403 "{} success + {} fail = {} out of {}",
404 number_of_successful_operations(),
405 number_of_failed_operations(),
406 number_of_performed_operations(),
std::vector< Tuple > get_all(PrimitiveType type) const
Generate a vector of Tuples from global vertex/edge/triangle/tetrahedron index.
attribute::Accessor< T, Mesh, D > create_accessor(const attribute::MeshAttributeHandle &handle)
void log(const size_t total)
SchedulerStats run_operation_on_all(operations::Operation &op)
SchedulerStats run_operation_on_all_coloring(operations::Operation &op, const TypedAttributeHandle< int64_t > &color_handle)
std::optional< size_t > m_update_frequency
std::vector< SchedulerStats > sub_stats
int64_t number_of_performed_operations() const
Returns the number of performed operations performed by the scheduler.
int64_t number_of_successful_operations() const
Returns the number of successful operations performed by the scheduler.
void print_update_log(size_t total, spdlog::level::level_enum=spdlog::level::info) const
Handle that represents attributes for some mesh.
const Mesh & mesh() const
virtual PrimitiveType primitive_type() const =0
virtual double priority(const simplex::Simplex &simplex) const
virtual bool use_random_priority() const
const std::vector< Simplex > & simplex_vector() const
Return const reference to the simplex vector.
static Simplex vertex(const Mesh &m, const Tuple &t)
std::vector< Simplex > tuple_vector_to_homogeneous_simplex_vector(const Mesh &m, const std::vector< Tuple > &tups, PrimitiveType primitive)
SimplexCollection link(const Mesh &mesh, const simplex::Simplex &simplex, const bool sort_and_clean)
SimplexCollection k_ring(const Mesh &mesh, const Simplex &simplex, int64_t k)
unsigned int get_random_seed()
spdlog::logger & logger()
Retrieves the current logger.
int64_t first_available_color(std::vector< int64_t > &used_neighbor_coloring)