Nvidia не разрешает доступ к сгенерированному LLVM IR в потоке компиляции ядра графического процессора, написанного на CUDA C/C++. Я хотел бы знать, возможно ли это, если я использую Alea GPU? Другими словами, позволяет ли процедура компиляции Alea GPU сохранить сгенерированный оптимизированный/неоптимизированный код LLVM IR?
Позволяет ли Alea GPU сохранять IR-код LLVM в цепочке компиляции?
Ответы (1)
Да, вы правы, Nvidia не показывает вам LLVM IR, вы можете получить только код PTX. В то время как Alea GPU позволяет получить доступ к LLVM IR несколькими способами:
Способ 1
Вы используете метод на основе рабочего процесса для кодирования модуля GPU как шаблон, затем вы компилируете шаблон в ИК-модуль LLVM, затем связываете LLVM IRModule, возможно, с некоторыми другими ИК-модулями, в модуль 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(...)
Способ 2
Если вы используете на основе метода или На основе экземпляра способ кодирования модуля GPU, вы можете добавить обработчик событий для кода LLVM IR генерируется, а PTX генерируется, хотя Alea.CUDA.Events
. Код на 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
Наконец, есть недокументированный способ, позволяющий вам напрямую работать с IR-кодом LLVM для построения функций. Это делается с помощью атрибута, реализующего некий интерфейс построения IR. Вот простой пример, который принимает параметр, печатает его (во время компиляции) и возвращает обратно:
[<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"