将结构数组从主机复制到设备cuda

时间:2017-04-03 01:01:57

标签: c cuda

假设我有一个结构如下:

typedef struct values{
int one, int two, int three
} values;

现在,假设我在主机上创建了一个值数组,并使用随机数据填充

values vals*;
__device__ values* d_vals;
int main(){
     vals = (values*)malloc(sizeof(values) * A_LARGE_NUMBER);
     PopulateWithDate(); //populates vals with random data
}

现在我希望能够将值复制到设备,以便我可以在我的内核中访问它们,如下所示:

__global__ void myKernel(){
     printf("%d", d_vals[0].one);//I don't really want to print, but whenever I try to access I get an error
}

无论我尝试什么,我都会遇到非法的内存访问错误。

这是我目前的尝试:

int main(){
     vals = (values*)malloc(sizeof(values) * A_LARGE_NUMBER);
     PopulateWithDate(); //populates vals with random data

     values* d_ptr;
     cudaGetSymbolAddress((void**)&d_ptr, d_vals);
     cudaMalloc((void**)&d_ptr, A_LARGE_NUMBER * sizeof(values));

     cudaMemcpyToSymbol(d_ptr, &vals, sizeof(values) * A_LARGE_NUMBER);
     cudaDeviceSynchronize();
     dim3    blocksPerGrid(2, 2);
     dim3    threadsPerBlock(16, 16);

    myKernel<< <blocksPerGrid, threadsPerBlock >> >();
}

1 个答案:

答案 0 :(得分:2)

对于你到目前为止所展示的内容,使用<?php $harvest = Array ( Array ( Array ( 'PRODUCT' => 'ROSE' , 'VARIETY' => 'ADELE', 'GOLD' => 160, 'NORMAL' => 0 , 'TOTAL' => 160 ) , Array ( 'PRODUCT' => 'ROSE', 'VARIETY' => 'ALESSO' , 'GOLD' => 1320 , 'NORMAL' => 550, 'TOTAL' => 1870 ) , Array ( 'PRODUCT' => 'ROSE', 'VARIETY' => 'ANASTACIA' , 'GOLD' => 440 , 'NORMAL' => 150 , 'TOTAL' => 590 ), Array ( 'PRODUCT' => 'ROSE1', 'VARIETY' => 'ANASTACIA1' , 'GOLD' => 420 , 'NORMAL' => 120 , 'TOTAL' => 540 ), Array ( 'PRODUCT' => 'ROSE1', 'VARIETY' => 'ANASTACIA1', 'GOLD' => 440 , 'NORMAL' => 100 , 'TOTAL' => 540 ), Array ( 'PRODUCT' => 'ROSE2', 'VARIETY' => 'ANASTACIA2', 'GOLD' => 640, 'NORMAL' => 0, 'TOTAL' => 640 ), Array ( 'PRODUCT' => 'ROSE2', 'VARIETY' => 'ANASTACIA2' , 'GOLD' => 440, 'NORMAL' => 440, 'TOTAL' => 880 ) ) ); $arrayThead = array(); for ($i=0; $i < count($harvest) ; $i++) { array_push($arrayThead, array_keys($harvest[$i][0])); } $totalByProduct = array(); foreach ($harvest as $items) { foreach ($items as $item) { if(!key_exists($item['PRODUCT'], $totalByProduct)){ $totalByProduct[$item['PRODUCT']] = $item; continue; } foreach ($arrayThead as $key => $values) { foreach ($values as $th) { if($th != 'PRODUCT' && $th != 'VARIETY'){ $totalByProduct[$item['PRODUCT']][$th] += $item[$th]; } } } } } $arrayfoot= array(); foreach ($harvest as $key => $value) { foreach ($value as $harv) { foreach ($arrayThead as $key => $values) { foreach ($values as $th) { if($th != 'PRODUCT' && $th != 'VARIETY'){ $arrayfoot[$th] += $harv[$th]; } } } } } $arrayComplete = array(); for ($i=0; $i < count($arrayThead) ; $i++) { for ($j=0; $j < count($arrayThead[$i]) ; $j++) { if($arrayThead[$i][$j] != 'PRODUCT' && $arrayThead[$i][$j] != 'VARIETY'){ array_push($arrayComplete, $arrayThead[$i][$j]); } } } $arrayFinal = array(); for ($j=0; $j < count($arrayComplete) ; $j++) { array_push($arrayFinal, $arrayfoot[$arrayComplete[$j]]); } $body = '<table style="border: 1px solid black;border-collapse: collapse;width: 100%;font-family:Calibri;">'; $body .= '<thead style="background-color:#f3f4f5;">'; $body .= '<tr>'; for ($i=0; $i < count($arrayThead) ; $i++) { for ($j=0; $j < count($arrayThead[$i]) ; $j++) { if($arrayThead[$i][$j] === 'PRODUCT' || $arrayThead[$i][$j] === 'VARIETY'){ $body .= '<th style="border: 1px solid black;height:50px;">'.$arrayThead[$i][$j].'</th>'; }else{ $body .= '<th style="border: 1px solid black;height:50px;">'.$arrayThead[$i][$j].'</th>'; } } } $body .= '</tr>'; $body .= '</thead>'; $body .= '<tbody>'; //Initialize the variable product $product = ""; foreach ($harvest as $items) { foreach ($items as $item) { //If the $product variable is different from the data product, print the total if($product != $item['PRODUCT']){ $body .= '<tr>'; $body .= '<th style="border: 1px solid black;text-align:left;font-size:12px;">TOTAL '.$item['PRODUCT'].'</th>'; $body .= '<th style="border: 1px solid black;text-align:left;font-size:12px;"></th>'; foreach ($arrayThead as $key => $values) { foreach ($values as $th) { if($th != 'PRODUCT' && $th != 'VARIETY'){ $body .= '<th style="border: 1px solid black;text-align:right;font-size:12px;">'.number_format($total).'</th>'; } } } $body .= '</tr>'; $product = $item['PRODUCT']; } $body .= '<tr>'; foreach ($arrayThead as $key => $values) { foreach ($values as $th) { if($th === 'PRODUCT' || $th === 'VARIETY'){ $body .= '<td style="border: 1px solid black;font-size:12px;">'.$item[$th].'</td>'; }else{ $body .= '<td style="border: 1px solid black; text-align:right;font-size:12px;">'.number_format($item[$th]).'</td>'; } } } $body .= '</tr>'; $product = $item['PRODUCT']; } } $body .= '</tbody>'; $body .= '<tfoot>'; $body .= '<tr>'; $body .= '<th style="border: 1px solid black;text-align:left;">TOTAL GENERAL</th>'; $body .= '<th style="border: 1px solid black;"></th>'; for ($i=0; $i < count($arrayFinal) ; $i++) { $body .= '<th style="border: 1px solid black;text-align:right;">'.number_format($arrayFinal[$i]).'</th>'; } $body .= '</tr>'; $body .= '</tfoot>'; $body .= '</table>'; echo $body; 指针变量只会造成不必要的复杂性。只需使用__device__的普通动态分配进行设备存储,否则请遵循类似于任何CUDA示例代码(如vectorAdd)的方法。这是一个例子:

cudaMalloc

您所展示的内容中存在各种其他基本(非CUDA)编码错误,我不会尝试全部贯穿它们。

如果你真的想保留你的$ cat t1315.cu #include <stdio.h> #define A_LARGE_NUMBER 10 struct values{ int one, two, three; }; values *vals; __global__ void myKernel(values *d_vals){ printf("%d\n", d_vals[0].one); } void PopulateWithData(){ for (int i = 0; i < A_LARGE_NUMBER; i++){ vals[i].one = 1; vals[i].two = 2; vals[i].three = 3; } } int main(){ vals = (values*)malloc(sizeof(values) * A_LARGE_NUMBER); PopulateWithData(); //populates vals with random data values* d_ptr; cudaMalloc((void**)&d_ptr, A_LARGE_NUMBER * sizeof(values)); cudaMemcpy(d_ptr, vals, A_LARGE_NUMBER *sizeof(values),cudaMemcpyHostToDevice); dim3 blocksPerGrid(1,1); dim3 threadsPerBlock(1, 1); myKernel<< <blocksPerGrid, threadsPerBlock >> >(d_ptr); cudaDeviceSynchronize(); } $ nvcc -arch=sm_35 -o t1315 t1315.cu $ cuda-memcheck ./t1315 ========= CUDA-MEMCHECK 1 ========= ERROR SUMMARY: 0 errors $ 指针变量,并使用它来指向设备数据(结构数组),那么你仍然需要使用__device__,整个过程需要额外的步骤。您可以按照答案here中的示例进行操作。

在该示例之后,以下是对上述代码的一组更改,以使其与cudaMalloc指针变量一起使用,而不是作为内核参数传递的指针:

__device__