gpt4 book ai didi

java - 是否可以从 JCuda 将数据发送到定义为 Union 的 GPU 内存?

转载 作者:行者123 更新时间:2023-12-03 18:32:56 30 4
gpt4 key购买 nike

我在 GPU 端(cuda)定义了一个新的数据类型:

typedef union {
int i;
double d;
long l;
char s[16];
} data_unit;

data_unit *d_array;

而在 Java 中,我们有一个数组,其中一种数组在定义的联合中可用。通常,如果我们有一个 int 类型的数组,例如,我们可以在 Java (JCuda) 中执行以下操作:

import static jcuda.driver.JCudaDriver.*;


int data_size;
CUdeviceptr d_array;
int[] h_array = new int[data_size];

cuMemAlloc(d_array, data_size * Sizeof.INT);
cuMemcpyHtoD(d_array, Pointer.to(h_array), data_size * Sizeof.INT);

但是如果device上有一个数组类型是我们的union怎么办呢? (假设h_array还是int类型)

int data_size;
CUdeviceptr d_array;
int[] h_array = new int[data_size];

cuMemAlloc(d_array, data_size * Sizeof.?);
// Here we should have some type of alignment (?)
cuMemcpyHtoD(d_array, Pointer.to(h_array), data_size * Sizeof.?);

最佳答案

我认为对于什么是工会存在根本性的误解。

让我们考虑一下。联合与结构有何不同?它可以在不同的时间存储不同类型的数据。

它是如何实现这一壮举的?好吧,可以使用某种单独的变量来动态指定类型或占用多少内存,但是 Union 不会这样做,它依赖于程序员确切地知道他们想要检索什么类型以及何时检索。因此,如果类型只是在任何给定时间点真正为程序员所知,那么唯一的选择就是确保为联合变量分配了足够的空间,以便人们始终可以将其用于任何类型。

确实,这就是工会的作用,请参阅 here (是的,我知道它是 C/C++,但这也适用于 CUDA)。这对你意味着什么?这意味着联合数组的大小应该是其最大成员的大小 x 元素数,因为联合的大小是其最大成员的大小。

让我们看看您的工会,看看如何解决这个问题。

typedef union {
int i;
double d;
long l;
char s[16];
} data_unit;

您的工会有:

  • int i,我们假设它是 4 个字节
  • double d,即8字节
  • long l,这令人困惑,因为根据编译器/平台的不同,可以是 4 字节或 8 字节,我们现在假设为 8 字节。
  • char s[16],简单,16 字节

因此任何成员占用的最大字节数是您的char s[16] 变量,16 个字节。这意味着您需要将代码更改为:

int data_size;
int union_size = 16;
CUdeviceptr d_array;
// copying this to the device will not result in what you expect with out over allocating
// if you just copy over integers, which occupy 4 bytes each, your integers will fill less space than the number of unions
// we need to make sure that there is a "stride" here if we want to actually copy real data from host to device.
// union_size / Sizeof.INT = 4, so there will be 4 x as many ints, 4 for each union.
int[] h_array = new int[data_size * (union_size / Sizeof.INT)];


// here we aren't looking for size of int to allocate, but the size of our union.
cuMemAlloc(d_array, data_size * union_size);
// we are copying, again, data_size * union_size bytes
cuMemcpyHtoD(d_array, Pointer.to(h_array), data_size * union_size);

注意

如果您想复制整数,这基本上意味着您需要将每第 4 个整数分配给您想要用于该索引的实际整数。

int 0 是h_array[0],int 1 是h_array[4] int 2 是h_array[8] int n 是h_array[n * 4] 等..

关于java - 是否可以从 JCuda 将数据发送到定义为 Union 的 GPU 内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56757118/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com