Проблема здесь:
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
). Для вычисления этого адреса не требуется доступ к памяти устройства.