-
Notifications
You must be signed in to change notification settings - Fork 995
Description
In cudf, for optimization, we frequently write template functions with various parameters and call the function with corresponding parameters values at run time. However, by doing so, we repeat the function calls too many times, with the only difference is the compiled-time values specified for template parameters. That is lengthy, leading to explosion in the code and causing more difficulty for maintenance.
For example:
if (has_nulls && has_complex_type) {
launch_filter_gather_map_kernel<true, true>(*left_table,
*right_table,
left_indices,
right_indices,
parser.device_expression_data,
config,
shmem_per_block,
predicate_results.data(),
stream);
} else if (has_nulls && !has_complex_type) {
launch_filter_gather_map_kernel<true, false>(*left_table,
*right_table,
left_indices,
right_indices,
parser.device_expression_data,
config,
shmem_per_block,
predicate_results.data(),
stream);
} else if (!has_nulls && has_complex_type) {
launch_filter_gather_map_kernel<false, true>(*left_table,
*right_table,
left_indices,
right_indices,
parser.device_expression_data,
config,
shmem_per_block,
predicate_results.data(),
stream);
} else {
launch_filter_gather_map_kernel<false, false>(*left_table,
*right_table,
left_indices,
right_indices,
parser.device_expression_data,
config,
shmem_per_block,
predicate_results.data(),
stream);
}
I propose to implement template parameter dispatchers for mitigating these situations. The dispatchers could probably be implemented as separate overloads to support various number of template parameters and various parameter types. For the first step, we can start with only boolean parameters and one or two parameters, such as:
template<typename Func>
void dispatch_template_params(bool t, Args... args) {
if (t) { Func<true>{}(args...); } else { Func<false>{}(args...); }
}
template<typename Func>
void dispatch_template_params(bool t0, bool t1, Args... args) {
if (t0 && t1) { Func<true, true>{}(args...); }
else if (t0 && !t1 { Func<true, false>{}(args...); }
else if ...
}
With the dispatchers, we can write a shorter code than the above example as:
dispatch_template_params<launch_filter_gather_map_kernel>(
has_nulls,
has_complex_type,
/* other parameters */
);