Giới Thiệu
Trong kỷ nguyên công nghệ 4.0, GPU (Graphics Processing Unit) đang ngày càng được áp dụng rộng rãi trong nhiều lĩnh vực tính toán, đặc biệt là trong AI (Trí Tuệ Nhân Tạo) và Deep Learning. Để trở thành một AI Engineer thành công, việc nắm vững nền tảng lập trình CUDA (Compute Unified Device Architecture) là vô cùng quan trọng. Tuy nhiên, việc phát triển và gỡ lỗi cho các đoạn mã kernel trên GPU không phải lúc nào cũng dễ dàng, do sự khác biệt trong cách xử lý lệnh của GPU và CPU. Điều này thường dẫn đến việc xuất hiện các lỗi (bugs) trong code, khiến quá trình phát triển trở nên mất thời gian và công sức.
Hiểu rõ vấn đề này, NVIDIA đã tích hợp NVIDIA Toolkit vào nhiều IDE và text editor phổ biến hiện nay như Eclipse, Visual Studio và Visual Studio Code. Trong bài viết này, chúng ta sẽ cùng tìm hiểu cách sử dụng extension Nsight Visual Studio Code Edition để gỡ lỗi kernel code trực tiếp trên trình gỡ lỗi của Visual Studio Code. Xin lưu ý rằng, thời điểm hiện tại extension này chỉ hỗ trợ gỡ lỗi GPU code trên hệ điều hành Linux.
Cài Đặt Môi Trường Phát Triển
Trước tiên, chúng ta cần cài đặt NVIDIA Toolkit, bao gồm các thư viện hỗ trợ giao tiếp với GPU, cùng với các công cụ gỡ lỗi và tối ưu, trình biên dịch C/C++ và thư viện runtime. Để cài đặt, bạn có thể thực hiện theo các bước sau:
- Truy cập trang download của NVIDIA Toolkit và làm theo hướng dẫn tại: NVIDIA CUDA Downloads.
- Cài đặt NVIDIA Nsight Visual Studio Code Edition từ Visual Studio Code.
- Lưu ý: Nếu bạn đang sử dụng WSL2 trên Windows làm hệ điều hành mục tiêu, cần kiểm tra và tạo registry key sau:
HKEY_LOCAL_MACHINE\SOFTWARE\NVIDIA Corporation\GPUDebugger\EnableInterface
, sau đó set thành (DWORD) = 1. Nếu chỉ cài NVIDIA Toolkit trên WSL2 mà không cài trên Windows, bạn sẽ thiếu mất key này.
- Lưu ý: Nếu bạn đang sử dụng WSL2 trên Windows làm hệ điều hành mục tiêu, cần kiểm tra và tạo registry key sau:
Ví Dụ Về Phép Tính Cộng Vector
Đến lúc này, chúng ta cần một đoạn code CUDA để biên dịch và gỡ lỗi. Dưới đây là một đoạn code cơ bản thực hiện phép cộng hai vector:
cpp
__global__ void add(int n, float *x, float *y) {
int index = blockIdx.x * blockDim.x + threadIdx.x;
int stride = blockDim.x * gridDim.x;
for (int i = index; i < n; i += stride)
y[i] = x[i] + y[i];
}
int main() {
int N = 1 << 20;
float *x, *y;
cudaMallocManaged(&x, N * sizeof(float));
cudaMallocManaged(&y, N * sizeof(float));
for (int i = 0; i < N; i++) {
x[i] = 1.0f;
y[i] = 2.0f;
}
int blockSize = 256;
int numBlocks = (N + blockSize - 1) / blockSize;
add<<<numBlocks, blockSize>>>(N, x, y);
cudaDeviceSynchronize();
cudaFree(x);
cudaFree(y);
return 0;
}
Đoạn code trên thực hiện phép cộng hai vector đơn giản. Mỗi phép tính được giao cho một thread trên GPU và kết quả sẽ được lưu vào vector thứ hai. Để biên dịch đoạn code này, sử dụng lệnh sau với nvcc, thêm các flag -g
và -G
để sinh symbol cho cả CPU và GPU code:
vcc -g -G main.cu -o main
Cài Đặt launch.json Và Bắt Đầu Debug
Tiếp theo, bạn cần tạo thư mục .vscode
trong thư mục làm việc của mình và một file launch.json
với nội dung sau:
json
{
"version": "0.2.0",
"configurations": [
{
"name": "CUDA C++: Launch",
"type": "cuda-gdb",
"request": "launch",
"program": "${workspaceFolder}/main"
}
]
}
Trong file này, bạn cần chỉ định đường dẫn tới file thực thi được biên dịch bởi nvcc. Sau đó, nhấn Ctrl + F5
để bắt đầu phiên gỡ lỗi. Từ đây, bạn có thể đặt breakpoint trực tiếp trong kernel code, biên dịch lại và gỡ lỗi như cách thức gỡ lỗi cho các chương trình C/C++ truyền thống.
Kết Luận
Với những hướng dẫn trong bài viết này, bạn đã có thể thiết lập môi trường phát triển và gỡ lỗi cho code CUDA một cách hiệu quả trên Visual Studio Code. Việc này không chỉ giúp bạn tiết kiệm thời gian mà còn tối ưu quá trình phát triển, cho phép bạn tập trung vào việc phát triển các ứng dụng AI và Deep Learning mạnh mẽ hơn.
source: viblo