2012-05-09 26 views
6

Tôi đang bắt đầu tạp chí của mình để tìm hiểu Cuda. Tôi đang chơi với một số mã cuda hello thế giới loại nhưng nó không làm việc, và tôi không chắc chắn lý do tại sao.Thêm đơn giản của hai int trong Cuda, kết quả luôn luôn giống nhau

Mã rất đơn giản, lấy hai int và thêm chúng vào GPU và trả lại kết quả, nhưng không có vấn đề gì tôi thay đổi các số để tôi nhận được kết quả tương tự (Nếu toán học theo cách đó tôi đã làm tốt hơn rất nhiều trong chủ đề hơn là tôi thực sự đã làm).

Dưới đây là đoạn code mẫu:

// CUDA-C includes 
#include <cuda.h> 
#include <stdio.h> 

__global__ void add(int a, int b, int *c) { 
    *c = a + b; 
} 

extern "C" 
void runCudaPart(); 

// Main cuda function 

void runCudaPart() { 

    int c; 
    int *dev_c; 

    cudaMalloc((void**)&dev_c, sizeof(int)); 
    add<<<1,1>>>(1, 4, dev_c); 

    cudaMemcpy(&c, dev_c, sizeof(int), cudaMemcpyDeviceToHost); 

    printf("1 + 4 = %d\n", c); 
    cudaFree(dev_c); 

} 

Kết quả có vẻ hơi off: 1 + 4 = -1065287167

tôi đang làm việc trên thiết lập môi trường của tôi và chỉ muốn biết nếu có một vấn đề với mã nếu không thì đó có lẽ là môi trường của tôi.

Cập nhật: Tôi đã cố gắng thêm một số mã để hiển thị lỗi nhưng tôi không nhận được kết quả nhưng thay đổi số (có phải là mã lỗi đầu ra thay vì câu trả lời không? Ngay cả khi tôi không thực hiện bất kỳ công việc nào trong kernal khác hơn là gán một biến tôi vẫn nhận được kết quả simlair).

// CUDA-C includes 
#include <cuda.h> 
#include <stdio.h> 

__global__ void add(int a, int b, int *c) { 
    //*c = a + b; 
    *c = 5; 
} 

extern "C" 
void runCudaPart(); 

// Main cuda function 

void runCudaPart() { 

    int c; 
    int *dev_c; 

    cudaError_t err = cudaMalloc((void**)&dev_c, sizeof(int)); 
    if(err != cudaSuccess){ 
     printf("The error is %s", cudaGetErrorString(err)); 
    } 
    add<<<1,1>>>(1, 4, dev_c); 

    cudaError_t err2 = cudaMemcpy(&c, dev_c, sizeof(int), cudaMemcpyDeviceToHost); 
    if(err2 != cudaSuccess){ 
     printf("The error is %s", cudaGetErrorString(err)); 
    } 


    printf("1 + 4 = %d\n", c); 
    cudaFree(dev_c); 

} 

Mã có vẻ ổn, có thể liên quan đến thiết lập của tôi. Đó là một cơn ác mộng để có được Cuda cài đặt trên sư tử OSX nhưng tôi nghĩ rằng nó làm việc như các ví dụ trong SDK dường như là tốt. Các bước tôi đã thực hiện cho đến nay là truy cập trang web Nvida và tải xuống bản phát hành mac mới nhất cho trình điều khiển, bộ công cụ và SDK. Sau đó tôi được export DYLD_LIBRARY_PATH=/usr/local/cuda/lib:$DYLD_LIBRARY_PATH và 'PATH =/usr/local/CUDA/bin: $ PATH` Tôi đã làm một deviceQuery và nó trôi qua với các thông tin sau đây về hệ thống của tôi:

[deviceQuery] starting... 

/Developer/GPU Computing/C/bin/darwin/release/deviceQuery Starting... 

CUDA Device Query (Runtime API) version (CUDART static linking) 

Found 1 CUDA Capable device(s) 

Device 0: "GeForce 320M" 
    CUDA Driver Version/Runtime Version   4.2/4.2 
    CUDA Capability Major/Minor version number: 1.2 
    Total amount of global memory:     253 MBytes (265027584 bytes) 
    (6) Multiprocessors x ( 8) CUDA Cores/MP: 48 CUDA Cores 
    GPU Clock rate:        950 MHz (0.95 GHz) 
    Memory Clock rate:        1064 Mhz 
    Memory Bus Width:        128-bit 
    Max Texture Dimension Size (x,y,z)    1D=(8192), 2D=(65536,32768), 3D=(2048,2048,2048) 
    Max Layered Texture Size (dim) x layers  1D=(8192) x 512, 2D=(8192,8192) x 512 
    Total amount of constant memory:    65536 bytes 
    Total amount of shared memory per block:  16384 bytes 
    Total number of registers available per block: 16384 
    Warp size:          32 
    Maximum number of threads per multiprocessor: 1024 
    Maximum number of threads per block:   512 
    Maximum sizes of each dimension of a block: 512 x 512 x 64 
    Maximum sizes of each dimension of a grid:  65535 x 65535 x 1 
    Maximum memory pitch:       2147483647 bytes 
    Texture alignment:        256 bytes 
    Concurrent copy and execution:     Yes with 1 copy engine(s) 
    Run time limit on kernels:      Yes 
    Integrated GPU sharing Host Memory:   Yes 
    Support host page-locked memory mapping:  Yes 
    Concurrent kernel execution:     No 
    Alignment requirement for Surfaces:   Yes 
    Device has ECC support enabled:    No 
    Device is using TCC driver mode:    No 
    Device supports Unified Addressing (UVA):  No 
    Device PCI Bus ID/PCI location ID:   4/0 
    Compute Mode: 
    < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) > 

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 4.2, CUDA Runtime Version = 4.2, NumDevs = 1, Device = GeForce 320M 
[deviceQuery] test results... 
PASSED 

UPDATE: những gì thực sự kỳ lạ là ngay cả khi Tôi loại bỏ tất cả các công việc trong hạt nhân tôi stil có được một kết quả cho c? Tôi đã cài đặt lại cuda và sử dụng làm cho các ví dụ và tất cả chúng vượt qua.

+0

Để bắt đầu, cả hai mã kết quả trả về cudaMalloc và cudaMemcpy. Nó có thể là giáo dục để in bất cứ điều gì đó không phải là cudaSuccess. –

+0

@ HenkHolterman không may mắn..Tôi thực sự mới với Cuda, vì vậy tôi có thể hoàn toàn sai nhưng tôi đã cố gắng tạo một đầu ra nếu có lỗi và không có thông báo về lỗi nhưng số đã thay đổi (ngay cả khi tôi đặt cụ thể số trong hạt nhân, nó không trả về.) Tôi cập nhật mã, có vẻ như hạt nhân thậm chí không được sử dụng. – Lostsoul

+0

Tôi thường là một người tin tưởng vào "nếu bạn nhìn thấy các bản in, nghĩ rằng ngựa, không phải ngựa vằn", nhưng tôi không thể tìm thấy bất cứ điều gì sai với điều này ... thiết lập của bạn như thế nào? GPU, phiên bản CUDA, trình biên dịch, v.v ...? – trycatch

Trả lời

8

Về cơ bản có hai vấn đề ở đây:

  1. You are not compile kernel cho kiến ​​trúc chính xác (lượm lặt từ comments)
  2. Mã của bạn chứa kiểm tra lỗi không hoàn hảo mà là mất tích điểm khi lỗi runtime đang xảy ra, dẫn đến các triệu chứng bí ẩn và không rõ nguyên nhân.

Trong API thời gian chạy, hầu hết các hành động liên quan đến ngữ cảnh được thực hiện "lười biếng". Khi bạn khởi chạy hạt nhân lần đầu tiên, API thời gian chạy sẽ gọi mã để tìm một hình ảnh CUBIN phù hợp từ bên trong hình ảnh nhị phân chất béo phát ra bởi chuỗi công cụ cho phần cứng đích và tải nó vào ngữ cảnh. Điều này cũng có thể bao gồm JIT biên dịch lại PTX cho một kiến ​​trúc tương thích ngược, nhưng không phải là cách khác. Vì vậy, nếu bạn đã có một hạt nhân biên dịch cho một khả năng tính toán 1.2 thiết bị và bạn chạy nó trên một khả năng tính toán 2.0 thiết bị, trình điều khiển có thể JIT biên dịch mã PTX 1.x nó chứa cho kiến ​​trúc mới hơn. Nhưng ngược lại không hiệu quả. Vì vậy, trong ví dụ của bạn, API thời gian chạy sẽ tạo ra một lỗi vì nó không thể tìm thấy một hình ảnh nhị phân có thể sử dụng trong hình ảnh chất béo CUDA được nhúng trong tệp thực thi. Thông báo lỗi khá khó hiểu, nhưng bạn sẽ gặp lỗi (xem this question để biết thêm thông tin).

Nếu mã của bạn chứa kiểm tra lỗi như thế này:

cudaError_t err = cudaMalloc((void**)&dev_c, sizeof(int)); 
if(err != cudaSuccess){ 
    printf("The error is %s", cudaGetErrorString(err)); 
} 

add<<<1,1>>>(1, 4, dev_c); 
if (cudaPeekAtLastError() != cudaSuccess) { 
    printf("The error is %s", cudaGetErrorString(cudaGetLastError())); 
} 

cudaError_t err2 = cudaMemcpy(&c, dev_c, sizeof(int), cudaMemcpyDeviceToHost); 
if(err2 != cudaSuccess){ 
    printf("The error is %s", cudaGetErrorString(err)); 
} 

lỗi thêm kiểm tra sau khi khởi động hạt nhân nên bắt lỗi runtime API được tạo ra bởi sự thất bại tải kernel/khởi động.

+1

Đây có lẽ là phương pháp hay nhất cho người mới bắt đầu. Kiểm tra lỗi ở từng bước trong khi bạn học. Bạn sẽ nhận được một lỗi liên quan đến kiến ​​trúc thiết bị. – pQB

+3

Nó cũng là phương pháp tốt nhất cho thuận :) Chắc chắn để gỡ lỗi xây dựng, nhưng tôi sẽ để lại các kiểm tra trong bản phát hành xây dựng là tốt. Nếu các kiểm tra không được mong muốn trong bản phát hành bản phát hành, hãy sử dụng bộ tiền xử lý để thay thế chúng bằng các khai báo. –

1
#include <stdio.h> 
#include <conio.h> 
#include <cuda.h> 
#include <cuda_runtime.h> 
#include <device_launch_parameters.h> 


__global__ void Addition(int *a,int *b,int *c) 
{ 

    *c = *a + *b; 
} 
int main() 
{ 
    int a,b,c; 
    int *dev_a,*dev_b,*dev_c; 
    int size = sizeof(int); 

    cudaMalloc((void**)&dev_a, size); 
    cudaMalloc((void**)&dev_b, size); 
    cudaMalloc((void**)&dev_c, size); 

    a=5,b=6; 

    cudaMemcpy(dev_a, &a,sizeof(int), cudaMemcpyHostToDevice); 
    cudaMemcpy(dev_b, &b,sizeof(int), cudaMemcpyHostToDevice); 

    Addition<<< 1,1 >>>(dev_a,dev_b,dev_c); 
    cudaMemcpy(&c, dev_c,size, cudaMemcpyDeviceToHost); 

    cudaFree(&dev_a); 
    cudaFree(&dev_b); 
    cudaFree(&dev_c); 

    printf("%d\n", c); 
    getch(); 
    return 0; 
} 
Các vấn đề liên quan