Как выделить в cudaMalloc & hellip ;? [Дубликат]

В приведенном ниже коде используется strtok() для разделения строки на токены и сохранения токенов в векторе.

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>

using namespace std;


char one_line_string[] = "hello hi how are you nice weather we are having ok then bye";
char seps[]   = " ,\t\n";
char *token;



int main()
{
   vector<string> vec_String_Lines;
   token = strtok( one_line_string, seps );

   cout << "Extracting and storing data in a vector..\n\n\n";

   while( token != NULL )
   {
      vec_String_Lines.push_back(token);
      token = strtok( NULL, seps );
   }
     cout << "Displaying end result in vector line storage..\n\n";

    for ( int i = 0; i < vec_String_Lines.size(); ++i)
    cout << vec_String_Lines[i] << "\n";
    cout << "\n\n\n";


return 0;
}
4
задан Andrea Sylar Solla 9 August 2012 в 13:05
поделиться

2 ответа

Проблема здесь:

cudaMalloc((void**)&nL,sizeof(NLayer));
cudaMalloc((void**)&nL->neurons,6*sizeof(Neuron));

В первой строке nL указывает на структуру в глобальной памяти на устройстве. Поэтому во второй строке первым аргументом cudaMalloc является адрес, который находится на GPU, что является неопределенным поведением (в моей тестовой системе это вызывает segfault, но в вашем случае есть что-то более тонкое).

Правильный способ сделать то, что вы хотите, это сначала создать структуру в памяти хоста, заполнить ее данными, а затем скопировать ее на устройство, например:

NLayer* nL;
NLayer h_nL;
int i;
int tmp=9;
// Allocate data on device
cudaMalloc((void**)&nL, sizeof(NLayer));
cudaMalloc((void**)&h_nL.neurons, 6*sizeof(Neuron));
// Copy nlayer with pointers to device
cudaMemcpy(nL, &h_nL, sizeof(NLayer), cudaMemcpyHostToDevice);

Кроме того, не забывайте всегда проверять наличие ошибок в процедурах CUDA.

UPDATE

Во второй версии вашего кода:

cudaMemcpy(&d_layer->neurons[i].weights,&d_weights,...) --- снова вы разыскиваете указатель устройства (d_layer) на хосте. Вместо этого вы должны использовать

cudaMemcpy(&h_layer.neurons[i].weights,&d_weights,sizeof(float*),cudaMemcpyHostToDevice

. Здесь вы берете h_layer (структура узла), читаете его элемент (h_layer.neurons), который является указателем на память устройства. Затем вы накладываете на него какую-то указательную арифметику (&h_layer.neurons[i].weights). Для вычисления этого адреса не требуется доступ к памяти устройства.

5
ответ дан aland 24 August 2018 в 03:56
поделиться

Все зависит от используемой вами карты GPU. Карточка Fermi использует единообразную адресацию общего и глобального пространства памяти, в то время как для карт с предварительным ферми нет.

Для случая до Ферми вы не знаете, должен ли адрес быть общим или глобальным. Компилятор обычно может это понять, но есть случаи, когда он не может. Когда требуется указатель на разделяемую память, вы обычно берете адрес общей переменной, и компилятор может это распознать. Сообщение, «предполагающее глобальное», появится, если это явно не определено.

Если вы используете графический процессор, который вычисляет пропускную способность 2.x или выше, он должен работать с флагом компилятора -arch = sm_20

0
ответ дан Beau Bellamy 24 August 2018 в 03:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: