Skip to content

Commit 548a5c8

Browse files
committed
First version of streaming
1 parent 76d2509 commit 548a5c8

File tree

5 files changed

+81
-12
lines changed

5 files changed

+81
-12
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,3 +266,5 @@ coverage.*.xml
266266
# Paket tool store
267267
.paket/.store
268268
.paket/paket
269+
270+
out/

src/ImageProcessing/ImageProcessing.fs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ open Brahma.FSharp
44
open SixLabors.ImageSharp
55
open SixLabors.ImageSharp.PixelFormats
66

7-
8-
9-
107
let loadAs2DArray (file:string) =
118
let img = Image.Load<L8> file
129
let res = Array2D.zeroCreate img.Height img.Width
@@ -117,18 +114,24 @@ let applyFiltersGPU (clContext: ClContext) localWorkSize =
117114
|]
118115
let clImage = clContext.CreateClArray<_> img
119116

120-
let mutable res = Unchecked.defaultof<_>
117+
let mutable res = None
121118

122119
for filter in filters do
123120
let filter = Array.concat filter
124121
let filterD = (Array.length filter) / 2
125122
let clFilter = clContext.CreateClArray<_> filter
126-
res <- kernel queue clFilter filterD clImage imgH imgW
123+
match res with
124+
| None ->
125+
res <- Some (kernel queue clFilter filterD clImage imgH imgW)
126+
| Some img ->
127+
res <- Some (kernel queue clFilter filterD img imgH imgW)
128+
queue.Post(Msg.CreateFreeMsg img)
127129
queue.Post(Msg.CreateFreeMsg clFilter)
128130

129131
let result' = Array.zeroCreate (imgH * imgW)
130-
let result' = queue.PostAndReply(fun ch -> Msg.CreateToHostMsg(res, result', ch))
132+
let result' = queue.PostAndReply(fun ch -> Msg.CreateToHostMsg(res.Value, result', ch))
131133
let result = Array2D.zeroCreate imgH imgW
132134
Array.Parallel.iteri (fun x v -> result.[x / imgW, x % imgW] <- v) result'
133-
clImage.Dispose()
135+
queue.Post(Msg.CreateFreeMsg clImage)
136+
queue.Post(Msg.CreateFreeMsg res.Value)
134137
result

src/ImageProcessing/ImageProcessing.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<Compile Include="AssemblyInfo.fs" />
1919
<None Include="App.config" />
2020
<Compile Include="ImageProcessing.fs" />
21+
<Compile Include="Streaming.fs" />
2122
<Compile Include="Main.fs" />
2223
</ItemGroup>
2324
<ItemGroup>

src/ImageProcessing/Main.fs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@ module Main =
88
let demoFile = System.IO.Path.Combine(inputFolder, "armin-djuhic-ohc29QXbS-s-unsplash.jpg")
99
[<EntryPoint>]
1010
let main (argv: string array) =
11-
let device = ClDevice.GetFirstAppropriateDevice()
11+
let device =
12+
//ClDevice.GetAvailableDevices(platform=Platform.Nvidia) |> Seq.head
13+
ClDevice.GetFirstAppropriateDevice()
1214
printfn $"Device: %A{device.Name}"
1315

1416
let context = ClContext(device)
15-
let applyFiltersGPU = ImageProcessing.applyFiltersGPU context 32
17+
let applyFiltersGPU = ImageProcessing.applyFiltersGPU context 64
1618

17-
let grayscaleImage = ImageProcessing.loadAs2DArray demoFile
19+
//let grayscaleImage = ImageProcessing.loadAs2DArray demoFile
1820
//let blur = ImageProcessing.applyFilter ImageProcessing.gaussianBlurKernel grayscaleImage
1921
//let edges = ImageProcessing.applyFilter ImageProcessing.edgesKernel blur
20-
let edges = applyFiltersGPU [ImageProcessing.gaussianBlurKernel; ImageProcessing.edgesKernel] grayscaleImage
21-
ImageProcessing.save2DByteArrayAsImage edges "../../../../../out/demo_grayscale.jpg"
22+
//let edges = applyFiltersGPU [ImageProcessing.gaussianBlurKernel; ImageProcessing.edgesKernel] grayscaleImage
23+
//ImageProcessing.save2DByteArrayAsImage edges "../../../../../out/demo_grayscale.jpg"
24+
Streaming.processAllFiles inputFolder "../../../../../out/" (applyFiltersGPU [ImageProcessing.gaussianBlurKernel;ImageProcessing.gaussianBlurKernel;ImageProcessing.edgesKernel])
2225
0

src/ImageProcessing/Streaming.fs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
module ImageProcessing.Streaming
2+
3+
let listAllFiles dir =
4+
let files = System.IO.Directory.GetFiles dir
5+
List.ofArray files
6+
7+
type msg =
8+
| Img of string*byte[,]
9+
| EOS of AsyncReplyChannel<unit>
10+
11+
let imgSaver outDir =
12+
let outFile (fileFullPath:string) =
13+
System.IO.Path.Combine(outDir, System.IO.Path.GetFileName fileFullPath)
14+
15+
MailboxProcessor.Start(fun inbox ->
16+
let rec loop () =
17+
async{
18+
let! msg = inbox.Receive()
19+
match msg with
20+
| EOS ch ->
21+
printfn "Image saver is finished!"
22+
ch.Reply()
23+
| Img (file, img) ->
24+
printfn $"Save: %A{file}"
25+
ImageProcessing.save2DByteArrayAsImage img (outFile file)
26+
return! loop ()
27+
}
28+
loop ()
29+
)
30+
31+
let imgProcessor filterApplicator (imgSaver:MailboxProcessor<_>) =
32+
33+
let filter = filterApplicator
34+
35+
MailboxProcessor.Start(fun inbox ->
36+
let rec loop cnt =
37+
async{
38+
let! msg = inbox.Receive()
39+
match msg with
40+
| EOS ch ->
41+
printfn "Image processor is ready to finish!"
42+
imgSaver.PostAndReply EOS
43+
printfn "Image processor is finished!"
44+
ch.Reply()
45+
| Img (file,img) ->
46+
printfn $"Filter: %A{file}"
47+
let filtered = filter img
48+
imgSaver.Post (Img (file,filtered))
49+
return! loop (not cnt)
50+
}
51+
loop true
52+
)
53+
54+
let processAllFiles inDir outDir filterApplicator =
55+
let imgSaver = imgSaver outDir
56+
let imgProcessor = imgProcessor filterApplicator imgSaver
57+
let filesToProcess = listAllFiles inDir
58+
for file in filesToProcess do
59+
imgProcessor.Post <| Img(file, ImageProcessing.loadAs2DArray file)
60+
imgProcessor.PostAndReply EOS

0 commit comments

Comments
 (0)