Parallel processing 块读取不同长度的序列gpu

Parallel processing 块读取不同长度的序列gpu,parallel-processing,cuda,gpu,nvidia,gpgpu,Parallel Processing,Cuda,Gpu,Nvidia,Gpgpu,我有一个数组,它有不同长度的序列,每个序列以'>'结尾。 顺序=[a,b,f,g,c,d,>,b,g,d,>…]。我计算了每个序列的长度,并将其存储在一个名为seq_length=[6,3,5,…]的不同数组中。然后,我使用独占扫描来计算偏移量,并将其存储在一个名为offset=[0,6,9,…]的数组中 我想要的是让每个块使用偏移量值从数组seq[]读取一个序列。例如,块0读取从seq[0]开始并在长度=6时停止的序列,块1读取从seq[6]开始并在长度=3时停止的序列,依此类推。 我怎么能在

我有一个数组,它有不同长度的序列,每个序列以'>'结尾。 顺序=[a,b,f,g,c,d,>,b,g,d,>…]。我计算了每个序列的长度,并将其存储在一个名为seq_length=[6,3,5,…]的不同数组中。然后,我使用独占扫描来计算偏移量,并将其存储在一个名为offset=[0,6,9,…]的数组中

我想要的是让每个块使用偏移量值从数组seq[]读取一个序列。例如,块0读取从seq[0]开始并在长度=6时停止的序列,块1读取从seq[6]开始并在长度=3时停止的序列,依此类推。 我怎么能在CUDA做到这一点??如何让每个块从不同的第I个数组条目(array seq[])读取数据

提前感谢:)

CUDA有类似的
threadIdx.x
blockIdx.x
来标识块中的每个线程,以及该线程所在的块。块中的每个线程将具有相同的
blockIdx.x
值,但块中的每个线程将具有不同的/唯一的(每个块)
threadIdx.x

因此,我们可以使用
blockIdx.x
为每个块选择特定的序列。此变量可用于选择正确的序列长度以及每个序列/块的偏移量

我们可以为每个序列项/字符为每个块分配一个线程。我们可以使用
threadIdx.x
为每个线程确定它应该选择哪个序列成员

下面是一个充分发挥作用的示例:

$ cat t405.cu
#include <stdio.h>

__global__ void tk(char *seq, int *offsets, int *seq_lengths, int num_seq){

  if (blockIdx.x < num_seq)
   if (threadIdx.x < seq_lengths[blockIdx.x])
     printf("block: %d, thread: %d, seq: %c\n", blockIdx.x, threadIdx.x, seq[offsets[blockIdx.x]+threadIdx.x]);
}

int main(){

  char seq[] = {'a','b','f','g','c','d','>','b','g','d','>','a','b', 'c', 'd', 'e', '>'};
  int seq_length[] = { 6, 3, 5 };
  int offsets[] = { 0, 7, 11 };
  int num_seq = 3;

  int seq_sz   = sizeof(seq);
  int seq_l_sz = sizeof(seq_length);
  int off_sz   = sizeof(offsets);

  char *d_seq;
  int *d_seq_length, *d_offsets;
  cudaMalloc(&d_seq, seq_sz);
  cudaMalloc(&d_seq_length, seq_l_sz);
  cudaMalloc(&d_offsets, off_sz);

  cudaMemcpy(d_seq, seq, seq_sz, cudaMemcpyHostToDevice);
  cudaMemcpy(d_seq_length, seq_length, seq_l_sz, cudaMemcpyHostToDevice);
  cudaMemcpy(d_offsets, offsets, off_sz, cudaMemcpyHostToDevice);
  tk<<<num_seq, 1024>>>(d_seq, d_offsets, d_seq_length, num_seq);
  cudaDeviceSynchronize();
  cudaError_t err = cudaGetLastError();
  if (cudaSuccess != err) printf("cuda error: %s\n", cudaGetErrorString(err));
  return 0;
}

$ nvcc -arch=sm_61 -o t405 t405.cu
$ ./t405
block: 1, thread: 0, seq: b
block: 1, thread: 1, seq: g
block: 1, thread: 2, seq: d
block: 2, thread: 0, seq: a
block: 2, thread: 1, seq: b
block: 2, thread: 2, seq: c
block: 2, thread: 3, seq: d
block: 2, thread: 4, seq: e
block: 0, thread: 0, seq: a
block: 0, thread: 1, seq: b
block: 0, thread: 2, seq: f
block: 0, thread: 3, seq: g
block: 0, thread: 4, seq: c
block: 0, thread: 5, seq: d
$
$cat t405.cu
#包括
__全局无效tk(字符*顺序,整数*偏移,整数*顺序长度,整数数量顺序){
if(blockIdx.x','b','g','d','>','a','b','c','d','e','>'};
int seq_length[]={6,3,5};
int偏移量[]={0,7,11};
int num_seq=3;
int-seq_-sz=尺寸(seq);
int seq_l_sz=尺寸(seq_长度);
int off_sz=sizeof(偏移量);
char*d_seq;
int*d_seq_长度,*d_偏移量;
cudaMalloc(和d_seq,seq_sz);
Cudamaloc(长度和长度,长度和深度);
Cudamaloc(d_偏移量和d_sz偏移量);
cudaMemcpy(d_seq,seq,seq_sz,cudaMemcpyHostToDevice);
cudaMemcpy(d_seq_length,seq_length,seq_l_sz,cudaMemcpyHostToDevice);
cudaMemcpy(d_偏移,偏移,off_sz,cudamemcpyhostodevice);
tk(d_-seq,d_偏移,d_-seq长度,num_-seq);
cudaDeviceSynchronize();
cudaError_t err=cudaGetLastError();
如果(cudaSuccess!=err)printf(“cuda错误:%s\n”,cudaGetErrorString(err));
返回0;
}
$nvcc-arch=sm_61-o t405 t405.cu
美元/t405
块:1,螺纹:0,序号:b
块:1,螺纹:1,序号:g
块:1,螺纹:2,序号:d
块:2,螺纹:0,序号:a
块:2,螺纹:1,序号:b
块:2,螺纹:2,序号:c
块:2,螺纹:3,序号:d
块:2,螺纹:4,序号:e
块:0,线程:0,序列:a
块:0,螺纹:1,序号:b
块:0,螺纹:2,序号:f
块:0,螺纹:3,序号:g
块:0,螺纹:4,序号:c
块:0,螺纹:5,序号:d
$
如果您希望一个序列中包含1024个以上的字符,那么您可能需要修改上面的内容,或者让每个线程处理多个字符,或者在一个循环中