当前位置: 首页 > 面试题库 >

为什么我不能用numba(cuda python)获得1D数组的正确和?

谭桐
2023-03-14
问题内容

我试着用cuda python和numba。代码是计算1D的和数组,但我不知道如何得到一个值结果而不是
三个价值观。python3.5和Nuba+CUDA8.0

import os,sys,time
import pandas as pd
import numpy as np
from numba import cuda, float32

os.environ['NUMBAPRO_NVVM']=r'D:\NVIDIA GPU Computing Toolkit\CUDA\v8.0\nvvm\bin\nvvm64_31_0.dll'
os.environ['NUMBAPRO_LIBDEVICE']=r'D:\NVIDIA GPU Computing Toolkit\CUDA\v8.0\nvvm\libdevice'

bpg = (1,1) 
tpb = (1,3)

@cuda.jit
def calcu_sum(D,T):
    ty = cuda.threadIdx.y
    bh = cuda.blockDim.y
    index_i = ty
    L = len(D)
    su = 0
    while index_i<L:
        su +=D[index_i]
        index_i +=bh
    print('su:',su)
    T[0,0]=su
    print('T:',T[0,0])


D = np.array([ 0.42487645,0.41607881,0.42027071,0.43751907,0.43512794,0.43656972,
               0.43940639,0.43864551,0.43447691,0.43120232], dtype=np.float32)
T = np.empty([1,1])
print('D: ',D)

stream = cuda.stream()
with stream.auto_synchronize():
    dD = cuda.to_device(D, stream)
    dT= cuda.to_device(TE, stream)
    calcu_sum[bpg, tpb, stream](dD,dT)

The output is:

D:  [ 0.42487645  0.41607881  0.42027071  0.43751907  0.43512794  0.43656972
  0.43940639  0.43864551  0.43447691  0.43120232]
su:  1.733004
su:  1.289852
su:  1.291317
T: 1.733004
T: 1.289852
T: 1.291317

为什么我不能得到输出“4.31417383”而不是“1.733004 1.289852”
1.291317” ? 1.733004+1.289852+1.291317=4.314173.
我是新来的麻木,阅读麻木文件,但不知道怎么做。
有人能给点建议吗?


问题答案:

你没有得到你所期望的总数是因为你没有写信
代码生成那个总和。
基本的CUDA编程模型(无论您是使用cudac、Fortran还是Python作为
你的语言)是你编写内核代码,由每个线程执行。
您已经为每个线程编写了代码来读取和求和输入数组的一部分。
您还没有为这些线程编写任何代码来共享和求和它们的
个别部分和变成最终和。
有一个非常好的算法来实现这一点——它是
称为平行还原。您可以在中找到该算法的介绍
在CUDA工具包的每个版本的示例中提供的PDF,或
下载相关演示文稿
这里.
你也可以阅读一个更现代版本的算法,它使用了更新的
CUDA的特点(warp-shuffle指令和原子事务)
[这里](https://devblogs.nvidia.com/parallelforall/faster-parallel-reductions-
开普勒/)。
在学习了约简算法之后,您将需要调整
将标准cudac内核代码转换成Numba Python内核方言。光秃秃的
最低限度,类似这样:

tpb = (1,3)

@cuda.jit
def calcu_sum(D,T):

    ty = cuda.threadIdx.y
    bh = cuda.blockDim.y
    index_i = ty
    sbuf = cuda.shared.array(tpb, float32)

    L = len(D)
    su = 0
    while index_i < L:
        su += D[index_i]
        index_i +=bh

    print('su:',su)

    sbuf[0,ty] = su
    cuda.syncthreads()

    if ty == 0:
        T[0,0] = 0
        for i in range(0, bh):
            T[0,0] += sbuf[0,i]
        print('T:',T[0,0])

可能会做你想做的事,尽管离成功还有很长的路要走
最佳的并行共享内存减少,当您阅读
我提供链接的材料。



 类似资料:
  • 问题内容: 我尝试将numa与cuda python配合使用。代码是按如下方法计算一维数组的总和,但我不知道如何获得一个值而不是三个值。 带有numba + CUDA8.0的python3.5 输出为: 为什么我无法获得输出“ 4.31417383”而不是“ 1.733004 1.289852 1.291317”?1.733004 + 1.289852 + 1.291317 = 4.314173。

  • 但是,正确的数据条目在被调用时会打印出来。我试着在网上寻找我应该做什么的答案,但我找不到任何实际可行的东西。我刚刚开始学习Java,所以可能有一个非常简单的答案,我只是忽略了。如果有人有什么想法,我将不胜感激。

  • 问题内容: 我尝试运行如下代码: 我认为的形状应为(1,3)而不是(3,)。 矩阵返回的结果应为: 数组([[23],[53],[83]]) 不 数组([23,53,83]) 为什么会发生结果? 问题答案: 顾名思义,该函数的主要目的是通过在两个形状相同的数组上执行 传统的线性代数点积 来提供标量结果。 鉴于这一主要目的,在文档中也对这种情况下的第一(第一子弹下方点)谈到: 您的案件已在他的评论的

  • 问题内容: 我正在创建一个小型Java Jpanel游戏,其中应该有一个火箭,它通过箭头上下移动,并通过太空射击。 触发方法应按以下方式工作:按下空格键,东西触发并在屏幕上移动,然后当它碰到某个x时,它就会消失。此外,您只能发射一次,直到另一颗子弹消失为止。 我不知道我在做什么错。首先,在我的代码启动后,您会看到子弹在屏幕上飞舞。 2,子弹没有消失。 第三,即使其他子弹仍然可见,它也允许我再次开火

  • 我正在尝试限制关键字输入。 每当用户输入一个关键字,它就会在该关键字后面加上'span',例如。 如下面的html代码。 我可以限制字,但计数不准确,但当它达到5,它停止输入。 如果我刷新页面,我可以再输入一个,然后再阻止我一次。 奇怪的是,如果我为使用id就不起作用了。我得利用课堂。 我试过把,但不起作用,我必须保留它的资本。 jQuery: HTML:

  • 基本上,我试图用一个名为“a”的变量设置数组的长度,并将其声明为3和int。当我试图用for循环查看所有元素时,我不会将“null”作为元素。到现在为止,一直都还不错。然而,当有人想向该数组中添加一个元素时,我会向提到的变量“a”中添加1,从而延长该数组的长度,并允许我向该数组中再添加一个元素。但它不起作用。以下是代码: }