2013-11-27 3 views
0

все: Недавно я попытался использовать последнее свойство cuda 5.5 для программирования, то есть динамического параллелизма. Но у меня есть очень запутанная проблема. Мой код здесь:cublas device api output weird result

/* Includes, system */ 
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    #include <iostream> 
    using namespace std; 
    /* Includes, cuda */ 
    #include <cuda_runtime.h> 
    #include <cublas_v2.h> 

    /* Includes, cuda helper functions */ 
    #include <helper_cuda.h> 

    #include "kernels.cu" 
    /* Matrix size */ 
    #define N (275) 

    #define LengthSignal (64) 

    #define AmountSignal (255025) 

    #define NBLOCKX (32768) 

    #define NTHREADS_PER_BLOCK (128) 
    /* Declaration of the function that computes sgemm using CUBLAS device API */ 

    __global__ void invokeDeviceCublasSgemm(float *d_A, float *Test); 

    /* Main */ 
    int main(int argc, char **argv) 
    { 
     float *h_A; 
     float *d_A = 0; 
     int n2 = N * N; 

     h_A = (float *)malloc(n2 * sizeof(h_A[0])); 
    /* Fill the matrices with test data */ 
    for (int i = 0; i < n2; i++) 
    { 
     h_A[i] = rand()/(float)RAND_MAX; 
    } 

     cudaMalloc((void **)&d_A, n2 * sizeof(h_A[0])); 

     /* Initialize the device matrices with the host matrices */ 
     // cudaMemcpy(d_A, h_A, sizeof(float) * LengthSignal * AmountSignal, cudaMemcpyHostToDevice); 
     cudaMemcpy(d_A, h_A, n2 * sizeof(h_A[0]), cudaMemcpyHostToDevice); 

     int Length = 100; 
     float *h_Test = (float *) malloc(sizeof(float) * Length); 
     float *d_Test; 
     cudaMalloc((void **) &d_Test, sizeof(float) * Length); 
     cudaMemset(d_Test, 0, sizeof(float) * Length); 

    invokeDeviceCublasSgemm<<<NBLOCKX, NTHREADS_PER_BLOCK>>>(d_A, d_Test); 
    cudaMemcpy(h_Test, d_Test, sizeof(float) * Length, cudaMemcpyDeviceToHost); 

    printf("\n The first 10 elements of d_A in location 1 are: \n"); 
    for (int j = 0; j < 10; j ++) 
    { 
     printf("%f ", h_Test[j]); 
    } 

    printf("\n The first 10 elements of d_A in location 2 are: \n"); 
    for (int j = 10; j < 20; j ++) 
    { 
     printf("%f ", h_Test[j]); 
    } 
    printf("\n"); 

    free(h_Test); 
    cudaFree(d_Test); 

    /* Memory clean up */ 
    free(h_A); 
    cudaFree(d_A); 
} 

#ifndef __GLOBAL__CU__ 
#define __GLOBAL__CU__ 

__global__ void invokeDeviceCublasSgemm(float *d_A, float *Test) 
{ 
    // save the first 10 elements of d_A in location 1 
    for (int j = 0; j < 10; j ++) 
    { 
     Test[j] = d_A[j]; 
    } 
    cublasHandle_t cnpHandle; 
    cublasCreate(&cnpHandle); 

    // save the first 10 elements of d_A in location 2 
    for (int j = 10; j < 20; j ++) 
     { 
     Test[j] = d_A[j - 10]; 
     } 
    cublasDestroy(cnpHandle); 
} 

#endif 

Если установить параметры конфигурации, как < < < 1, 1 >>>, все работает хорошо. И выход такова:

Первые 10 элементов D_A в местоположении 1 являются:

0,840188 0,394383 0,783099 0,798440 0,911647 0,197551 0,335223 0,768230 0,277775 0,553970

Первые 10 элементов D_A в местоположении 2 являются :

0,840188 0,394383 0,783099 0,798440 0,911647 0,197551 0,335223 0,768230 0,277775 0,553970

Однако, если установить параметры конфигурации, как < < < 32768, 128 >>>, выход довольно странный. И выход такова:

Первые 10 элементов D_A в местоположении 1 являются:

-0,000000 0,000000 0,000000 0,000000 0,000000 0,000000 0,000000 0,000000 0,000000 0,000000

Первые 10 элементов D_A в местоположении 2 являются:

0,000000 0,000000 0,000000 0,000000 0,000000 0,000000 0,000000 0,000000 0,000000 0,000000

Я действительно не знаю, почему! Мой код только что пришел из «образцов» с небольшим изменением.


А потом я просто удалить последний код "cublasDestroy (cnpHandle);", то это становится нормальным. А выход:

Первые 10 элементов D_A в местоположении 1 являются:

0,840188 0,394383 0,783099 0,798440 0,911647 0,197551 0,335223 0,768230 0,277775 0,553970

Первые 10 элементов D_A в местоположении 2 являются:

0,840188 0,394383 0,783099 0,798440 0,911647 0,197551 0,335223 0,768230 0,277775 0,553970


ли у кого-то такая же проблема?

Спасибо!

ответ

2

Сделайте несколько proper cuda error checking Вы можете сделать это на ваших вызовах API хоста, а также на вызовы API вашего устройства и вызовы API CUBLAS (и вызовы ядра). Если вы не уверены, прочитайте динамический параллелизм documentation.

Вполне вероятно, что вы находитесь в exceeding the number of kernel launches that can be outstanding в любое время. Существует (настраиваемый) предел 2048 запусков ядра, которые могут быть выдающимися. Так как ваш код выходит из строя с параметрами запуска ядра ядра <<<32768, 128>>>, это означает, что вы пытаетесь запустить потоки 32768x128, каждый из которых может попытаться запустить дочернее ядро. Если количество запусков ядра превысит лимит, оставшиеся запуски ядра будут терпеть неудачу.

«Но я не запускаю какие-либо дочерние ядра?» Фактически, использование устройства CUBLAS API предполагает, что ядра могут запускаться. Так работает система CUBLAS.

Чтобы получить ясность, я снова настоятельно рекомендую вам провести тщательную проверку ошибок.