2010-11-14 36 views
11

Tôi mới dùng CUDA C và đang cố chuyển cấu trúc typedef'd vào hạt nhân. Phương pháp của tôi làm việc tốt khi tôi thử nó với một cấu trúc chỉ chứa int, nhưng khi tôi chuyển sang float, tôi nhận được các số vô nghĩa trở lại dưới dạng kết quả. Tôi cho rằng điều này liên quan đến sự liên kết, và tôi đã thử bao gồm cả __align__ cùng với khai báo kiểu của tôi, nhưng vô ích. Ai đó có thể cho tôi một ví dụ về cách thức này được thực hiện, hoặc cung cấp một cách tiếp cận thay thế? Tôi đang cố gắng để thiết lập nó để tôi có thể dễ dàng thêm hoặc loại bỏ các lĩnh vực mà không thay đổi bất cứ điều gì khác hơn là cấu trúc và hạt nhân. Mã của tôi:Chuyển cấu trúc tới hạt CUDA

typedef struct __align__(8) 
{ 
    float a, b; 
} point; 

__global__ void testKernel(point *p) 
{ 
    int i = blockIdx.x * blockDim.x + threadIdx.x; 
    p[i].a = 1.1; 
    p[i].b = 2.2; 
} 

int main(void) 
{ 
     // set number of points 
    int numPoints = 16, 
     gpuBlockSize = 4, 
     pointSize = sizeof(point), 
     numBytes  = numPoints * pointSize, 
     gpuGridSize = numPoints/gpuBlockSize; 

     // allocate memory 
    point *cpuPointArray = new point[numPoints], 
      *gpuPointArray = new point[numPoints]; 
    cpuPointArray = (point*)malloc(numBytes); 
    cudaMalloc((void**)&gpuPointArray, numBytes); 

     // launch kernel 
    testKernel<<<gpuGridSize,gpuBlockSize>>>(gpuPointArray); 

     // retrieve the results 
    cudaMemcpy(cpuPointArray, gpuPointArray, numBytes, cudaMemcpyDeviceToHost); 
    printf("testKernel results:\n"); 
    for(int i = 0; i < numPoints; ++i) 
    { 
     printf("point.a: %d, point.b: %d\n",cpuPointArray[i].a,cpuPointArray[i].b); 
    } 

     // deallocate memory 
    free(cpuPointArray); 
    cudaFree(gpuPointArray); 

    return 0; 
} 
+0

điểm * gpuPointArray = new ... có vẻ sai với tôi? Bạn đang phân bổ trên máy chủ và sau đó làm một cudaMalloc trên thiết bị ... – Bart

+0

Tôi có cần phân bổ bộ nhớ trước khi truyền nó làm đối số cho hạt nhân không? Rời khỏi dòng cudaMalloc đưa ra một "lỗi khởi chạy không xác định". Tôi cũng có thể đặt gpuPointArray thành NULL, nhưng nó dường như không thay đổi kết quả ban đầu của tôi. – Paul

+3

Tuyệt đối. Bạn cần cudaMalloc. Bạn không cần "mới" trước khi nó mặc dù. Cũng vậy với cpuPointArray. Sử dụng malloc và miễn phí (bạn đang lập trình C) và không sử dụng mới ở đây. (Không bao giờ trộn lẫn malloc mới và miễn phí) – Bart

Trả lời

3

Hãy xem cách thực hiện trong tiêu đề vector_types.h có trong thư mục CUDA của bạn. Điều đó đã cung cấp cho bạn một số gợi ý.

Tuy nhiên, vấn đề chính ở đây là %d trong các cuộc gọi printf của bạn. Bạn đang cố gắng in nổi bây giờ, không phải số nguyên. Vì vậy, những người thực sự nên sử dụng %f thay thế.

+0

Được rồi, tôi đã xem vector_types.h và tôi đã thử làm những gì họ đã làm: 'typedef struct __align __ (2 * sizeof (float)) point {' ..., nhưng nó vẫn mang lại kết quả tương tự. Có cái gì khác ở đây mà tôi nên được nhìn thấy? – Paul

+2

Nhân tiện, thay đổi printf của bạn để sử dụng% f thay vì% d ... điều đó có thay đổi gì không? Bạn đang cố gắng in nổi bây giờ, không phải là ... – Bart

+1

Ha! Điều đó đã làm điều đó, cảm ơn. Đôi khi rõ ràng là điều dễ nhất để bỏ lỡ ... – Paul

15

Vì dường như không có bất kỳ tài liệu phong nha nào về cách thực hiện việc này, tôi nghĩ tôi sẽ đăng mã cuối cùng, sửa đổi tại đây. Nó chỉ ra rằng phần __align__ là không cần thiết là tốt, vấn đề thực tế là việc sử dụng% d trong printf khi cố gắng in nổi.

#include <stdlib.h> 
#include <stdio.h> 

typedef struct 
{ 
    float a, b; 
} point; 

__global__ void testKernel(point *p) 
{ 
    int i = blockIdx.x * blockDim.x + threadIdx.x; 
    p[i].a = 1.1; 
    p[i].b = 2.2; 
} 

int main(void) 
{ 
     // set number of points 
    int numPoints = 16, 
     gpuBlockSize = 4, 
     pointSize = sizeof(point), 
     numBytes  = numPoints * pointSize, 
     gpuGridSize = numPoints/gpuBlockSize; 

     // allocate memory 
    point *cpuPointArray, 
      *gpuPointArray; 
    cpuPointArray = (point*)malloc(numBytes); 
    cudaMalloc((void**)&gpuPointArray, numBytes); 

     // launch kernel 
    testKernel<<<gpuGridSize,gpuBlockSize>>>(gpuPointArray); 

     // retrieve the results 
    cudaMemcpy(cpuPointArray, gpuPointArray, numBytes, cudaMemcpyDeviceToHost); 
    printf("testKernel results:\n"); 
    for(int i = 0; i < numPoints; ++i) 
    { 
     printf("point.a: %f, point.b: %f\n",cpuPointArray[i].a,cpuPointArray[i].b); 
    } 

     // deallocate memory 
    free(cpuPointArray); 
    cudaFree(gpuPointArray); 

    return 0; 
} 
Các vấn đề liên quan