Нужна консультация относительно библиотеки GPGPU - PullRequest
0 голосов
/ 12 января 2012

Я пишу приложение, и в итоге оно приходит к хорошо распараллеливаемой части:

two dimensional float initialData and result arrays
for each cell (a, b) in result array:
    for each cell (i, j) in initialData:
        result(a, b) += someComputation(initialData(i, j), a, b, i, j, some global data...);

Некоторые подробности об алгоритме:

  • Я бы хотел, чтобы итерации первого цикла выполнялись одновременно (возможно, есть лучший подход?)
  • Исходные данные доступны только для чтения.
  • someComputation довольно прост, оно включает в себя умножение, сложение, косинус-вычисления, поэтому оно может быть выполнено с помощью графического процессора, однако ему нужны индексы элементов, над которыми он в данный момент работает
  • Массивы не будут превышать ~ 4000 в любом измерении

Свойства библиотеки:

  • Программа будет написана на C # (с WPF), поэтому было бы неплохо, если бы она (уже) имела простые в использовании привязки .NET
  • Если GPU не найден, алгоритм должен работать на CPU
  • Программа будет доступна только для Windows, и поддержка Windows XP является наиболее предпочтительной.
  • Алгоритм может быть переписан в OpenCL, однако я считаю, что он не так широко поддерживается, как пиксельные шейдеры. Но, если нет альтернативы, OpenCL будет в порядке. (AFAIK CUDA работает только на графических процессорах nVidia, а OpenCL охватывает как графические процессоры nVidia, так и AMD)

Я пытался взглянуть на библиотеку Microsoft Accelerator, но я не нашел способа передать индексы массива. Любая помощь будет признательна и извините за мой английский.

1 Ответ

0 голосов
/ 25 января 2013

Есть низкоуровневые привязки OpenCL: OpenCL.NET: http://openclnet.codeplex.com/. Также существуют привязки на основе OpenCL.NET для F #: https://github.com/YaccConstructor/Brahma.FSharp

Это позволяет писатьродной "F # код и запустить его на GPU через OpenCL.Например, код для умножения матриц (без настройки провайдера):

//Code for run on GPU
let command = 
    <@
        fun (r:_2D) columns (a:array<_>) (b:array<_>) (c:array<_>) -> 
            let tx = r.GlobalID0
            let ty = r.GlobalID1
            let mutable buf = c.[ty * columns + tx]
            for k in 0 .. columns - 1 do
                buf <- buf + (a.[ty * columns + k] * b.[k * columns + tx])
            c.[ty * columns + tx] <- buf
    @>

//compile code and configure kernel
let kernel, kernelPrepare, kernelRun = provider.Compile command
let d =(new _2D(rows, columns, localWorkSize, localWorkSize))
kernelPrepare d columns aValues bValues cParallel
//run computations on GPU
let _ = commandQueue.Add(kernelRun()).Finish()            

//read result back
let _ = commandQueue.Add(cParallel.ToHost(kernel)).Finish()
...