@@ -62,22 +62,36 @@ struct ClustersAlgorithm {
6262 const WarmStartMesh& warm_start_mesh,
6363 const std::vector<Eigen::Vector3d>& points) {
6464 Algorithm algo;
65- algo.warm_start_algo = UsedAlgorithm::fromPoints (warm_start_mesh.points );
65+ // This algo will search closest point on all the warm start mesh
66+ auto init_warm_start_algo =
67+ UsedAlgorithm::fromPoints (warm_start_mesh.points );
6668 algo.clusters_algo .reserve (warm_start_mesh.points .size ());
6769
6870 std::vector<std::vector<Eigen::Vector3d>> clusters_points;
6971 clusters_points.resize (warm_start_mesh.points .size ());
7072
73+ // Affect points to a cluster
7174 for (const auto & p : points) {
7275 auto [_, index] =
73- algo. warm_start_algo .supportWithIndex (p.template cast <Scalar>());
76+ init_warm_start_algo .supportWithIndex (p.template cast <Scalar>());
7477 clusters_points[index].push_back (p);
7578 }
7679
77- for (const auto & c_points : clusters_points) {
78- // TODO manage empty cluster ?
79- algo.clusters_algo .push_back (UsedAlgorithm::fromPoints (c_points));
80+ // Store warm start mesh with at least one point attached to them.
81+ // Only construct cluster if they is at least one point.
82+ std::vector<Eigen::Vector3d> filtered_warm_start_points;
83+ filtered_warm_start_points.reserve (warm_start_mesh.points .size ());
84+ for (std::size_t i = 0 ; i < clusters_points.size (); ++i) {
85+ const auto & c_points = clusters_points[i];
86+ if (c_points.size () != 0 ) {
87+ filtered_warm_start_points.push_back (warm_start_mesh.points [i]);
88+ algo.clusters_algo .push_back (UsedAlgorithm::fromPoints (c_points));
89+ }
8090 }
91+ // Create the warm start algorithm from filtered warm start mesh
92+ algo.warm_start_algo =
93+ UsedAlgorithm::fromPoints (filtered_warm_start_points);
94+
8195 return algo;
8296 }
8397
@@ -361,11 +375,49 @@ static void legacyLogAlgorithmBench(benchmark::State& state) {
361375 }
362376}
363377
378+ template <typename Scalar>
379+ static void legacyLogWarmStartAlgorithmBench (benchmark::State& state) {
380+ using Algorithm = LegacyLogAlgorithm<Scalar>;
381+ // using InitAlgorithm = SOAHighwayAlgorithm<Scalar>;
382+ using InitAlgorithm = LegacyLinearAlgorithm<Scalar>;
383+
384+ const auto num_subdiv = state.range (0 );
385+
386+ auto ico = utils::IcosahedronWithNeighborsDatabase::get (
387+ static_cast <std::size_t >(num_subdiv));
388+ auto algo = Algorithm::fromPointsAndNeighbors (ico.points , ico.neighbors );
389+ auto init_warm_start_algo = InitAlgorithm::fromPoints (ico.points );
390+
391+ auto warm_start_mesh = WarmStartMesh::construct (4 , 3 );
392+ auto warm_start_algo = InitAlgorithm::fromPoints (warm_start_mesh.points );
393+ std::vector<std::size_t > closest_index;
394+ closest_index.reserve (warm_start_mesh.points .size ());
395+ for (const auto & p : warm_start_mesh.points ) {
396+ auto [_, index] =
397+ init_warm_start_algo.supportWithIndex (p.template cast <Scalar>());
398+ closest_index.push_back (index);
399+ }
400+
401+ // auto vec = Algorithm::Vec3::UnitX();
402+ auto vec = typename Algorithm::Vec3 (static_cast <Scalar>(0.9 ),
403+ static_cast <Scalar>(0.2 ),
404+ static_cast <Scalar>(0.2 ))
405+ .normalized ();
406+
407+ for (auto _ : state) {
408+ auto [__, index] = warm_start_algo.supportWithIndex (vec);
409+ benchmark::DoNotOptimize (index);
410+ auto hint = closest_index[index];
411+ auto res = algo.support (vec, hint);
412+ benchmark::DoNotOptimize (res);
413+ }
414+ }
415+
364416template <typename Scalar>
365417static void SOAClusterAlgorithmBench (benchmark::State& state) {
366418 using Algorithm = ClustersAlgorithm<Scalar>;
367419
368- auto warm_start_mesh = WarmStartMesh::construct (4 , 5 );
420+ auto warm_start_mesh = WarmStartMesh::construct (10 , 8 );
369421
370422 const auto target = state.range (0 );
371423 const auto num_subdiv = state.range (1 );
@@ -401,10 +453,12 @@ static void LinearCustomArgumentsHighway(benchmark::internal::Benchmark* b) {
401453 for (std::int64_t target : hwy::SupportedAndGeneratedTargets ()) {
402454 if (target != HWY_SSSE3 && target != HWY_SSE4 && target != HWY_NEON_BF16) {
403455 // 4 subdivide doesn't fit into L1 cache 5112 points > 48KB
404- // b->Args({target, 0})
405- // ->Args({target, 1})
406- // ->Args({target, 2})
407- b->Args ({target, 3 })->Args ({target, 4 })->Args ({target, 5 });
456+ b->Args ({target, 0 })
457+ ->Args ({target, 1 })
458+ ->Args ({target, 2 })
459+ ->Args ({target, 3 })
460+ ->Args ({target, 4 })
461+ ->Args ({target, 5 });
408462 }
409463 }
410464}
@@ -422,6 +476,10 @@ BENCHMARK(SOAHighwayLinearWithIndexAlgorithmBench<double>)
422476 ->Apply (LinearCustomArgumentsHighway);
423477BENCHMARK (legacyLogAlgorithmBench<float >)->Apply (LogCustomArguments);
424478BENCHMARK (legacyLogAlgorithmBench<double >)->Apply (LogCustomArguments);
479+ BENCHMARK (legacyLogWarmStartAlgorithmBench<float >)
480+ ->Apply (LinearCustomArguments);
481+ BENCHMARK (legacyLogWarmStartAlgorithmBench<double >)
482+ ->Apply (LinearCustomArguments);
425483BENCHMARK (SOAClusterAlgorithmBench<float >)->Apply (LinearCustomArgumentsHighway);
426484BENCHMARK (SOAClusterAlgorithmBench<double >)
427485 ->Apply (LinearCustomArgumentsHighway);
0 commit comments