Skip to content

Commit 58f47c0

Browse files
committed
Merge remote-tracking branch 'origin' into type_date
2 parents 8cfddfa + f100550 commit 58f47c0

9 files changed

Lines changed: 157 additions & 41 deletions

File tree

docker/Dockerfile

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,32 @@
1-
FROM nvidia/cuda:12.5.1-cudnn-devel-ubuntu22.04
1+
FROM nvidia/cuda:12.6.1-devel-ubuntu22.04
2+
ENV DEBIAN_FRONTEND=noninteractive
3+
WORKDIR /root
24

3-
ENV TZ=Asia/Dubai
4-
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
5+
# Common dependencies
6+
RUN apt-get update && apt-get install -y git g++ cmake ninja-build libssl-dev wget vim unzip
57

6-
RUN apt update -y
7-
RUN apt-get update -y
8-
RUN apt install -y g++ make wget unzip vim htop git dstat
9-
RUN apt install -y software-properties-common
10-
RUN add-apt-repository -y ppa:ubuntu-toolchain-r/test
11-
RUN apt update
12-
RUN apt-get install -y build-essential
13-
RUN apt-get install -y libc-dev
14-
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 11
15-
RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 11
8+
# CMake 3.30.4
9+
RUN wget https://github.com/Kitware/CMake/releases/download/v3.30.4/cmake-3.30.4-linux-x86_64.sh && \
10+
chmod +x cmake-3.30.4-linux-x86_64.sh && \
11+
./cmake-3.30.4-linux-x86_64.sh --skip-license --prefix=/usr/local && \
12+
rm cmake-3.30.4-linux-x86_64.sh
1613

17-
# install cmake
18-
RUN wget https://github.com/Kitware/CMake/releases/download/v3.28.0/cmake-3.28.0-linux-x86_64.sh
19-
RUN mkdir /opt/cmake
20-
RUN sh cmake-3.28.0-linux-x86_64.sh --skip-license --prefix=/opt/cmake/
21-
RUN ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake
22-
RUN apt install -y ninja-build
14+
# Install Miniconda
15+
ENV CONDA_DIR=/opt/conda
16+
RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
17+
bash Miniconda3-latest-Linux-x86_64.sh -b -p $CONDA_DIR && \
18+
rm Miniconda3-latest-Linux-x86_64.sh
19+
ENV PATH=$CONDA_DIR/bin:$PATH
2320

24-
# Install nsight compute
25-
RUN apt-get install -y nsight-compute-2024.1.1
21+
# Create conda env with libcudf
22+
RUN conda update -n base -c defaults conda && \
23+
conda create -n libcudf-env -y && \
24+
conda run -n libcudf-env conda install -y -c rapidsai -c conda-forge -c nvidia rapidsai::libcudf
25+
ENV USE_CUDF=1
26+
ENV LIBCUDF_ENV_PREFIX=$CONDA_DIR/envs/libcudf-env
2627

27-
RUN mkdir -p /working_dir
28-
WORKDIR /working_dir
29-
RUN git config --global --add safe.directory "*"
28+
# Activates libcudf env at runtime beginning
29+
RUN echo 'echo "[INFO] Initializing conda environment... please wait (conda activation can take a few seconds)"' >> ~/.bashrc && \
30+
echo "source /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc && \
31+
echo "conda activate libcudf-env" >> ~/.bashrc && \
32+
echo 'echo "[INFO] Finished initializing conda environment"' >> ~/.bashrc

docs/README.md

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,22 @@ Sirius is a GPU acceleration layer for SQL analytics. It plugs into existing eng
1717
- CUDA >= 11.2
1818
- CMake >= 3.30.4 (follow this [instruction](https://medium.com/@yulin_li/how-to-update-cmake-on-ubuntu-9602521deecb) to upgrade CMake)
1919

20-
## Installing dependencies
20+
## Dependencies (Option 1): Use Docker Image
21+
To use the docker image with dependencies fully installed:
22+
```
23+
sudo docker run --gpus all -it yifeiyang7/sirius_dependencies:latest bash
24+
```
25+
26+
Make sure both `nvidia-driver` and `nvidia-container-toolkit` are installed, `nvidia-driver` can be installed by
27+
```
28+
sudo apt install nvidia-driver-535
29+
```
30+
and `nvidia-container-toolkit` can be installed following the [instructions](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html). Then restart docker by
31+
```
32+
sudo systemctl restart docker
33+
```
34+
35+
## Dependencies (Option 2): Install Manually
2136

2237
### Install duckdb dependencies
2338
```
@@ -46,7 +61,8 @@ export USE_CUDF=1
4661
export LIBCUDF_ENV_PREFIX={PATH to libcudf-env}
4762
```
4863

49-
### Clone the Sirius repository
64+
## Building Sirius
65+
To clone the Sirius repository:
5066
```
5167
git clone --recurse-submodules https://github.com/sirius-db/sirius.git
5268
cd sirius
@@ -60,14 +76,20 @@ cd $SIRIUS_HOME_PATH
6076
```
6177
The `--recurse-submodules` will ensure DuckDB is pulled which is required to build the extension.
6278

63-
## Building Sirius
6479
To build Sirius:
6580
```
6681
make -j {nproc}
6782
```
6883

69-
## Generating TPC-H dataset
70-
Unzip `dbgen.zip` and run `./dbgen -s {SF}`.
84+
## Generating and Loading TPC-H dataset
85+
To generate the TPC-H dataset
86+
```
87+
unzip dbgen.zip
88+
cd dbgen
89+
./dbgen -s 1 && mkdir s1 && mv *.tbl s1 # this generates dataset of SF1
90+
cd ..
91+
```
92+
7193
To load the TPC-H dataset to duckdb:
7294
```
7395
./build/release/duckdb {DATABASE_NAME}.duckdb
@@ -79,7 +101,7 @@ To run Sirius, simply start the shell with `./build/release/duckdb {DATABASE_NAM
79101
From the duckdb shell, initialize the Sirius buffer manager with `call gpu_buffer_init`. This API accepts 2 parameters, the GPU caching region size and the GPU processing region size. The GPU caching region is a memory region where the raw data is stored in GPUs, whereas the GPU processing region is where intermediate results are stored in GPUs (hash tables, join results .etc).
80102
For example, to set the caching region as 1 GB and the processing region as 2 GB, we can run the following command:
81103
```
82-
call gpu_buffer_init("1 GB", "2 GB")
104+
call gpu_buffer_init("1 GB", "2 GB");
83105
```
84106

85107
After setting up Sirius, we can execute SQL queries using the `call gpu_processing`:

src/cuda/cudf/cudf_aggregate.cu

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,15 @@ static std::unique_ptr<cudf::reduce_aggregation> make_reduce_aggregation()
2525

2626
void cudf_aggregate(vector<shared_ptr<GPUColumn>>& column, uint64_t num_aggregates, AggregationType* agg_mode)
2727
{
28+
GPUBufferManager *gpuBufferManager = &(GPUBufferManager::GetInstance());
29+
cudf::set_current_device_resource(gpuBufferManager->mr);
2830
if (column[0]->column_length == 0) {
2931
SIRIUS_LOG_DEBUG("Input size is 0");
3032
for (int agg_idx = 0; agg_idx < num_aggregates; agg_idx++) {
3133
if (agg_mode[agg_idx] == AggregationType::COUNT_STAR || agg_mode[agg_idx] == AggregationType::COUNT) {
32-
column[agg_idx] = make_shared_ptr<GPUColumn>(0, ColumnType::INT64, column[agg_idx]->data_wrapper.data);
34+
uint64_t* temp = gpuBufferManager->customCudaMalloc<uint64_t>(1, 0, 0);
35+
cudaMemset(temp, 0, sizeof(uint64_t));
36+
column[agg_idx] = make_shared_ptr<GPUColumn>(1, ColumnType::INT64, reinterpret_cast<uint8_t*>(temp));
3337
} else {
3438
column[agg_idx] = make_shared_ptr<GPUColumn>(0, column[agg_idx]->data_wrapper.type, column[agg_idx]->data_wrapper.data);
3539
}
@@ -42,9 +46,6 @@ void cudf_aggregate(vector<shared_ptr<GPUColumn>>& column, uint64_t num_aggregat
4246
SETUP_TIMING();
4347
START_TIMER();
4448

45-
GPUBufferManager *gpuBufferManager = &(GPUBufferManager::GetInstance());
46-
cudf::set_current_device_resource(gpuBufferManager->mr);
47-
4849
uint64_t size = 0;
4950
for (int agg = 0; agg < num_aggregates; agg++) {
5051
if (column[agg]->data_wrapper.data != nullptr || (column[agg]->data_wrapper.data == nullptr && agg_mode[agg] == AggregationType::COUNT_STAR && column[agg]->column_length > 0)) {

src/cuda/utils.cu

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,63 @@ __device__ __forceinline__ uint64_t convert_endianess(uint64_t value) {
2626
return (bottom_swapped << 32) | top_swapped;
2727
}
2828

29+
__global__ void convert_int64_to_int128(uint8_t *input, uint8_t *output, size_t count) {
30+
size_t idx = blockIdx.x * blockDim.x + threadIdx.x;
31+
if (idx < count) {
32+
// Store the converted value as 16 bytes in output
33+
uint64_t* input_ptr = reinterpret_cast<uint64_t*>(input + idx * 8);
34+
uint64_t* output_ptr = reinterpret_cast<uint64_t*>(output + idx * 16);
35+
// for (int i = 0; i < 8; ++i) {
36+
// output[idx * 16 + i] = input[idx * 8 + i];
37+
// output[idx * 16 + i + 8] = 0;
38+
output_ptr[0] = input_ptr[0];
39+
output_ptr[1] = 0; // Set the upper 64 bits to zero
40+
// }
41+
}
42+
}
43+
44+
__global__ void convert_int32_to_int128(uint8_t *input, uint8_t *output, size_t count) {
45+
size_t idx = blockIdx.x * blockDim.x + threadIdx.x;
46+
if (idx < count) {
47+
// Store the converted value as 16 bytes in output
48+
int32_t* input_ptr = reinterpret_cast<int32_t*>(input + idx * 4);
49+
int32_t* output_ptr = reinterpret_cast<int32_t*>(output + idx * 16);
50+
// for (int i = 0; i < 8; ++i) {
51+
output_ptr[0] = input_ptr[0];
52+
output_ptr[1] = 0; // Set the upper 64 bits to zero
53+
output_ptr[2] = 0; // Set the upper 64 bits to zero
54+
output_ptr[3] = 0; // Set the upper 64 bits to zero
55+
// }
56+
}
57+
}
58+
2959
void warmup_gpu() {
3060
// Perform the warmup
3161
cudaFree(0);
3262
warmup_kernel<<<WARMUP_BLOCKS, WARMUP_THREADS_PER_BLOCK>>>();
3363
cudaDeviceSynchronize();
3464
}
3565

66+
void convertInt64ToInt128(uint8_t *input, uint8_t *output, size_t count) {
67+
if (count == 0) return;
68+
69+
// Launch the kernel to convert the data
70+
size_t threads_per_block = 256;
71+
size_t blocks = (count + threads_per_block - 1) / threads_per_block;
72+
73+
convert_int64_to_int128<<<blocks, threads_per_block>>>(input, output, count);
74+
cudaDeviceSynchronize();
75+
}
76+
77+
void convertInt32ToInt128(uint8_t *input, uint8_t *output, size_t count) {
78+
if (count == 0) return;
79+
80+
// Launch the kernel to convert the data
81+
size_t threads_per_block = 256;
82+
size_t blocks = (count + threads_per_block - 1) / threads_per_block;
83+
84+
convert_int32_to_int128<<<blocks, threads_per_block>>>(input, output, count);
85+
cudaDeviceSynchronize();
86+
}
87+
3688
} // namespace duckdb

src/include/gpu_columns.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ enum class ColumnType {
2222
FLOAT64,
2323
BOOLEAN,
2424
DATE,
25-
VARCHAR
25+
VARCHAR,
26+
INT128
2627
};
2728

2829
inline ColumnType convertLogicalTypeToColumnType(LogicalType type) {

src/include/utils.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@
55
namespace duckdb {
66

77
void warmup_gpu();
8+
void convertInt64ToInt128(uint8_t *input, uint8_t *output, size_t count);
9+
void convertInt32ToInt128(uint8_t *input, uint8_t *output, size_t count);
810

911
} // namespace duckdb

src/operator/gpu_physical_grouped_aggregate.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,10 @@ HandleGroupByAggregateCuDF(vector<shared_ptr<GPUColumn>> &group_by_keys, vector<
300300
agg_mode[agg_idx] = AggregationType::SUM;
301301
} else if (expr.function.name.compare("sum") == 0 && aggregate_keys[agg_idx]->data_wrapper.data != nullptr) {
302302
agg_mode[agg_idx] = AggregationType::SUM;
303+
} else if (expr.function.name.compare("sum_no_overflow") == 0 && aggregate_keys[agg_idx]->data_wrapper.data == nullptr && aggregate_keys[agg_idx]->column_length == 0) {
304+
agg_mode[agg_idx] = AggregationType::SUM;
305+
} else if (expr.function.name.compare("sum_no_overflow") == 0 && aggregate_keys[agg_idx]->data_wrapper.data != nullptr) {
306+
agg_mode[agg_idx] = AggregationType::SUM;
303307
} else if (expr.function.name.compare("avg") == 0 && aggregate_keys[agg_idx]->data_wrapper.data != nullptr) {
304308
agg_mode[agg_idx] = AggregationType::AVERAGE;
305309
} else if (expr.function.name.compare("max") == 0 && aggregate_keys[agg_idx]->data_wrapper.data != nullptr) {

src/operator/gpu_physical_result_collector.cpp

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "gpu_buffer_manager.hpp"
1010
#include "gpu_materialize.hpp"
1111
#include "log/logging.hpp"
12+
#include "utils.hpp"
1213

1314
namespace duckdb {
1415

@@ -178,6 +179,8 @@ LogicalType ColumnTypeToLogicalType(ColumnType type) {
178179
return LogicalType::DATE;
179180
case ColumnType::VARCHAR:
180181
return LogicalType::VARCHAR;
182+
case ColumnType::INT128:
183+
return LogicalType::HUGEINT;
181184
default:
182185
throw NotImplementedException("Unsupported sirius column type in `ColumnTypeToLogicalType`: %d",
183186
static_cast<int>(type));
@@ -198,6 +201,8 @@ Vector rawDataToVector(uint8_t* host_data, size_t vector_offset, ColumnType type
198201
sizeof_type = sizeof(double); break;
199202
case ColumnType::BOOLEAN:
200203
sizeof_type = sizeof(uint8_t); break;
204+
case ColumnType::INT128:
205+
sizeof_type = 2 * sizeof(uint64_t); break;
201206
default:
202207
throw NotImplementedException("Unsupported sirius column type in `rawDataToVector`: %d",
203208
static_cast<int>(type));
@@ -238,8 +243,8 @@ SinkResultType GPUPhysicalMaterializedCollector::Sink(GPUIntermediateRelation &i
238243
char* all_columns_chars = reinterpret_cast<char*>(combined_buffer + all_columns_strings_buffer_size);
239244

240245
size_t size_bytes = 0;
241-
Allocator& allocator = Allocator::DefaultAllocator();
242246
uint8_t** host_data = gpuBufferManager->customCudaHostAlloc<uint8_t*>(input_relation.columns.size());
247+
243248
GPUIntermediateRelation materialized_relation(input_relation.columns.size());
244249
string_t** duckdb_strings = gpuBufferManager->customCudaHostAlloc<string_t*>(input_relation.columns.size());
245250
string_t* curr_column_string_buffer = all_columns_string;
@@ -256,9 +261,26 @@ SinkResultType GPUPhysicalMaterializedCollector::Sink(GPUIntermediateRelation &i
256261
ColumnType col_type = input_relation.columns[col]->data_wrapper.type;
257262
bool is_string = false;
258263
if(col_type != ColumnType::VARCHAR) {
259-
// host_data[col] = allocator.AllocateData(size_bytes);
260-
host_data[col] = gpuBufferManager->customCudaHostAlloc<uint8_t>(size_bytes);
261-
callCudaMemcpyDeviceToHost<uint8_t>(host_data[col], materialized_relation.columns[col]->data_wrapper.data, size_bytes, 0);
264+
if (types[col].InternalType() == PhysicalType::INT128) {
265+
if (materialized_relation.columns[col]->data_wrapper.type == ColumnType::INT64) {
266+
SIRIUS_LOG_DEBUG("Converting INT64 to INT128 for column {}", col);
267+
uint8_t* temp_int128 = gpuBufferManager->customCudaMalloc<uint8_t>(size_bytes * 2, 0, 0);
268+
convertInt64ToInt128(materialized_relation.columns[col]->data_wrapper.data, temp_int128, materialized_relation.columns[col]->column_length);
269+
host_data[col] = gpuBufferManager->customCudaHostAlloc<uint8_t>(size_bytes * 2);
270+
callCudaMemcpyDeviceToHost<uint8_t>(host_data[col], temp_int128, size_bytes * 2, 0);
271+
} else if (materialized_relation.columns[col]->data_wrapper.type == ColumnType::INT32) {
272+
SIRIUS_LOG_DEBUG("Converting INT32 to INT128 for column {}", col);
273+
uint8_t* temp_int128 = gpuBufferManager->customCudaMalloc<uint8_t>(size_bytes * 4, 0, 0);
274+
convertInt32ToInt128(materialized_relation.columns[col]->data_wrapper.data, temp_int128, materialized_relation.columns[col]->column_length);
275+
host_data[col] = gpuBufferManager->customCudaHostAlloc<uint8_t>(size_bytes * 4);
276+
callCudaMemcpyDeviceToHost<uint8_t>(host_data[col], temp_int128, size_bytes * 4, 0);
277+
} else {
278+
throw NotImplementedException("Unsupported column type for INT128 conversion");
279+
}
280+
} else {
281+
host_data[col] = gpuBufferManager->customCudaHostAlloc<uint8_t>(size_bytes);
282+
callCudaMemcpyDeviceToHost<uint8_t>(host_data[col], materialized_relation.columns[col]->data_wrapper.data, size_bytes, 0);
283+
}
262284
} else {
263285
// Use the helper method to materialize the string on the GPU
264286
shared_ptr<GPUColumn> str_column = materialized_relation.columns[col];
@@ -291,8 +313,13 @@ SinkResultType GPUPhysicalMaterializedCollector::Sink(GPUIntermediateRelation &i
291313
chunk.InitializeEmpty(types);
292314
for (int col = 0; col < materialized_relation.columns.size(); col++) {
293315
if(materialized_relation.columns[col]->data_wrapper.type != ColumnType::VARCHAR) {
294-
Vector vector = rawDataToVector(host_data[col], vec, materialized_relation.columns[col]->data_wrapper.type);
295-
chunk.data[col].Reference(vector);
316+
if (types[col].InternalType() == PhysicalType::INT128) {
317+
Vector vector = rawDataToVector(host_data[col], vec, ColumnType::INT128);
318+
chunk.data[col].Reference(vector);
319+
} else {
320+
Vector vector = rawDataToVector(host_data[col], vec, materialized_relation.columns[col]->data_wrapper.type);
321+
chunk.data[col].Reference(vector);
322+
}
296323
} else {
297324
// Add the strings to the vector
298325
Vector str_vector(LogicalType::VARCHAR, reinterpret_cast<data_ptr_t>(duckdb_strings[col] + read_index));

src/operator/gpu_physical_ungrouped_aggregate.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ HandleAggregateExpressionCuDF(vector<shared_ptr<GPUColumn>> &aggregate_keys, GPU
115115
agg_mode[agg_idx] = AggregationType::SUM;
116116
} else if (expr.function.name.compare("sum") == 0 && aggregate_keys[agg_idx]->data_wrapper.data != nullptr) {
117117
agg_mode[agg_idx] = AggregationType::SUM;
118+
} else if (expr.function.name.compare("sum_no_overflow") == 0 && aggregate_keys[agg_idx]->data_wrapper.data == nullptr && aggregate_keys[agg_idx]->column_length == 0) {
119+
agg_mode[agg_idx] = AggregationType::SUM;
120+
} else if (expr.function.name.compare("sum_no_overflow") == 0 && aggregate_keys[agg_idx]->data_wrapper.data != nullptr) {
121+
agg_mode[agg_idx] = AggregationType::SUM;
118122
} else if (expr.function.name.compare("avg") == 0 && aggregate_keys[agg_idx]->data_wrapper.data != nullptr) {
119123
agg_mode[agg_idx] = AggregationType::AVERAGE;
120124
} else if (expr.function.name.compare("max") == 0 && aggregate_keys[agg_idx]->data_wrapper.data != nullptr) {

0 commit comments

Comments
 (0)