F# GPU.

. CUDA NVIDIA. , , Alea.cuBase Quantalea. - F Sharp. , Microsoft Visual Studio 2012.
, , . -, . . - , , , 10000 5000 . . Jpg , e, , , , . . CPU, GPU , CPU. , , , c. .
1. .
, :

1. NVIDIA, CUDA.
2. .
3. Alea.cuBase Quantalea.
4. . Visual Studio 2012 Windows 7.

2. CPU.
, . readImageBytes(), ( ):

1. Bitmap .
2. Rectangle .
3. Bitmap.
4. .
6. imageBytes.
7. bitmapData imageBytes.

, , GPU. updateImageCPU(), . :

1. imageBytes bitmapData
2. .
3. .
4. .

, GPU.
Code
// 25.05.2014 JPG .
// .
// F#, CUDA NVIDIA Alea.cuBase Quantalea.

open System
open System.IO
open System.Drawing
open System.Drawing.Imaging
open System.Runtime.InteropServices
open Microsoft.FSharp.Quotations
open Alea.CUDA
open Alea.CUDA.Utilities

//
let fileNameImage= @"Test.jpg"
//
let outFileNameImage= @"Test_out.jpg"
//
let original= 128
//
let amount= 3

// GPU
let pfunct = cuda {
let! kernel =
<@ fun n (x:deviceptr<byte>)
(z:deviceptr<byte>) ->
let start = blockIdx.x * blockDim.x + threadIdx.x
let stride = gridDim.x * blockDim.x
let mutable i = start
while i < n do
// original = 128, amount = 3
z.[i]<- if x.[i] <= 85uy then 0uy elif x.[i] > 170uy then 255uy else128uy + (x.[i] - 128uy) * 3uy
i <- i + stride @>
|> Compiler.DefineKernel

let divUp num den = (num + den - 1) / den

// GPU
return Entry(fun program ->
let worker = program.Worker
let kernel = program.Apply kernel

// run
let run (x:byte[])=
let n = x.Length
use x = worker.Malloc(x)
use output = worker.Malloc(n)

//
let blockSize = 128
let numSm = worker.Device.Attributes.MULTIPROCESSOR_COUNT
let gridSize = min (numSm * 16) (divup n blockSize)
//let lp = LaunchParam(gridSize, blockSize)
let lp = LaunchParam(1024, 512)

// GPU
use start = worker.CreateEvent()
use stop = worker.CreateEvent()
worker.Synchronize()
start.Record()

// GPU
kernel.Launch lp n x.Ptr output.Ptr

//
stop.Record()
stop.Synchronize()
let msec = Event.ElapsedMilliseconds(start, stop)
//
let output = output.Gather()
output, msec
run) }

//
let readImageBytes() =
// Bitmap
let image = new Bitmap(fileNameImage)
//
let rect=new Rectangle(0,0, image.Width,image.Height)
//
let bitmapData=image.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb)
// image
let all_Bytes = Math.Abs(bitmapData.Stride) * bitmapData.Height
// imageBytes
let imgBytes:byte[] = Array.zeroCreate<byte> all_Bytes
// imageBytes
let copy() = Marshal.Copy(bitmapData.Scan0, imgBytes, 0, all_Bytes)
copy()
imgBytes, image, bitmapData, all_Bytes

// jpg GPU
let updateImageGPU() =
use program = pfunct |> Compiler.load Worker.Default
let calc =
// GPU
let watchGPU = System.Diagnostics.Stopwatch.StartNew()
// jpg
let imageBytes, image, bitmapData, all_Bytes= readImageBytes()
//
let gpuResults, gpuTime = program.Run imageBytes
//
printfn "GPU %10.6f ms"gpuTime
// , gpuResults bitmapData
Marshal.Copy(gpuResults, 0, bitmapData.Scan0, all_Bytes)
//
image.UnlockBits(bitmapData)
//
image.Save(outFileNameImage, Imaging.ImageFormat.Jpeg)
//
printfn "GPU %10.6f ms"watchGPU.Elapsed.TotalMilliseconds
calc

// jpg CPU
let updateImageCPU() =
// CPU
let watchCPU = System.Diagnostics.Stopwatch.StartNew()
// jpg
let imageBytes, image, bitmapData, all_Bytes= readImageBytes()

//
let setupBrightness() =
// CPU
let watchImg = System.Diagnostics.Stopwatch.StartNew()
for y = 0 to image.Height - 1 do
for x = 0 to image.Width - 1 do
//
let i =y * bitmapData.Stride + x * 4
// blue
let tempColor=original + (int imageBytes.[i] - original) * amount
let blue= if tempColor < 0 then0elseif tempColor > 255 then 255 else tempColor
imageBytes.[i]<-byte blue
//green
let tempColor=original + (int imageBytes.[i + 1] - original) * amount
let green= if tempColor < 0 then0elseif tempColor > 255 then 255 else tempColor
imageBytes.[i + 1]<-byte green
//red
let tempColor=original + (int imageBytes.[i + 2] - original) * amount
let red= if tempColor < 0 then0elseif tempColor > 255 then 255 else tempColor
imageBytes.[i + 2]<-byte red
// alpha
imageBytes.[i + 3] <- imageBytes.[i + 3]
//
watchImg.Stop()
// CPU
printfn "(CPU %10.6f ms)" watchImg.Elapsed.TotalMilliseconds

// 蠠
setupBrightness()
// , ImageBytes bitmapData
Marshal.Copy(imageBytes, 0, bitmapData.Scan0, all_Bytes)
//
image.UnlockBits(bitmapData)
//
image.Save(outFileNameImage, Imaging.ImageFormat.Jpeg)
//
watchCPU.Stop()
// CPU
printfn "(CPU %10.6f ms)" watchCPU.Elapsed.TotalMilliseconds

[<EntryPoint>]
let main argv =
updateImageCPU()
updateImageGPU()
System.Console.ReadKey() |> ignore
0
3. GPU.
Image, GPU :

1. pfunct.
2. updateImageGPU().
3. readImageBytes(), , , CPU GPU.

pfunct - Quantalea GPU. . GPU, , , , , - .
, GPU float.

updateImageGPU() - GPU. , , .
4. .
, , GPU CPU , . .
CPU GPU . , CPU , , . GPU (10000 x 5000 x 4) GPU, GPU CPU.
GPU , , , .

.
, .
25.05.2014 .

© Argument Ltd, 2017 ,  : 8-921-215-45-70,   e-mail