假设我有一个结构如下:
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 >> >();
}
答案 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__