API устройства Cublas выводит странный результат

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

    /* 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


У кого-то была такая же проблема?

Спасибо!

0

Решение

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

Вполне вероятно, что вы превышение количества запусков ядра, которые могут быть выдающимися в любое время. Существует (настраиваемый) лимит в 2048 запусков ядра, который может быть выдающимся. Поскольку ваш код не работает с параметрами запуска ядра хоста <<<32768, 128>>>, это означает, что вы пытаетесь запустить потоки 32768×128, каждый из которых может быть попробуй запустить дочернее ядро. Если количество запусков ядра превышает лимит, остальные запуски ядра завершатся неудачно.

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

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

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]