@@ -671,22 +671,23 @@ void tns::TreeNSearch::_points_to_cells()
671671 */
672672
673673 // Compute cells in thread buffers
674- // Note: We distribute the work to the threads from all the point sets simulataneously
674+ // Note: We distribute the work to the threads from all the point sets simultaneously
675675 this ->thread_cells .resize (this ->n_threads );
676676 #pragma omp parallel num_threads(this->n_threads)
677677 {
678678 const int thread_id = omp_get_thread_num ();
679- CellList& cells = this ->thread_cells [thread_id];
680- cells.init_with_at_least_size (std::max (10000 , (int )(0.1 *this ->get_total_n_points ())));
681- int cell_i = 0 ;
682679
683680 const int n_points = this ->get_total_n_points ();
684681 const int chunksize = n_points / n_threads;
685682 const int begin_thread_point = chunksize * thread_id;
686683 const int end_thread_point = (thread_id == n_threads - 1 ) ? n_points : chunksize * (thread_id + 1 );
684+ const int thread_n_points = end_thread_point - begin_thread_point;
685+
686+ CellList& cells = this ->thread_cells [thread_id];
687+ cells.init_with_at_least_size (std::max (10000 , (int )(0.1 *this ->get_total_n_points ())));
688+ int cell_i = 0 ;
687689
688690 // Do not process if there are no points
689- const int thread_n_points = end_thread_point - begin_thread_point;
690691 if (thread_n_points > 0 ) {
691692
692693 // Find the set of the first point
@@ -715,8 +716,12 @@ void tns::TreeNSearch::_points_to_cells()
715716 if (begin_point >= end_point) { continue ; }
716717
717718 const float * points = this ->set_points [set_i];
718-
719+
719720 // Insert first cell
721+ if (cell_i >= cells.capacity ) {
722+ cells.grow_while_keeping_data (std::max (cell_i + 1 , 2 * cells.capacity ));
723+ }
724+
720725 // Note: For every set, we create a new cell to avoid points from different sets sharing the same cell
721726 const int point_idx = begin_point - set_offset;
722727 const float * p = points + 3 * point_idx;
@@ -730,8 +735,8 @@ void tns::TreeNSearch::_points_to_cells()
730735 int point_i = begin_point + 1 ;
731736 for (; point_i < end_point; point_i++) {
732737
733- if (cells. capacity <= cell_i ) {
734- cells.grow_while_keeping_data (2 * cells.capacity );
738+ if (cell_i >= cells. capacity ) {
739+ cells.grow_while_keeping_data (std::max (cell_i + 1 , 2 * cells.capacity ) );
735740 }
736741
737742 // Load
@@ -849,28 +854,29 @@ void tns::TreeNSearch::_points_to_cells_simd()
849854{
850855 /*
851856 In this SIMD implementation of _points_to_cells() eight points are processed at the
852- same time. The eight ijk cell coordiantes are computed and points have different
857+ same time. The eight ijk cell coordinates are computed and points have different
853858 cell indices are identified. Then, SIMD permutations are used to append the cell
854859 boundaries to the global array without using branches.
855860 */
856861
857862 // Compute cells in thread buffers
858- // Note: We distribute the work to the threads from all the point sets simulataneously
863+ // Note: We distribute the work to the threads from all the point sets simultaneously
859864 this ->thread_cells .resize (this ->n_threads );
860865 #pragma omp parallel num_threads(this->n_threads)
861866 {
862867 const int thread_id = omp_get_thread_num ();
863- CellList& cells = this ->thread_cells [thread_id];
864- cells.init_with_at_least_size (std::max (10000 , (int )(0.1 *this ->get_total_n_points ())));
865- int cell_i = 0 ;
866868
867869 const int n_points = this ->get_total_n_points ();
868870 const int chunksize = n_points / n_threads;
869871 const int begin_thread_point = chunksize * thread_id;
870872 const int end_thread_point = (thread_id == n_threads - 1 ) ? n_points : chunksize * (thread_id + 1 );
873+ const int thread_n_points = end_thread_point - begin_thread_point;
874+
875+ CellList& cells = this ->thread_cells [thread_id];
876+ cells.init_with_at_least_size (std::max (10000 , (int )(0.1 *this ->get_total_n_points ())));
877+ int cell_i = 0 ;
871878
872879 // Do not process if there are no points
873- const int thread_n_points = end_thread_point - begin_thread_point;
874880 if (thread_n_points > 0 ) {
875881
876882 // Find the set of the first point
@@ -899,8 +905,12 @@ void tns::TreeNSearch::_points_to_cells_simd()
899905 if (begin_point >= end_point) { continue ; }
900906
901907 const float * points = this ->set_points [set_i];
902-
908+
903909 // Insert first cell
910+ if (cell_i >= cells.capacity ) {
911+ cells.grow_while_keeping_data (std::max (cell_i + 1 , 2 * cells.capacity ));
912+ }
913+
904914 // Note: For every set, we create a new cell to avoid points from different sets sharing the same cell
905915 const int point_idx = begin_point - set_offset;
906916 const float * p = points + 3 * point_idx;
@@ -925,8 +935,8 @@ void tns::TreeNSearch::_points_to_cells_simd()
925935 int point_i = begin_point + 1 ;
926936 for (; point_i < end_point - 8 ; point_i += 8 ) {
927937
928- if (cells. capacity - cell_i <= 16 ) { // 16 so it can write a full 8SIMD line, then 7 remainder and then 1 from a new set
929- cells.grow_while_keeping_data (16 + 2 * cells.capacity );
938+ if (cell_i + 8 > cells. capacity ) {
939+ cells.grow_while_keeping_data (std::max (cell_i + 8 , 2 * cells.capacity ) );
930940 }
931941
932942 // Load
@@ -1013,6 +1023,10 @@ void tns::TreeNSearch::_points_to_cells_simd()
10131023
10141024 const bool cmp = (i == cells.i [cell_i - 1 ] && j == cells.j [cell_i - 1 ] && k == cells.k [cell_i - 1 ]);
10151025 if (!cmp) {
1026+ if (cell_i >= cells.capacity ) {
1027+ cells.grow_while_keeping_data (std::max (cell_i + 1 , 2 * cells.capacity ));
1028+ }
1029+
10161030 cells.offsets [cell_i] = point_i;
10171031 cells.i [cell_i] = i;
10181032 cells.j [cell_i] = j;
@@ -1396,12 +1410,6 @@ void tns::TreeNSearch::_run_octree_node(RecursiveOctreeNode& node_buffer, const
13961410
13971411 // Variable of fixed search radius
13981412 if (!this ->is_global_search_radius_set ) {
1399- // if (this->symmetric_search) {
1400- // for (int child_i = 0; child_i < 8; child_i++) {
1401- // node_buffer.children[child_i]->buffer.max_search_radius = this->max_search_radius;
1402- // }
1403- // }
1404- // else {
14051413 for (int child_i = 0 ; child_i < 8 ; child_i++) {
14061414 auto & child_cell_indices = node_buffer.children [child_i]->buffer .cell_indices ;
14071415 const int n_cells = child_cell_indices.size ();
@@ -1411,7 +1419,6 @@ void tns::TreeNSearch::_run_octree_node(RecursiveOctreeNode& node_buffer, const
14111419 max_radius = std::max (max_radius, this ->cells .radii [c]);
14121420 }
14131421 node_buffer.children [child_i]->buffer .max_search_radius = max_radius;
1414- // }
14151422 }
14161423 }
14171424 else {
@@ -1787,12 +1794,6 @@ void tns::TreeNSearch::_run_octree_node_simd(RecursiveOctreeNode& node_buffer, c
17871794
17881795 // Variable of fixed search radius
17891796 if (!this ->is_global_search_radius_set ) {
1790- // if (this->symmetric_search) {
1791- // for (int child_i = 0; child_i < 8; child_i++) {
1792- // node_buffer.children[child_i]->buffer.max_search_radius = this->max_search_radius;
1793- // }
1794- // }
1795- // else {
17961797 for (int child_i = 0 ; child_i < 8 ; child_i++) {
17971798 auto & child_cell_indices = node_buffer.children [child_i]->buffer .cell_indices ;
17981799 const int n_cells = child_cell_indices.size ();
@@ -1802,7 +1803,6 @@ void tns::TreeNSearch::_run_octree_node_simd(RecursiveOctreeNode& node_buffer, c
18021803 max_radius = std::max (max_radius, this ->cells .radii [c]);
18031804 }
18041805 node_buffer.children [child_i]->buffer .max_search_radius = max_radius;
1805- // }
18061806 }
18071807 }
18081808 else {
0 commit comments