Alea GPU 是否允许在编译链中保留 LLVM IR 代码?
Does Alea GPU allow keeping LLVM IR code in the compilation chain?
Nvidia 不允许在用 CUDA C/C++ 编写的 GPU 内核的编译流程中访问生成的 LLVM IR。我想知道如果我使用 Alea GPU 是否可行?换句话说,Alea GPU 编译过程是否允许保留生成的 optimized/unoptimized LLVM IR 代码?
是的,你是对的,Nvidia 没有给你展示 LLVM IR,你只能得到 PTX 代码。虽然 Alea GPU 允许您以多种方式访问 LLVM IR:
方法一
你使用 workflow-based method 将 GPU 模块编码为模板,然后你将模板编译成 LLVM IR 模块,然后你 link LLVM IRModule,可选地与一些其他 IR 模块, 进入 PTX 模块。最后,将 PTX 模块加载到 GPU 工作器中。当您获得 LLVM IRModule 时,您可以调用其方法 Dump()
将 IR 代码打印到控制台。或者您可以获得位码 byte[]
.
我建议您在此处阅读更多详细信息:
F# 应该是这样的:
let template = cuda {
// define your kernel functions or other gpu moudle stuff
let! kernel = <@ fun .... @> |> Compiler.DefineKernel
// return an entry pointer for this module, something like the
// main() function for a C program
return Entry(fun program ->
let worker = program.Worker
let kernel = program.Apply kernel
let main() = ....
main ) }
let irModule = Compiler.Compile(template).IRModule
irModule.Dump() // dump the IR code
let ptxModule = Compiler.Link(irModule).PTXModule
ptxModule.Dump()
use program = worker.LoadProgram(ptxModule)
program.Run(...)
方法二
如果您使用 Method-based or Instance-based 方式对 GPU 模块进行编码,您可以为通过 Alea.CUDA.Events
生成的 LLVM IR 代码和生成的 PTX 添加事件处理程序。 F# 中的代码如下所示:
let desktopFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
let (@@) a b = Path.Combine(a, b)
Events.Instance.IRCode.Add(fun ircode ->
File.WriteAllBytes(desktopFolder @@ "module.ir", ircode))
Events.Instance.PTXCode.Add(fun ptxcode ->
File.WriteAllBytes(desktopFolder @@ "module.ptx", ptxcode))
使用LLVM代码扩展GPU功能
最后,还有一个未记录的方法,让你直接操作LLVM IR代码来构造函数。它是由实现一些 IR 构建接口的属性完成的。这是一个简单的例子,它接受参数,并打印它(在编译时),然后 return 它返回:
[<AttributeUsage(AttributeTargets.Method, AllowMultiple = false)>]
type IdentityAttribute() =
inherit Attribute()
interface ICustomCallBuilder with
member this.Build(ctx, irObject, info, irParams) =
match irObject, irParams with
| None, irParam :: [] ->
// the irParam is of type IRValue, which you
// can get the LLVM native handle, by irParam.LLVM
// Also, you can get the type by irParam.Type, which
// is of type IRType, again, you can get LLVMTypeRef
// handle by irParam.Type.LLVM
// You can optionally construct LLVM instructions here.
printfn "irParam: %A" irParam
Some irParam
| _ -> None
[<Identity>]
let identity(x:'T) : 'T = failwith "this is device function, better not call it from host"
Nvidia 不允许在用 CUDA C/C++ 编写的 GPU 内核的编译流程中访问生成的 LLVM IR。我想知道如果我使用 Alea GPU 是否可行?换句话说,Alea GPU 编译过程是否允许保留生成的 optimized/unoptimized LLVM IR 代码?
是的,你是对的,Nvidia 没有给你展示 LLVM IR,你只能得到 PTX 代码。虽然 Alea GPU 允许您以多种方式访问 LLVM IR:
方法一
你使用 workflow-based method 将 GPU 模块编码为模板,然后你将模板编译成 LLVM IR 模块,然后你 link LLVM IRModule,可选地与一些其他 IR 模块, 进入 PTX 模块。最后,将 PTX 模块加载到 GPU 工作器中。当您获得 LLVM IRModule 时,您可以调用其方法 Dump()
将 IR 代码打印到控制台。或者您可以获得位码 byte[]
.
我建议您在此处阅读更多详细信息:
F# 应该是这样的:
let template = cuda {
// define your kernel functions or other gpu moudle stuff
let! kernel = <@ fun .... @> |> Compiler.DefineKernel
// return an entry pointer for this module, something like the
// main() function for a C program
return Entry(fun program ->
let worker = program.Worker
let kernel = program.Apply kernel
let main() = ....
main ) }
let irModule = Compiler.Compile(template).IRModule
irModule.Dump() // dump the IR code
let ptxModule = Compiler.Link(irModule).PTXModule
ptxModule.Dump()
use program = worker.LoadProgram(ptxModule)
program.Run(...)
方法二
如果您使用 Method-based or Instance-based 方式对 GPU 模块进行编码,您可以为通过 Alea.CUDA.Events
生成的 LLVM IR 代码和生成的 PTX 添加事件处理程序。 F# 中的代码如下所示:
let desktopFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
let (@@) a b = Path.Combine(a, b)
Events.Instance.IRCode.Add(fun ircode ->
File.WriteAllBytes(desktopFolder @@ "module.ir", ircode))
Events.Instance.PTXCode.Add(fun ptxcode ->
File.WriteAllBytes(desktopFolder @@ "module.ptx", ptxcode))
使用LLVM代码扩展GPU功能
最后,还有一个未记录的方法,让你直接操作LLVM IR代码来构造函数。它是由实现一些 IR 构建接口的属性完成的。这是一个简单的例子,它接受参数,并打印它(在编译时),然后 return 它返回:
[<AttributeUsage(AttributeTargets.Method, AllowMultiple = false)>]
type IdentityAttribute() =
inherit Attribute()
interface ICustomCallBuilder with
member this.Build(ctx, irObject, info, irParams) =
match irObject, irParams with
| None, irParam :: [] ->
// the irParam is of type IRValue, which you
// can get the LLVM native handle, by irParam.LLVM
// Also, you can get the type by irParam.Type, which
// is of type IRType, again, you can get LLVMTypeRef
// handle by irParam.Type.LLVM
// You can optionally construct LLVM instructions here.
printfn "irParam: %A" irParam
Some irParam
| _ -> None
[<Identity>]
let identity(x:'T) : 'T = failwith "this is device function, better not call it from host"