FSCL错误的简单示例

时间:2016-07-28 10:07:53

标签: f# opencl f#-interactive

我试图在F#上使用带有FSCL的openCL但是我得到了一些我不明白的错误

open FSCL.Compiler
open FSCL.Language
open FSCL.Runtime

open Microsoft.FSharp.Linq.RuntimeHelpers
open System.Runtime.InteropServices

[<StructLayout(LayoutKind.Sequential)>]
type gpu_point2 =
    struct
        val mutable x: float32
        val mutable y: float32
        new ( q ,w) = {x=q; y=w} 
    end  

[<ReflectedDefinition>]
let PointSum(a:gpu_point2,b:gpu_point2) =
     let sx =(a.x+b.x)
     let sy =(a.y+b.y)
     gpu_point2(sx,sy)       
[<ReflectedDefinition;Kernel>]
let Modgpu(b:float32[], c:float32[],wi:WorkItemInfo) =
    let gid = wi.GlobalID(0)
    let arp = Array.zeroCreate<gpu_point2> b.Length
    let newpoint = gpu_point2(b.[gid],c.[gid])
    arp.[gid] <- newpoint
    arp

[<ReflectedDefinition;Kernel>]
let ModSum(a:gpu_point2[],b:gpu_point2[],wi:WorkItemInfo) =
    let gid = wi.GlobalID(0)
    let cadd = Array.zeroCreate<gpu_point2> a.Length 
    let newsum = PointSum(a.[gid],b.[gid]) 
    cadd.[gid] <- newsum
    cadd

[<ReflectedDefinition;Kernel>]
let ModSum2(a:gpu_point2[],b:gpu_point2[],wi:WorkItemInfo) =
    let gid = wi.GlobalID(0)
    let cadd = Array.zeroCreate<gpu_point2> a.Length 
    let newsum = gpu_point2(a.[gid].x+b.[gid].x,a.[gid].y+b.[gid].y) 
    cadd.[gid] <- newsum
    cadd

let ws = WorkSize(64L)
let arr_s1= <@ Modgpu([|0.f..63.f|],[|63.f..(-1.f)..0.f|],ws)@>.Run()
let arr_s2 = <@ Modgpu([|63.f..(-1.f)..0.f|],[|0.f..63.f|],ws)@>.Run()

当我尝试将ModSum用作

时使用此代码
let rsum = <@ ModSum(arr_s1,arr_s2,ws)@>.Run()

不起作用,相反,当我使用ModSum2时效果很好

let rsum = <@ ModSum2(arr_s1,arr_s2,ws)@>.Run()

我第一次运行时获得的错误是
   FSCL.Compiler.CompilerException:内核体NewObject(gpu_point2,sx,sy)中无法识别的构造
如果我重新运行fsi控制台说 System.NullReferenceException:未将对象引用设置为对象的实例。

我唯一知道的是错误不是来自另一个函数的使用,因为我可以定义一个有效的点积函数。

[<ReflectedDefinition>]
let PointProd(a:gpu_point2,b:gpu_point2) = 
    let f = (a.x*b.x)
    let s = (a.y*b.y)
    f+s 

因此,我猜问题来自 PointSum 的返回类型,但有没有办法创建这样一个函数来求和两个点并返回点类型?为什么不工作?

修改/更新
如果我将类型定义为:

,也会发生相同的记录
[<StructLayout(LayoutKind.Sequential)>]
type gpu_point_2 = {x:float32; y:float32} 

如果我尝试创建一个直接求和函数上的两个gpu_point_2的函数,但是如果我调用第二个函数,它会引发与使用结构相同的错误。

1 个答案:

答案 0 :(得分:0)

尝试在[<ReflectedDefinition>]的构造函数中添加gpu_point2

[<StructLayout(LayoutKind.Sequential)>]
type gpu_point2 =
    struct
        val mutable x: float32
        val mutable y: float32
        [<ReflectedDefinition>] new (q, w) = {x=q; y=w} 
    end  

通常,从设备调用的每个代码都需要此属性,包括构造函数。