@@ -171,35 +171,39 @@ def __init__(self, X_binned, max_bins, n_bins_per_feature,
171171 self .right_indices_buffer = np .empty_like (self .partition )
172172 self .left_indices_buffer = np .empty_like (self .partition )
173173
174+ def split_indices (self , split_info , sample_indices ):
175+ """Split samples into left and right arrays.
176+
177+ Parameters
178+ ----------
179+ split_info : SplitInfo
180+ The SplitInfo of the node to split
181+ sample_indices : array of int
182+ The indices of the samples at the node to split. This is a view on
183+ context.partition, and it is modified inplace by placing the indices
184+ of the left child at the beginning, and the indices of the right child
185+ at the end.
186+
187+ Returns
188+ -------
189+ left_indices : array of int
190+ The indices of the samples in the left child. This is a view on
191+ context.partition.
192+ right_indices : array of int
193+ The indices of the samples in the right child. This is a view on
194+ context.partition.
195+ """
196+ if self .parallel_splitting :
197+ return _split_indices_parallel (self , split_info , sample_indices )
198+ else :
199+ return _split_indices_single_threaded (self , split_info , sample_indices )
200+
174201
175202@njit (parallel = True ,
176203 locals = {'sample_idx' : uint32 ,
177204 'left_count' : uint32 ,
178205 'right_count' : uint32 })
179- def split_indices_parallel (context , split_info , sample_indices ):
180- """Split samples into left and right arrays.
181-
182- Parameters
183- ----------
184- context : SplittingContext
185- The splitting context
186- split_ingo : SplitInfo
187- The SplitInfo of the node to split
188- sample_indices : array of int
189- The indices of the samples at the node to split. This is a view on
190- context.partition, and it is modified inplace by placing the indices
191- of the left child at the beginning, and the indices of the right child
192- at the end.
193-
194- Returns
195- -------
196- left_indices : array of int
197- The indices of the samples in the left child. This is a view on
198- context.partition.
199- right_indices : array of int
200- The indices of the samples in the right child. This is a view on
201- context.partition.
202- """
206+ def _split_indices_parallel (context , split_info , sample_indices ):
203207 # This is a multi-threaded implementation inspired by lightgbm.
204208 # Here is a quick break down. Let's suppose we want to split a node with
205209 # 24 samples named from a to x. context.partition looks like this (the *
@@ -309,47 +313,20 @@ def split_indices_parallel(context, split_info, sample_indices):
309313 sample_indices [right_child_position :])
310314
311315@njit (parallel = False )
312- def split_indices_single_thread (context , split_info , sample_indices ):
313- """Split samples into left and right arrays.
314-
315- This implementation requires less memory than the parallel version.
316-
317- Parameters
318- ----------
319- context : SplittingContext
320- The splitting context
321- split_ingo : SplitInfo
322- The SplitInfo of the node to split
323- sample_indices : array of int
324- The indices of the samples at the node to split. This is a view on
325- context.partition, and it is modified inplace by placing the indices
326- of the left child at the beginning, and the indices of the right child
327- at the end.
328-
329- Returns
330- -------
331- left_indices : array of int
332- The indices of the samples in the left child. This is a view on
333- context.partition.
334- right_indices : array of int
335- The indices of the samples in the right child. This is a view on
336- context.partition.
337- """
338- X_binned = context .X_binned .T [split_info .feature_idx ]
316+ def _split_indices_single_threaded (context , split_info , sample_indices ):
317+ binned_feature = context .X_binned .T [split_info .feature_idx ]
339318 n_samples = sample_indices .shape [0 ]
340-
341319 # approach from left with i
342320 i = 0
343321 # approach from right with j
344322 j = n_samples - 1
345- X = X_binned
346323 pivot = split_info .bin_idx
347324 while i != j :
348325 # continue until we find an element that should be on right
349- while X [sample_indices [i ]] <= pivot and i < n_samples :
326+ while binned_feature [sample_indices [i ]] <= pivot and i < n_samples :
350327 i += 1
351328 # same, but now an element that should be on the left
352- while X [sample_indices [j ]] > pivot and j >= 0 :
329+ while binned_feature [sample_indices [j ]] > pivot and j >= 0 :
353330 j -= 1
354331 if i >= j : # j can become smaller than j!
355332 break
@@ -358,8 +335,7 @@ def split_indices_single_thread(context, split_info, sample_indices):
358335 sample_indices [i ], sample_indices [j ] = sample_indices [j ], sample_indices [i ]
359336 i += 1
360337 j -= 1
361- return (sample_indices [:i ],
362- sample_indices [i :])
338+ return (sample_indices [:i ], sample_indices [i :])
363339
364340
365341@njit (parallel = True )
0 commit comments