39 CUGAR_HOST_DEVICE
Split_task(
const uint32
id,
const uint32
begin,
const uint32 end,
const uint32 level,
const uint32 parent)
40 : m_node(
id ), m_begin( begin ), m_end( end ), m_parent( parent ), m_level( level ) {}
50 template <
typename Integer>
51 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE int32 find_leading_bit_difference(
52 const int32 start_level,
56 int32 level = start_level;
60 const Integer mask = Integer(1u) << level;
73 template <
typename Tree,
typename Integer>
78 const uint32 max_leaf_size,
79 const bool keep_singletons,
80 const bool middle_splits,
85 tree.reserve_nodes( n_codes * 2 );
86 tree.reserve_leaves( n_codes );
88 std::vector<Split_task> task_queues[2];
89 std::vector<uint32> skip_queues[2];
91 task_queues[0].push_back( Split_task(0,0,n_codes,bits-1,uint32(-1)) );
92 skip_queues[0].push_back( uint32(-1) );
94 uint32 node_count = 1;
95 uint32 leaf_count = 0;
97 typename Tree::context_type context = tree.get_context();
100 uint32 out_queue = 1;
102 while (task_queues[ in_queue ].size())
104 task_queues[ out_queue ].erase(
105 task_queues[ out_queue ].
begin(),
106 task_queues[ out_queue ].end() );
108 for (uint32 task_id = 0; task_id < task_queues[ in_queue ].size(); ++task_id)
110 const Split_task task = task_queues[ in_queue ][ task_id ];
111 const uint32 skip_node = skip_queues[ in_queue ][ task_id ];
113 const uint32 node = task.m_node;
114 const uint32
begin = task.m_begin;
115 const uint32 end = task.m_end;
116 uint32 level = task.m_level;
117 uint32 parent = task.m_parent;
119 if (!keep_singletons)
121 level = bintree::find_leading_bit_difference(
127 uint32 output_count = 0;
131 if (end - begin > max_leaf_size && level != uint32(-1))
139 output_count = (split_index == begin || split_index == end) ? 1u : 2u;
142 const uint32 node_offset = node_count;
143 const uint32 first_end = (output_count == 1) ? end : split_index;
144 const uint32 first_skip = (output_count == 1) ? skip_node : node_offset+1;
146 if (output_count >= 1) { task_queues[ out_queue ].push_back( Split_task( node_offset+0, begin, first_end, level-1, node ) ); skip_queues[ out_queue ].push_back( first_skip ); }
147 if (output_count == 2) { task_queues[ out_queue ].push_back( Split_task( node_offset+1, split_index, end, level-1, node ) ); skip_queues[ out_queue ].push_back( skip_node ); }
149 const bool generate_leaf = output_count == 0;
152 const uint32 leaf_index = leaf_count;
154 node_count += output_count;
155 leaf_count += generate_leaf ? 1 : 0;
161 output_count ? split_index != begin :
false,
162 output_count ? split_index != end :
false,
163 output_count ? node_offset : leaf_index,
168 output_count ? split_index : uint32(-1) );
172 context.write_leaf( leaf_index, node, begin, end );
175 std::swap( in_queue, out_queue );
thrust::device_vector< T >::iterator begin(thrust::device_vector< T > &vec)
Definition: thrust_view.h:89
Defines some general purpose functors.
Definition: radixtree_inline.h:36
Defines some general purpose algorithms.
Definition: functors.h:481
Define a vector_view POD type and plain_view() for std::vector.
Definition: diff.h:38
void generate_radix_tree(const uint32 n_codes, const Integer *codes, const uint32 bits, const uint32 max_leaf_size, const bool keep_singletons, const bool middle_splits, Tree_writer &tree)
Definition: radixtree_inline.h:381
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Iterator find_pivot(Iterator begin, const uint32 n, const Predicate predicate)
Definition: algorithms.h:63