1

我有签名双[] []的数组a和b。

我想在我的内核中比较这些数组的孩子(它们的长度相同)。

目前我得到一个错误

use data = this.GPUWorker.MallocArray(data)

叫做。

抛出异常:Alea.CUDA.dll 中的“System.Exception”附加信息:主机数组零拷贝绑定是非公共功能。

我看不到我是如何错误地使用 MallocArray 函数的?

let inline (?+) a b = ((b - a) / a) * 100.0

let inline change a b = 
    let a = a |> Array.reduce (+)
    let b = b |> Array.reduce (+)
    if a > 0.0 && b > 0.0 && (?+) a b >= 5.0 then a else 0.0

type GPU<'T>(target, op : Expr<'T[] -> 'T[] -> 'T>) = 
    inherit ILGPUModule(target)

    new(target, op : Func<'T[], 'T[], 'T>) = 
        new GPU<'T>(target, <@ fun x y -> op.Invoke(x, y) @>)

    [<Kernel;ReflectedDefinition>]
    member this.Kernel (n : int) (input : deviceptr<'T[]>) (input2 : deviceptr<'T[]>) (output : deviceptr<'T>) = 

        let start = blockIdx.x * blockDim.x + threadIdx.x
        let stride = gridDim.x * blockDim.x
        let mutable i = start

        // TODO this is the actual logic.
        while i < n do
            let a = input.[i]
            let b = input2.[i]
            output.[i] <- __eval(op) a b
            i <- i + stride

    member this.Apply(n : int, input : deviceptr<'T[]>, input2 : deviceptr<'T[]>, output : deviceptr<'T>) = 
        let numSm = this.GPUWorker.Device.Attributes.MULTIPROCESSOR_COUNT
        let blockSize = 256
        let gridSize = min (16 * numSm) (divup n blockSize)
        let lp = LaunchParam(gridSize, blockSize)
        this.GPULaunch <@ this.Kernel @> lp n input input2 output

    /// Takes in generic array to be used by GPU.
    // May need modification to support other input parameters.
    member this.Apply(data : 'T[][], pattern : 'T[][]) = 

        // Allocate GPU memory for the data sets.
        use data = this.GPUWorker.MallocArray(data)
        use pattern = this.GPUWorker.MallocArray(pattern)

        // Output length is likely to match the number of elements in the input array.
        use output = this.GPUWorker.Malloc(data.Length)

        // Execute GPU compuation. 
        this.Apply(data.Length, data.Ptr, pattern.Ptr, output.Ptr)

        // Copy data from GPU to CPU memory.
        output.Gather()

[<AOTCompile>]
type GPUModule(target) = 
    inherit GPU<double>(target, fun a b -> change a b)
    static let instance = lazy new GPUModule(GPUModuleTarget.DefaultWorker)
    static member DefaultInstance = instance.Value
4

1 回答 1

1

在版本 2 中,您不能使用锯齿状数组,因为锯齿状数组本身不是 blittable。我们将在下一个版本中支持它。

我认为目前您有两种选择:

  1. 如果你的锯齿数组的维度是已知的,你可以把它变成一个线性数组,并做一些索引计算。

  2. 您必须分别分配内部数组,并将它们的指针填充到外部数组,例如:

代码:

let innerDMems = jaggedHostArray |> Array.map (fun array -> worker.Malloc array)
use outterDMem = worker.Malloc(innerDMems |> Array.map (fun dmem -> dmem.Ptr))        
....
//launch kernel with outterDMem.Ptr which is deviceptr<deviceptr<T>>
....
innerDMems |> Array.iter (fun dmem -> dmem.Dispose())

然后你的签名是deviceptr<deviceptr<T>>,就像在 C 语言中一样T**

于 2015-11-10T09:05:31.590 回答