f# - 简单示例中的 FSCL 错误

标签 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 求和的函数,但如果我调用第二个函数,它会引发与使用结构相同的错误。

最佳答案

尝试添加 [<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  

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

关于f# - 简单示例中的 FSCL 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38633301/

相关文章:

f# - Newtonsoft Converter FromJson - 意外标记

c# - 您可以在一个项目中混合使用 .net 语言吗?

c# - 从 C# 代码内部访问 F# 映射

Linux 上的 OpenCL 编译

visual-studio-2010 - 如何在 Visual Studio 2010 中更改 F# 交互式 shell 的颜色

winforms - F# 脚本执行后立即结束 (FSI)

recursion - F# - 在运行时创建递归可区分联合

linux - 是否有适用于 Linux 的 32 位版本的 OpenCL(任何供应商)?

OpenCL 工作项和工作组

f# - 如果列表为空,如何修复 List.head 中的异常 hell