Skip to content

Commit 0e7d64e

Browse files
committed
remove hybrid sort
1 parent af20b5e commit 0e7d64e

8 files changed

Lines changed: 24 additions & 334 deletions

src/cuda/cuda_sampling.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,4 @@ void DispatchBlockwiseSoftmaxForward(cudaStream_t stream, float* output, const f
4242
int input_stride, int output_stride, int batch_count);
4343

4444
} // namespace cuda
45-
} // namespace Generators
45+
} // namespace Generators

src/cuda/cuda_topk.cu

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,47 +5,38 @@
55

66
#include "cuda_topk.h"
77
#include "cuda_topk_full_sort.cuh"
8-
#include "cuda_topk_hybrid_sort.cuh"
98
#include "cuda_topk_select_sort.cuh"
109

1110
namespace Generators {
1211
namespace cuda {
1312

14-
// Helper to determine the optimal partition size for the hybrid sort algorithm
15-
// based on vocabulary and batch size.
16-
inline int GetHybridSortPartitionSize(int vocab_size, int batch_size) {
17-
if (vocab_size >= 147456) {
18-
return (vocab_size > 256 * 1024) ? 8192 : 4096;
19-
} else {
20-
if (vocab_size >= 65536 || batch_size >= 4 && vocab_size > 49152) {
21-
return 2048;
22-
}
23-
}
24-
25-
return 1024;
26-
}
27-
2813
TopkData::TopkData(int batch_size, int vocab_size, cudaStream_t stream) {
29-
// The intermediate buffers are used by hybrid and full sort algorithms.
30-
int partition_size = GetHybridSortPartitionSize(vocab_size, batch_size);
31-
size_t intermediate_buffer_elements = GetHybridSortIntermediateSize(batch_size, vocab_size, partition_size);
32-
3314
size_t vocab_batch_size = static_cast<size_t>(vocab_size) * batch_size;
3415

35-
// Selection sort uses a buffer of batch_size * 64 elements, which is smaller than intermediate_buffer_elements.
36-
size_t max_buffer_elements = std::max(vocab_batch_size, intermediate_buffer_elements);
37-
3816
// Allocate all necessary device memory
39-
intermediate_indices_1 = CudaMallocArray<int>(max_buffer_elements);
40-
intermediate_indices_2 = CudaMallocArray<int>(max_buffer_elements);
41-
intermediate_scores_1 = CudaMallocArray<float>(max_buffer_elements);
42-
intermediate_scores_2 = CudaMallocArray<float>(max_buffer_elements);
17+
// The buffers are sized for the full sort algorithm, which is the largest.
18+
intermediate_indices_1 = CudaMallocArray<int>(vocab_batch_size);
19+
intermediate_indices_2 = CudaMallocArray<int>(vocab_batch_size);
20+
intermediate_scores_1 = CudaMallocArray<float>(vocab_batch_size);
21+
intermediate_scores_2 = CudaMallocArray<float>(vocab_batch_size);
4322
batch_offsets = CudaMallocArray<int>(batch_size + 1);
4423

4524
cub_temp_storage_bytes = GetFullSortCubTempStorageBytes(vocab_batch_size, batch_size, stream);
4625
cub_temp_storage = CudaMallocArray<unsigned char>(this->cub_temp_storage_bytes);
4726
}
4827

28+
// Kernel to compact strided data into a dense layout.
29+
// Used to convert data from a [batch, stride] layout to a dense [batch, k] layout.
30+
template <typename T>
31+
__global__ void CompactStridedData(const T* input, T* output, int k, int batch_size, int input_stride) {
32+
const int batch_idx = blockIdx.x;
33+
for (int i = threadIdx.x; i < k; i += blockDim.x) {
34+
int in_idx = batch_idx * input_stride + i;
35+
int out_idx = batch_idx * k + i;
36+
output[out_idx] = input[in_idx];
37+
}
38+
}
39+
4940
void TopkDataCompact::CompactOutput(int batch_size, int vocab_size, cudaStream_t stream, int k) {
5041
topk_scores_compact = CudaMallocArray<float>(static_cast<size_t>(batch_size) * k);
5142
topk_indices_compact = CudaMallocArray<int>(static_cast<size_t>(batch_size) * k);
@@ -59,15 +50,12 @@ void TopkDataCompact::CompactOutput(int batch_size, int vocab_size, cudaStream_t
5950
void GetTopK(TopkData* topk_data, cudaStream_t stream, const float* scores_in, int vocab_size, int batch_size, int k) {
6051
assert(topk_data != nullptr);
6152

62-
if (k > kHybridSortMaxK) {
53+
if (k > 64) {
6354
LaunchSort(topk_data, stream, scores_in, topk_data->intermediate_scores_1.get(),
6455
topk_data->intermediate_indices_1.get(), vocab_size, batch_size);
65-
} else if (k <= 8 || vocab_size < 1024) {
56+
} else {
6657
// NOTE: This modifies scores_in in-place
6758
RunTopKViaSelectionSort(topk_data, stream, const_cast<float*>(scores_in), vocab_size, batch_size, k);
68-
} else {
69-
int partition_size = GetHybridSortPartitionSize(vocab_size, batch_size);
70-
RunTopKViaHybridSort(topk_data, stream, scores_in, vocab_size, batch_size, k, partition_size);
7159
}
7260
}
7361

src/cuda/cuda_topk.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,18 @@ struct TopkData {
1818

1919
// --- Intermediate Buffers for Top-K Algorithms ---
2020

21-
// Used to hold initial vocabulary indices for full sort, and intermediate
22-
// indices during the reduction phase of hybrid sort.
21+
// Used to hold initial vocabulary indices for full sort.
2322
cuda_unique_ptr<int> intermediate_indices_1;
2423

25-
// A dedicated "ping-pong" buffer for the hybrid sort index reduction.
24+
// A dedicated "ping-pong" buffer for full sort.
2625
cuda_unique_ptr<int> intermediate_indices_2;
2726

2827
// Primary buffer for holding raw scores.
2928
// - Full sort: Holds the fully sorted raw scores.
3029
// - Selection sort: Not used directly for output, but reserved.
31-
// - Hybrid sort: Holds intermediate and final reduced raw scores.
3230
cuda_unique_ptr<float> intermediate_scores_1;
3331

34-
// A secondary "ping-pong" buffer used by the hybrid sort's score reduction phase.
32+
// A secondary "ping-pong" buffer.
3533
cuda_unique_ptr<float> intermediate_scores_2;
3634

3735
// General-purpose temporary storage for CUB's DeviceSegmentedRadixSort (for full sort only).
@@ -44,7 +42,7 @@ struct TopkData {
4442
// --- Information of Final Output (Input to Sampling Stage) ---
4543
const float* topk_scores = nullptr; // pointer to the top-k scores data (in intermediate_scores_1 or intermediate_scores_2)
4644
const int* topk_indices = nullptr; // pointer to the top-k indices data (in intermediate_indices_1 or intermediate_indices_2)
47-
int topk_stride = 0; // stride of the top-k output data: k for selection sort, vocab_size for full sort, max_k (kHybridSortMaxK) for hybrid sort
45+
int topk_stride = 0; // stride of the top-k output data: k for selection sort, vocab_size for full sort
4846
};
4947

5048
// For parity test, a derived struct to help compact output buffers.
@@ -64,7 +62,6 @@ void GetTopK(TopkData* topk_data, cudaStream_t stream, const float* scores_in, i
6462
// to `scores_out` and `indices_out` in a compact [batch_size, k] layout.
6563
void RunTopKViaSelectionSort(TopkData* data, cudaStream_t stream, float* scores_in, int vocab_size, int batch_size, int k);
6664
void RunTopKViaFullSort(TopkData* data, cudaStream_t stream, const float* scores_in, int vocab_size, int batch_size, int k);
67-
void RunTopKViaHybridSort(TopkData* data, cudaStream_t stream, const float* scores_in, int vocab_size, int batch_size, int k, int partition_size);
6865

6966
} // namespace cuda
7067
} // namespace Generators

src/cuda/cuda_topk_bitonic_sort_helper.cuh

Lines changed: 0 additions & 136 deletions
This file was deleted.

src/cuda/cuda_topk_full_sort.cuh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
#include <cub/device/device_segmented_radix_sort.cuh>
77
#include "cuda_topk.h"
8-
#include "cuda_topk_hybrid_sort.cuh" // For CompactStridedData
98

109
namespace Generators {
1110
namespace cuda {

0 commit comments

Comments
 (0)