5353#include < optional>
5454#include < queue>
5555#include < random>
56+ #include < type_traits>
5657
5758namespace cuvs ::neighbors::nn_descent::detail {
5859
@@ -566,6 +567,10 @@ __launch_bounds__(BLOCK_SIZE)
566567
567568 __syncthreads ();
568569
570+ // if we have a distance epilogue, distances need to be fully calculated instead of postprocessing
571+ // them.
572+ bool can_postprocess_dist = std::is_same_v<DistEpilogue_t, raft::identity_op>;
573+
569574 remove_duplicates (new_neighbors,
570575 list_new_size2.x ,
571576 new_neighbors + list_new_size2.x ,
@@ -638,7 +643,7 @@ __launch_bounds__(BLOCK_SIZE)
638643 int col_id = i / SKEWED_MAX_NUM_BI_SAMPLES ;
639644
640645 if (row_id < list_new_size && col_id < list_new_size) {
641- if (metric == cuvs::distance::DistanceType::InnerProduct) {
646+ if (metric == cuvs::distance::DistanceType::InnerProduct && can_postprocess_dist ) {
642647 s_distances[i] = -s_distances[i];
643648 } else if (metric == cuvs::distance::DistanceType::CosineExpanded) {
644649 s_distances[i] = 1.0 - s_distances[i];
@@ -658,6 +663,9 @@ __launch_bounds__(BLOCK_SIZE)
658663 // for fp32 vs fp16 precision differences resulting in negative distances when distance
659664 // should be 0 related issue: https://github.com/rapidsai/cuvs/issues/991
660665 s_distances[i] = s_distances[i] < 0 .0f ? 0 .0f : s_distances[i];
666+ if (!can_postprocess_dist && metric == cuvs::distance::DistanceType::L2SqrtExpanded) {
667+ s_distances[i] = sqrtf (s_distances[i]);
668+ }
661669 }
662670 s_distances[i] = dist_epilogue (s_distances[i], new_neighbors[row_id], new_neighbors[col_id]);
663671 } else {
@@ -737,7 +745,7 @@ __launch_bounds__(BLOCK_SIZE)
737745 int row_id = i % SKEWED_MAX_NUM_BI_SAMPLES ;
738746 int col_id = i / SKEWED_MAX_NUM_BI_SAMPLES ;
739747 if (row_id < list_old_size && col_id < list_new_size) {
740- if (metric == cuvs::distance::DistanceType::InnerProduct) {
748+ if (metric == cuvs::distance::DistanceType::InnerProduct && can_postprocess_dist ) {
741749 s_distances[i] = -s_distances[i];
742750 } else if (metric == cuvs::distance::DistanceType::CosineExpanded) {
743751 s_distances[i] = 1.0 - s_distances[i];
@@ -757,6 +765,9 @@ __launch_bounds__(BLOCK_SIZE)
757765 // for fp32 vs fp16 precision differences resulting in negative distances when distance
758766 // should be 0 related issue: https://github.com/rapidsai/cuvs/issues/991
759767 s_distances[i] = s_distances[i] < 0 .0f ? 0 .0f : s_distances[i];
768+ if (!can_postprocess_dist && metric == cuvs::distance::DistanceType::L2SqrtExpanded) {
769+ s_distances[i] = sqrtf (s_distances[i]);
770+ }
760771 }
761772 s_distances[i] = dist_epilogue (s_distances[i], old_neighbors[row_id], new_neighbors[col_id]);
762773 } else {
@@ -1257,10 +1268,12 @@ void GNND<Data_t, Index_t>::build(Data_t* data,
12571268 auto output_dist_view = raft::make_device_matrix_view<DistData_t, int64_t , raft::row_major>(
12581269 output_distances, nrow_, build_config_.output_graph_degree );
12591270 // distance post-processing
1260- if (build_config_.metric == cuvs::distance::DistanceType::L2SqrtExpanded) {
1271+ bool can_postprocess_dist = std::is_same_v<DistEpilogue_t, raft::identity_op>;
1272+ if (build_config_.metric == cuvs::distance::DistanceType::L2SqrtExpanded &&
1273+ can_postprocess_dist) {
12611274 raft::linalg::map (
12621275 res, output_dist_view, raft::sqrt_op{}, raft::make_const_mdspan (output_dist_view));
1263- } else if (!cuvs::distance::is_min_close (build_config_.metric )) {
1276+ } else if (!cuvs::distance::is_min_close (build_config_.metric ) && can_postprocess_dist ) {
12641277 // revert negated innerproduct
12651278 raft::linalg::map (res,
12661279 output_dist_view,
0 commit comments