diff --git a/App/App.fsproj b/App/App.fsproj
new file mode 100644
index 00000000..5a3c6972
--- /dev/null
+++ b/App/App.fsproj
@@ -0,0 +1,12 @@
+
+
+
+ Exe
+ net8.0
+
+
+
+
+
+
+
diff --git a/App/Program.fs b/App/Program.fs
new file mode 100644
index 00000000..87a889fa
--- /dev/null
+++ b/App/Program.fs
@@ -0,0 +1,25 @@
+open System.Threading.Tasks
+
+let height = 10
+let width = 20
+
+// Parallel.For(0, height * width, fun index ->
+// let i = index / width
+// let j = index % width
+
+// printfn "i: %d, j: %d, Thread: %d" i j System.Threading.Thread.CurrentThread.ManagedThreadId
+// ) |> ignore
+
+(*
+0 .. 10
+..
+20
+*)
+
+// for k in 0 .. 10 * 20 - 1 do
+// let i = k / 10
+// let j = k % 10
+// printfn "%d %d %d" k i j
+let a = 5 / 2
+
+printfn "%d" a
\ No newline at end of file
diff --git a/Benchmarks/ImageProcessingB/ImageProcessingB.fsproj b/Benchmarks/ImageProcessingB/ImageProcessingB.fsproj
new file mode 100644
index 00000000..956482e1
--- /dev/null
+++ b/Benchmarks/ImageProcessingB/ImageProcessingB.fsproj
@@ -0,0 +1,21 @@
+
+
+
+ Exe
+ net8.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Benchmarks/ImageProcessingB/Program.fs b/Benchmarks/ImageProcessingB/Program.fs
new file mode 100644
index 00000000..2fdaa4db
--- /dev/null
+++ b/Benchmarks/ImageProcessingB/Program.fs
@@ -0,0 +1,55 @@
+namespace ImageProcessingB
+
+open System
+open BenchmarkDotNet.Attributes
+open BenchmarkDotNet.Running
+open BenchmarkDotNet.Configs
+open BenchmarkDotNet.Reports
+open Perfolizer.Horology
+
+open ImageProcessing.ImProcessing
+open SixLabors.ImageSharp.PixelFormats
+
+type ipBenchmark() =
+
+ static member Sizes = [|2; 4|]
+ member this.Random = System.Random()
+
+ []
+ member val MatrixSize = 0 with get, set
+ member val MatrixToSort = Array2D.zeroCreate 1 1 with get, set
+
+ []
+ member this.GetArrayToSort () =
+ this.MatrixToSort <- Array2D.init this.MatrixSize this.MatrixSize (fun _ _ ->
+ let r = byte (this.Random.Next 256)
+ let g = byte (this.Random.Next 256)
+ let b = byte (this.Random.Next 256)
+ let a = byte (this.Random.Next 256)
+ Rgba32 (r, g, b, a)
+ )
+
+ []
+ member this.NoParallelism () = applyFilterNoParallelism gaussianBlur this.MatrixToSort
+
+ []
+ member this.PixelParallelism () = applyFilterPixelParallelism gaussianBlur this.MatrixToSort
+
+ []
+ member this.ParallelismInParts () = applyFilterParallelismInParts gaussianBlur this.MatrixToSort
+
+ []
+ member this.RowParallelism () = applyFilterRowParallelism gaussianBlur this.MatrixToSort
+
+ []
+ member this.ColParallelism () = applyFilterColParallelism gaussianBlur this.MatrixToSort
+
+
+module Main =
+ []
+ let main argv =
+ let benchmarks =
+ BenchmarkSwitcher [| typeof |]
+
+ benchmarks.Run argv |> ignore
+ 0
\ No newline at end of file
diff --git a/Benchmarks/Benchmarks.fsproj b/Benchmarks/SortingsB/Benchmarks.fsproj
similarity index 80%
rename from Benchmarks/Benchmarks.fsproj
rename to Benchmarks/SortingsB/Benchmarks.fsproj
index 5d5d8caf..eb948afd 100644
--- a/Benchmarks/Benchmarks.fsproj
+++ b/Benchmarks/SortingsB/Benchmarks.fsproj
@@ -1,20 +1,20 @@
-
-
-
- Exe
- net8.0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Exe
+ net8.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Benchmarks/Program.fs b/Benchmarks/SortingsB/Program.fs
similarity index 95%
rename from Benchmarks/Program.fs
rename to Benchmarks/SortingsB/Program.fs
index 34a08ad2..ecb872e3 100644
--- a/Benchmarks/Program.fs
+++ b/Benchmarks/SortingsB/Program.fs
@@ -1,76 +1,76 @@
-namespace Benchmarks
-
-open System
-open BenchmarkDotNet.Attributes
-open BenchmarkDotNet.Running
-open BenchmarkDotNet.Configs
-open BenchmarkDotNet.Reports
-open Perfolizer.Horology
-
-open ArraySorts
-open MyListSorts
-
-type ArraysBenchmark() =
-
- static member Lengths = [|10000..10000..100000|]
- member this.Random = System.Random()
-
- []
- member val ArrayLength = 0 with get, set
- member val ArrayToSort = [|0.0|] with get, set
-
- []
- member this.GetArrayToSort () =
- this.ArrayToSort <- Array.init this.ArrayLength (fun _ -> this.Random.NextDouble())
-
- []
- member this.ArrayQuickSort () = Arrays.quickSort this.ArrayToSort
-
- []
- member this.ArrayBubbleSort () = Arrays.bubbleSort this.ArrayToSort
-
- []
- member this.ArrayMergeSort () = Arrays.mergeSort this.ArrayToSort
-
- []
- member this.ArraySystem () = Array.Sort this.ArrayToSort
-
-
-type ListBenchmark() =
-
- static member Lengths = [|10000..10000..100000|]
- member this.Random = System.Random()
-
- []
- member val ListLength = 0 with get, set
- member val ListToSort = [0.0] with get, set
-
- []
- member this.GetListToSort () =
- this.ListToSort <- List.init this.ListLength (fun _ -> this.Random.NextDouble())
-
- []
- member this.MyListBubbleSort () = MyList.fromSystemList this.ListToSort |> MyList.quickSort
-
- []
- member this.MyListQuickSort () = MyList.fromSystemList this.ListToSort |> MyList.bubbleSort
-
- []
- member this.MyListMergeSort () = MyList.fromSystemList this.ListToSort |> MyList.mergeSort
-
- []
- member this.MyListSystem () = List.sort this.ListToSort
-
-
-module Main =
- []
- let main argv =
-
- let config = ManualConfig.Create(DefaultConfig.Instance)
- .WithSummaryStyle(SummaryStyle.Default.WithTimeUnit(TimeUnit.Millisecond))
- .WithOptions(ConfigOptions.DisableOptimizationsValidator)
- let benchmarks =
- BenchmarkSwitcher [| typeof; typeof|]
-
- benchmarks.Run argv |> ignore
- 0
+namespace SortingsB
+
+open System
+open BenchmarkDotNet.Attributes
+open BenchmarkDotNet.Running
+open BenchmarkDotNet.Configs
+open BenchmarkDotNet.Reports
+open Perfolizer.Horology
+
+open ArraySorts
+open MyListSorts
+
+type ArraysBenchmark() =
+
+ static member Lengths = [|10000..10000..100000|]
+ member this.Random = System.Random()
+
+ []
+ member val ArrayLength = 0 with get, set
+ member val ArrayToSort = [|0.0|] with get, set
+
+ []
+ member this.GetArrayToSort () =
+ this.ArrayToSort <- Array.init this.ArrayLength (fun _ -> this.Random.NextDouble())
+
+ []
+ member this.ArrayQuickSort () = Arrays.quickSort this.ArrayToSort
+
+ []
+ member this.ArrayBubbleSort () = Arrays.bubbleSort this.ArrayToSort
+
+ []
+ member this.ArrayMergeSort () = Arrays.mergeSort this.ArrayToSort
+
+ []
+ member this.ArraySystem () = Array.Sort this.ArrayToSort
+
+
+type ListBenchmark() =
+
+ static member Lengths = [|10000..10000..100000|]
+ member this.Random = System.Random()
+
+ []
+ member val ListLength = 0 with get, set
+ member val ListToSort = [0.0] with get, set
+
+ []
+ member this.GetListToSort () =
+ this.ListToSort <- List.init this.ListLength (fun _ -> this.Random.NextDouble())
+
+ []
+ member this.MyListBubbleSort () = MyList.fromSystemList this.ListToSort |> MyList.quickSort
+
+ []
+ member this.MyListQuickSort () = MyList.fromSystemList this.ListToSort |> MyList.bubbleSort
+
+ []
+ member this.MyListMergeSort () = MyList.fromSystemList this.ListToSort |> MyList.mergeSort
+
+ []
+ member this.MyListSystem () = List.sort this.ListToSort
+
+
+module Main =
+ []
+ let main argv =
+
+ let config = ManualConfig.Create(DefaultConfig.Instance)
+ .WithSummaryStyle(SummaryStyle.Default.WithTimeUnit(TimeUnit.Millisecond))
+ .WithOptions(ConfigOptions.DisableOptimizationsValidator)
+ let benchmarks =
+ BenchmarkSwitcher [| typeof; typeof|]
+
+ benchmarks.Run argv |> ignore
+ 0
diff --git a/HomeWork.sln b/HomeWork.sln
index afb549e7..eb7e6948 100644
--- a/HomeWork.sln
+++ b/HomeWork.sln
@@ -15,12 +15,14 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Sortings", "src\Sortings\So
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "SortingsT", "Tests\SortingsT\SortingsT.fsproj", "{1D6CFA13-FD9D-4586-A463-1C023123E2CA}"
EndProject
-Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Benchmarks", "Benchmarks\Benchmarks.fsproj", "{66023F5A-8456-4F66-9318-A0BFB68ED14A}"
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "SortingsB", "Benchmarks\SortingsB\Benchmarks.fsproj", "{66023F5A-8456-4F66-9318-A0BFB68ED14A}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "ImageProcessing", "src\ImageProcessing\ImageProcessing.fsproj", "{7B9D1692-F56C-43C7-92BA-2CDDE21A7D57}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "ImageProcessingT", "Tests\ImageProcessingT\ImageProcessingT.fsproj", "{EB2F699B-DE06-42EC-974A-A2C39E5C8D2A}"
EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "ImageProcessingB", "Benchmarks\ImageProcessingB\ImageProcessingB.fsproj", "{538E3C6C-8ADC-44EE-919C-EAD4C67C3AF0}"
+EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Trees", "src\Trees\Trees.fsproj", "{CAC5303C-D4CF-493E-94B4-4409BE7F2865}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "TreesT", "Tests\TreesT\TreesT.fsproj", "{7E4032B2-27F7-4691-8474-5C57A97F5721}"
@@ -29,6 +31,12 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "LineralAlgebra", "src\Liner
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "LineralAlgebraT", "Tests\LineralAlgebraT\LineralAlgebraT.fsproj", "{C42A6017-8A61-4469-8FCD-EEBF49198D80}"
EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "App", "App\App.fsproj", "{9C6529F4-1014-4655-A47E-D807D8604BD0}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Benchmarks\SortingsB", "Benchmarks\SortingsB", "{2DE1F8AE-2C09-422E-84AD-AC77FA4BFDED}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Benchmarks", "Benchmarks", "{BD15DB9C-BF1B-4219-AF93-796337C6399A}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -58,6 +66,10 @@ Global
{66023F5A-8456-4F66-9318-A0BFB68ED14A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{66023F5A-8456-4F66-9318-A0BFB68ED14A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{66023F5A-8456-4F66-9318-A0BFB68ED14A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {538E3C6C-8ADC-44EE-919C-EAD4C67C3AF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {538E3C6C-8ADC-44EE-919C-EAD4C67C3AF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {538E3C6C-8ADC-44EE-919C-EAD4C67C3AF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {538E3C6C-8ADC-44EE-919C-EAD4C67C3AF0}.Release|Any CPU.Build.0 = Release|Any CPU
{7B9D1692-F56C-43C7-92BA-2CDDE21A7D57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7B9D1692-F56C-43C7-92BA-2CDDE21A7D57}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B9D1692-F56C-43C7-92BA-2CDDE21A7D57}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -82,6 +94,10 @@ Global
{C42A6017-8A61-4469-8FCD-EEBF49198D80}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C42A6017-8A61-4469-8FCD-EEBF49198D80}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C42A6017-8A61-4469-8FCD-EEBF49198D80}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9C6529F4-1014-4655-A47E-D807D8604BD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9C6529F4-1014-4655-A47E-D807D8604BD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9C6529F4-1014-4655-A47E-D807D8604BD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9C6529F4-1014-4655-A47E-D807D8604BD0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{F793D6BB-E68A-473E-B11F-1D7888DF4D4A} = {00DFC406-0A95-4C11-8BF2-4FD28C28061D}
@@ -94,5 +110,7 @@ Global
{7E4032B2-27F7-4691-8474-5C57A97F5721} = {B4AC50D2-34AD-46DF-B39E-FBCC5D0653C6}
{C05FDC93-8EE3-442C-868A-031CE2A5F4E4} = {00DFC406-0A95-4C11-8BF2-4FD28C28061D}
{C42A6017-8A61-4469-8FCD-EEBF49198D80} = {B4AC50D2-34AD-46DF-B39E-FBCC5D0653C6}
+ {66023F5A-8456-4F66-9318-A0BFB68ED14A} = {2DE1F8AE-2C09-422E-84AD-AC77FA4BFDED}
+ {538E3C6C-8ADC-44EE-919C-EAD4C67C3AF0} = {BD15DB9C-BF1B-4219-AF93-796337C6399A}
EndGlobalSection
EndGlobal
diff --git a/Tests/ImageProcessingT/PropertyImageProcessing.fs b/Tests/ImageProcessingT/PropertyImageProcessing.fs
index 32d65918..70a6c24b 100644
--- a/Tests/ImageProcessingT/PropertyImageProcessing.fs
+++ b/Tests/ImageProcessingT/PropertyImageProcessing.fs
@@ -18,12 +18,13 @@ module ImageGen =
let a = byte 255
return Rgba32(r, g, b, a)
}
- let array2DGen (size: int) : Gen =
+ let array2DGen (size: int) : Gen> =
gen {
let! pixels = Gen.array2DOfDim (size, size) pixelGen
- return pixels
+ return async { return pixels }
}
-
+
+
type Image100() =
static member Rgba32() =
Arb.fromGen (ImageGen.array2DGen 100)
@@ -37,40 +38,149 @@ type Image2() =
type Filter() =
[ |])>]
- member _.filterDoesntChangeSize (image: Rgba32[,]) =
- let imageAfterFilter = applyFilter gaussianBlur image
- Assert.Equal(100, imageAfterFilter.GetLength(0))
- Assert.Equal(100, imageAfterFilter.GetLength(1))
+ member _.filterDoesntChangeSize (image: Async) =
+ let resNoParallelism =
+ applyFilterNoParallelismA gaussianBlur image
+ |> Async.RunSynchronously
+
+ let resPixelParallelism =
+ applyFilterPixelParallelismA gaussianBlur image
+ |> Async.RunSynchronously
+
+ let resPartsParallelism =
+ applyFilterParallelismInPartsA gaussianBlur image
+ |> Async.RunSynchronously
+
+ let resRowParallelism =
+ applyFilterRowParallelismA gaussianBlur image
+ |> Async.RunSynchronously
+
+ let resColParallelism =
+ applyFilterColParallelismA gaussianBlur image
+ |> Async.RunSynchronously
+
+ Assert.Equal(100, resNoParallelism.GetLength 0)
+ Assert.Equal(100, resNoParallelism.GetLength 1)
+
+ Assert.Equal(100, resPixelParallelism.GetLength 0)
+ Assert.Equal(100, resPixelParallelism.GetLength 1)
+
+ Assert.Equal(100, resPartsParallelism.GetLength 0)
+ Assert.Equal(100, resPartsParallelism.GetLength 1)
+
+ Assert.Equal(100, resRowParallelism.GetLength 0)
+ Assert.Equal(100, resRowParallelism.GetLength 1)
+
+ Assert.Equal(100, resColParallelism.GetLength 0)
+ Assert.Equal(100, resColParallelism.GetLength 1)
[ |])>]
- member _.idDoesntChangeData (image: Rgba32[,]) =
- let imageAfterFilter = applyFilter id image
- Assert.Equal(image, imageAfterFilter)
+ member _.idDoesntChangeData (image: Async) =
+ let resNoParallelism = applyFilterNoParallelismA id image
+ let resPixelParallelism = applyFilterPixelParallelismA id image
+ let resPartsParallelism = applyFilterParallelismInPartsA id image
+ let resRowParallelism = applyFilterRowParallelismA id image
+ let resColParallelism = applyFilterColParallelismA id image
+
+ Assert.Equal(image |> Async.RunSynchronously, resNoParallelism |> Async.RunSynchronously)
+ Assert.Equal(image |> Async.RunSynchronously, resPixelParallelism |> Async.RunSynchronously)
+ Assert.Equal(image |> Async.RunSynchronously, resPartsParallelism |> Async.RunSynchronously)
+ Assert.Equal(image |> Async.RunSynchronously, resRowParallelism |> Async.RunSynchronously)
+ Assert.Equal(image |> Async.RunSynchronously, resColParallelism |> Async.RunSynchronously)
[ |])>]
- member _.imageSmallerThanFilter (image: Rgba32[,]) =
- let imageAfterFilter = applyFilter black image
- Assert.Equal(true, imageIsBlack imageAfterFilter)
+ member _.imageSmallerThanFilter (image: Async) =
+ let resNoParallelism = applyFilterNoParallelismA black image
+ let resPixelParallelism = applyFilterPixelParallelismA black image
+ let resPartsParallelism = applyFilterParallelismInPartsA black image
+ let resRowParallelism = applyFilterRowParallelismA black image
+ let resColParallelism = applyFilterColParallelismA black image
+
+ Assert.Equal(true, imageIsBlack resNoParallelism)
+ Assert.Equal(true, imageIsBlack resPixelParallelism)
+ Assert.Equal(true, imageIsBlack resPartsParallelism)
+ Assert.Equal(true, imageIsBlack resRowParallelism)
+ Assert.Equal(true, imageIsBlack resColParallelism)
[ |])>]
- member _.blackFilter (image: Rgba32[,]) =
- let imageBlack = applyFilter black image
- Assert.Equal(true, imageIsBlack imageBlack)
+ member _.blackFilter (image: Async) =
+ let imageBlack_NoParallelism = applyFilterNoParallelismA black image
+ let imageBlack_PixelParallelism = applyFilterPixelParallelismA black image
+ let imageBlack_PartsParallelism = applyFilterParallelismInPartsA black image
+ let imageBlac_RowParallelism = applyFilterRowParallelismA black image
+ let imageBlack_ColParallelism = applyFilterColParallelismA black image
+
+ Assert.Equal(true, imageIsBlack imageBlack_NoParallelism)
+ Assert.Equal(true, imageIsBlack imageBlack_PixelParallelism)
+ Assert.Equal(true, imageIsBlack imageBlack_PartsParallelism)
+ Assert.Equal(true, imageIsBlack imageBlac_RowParallelism)
+ Assert.Equal(true, imageIsBlack imageBlack_ColParallelism)
[ |])>]
- member _.shiftComposition (image: Rgba32[,]) =
- let trivial1and2 = applyFilter shiftRight image |> applyFilter shiftDown
- let trivial12 = applyFilter shiftDiagonal image
- Assert.Equal(trivial1and2, trivial12)
+ member _.shiftComposition (image: Async) =
+ let trivial1and2_NoParallelism = applyFilterNoParallelismA shiftRight image |> applyFilterNoParallelismA shiftDown
+ let trivial12_NoParallelism = applyFilterNoParallelismA shiftDiagonal image
+
+ let trivial1and2_PixelParallelism = applyFilterPixelParallelismA shiftRight image |> applyFilterPixelParallelismA shiftDown
+ let trivial12_PixelParallelism = applyFilterPixelParallelismA shiftDiagonal image
+
+ let trivial1and2_PartsParallelism = applyFilterParallelismInPartsA shiftRight image |> applyFilterParallelismInPartsA shiftDown
+ let trivial12_PartsParallelism = applyFilterParallelismInPartsA shiftDiagonal image
+
+ let trivial1and2_RowParallelism = applyFilterRowParallelismA shiftRight image |> applyFilterRowParallelismA shiftDown
+ let trivial12_RowParallelism = applyFilterRowParallelismA shiftDiagonal image
+
+ let trivial1and2_ColParallelism = applyFilterColParallelismA shiftRight image |> applyFilterColParallelismA shiftDown
+ let trivial12_ColParallelism = applyFilterColParallelismA shiftDiagonal image
+
+ Assert.Equal(trivial1and2_NoParallelism |> Async.RunSynchronously, trivial12_NoParallelism |> Async.RunSynchronously)
+ Assert.Equal(trivial1and2_PixelParallelism |> Async.RunSynchronously, trivial12_PixelParallelism |> Async.RunSynchronously)
+ Assert.Equal(trivial1and2_PartsParallelism |> Async.RunSynchronously, trivial12_PartsParallelism |> Async.RunSynchronously)
+ Assert.Equal(trivial1and2_RowParallelism |> Async.RunSynchronously, trivial12_RowParallelism |> Async.RunSynchronously)
+ Assert.Equal(trivial1and2_ColParallelism |> Async.RunSynchronously, trivial12_ColParallelism |> Async.RunSynchronously)
[ |])>]
- member _.extendedComposition (image: Rgba32[,]) =
- let imageAfterFilter = applyFilter kernel image
- let imageAfterExtendedFilter = applyFilter kernelExtended image
- Assert.Equal(imageAfterFilter, imageAfterExtendedFilter)
+ member _.extendedComposition (image: Async) =
+ let imageAfterFilter_NoParallelism = applyFilterNoParallelismA kernel image
+ let imageAfterExtendedFilter_NoParallelism = applyFilterNoParallelismA kernelExtended image
+
+ let imageAfterFilter_PixelParallelism = applyFilterPixelParallelismA kernel image
+ let imageAfterExtendedFilter_PixelParallelism = applyFilterPixelParallelismA kernelExtended image
+
+ let imageAfterFilter_PartsParallelism = applyFilterParallelismInPartsA kernel image
+ let imageAfterExtendedFilter_PartsParallelism = applyFilterParallelismInPartsA kernelExtended image
+
+ let imageAfterFilter_RowParallelism = applyFilterRowParallelismA kernel image
+ let imageAfterExtendedFilter_RowParallelism = applyFilterRowParallelismA kernelExtended image
+
+ let imageAfterFilter_ColParallelism = applyFilterColParallelismA kernel image
+ let imageAfterExtendedFilter_ColParallelism = applyFilterColParallelismA kernelExtended image
+
+ Assert.Equal(imageAfterFilter_NoParallelism |> Async.RunSynchronously, imageAfterExtendedFilter_NoParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageAfterFilter_PixelParallelism |> Async.RunSynchronously, imageAfterExtendedFilter_PixelParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageAfterFilter_PartsParallelism |> Async.RunSynchronously, imageAfterExtendedFilter_PartsParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageAfterFilter_RowParallelism |> Async.RunSynchronously, imageAfterExtendedFilter_RowParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageAfterFilter_ColParallelism |> Async.RunSynchronously, imageAfterExtendedFilter_ColParallelism |> Async.RunSynchronously)
[ |])>]
- member _.someAreCommutative (image: Rgba32[,]) =
- let image12 = applyFilter shiftRight image |> applyFilter shiftDown
- let image21 = applyFilter shiftDown image |> applyFilter shiftRight
- Assert.Equal(image12, image21)
\ No newline at end of file
+ member _.someAreCommutative (image: Async) =
+ let image12_NoParallelism = applyFilterNoParallelismA shiftRight image |> applyFilterNoParallelismA shiftDown
+ let image21_NoParallelism = applyFilterNoParallelismA shiftDown image |> applyFilterNoParallelismA shiftRight
+
+ let image12_PixelParallelism = applyFilterPixelParallelismA shiftRight image |> applyFilterPixelParallelismA shiftDown
+ let image21_PixelParallelism = applyFilterPixelParallelismA shiftDown image |> applyFilterPixelParallelismA shiftRight
+
+ let image12_PartsParallelism = applyFilterParallelismInPartsA shiftRight image |> applyFilterParallelismInPartsA shiftDown
+ let image21_PartsParallelism = applyFilterParallelismInPartsA shiftDown image |> applyFilterParallelismInPartsA shiftRight
+
+ let image12_RowParallelism = applyFilterRowParallelismA shiftRight image |> applyFilterRowParallelismA shiftDown
+ let image21_RowParallelism = applyFilterRowParallelismA shiftDown image |> applyFilterRowParallelismA shiftRight
+
+ let image12_ColParallelism = applyFilterColParallelismA shiftRight image |> applyFilterColParallelismA shiftDown
+ let image21_ColParallelism = applyFilterColParallelismA shiftDown image |> applyFilterColParallelismA shiftRight
+
+ Assert.Equal(image12_NoParallelism |> Async.RunSynchronously, image21_NoParallelism |> Async.RunSynchronously)
+ Assert.Equal(image12_PixelParallelism |> Async.RunSynchronously, image21_PixelParallelism |> Async.RunSynchronously)
+ Assert.Equal(image12_PartsParallelism |> Async.RunSynchronously, image21_PartsParallelism |> Async.RunSynchronously)
+ Assert.Equal(image12_RowParallelism |> Async.RunSynchronously, image21_RowParallelism |> Async.RunSynchronously)
+ Assert.Equal(image12_ColParallelism |> Async.RunSynchronously, image21_ColParallelism |> Async.RunSynchronously)
\ No newline at end of file
diff --git a/Tests/ImageProcessingT/UnitImageProcessing.fs b/Tests/ImageProcessingT/UnitImageProcessing.fs
index 73880dc0..3ac54427 100644
--- a/Tests/ImageProcessingT/UnitImageProcessing.fs
+++ b/Tests/ImageProcessingT/UnitImageProcessing.fs
@@ -10,8 +10,8 @@ module Data =
let im1 = "../../../Images/image1.png"
let imSmall = "../../../Images/image2x2px.png"
- let image1 = loadAsRgba2D im1
- let imageSmall = loadAsRgba2D imSmall
+ let image1 = loadAsRgba2DA im1
+ let imageSmall = loadAsRgba2DA imSmall
let imId = "../../../Images/id.png"
let imShiftRightDown = "../../../Images/shiftRightDown.png"
@@ -19,12 +19,12 @@ module Data =
let imShiftDiagonal = "../../../Images/shiftDiagonal.png"
let imKernel = "../../../Images/kernel.png"
let imKernelExtended = "../../../Images/kernelExtended.png"
- let imageId= loadAsRgba2D imId
- let imageShiftRightDown= loadAsRgba2D imShiftRightDown
- let imageShiftDownRight= loadAsRgba2D imShiftDownRight
- let imageShiftDiagonal= loadAsRgba2D imShiftDiagonal
- let imageKernel= loadAsRgba2D imKernel
- let imageKernelExtended= loadAsRgba2D imKernelExtended
+ let imageId= loadAsRgba2DA imId |> Async.RunSynchronously
+ let imageShiftRightDown= loadAsRgba2DA imShiftRightDown |> Async.RunSynchronously
+ let imageShiftDownRight= loadAsRgba2DA imShiftDownRight |> Async.RunSynchronously
+ let imageShiftDiagonal= loadAsRgba2DA imShiftDiagonal |> Async.RunSynchronously
+ let imageKernel= loadAsRgba2DA imKernel |> Async.RunSynchronously
+ let imageKernelExtended= loadAsRgba2DA imKernelExtended |> Async.RunSynchronously
let id =
@@ -86,19 +86,23 @@ module Data =
|> Array.map (Array.map float32)
- let imageIsBlack (image: Rgba32[,]) =
- let h = image.GetLength 0
- let w = image.GetLength 1
+ let imageIsBlack (imageAsync: Async) =
+ async {
+ let! image = imageAsync
+ let h = image.GetLength 0
+ let w = image.GetLength 1
- let mutable isBlack = true
+ let mutable isBlack = true
- for i in 0 .. h - 1 do
- for j in 0 .. w - 1 do
- let pixel = image.[i, j]
- if pixel <> Rgba32(byte 0, byte 0, byte 0, byte 255) then
- isBlack <- false
+ for i in 0 .. h - 1 do
+ for j in 0 .. w - 1 do
+ let pixel = image.[i, j]
+ if pixel <> Rgba32(byte 0, byte 0, byte 0, byte 255) then
+ isBlack <- false
+
+ return isBlack
+ } |> Async.RunSynchronously
- isBlack
module Filter =
@@ -106,29 +110,113 @@ module Filter =
[]
let idDoesntChangeData () =
- let imageAfterFilter = applyFilter id image1
- Assert.Equal(imageId, imageAfterFilter)
+ let resNoParallelism = applyFilterNoParallelismA id image1
+ let resPixelParallelism = applyFilterPixelParallelismA id image1
+ let resPartsParallelism = applyFilterParallelismInPartsA id image1
+ let resRowParallelism = applyFilterRowParallelismA id image1
+ let resColParallelism = applyFilterColParallelismA id image1
+
+ Assert.Equal(imageId, resNoParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageId, resPixelParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageId, resPartsParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageId, resRowParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageId, resColParallelism |> Async.RunSynchronously)
[]
let shiftComposition () =
- let shiftRightDown = applyFilter shiftRight image1 |> applyFilter shiftDown
- let shiftDiagonal = applyFilter shiftDiagonal image1
+ let shiftRightDown_NoParallelism = applyFilterNoParallelismA shiftRight image1 |> applyFilterNoParallelismA shiftDown
+ let shiftDiagonal_NoParallelism = applyFilterNoParallelismA shiftDiagonal image1
+
+ let shiftRightDown_PixelParallelism = applyFilterPixelParallelismA shiftRight image1 |> applyFilterPixelParallelismA shiftDown
+ let shiftDiagonal_PixelParallelism = applyFilterPixelParallelismA shiftDiagonal image1
+
+ let shiftRightDown_PartsParallelism = applyFilterParallelismInPartsA shiftRight image1 |> applyFilterParallelismInPartsA shiftDown
+ let shiftDiagonal_PartsParallelism = applyFilterParallelismInPartsA shiftDiagonal image1
+
+ let shiftRightDown_RowParallelism = applyFilterRowParallelismA shiftRight image1 |> applyFilterRowParallelismA shiftDown
+ let shiftDiagonal_RowParallelism = applyFilterRowParallelismA shiftDiagonal image1
+
+ let shiftRightDown_ColParallelism = applyFilterColParallelismA shiftRight image1 |> applyFilterColParallelismA shiftDown
+ let shiftDiagonal_ColParallelism = applyFilterColParallelismA shiftDiagonal image1
+
Assert.Equal(imageShiftRightDown, imageShiftDiagonal)
- Assert.Equal(imageShiftRightDown, shiftRightDown)
- Assert.Equal(imageShiftRightDown, shiftDiagonal)
+ Assert.Equal(imageShiftRightDown, shiftRightDown_NoParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageShiftRightDown, shiftDiagonal_NoParallelism |> Async.RunSynchronously)
+
+ Assert.Equal(imageShiftRightDown, shiftRightDown_PixelParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageShiftRightDown, shiftDiagonal_PixelParallelism |> Async.RunSynchronously)
+
+ Assert.Equal(imageShiftRightDown, shiftRightDown_PartsParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageShiftRightDown, shiftDiagonal_PartsParallelism |> Async.RunSynchronously)
+
+ Assert.Equal(imageShiftRightDown, shiftRightDown_RowParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageShiftRightDown, shiftDiagonal_RowParallelism |> Async.RunSynchronously)
+
+ Assert.Equal(imageShiftRightDown, shiftRightDown_ColParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageShiftRightDown, shiftDiagonal_ColParallelism |> Async.RunSynchronously)
[]
let extendedComposition () =
- let kernel = applyFilter kernel image1
- let kernelExtended = applyFilter kernelExtended image1
+ let kernel_NoParallelism = applyFilterNoParallelismA kernel image1
+ let kernelExtended_NoParallelism = applyFilterNoParallelismA kernelExtended image1
+
+ let kernel_PixelParallelism = applyFilterPixelParallelismA kernel image1
+ let kernelExtended_PixelParallelism = applyFilterPixelParallelismA kernelExtended image1
+
+ let kernel_PartsParallelism = applyFilterParallelismInPartsA kernel image1
+ let kernelExtended_PartsParallelism = applyFilterParallelismInPartsA kernelExtended image1
+
+ let kernel_RowParallelism = applyFilterRowParallelismA kernel image1
+ let kernelExtended_RowParallelism = applyFilterRowParallelismA kernelExtended image1
+
+ let kernel_ColParallelism = applyFilterColParallelismA kernel image1
+ let kernelExtended_ColParallelism = applyFilterColParallelismA kernelExtended image1
+
Assert.Equal(imageKernel, imageKernelExtended)
- Assert.Equal(imageKernel, kernel)
- Assert.Equal(imageKernel, kernelExtended)
+ Assert.Equal(imageKernel, kernel_NoParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageKernel, kernelExtended_NoParallelism |> Async.RunSynchronously)
+
+ Assert.Equal(imageKernel, kernel_PixelParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageKernel, kernelExtended_PixelParallelism |> Async.RunSynchronously)
+
+ Assert.Equal(imageKernel, kernel_PartsParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageKernel, kernelExtended_PartsParallelism |> Async.RunSynchronously)
+
+ Assert.Equal(imageKernel, kernel_RowParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageKernel, kernelExtended_RowParallelism |> Async.RunSynchronously)
+
+ Assert.Equal(imageKernel, kernel_ColParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageKernel, kernelExtended_ColParallelism |> Async.RunSynchronously)
[]
let someAreCommutative () =
- let imageRD = applyFilter shiftRight image1 |> applyFilter shiftDown
- let imageDR = applyFilter shiftDown image1 |> applyFilter shiftRight
+ let imageRD_NoParallelism = applyFilterNoParallelismA shiftRight image1 |> applyFilterNoParallelismA shiftDown
+ let imageDR_NoParallelism = applyFilterNoParallelismA shiftDown image1 |> applyFilterNoParallelismA shiftRight
+
+ let imageRD_PixelParallelism = applyFilterPixelParallelismA shiftRight image1 |> applyFilterPixelParallelismA shiftDown
+ let imageDR_PixelParallelism = applyFilterPixelParallelismA shiftDown image1 |> applyFilterPixelParallelismA shiftRight
+
+ let imageRD_PartsParallelism = applyFilterParallelismInPartsA shiftRight image1 |> applyFilterParallelismInPartsA shiftDown
+ let imageDR_PartsParallelism = applyFilterParallelismInPartsA shiftDown image1 |> applyFilterParallelismInPartsA shiftRight
+
+ let imageRD_RowParallelism = applyFilterRowParallelismA shiftRight image1 |> applyFilterRowParallelismA shiftDown
+ let imageDR_RowParallelism = applyFilterRowParallelismA shiftDown image1 |> applyFilterRowParallelismA shiftRight
+
+ let imageRD_ColParallelism = applyFilterColParallelismA shiftRight image1 |> applyFilterColParallelismA shiftDown
+ let imageDR_ColParallelism = applyFilterColParallelismA shiftDown image1 |> applyFilterColParallelismA shiftRight
+
Assert.Equal(imageShiftDownRight, imageShiftRightDown)
- Assert.Equal(imageShiftDownRight, imageDR)
- Assert.Equal(imageShiftDownRight, imageRD)
\ No newline at end of file
+ Assert.Equal(imageShiftDownRight, imageDR_NoParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageShiftDownRight, imageRD_NoParallelism |> Async.RunSynchronously)
+
+ Assert.Equal(imageShiftDownRight, imageDR_PixelParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageShiftDownRight, imageRD_PixelParallelism |> Async.RunSynchronously)
+
+ Assert.Equal(imageShiftDownRight, imageDR_PartsParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageShiftDownRight, imageRD_PartsParallelism |> Async.RunSynchronously)
+
+ Assert.Equal(imageShiftDownRight, imageDR_RowParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageShiftDownRight, imageRD_RowParallelism |> Async.RunSynchronously)
+
+ Assert.Equal(imageShiftDownRight, imageDR_ColParallelism |> Async.RunSynchronously)
+ Assert.Equal(imageShiftDownRight, imageRD_ColParallelism |> Async.RunSynchronously)
\ No newline at end of file
diff --git a/Tests/LineralAlgebraT/PropertyLA.fs b/Tests/LineralAlgebraT/PropertyLA.fs
index c5a64777..fe7569e0 100644
--- a/Tests/LineralAlgebraT/PropertyLA.fs
+++ b/Tests/LineralAlgebraT/PropertyLA.fs
@@ -8,9 +8,7 @@ open FsCheck
open FsCheck.Xunit
open FsCheck.FSharp
-open LineralAlgebra
-open LineralAlgebra.QTrees
-open LineralAlgebra.Matrix
+open LineralAlgebra
open UnitTrees.dataAndFuncs
@@ -27,27 +25,6 @@ module DataAndFuncs =
areAlmostEqual value1 value2 1e-5f
| _ -> false
- let rec toCorrectQTree qtree =
- match qtree with
- | Leaf value -> Leaf value
-
- | Node (nw, ne, se, sw) ->
- let NW = toCorrectQTree nw
- let NE = toCorrectQTree ne
- let SE = toCorrectQTree se
- let SW = toCorrectQTree sw
-
- match NW, NE, SE, SW with
- | Leaf value1,
- Leaf value2,
- Leaf value3,
- Leaf value4
- when value1 = value2 && value2 = value3 && value3 = value4 ->
-
- Leaf value1
-
- | _ -> Node (NW, NE, SE, SW)
-
let multiplyArray2D (arr1: 't[,]) (arr2: 't[,]) : 't[,] =
let rows1 = Array2D.length1 arr1
let cols1 = Array2D.length2 arr1
@@ -90,7 +67,7 @@ module DataAndFuncs =
let MatrGen (size: int) =
let qtree = QTreeGen size typeOfMatr
- { n = size; qtree = toCorrectQTree qtree }
+ { n = size; qtree = QTrees.toCorrectQTree qtree }
let res = MatrGen size
res
@@ -103,31 +80,31 @@ type Map() =
[]
member _.intId (qtree: QTree) =
- qtree |> toCorrectQTree = map id qtree
+ qtree |> QTrees.toCorrectQTree = QTrees.map id qtree
[]
member _.floatId (qtree: QTree) =
- let res = map id qtree
- Assert.True(floatQTreesAreEqual (qtree |> toCorrectQTree) res)
+ let res = QTrees.map id qtree
+ Assert.True(floatQTreesAreEqual (qtree |> QTrees.toCorrectQTree) res)
[]
member _.intComposition (qtree: QTree) =
- let qtree1 = map ((+) 1)((map ((+) 2)) qtree)
- let qtree2 = map ((+) 3) qtree
+ let qtree1 = QTrees.map ((+) 1)((QTrees.map ((+) 2)) qtree)
+ let qtree2 = QTrees.map ((+) 3) qtree
qtree1 = qtree2
[]
member _.floatComposition (qtree: QTree) =
- let qtree1 = map ((+) 1.0f) (map ((+) 2.0f) qtree)
- let qtree2 = map ((+) 3.0f) qtree
+ let qtree1 = QTrees.map ((+) 1.0f) (QTrees.map ((+) 2.0f) qtree)
+ let qtree2 = QTrees.map ((+) 3.0f) qtree
Assert.True(floatQTreesAreEqual qtree1 qtree2)
[]
member _.intHighIsConst (qtree: QTree) =
- let h1 = height (qtree |> toCorrectQTree)
- let h2 = height (map ((+) 1) qtree)
+ let h1 = QTrees.height (qtree |> QTrees.toCorrectQTree)
+ let h2 = QTrees.height (QTrees.map ((+) 1) qtree)
h1 = h2
@@ -141,47 +118,47 @@ type Multiply() =
member _.leafLeaf () =
let matr1 = MatrixGen 1 "Leaf"
let matr2 = MatrixGen 1 "Leaf"
- let res = multiply matr1 matr2 (+) ( * )
- let arrayRess = qtreeToArray2D res.qtree res.n
- let arrayEx = multiplyArray2D (qtreeToArray2D matr1.qtree matr1.n) (qtreeToArray2D matr2.qtree matr2.n)
+ let res = Matrix.multiply matr1 matr2 (+) ( * )
+ let arrayRess = QTrees.qtreeToArray2D res.qtree res.n
+ let arrayEx = multiplyArray2D (QTrees.qtreeToArray2D matr1.qtree matr1.n) (QTrees.qtreeToArray2D matr2.qtree matr2.n)
Assert.Equal(arrayEx, arrayRess)
[]
member _.nodeLeaf () =
let matr1 = MatrixGen size "Node"
let matr2 = MatrixGen size "Leaf"
- let res = multiply matr1 matr2 (+) ( * )
- let arrayRess = qtreeToArray2D res.qtree res.n
- let arrayEx = multiplyArray2D (qtreeToArray2D matr1.qtree matr1.n) (qtreeToArray2D matr2.qtree matr2.n)
+ let res = Matrix.multiply matr1 matr2 (+) ( * )
+ let arrayRess = QTrees.qtreeToArray2D res.qtree res.n
+ let arrayEx = multiplyArray2D (QTrees.qtreeToArray2D matr1.qtree matr1.n) (QTrees.qtreeToArray2D matr2.qtree matr2.n)
Assert.Equal(arrayEx, arrayRess)
[]
member _.leafNode () =
let matr1 = MatrixGen size "Leaf"
let matr2 = MatrixGen size "Node"
- let res = multiply matr1 matr2 (+) ( * )
- let arrayRess = qtreeToArray2D res.qtree res.n
- let arrayEx = multiplyArray2D (qtreeToArray2D matr1.qtree matr1.n) (qtreeToArray2D matr2.qtree matr2.n)
+ let res = Matrix.multiply matr1 matr2 (+) ( * )
+ let arrayRess = QTrees.qtreeToArray2D res.qtree res.n
+ let arrayEx = multiplyArray2D (QTrees.qtreeToArray2D matr1.qtree matr1.n) (QTrees.qtreeToArray2D matr2.qtree matr2.n)
Assert.Equal(arrayEx, arrayRess)
[]
member _.nodeNode () =
let matr1 = MatrixGen size "Node"
let matr2 = MatrixGen size "Node"
- let res = multiply matr1 matr2 (+) ( * )
- let arrayRess = qtreeToArray2D res.qtree res.n
- let arrayEx = multiplyArray2D (qtreeToArray2D matr1.qtree matr1.n) (qtreeToArray2D matr2.qtree matr2.n)
+ let res = Matrix.multiply matr1 matr2 (+) ( * )
+ let arrayRess = QTrees.qtreeToArray2D res.qtree res.n
+ let arrayEx = multiplyArray2D (QTrees.qtreeToArray2D matr1.qtree matr1.n) (QTrees.qtreeToArray2D matr2.qtree matr2.n)
Assert.Equal(arrayEx, arrayRess)
[]
member _.zero () =
let matr1 = MatrixGen size "Zero"
let matr2 = MatrixGen size "Node"
- let res = multiply matr1 matr2 (+) ( * )
- let arrayRess = qtreeToArray2D res.qtree res.n
- let res1 = multiply matr2 matr1 (+) ( * )
- let arrayRess1 = qtreeToArray2D res1.qtree res1.n
+ let res = Matrix.multiply matr1 matr2 (+) ( * )
+ let arrayRess = QTrees.qtreeToArray2D res.qtree res.n
+ let res1 = Matrix.multiply matr2 matr1 (+) ( * )
+ let arrayRess1 = QTrees.qtreeToArray2D res1.qtree res1.n
- let arrayEx = multiplyArray2D (qtreeToArray2D matr1.qtree matr1.n) (qtreeToArray2D matr2.qtree matr2.n)
+ let arrayEx = multiplyArray2D (QTrees.qtreeToArray2D matr1.qtree matr1.n) (QTrees.qtreeToArray2D matr2.qtree matr2.n)
Assert.Equal(arrayEx, arrayRess)
Assert.Equal(arrayEx, arrayRess1)
\ No newline at end of file
diff --git a/Tests/LineralAlgebraT/UnitLA.fs b/Tests/LineralAlgebraT/UnitLA.fs
index 3ecb263a..90523cda 100644
--- a/Tests/LineralAlgebraT/UnitLA.fs
+++ b/Tests/LineralAlgebraT/UnitLA.fs
@@ -4,8 +4,6 @@ open System
open Xunit
open LineralAlgebra
-open LineralAlgebra.QTrees
-open LineralAlgebra.Matrix
module DataAndFuncs =
@@ -68,18 +66,18 @@ module Map =
[]
let intId () =
- let res = map id intQTree1
+ let res = QTrees.map id intQTree1
Assert.Equal(intQTree1, res)
[]
let floatId () =
- let res = map id floatQTree1
+ let res = QTrees.map id floatQTree1
Assert.Equal(floatQTree1, res)
[]
let intAdd () =
- let res = map ((+) 1) intQTree1
+ let res = QTrees.map ((+) 1) intQTree1
let ex = Node (
Node ( Leaf 2, Leaf 3, Leaf 4, Leaf 5),
Node ( Leaf -4, Leaf -5, Leaf -6, Leaf -7),
@@ -90,7 +88,7 @@ module Map =
[]
let floatAdd () =
- let res = map ((+) 1.0) floatQTree1
+ let res = QTrees.map ((+) 1.0) floatQTree1
let ex = Node (
Node ( Leaf 2.0, Leaf 3.0, Leaf 4.0, Leaf 5.0),
Node ( Leaf -4.0, Leaf -5.0, Leaf -6.0, Leaf -7.0),
@@ -102,7 +100,7 @@ module Map =
[]
let intMult () =
- let res = map (fun x -> 2 * x) intQTree1
+ let res = QTrees.map (fun x -> 2 * x) intQTree1
let ex = Node (
Node ( Leaf 2, Leaf 4, Leaf 6, Leaf 8),
Node ( Leaf -10, Leaf -12, Leaf -14, Leaf -16),
@@ -113,7 +111,7 @@ module Map =
[]
let floatMult () =
- let res = map (fun x -> 2.0 * x) floatQTree1
+ let res = QTrees.map (fun x -> 2.0 * x) floatQTree1
let ex = Node (
Node ( Leaf 2.0, Leaf 4.0, Leaf 6.0, Leaf 8.0),
Node ( Leaf -10.0, Leaf -12.0, Leaf -14.0, Leaf -16.0),
@@ -127,7 +125,7 @@ module Map =
[]
let intSign () =
- let res = map (fun (x: int) -> Math.Sign x) intQTree1
+ let res = QTrees.map (fun (x: int) -> Math.Sign x) intQTree1
let ex = Node (
Leaf 1,
Leaf -1,
@@ -138,7 +136,7 @@ module Map =
[]
let floatSign () =
- let res = map (fun (x: float) -> Math.Sign x) floatQTree1
+ let res = QTrees.map (fun (x: float) -> Math.Sign x) floatQTree1
let ex = Node (
Leaf 1,
Leaf -1,
@@ -150,8 +148,8 @@ module Map =
[]
let intComposition () =
- let tree1 = map ((+) 1)((map ((+) 2)) intQTree1)
- let tree2 = map ((+) 3) intQTree1
+ let tree1 = QTrees.map ((+) 1)((QTrees.map ((+) 2)) intQTree1)
+ let tree2 = QTrees.map ((+) 3) intQTree1
let ex = Node (
Node ( Leaf 4, Leaf 5, Leaf 6, Leaf 7),
Node ( Leaf -2, Leaf -3, Leaf -4, Leaf -5),
@@ -163,8 +161,8 @@ module Map =
[]
let floatComposition () =
- let tree1 = map ((+) 1.0) (map ((+) 2.0) floatQTree1)
- let tree2 = map ((+) 3.0) floatQTree1
+ let tree1 = QTrees.map ((+) 1.0) (QTrees.map ((+) 2.0) floatQTree1)
+ let tree2 = QTrees.map ((+) 3.0) floatQTree1
let ex = Node (
Node ( Leaf 4.0, Leaf 5.0, Leaf 6.0, Leaf 7.0),
Node ( Leaf -2.0, Leaf -3.0, Leaf -4.0, Leaf -5.0),
@@ -177,15 +175,15 @@ module Map =
[]
let intHighIsConst () =
- let h1 = height intQTree1
- let h2 = height (map ((+) 1) intQTree1)
+ let h1 = QTrees.height intQTree1
+ let h2 = QTrees.height (QTrees.map ((+) 1) intQTree1)
Assert.Equal(3, h1)
Assert.Equal(3, h2)
[]
let floatHighIsConst () =
- let h1 = height floatQTree1
- let h2 = height (map ((+) 1.0) floatQTree1)
+ let h1 = QTrees.height floatQTree1
+ let h2 = QTrees.height (QTrees.map ((+) 1.0) floatQTree1)
Assert.Equal(3, h1)
Assert.Equal(3, h2)
@@ -197,12 +195,12 @@ module Map =
[]
let intHighIsExpected () =
- let h = height (map (fun (x: int) -> Math.Sign x) intQTree1)
+ let h = QTrees.height (QTrees.map (fun (x: int) -> Math.Sign x) intQTree1)
Assert.Equal(2, h)
[]
let floatHighIsExpected () =
- let h = height (map (fun (x: float) -> Math.Sign x) floatQTree1)
+ let h = QTrees.height (QTrees.map (fun (x: float) -> Math.Sign x) floatQTree1)
Assert.Equal(2, h)
@@ -211,7 +209,7 @@ module Map2 =
[]
let intAdd () =
- let res = map2 (+) intQTree1 intQTree2
+ let res = QTrees.map2 (+) intQTree1 intQTree2
let ex = Node (
Node ( Leaf 2, Leaf 4, Leaf 6, Leaf 8),
Node ( Leaf 0, Leaf -1, Leaf -2, Leaf -3),
@@ -222,7 +220,7 @@ module Map2 =
[]
let floatAdd () =
- let res = map2 (+) floatQTree1 floatQTree2
+ let res = QTrees.map2 (+) floatQTree1 floatQTree2
let ex = Node (
Node ( Leaf 2.0, Leaf 4.0, Leaf 6.0, Leaf 8.0),
Node ( Leaf 0.0, Leaf -1.0, Leaf -2.0, Leaf -3.0),
@@ -234,7 +232,7 @@ module Map2 =
[]
let intMult () =
- let res = map2 (fun x y -> x * y) intQTree1 intQTree2
+ let res = QTrees.map2 (fun x y -> x * y) intQTree1 intQTree2
let ex = Node (
Node ( Leaf 1, Leaf 4, Leaf 9, Leaf 16),
Node ( Leaf -25, Leaf -30, Leaf -35, Leaf -40),
@@ -245,7 +243,7 @@ module Map2 =
[]
let floatMult () =
- let res = map2 (fun x y -> x * y) floatQTree1 floatQTree2
+ let res = QTrees.map2 (fun x y -> x * y) floatQTree1 floatQTree2
let ex = Node (
Node ( Leaf 1.0, Leaf 4.0, Leaf 9.0, Leaf 16.0),
Node ( Leaf -25.0, Leaf -30.0, Leaf -35.0, Leaf -40.0),
@@ -257,19 +255,19 @@ module Map2 =
[]
let intHighIsExpected () =
- let h1 = height intQTree1
- let h2 = height intOneLeaf1
+ let h1 = QTrees.height intQTree1
+ let h2 = QTrees.height intOneLeaf1
let h3 = max h1 h2
- let h4 = height (map2 (+) intQTree1 intOneLeaf1)
+ let h4 = QTrees.height (QTrees.map2 (+) intQTree1 intOneLeaf1)
Assert.Equal(3, h3)
Assert.Equal(3, h4)
[]
let floatHighIsExpected () =
- let h1 = height floatQTree1
- let h2 = height floatOneLeaf
+ let h1 = QTrees.height floatQTree1
+ let h2 = QTrees.height floatOneLeaf
let h3 = max h1 h2
- let h4 = height (map2 (+) floatQTree1 floatOneLeaf)
+ let h4 = QTrees.height (QTrees.map2 (+) floatQTree1 floatOneLeaf)
Assert.Equal(3, h3)
Assert.Equal(3, h4)
@@ -279,22 +277,22 @@ module Mult =
[]
let sizeIsImportant () =
- let res1 = multiply MintOneLeaf3 MintOneLeaf4 (+) ( * )
+ let res1 = Matrix.multiply MintOneLeaf3 MintOneLeaf4 (+) ( * )
let ex1 = { n = 1; qtree = Leaf 6 }
- let res2 = multiply MintNode1 MintNode2 (+) ( * )
+ let res2 = Matrix.multiply MintNode1 MintNode2 (+) ( * )
let ex2 = { n = 2; qtree = Leaf 12 }
Assert.Equal(ex1, res1)
Assert.Equal(ex2, res2)
[]
let leafLeaf () =
- let res = multiply MintOneLeaf3 MintOneLeaf4 (+) ( * )
+ let res = Matrix.multiply MintOneLeaf3 MintOneLeaf4 (+) ( * )
let ex = { n = 1; qtree = Leaf 6 }
Assert.Equal(ex, res)
[]
let nodeLeaf () =
- let res = multiply MintQTree1 MintOneLeaf1 (+) ( * )
+ let res = Matrix.multiply MintQTree1 MintOneLeaf1 (+) ( * )
let ex = {
n = 4;
qtree = Node (
@@ -308,7 +306,7 @@ module Mult =
[]
let leafNode () =
- let res = multiply MintOneLeaf1 MintQTree1 (+) ( * )
+ let res = Matrix.multiply MintOneLeaf1 MintQTree1 (+) ( * )
let ex = {
n = 4;
qtree = Node (
@@ -322,7 +320,7 @@ module Mult =
[]
let nodeNode () =
- let res = multiply MintQTree1 MintQTree2 (+) ( * )
+ let res = Matrix.multiply MintQTree1 MintQTree2 (+) ( * )
let ex = {
n = 4;
qtree = Node (
@@ -336,8 +334,8 @@ module Mult =
[]
let zero () =
- let res1 = multiply MintQTree1 MintZero (+) ( * )
- let res2 = multiply MintZero MintQTree1 (+) ( * )
+ let res1 = Matrix.multiply MintQTree1 MintZero (+) ( * )
+ let res2 = Matrix.multiply MintZero MintQTree1 (+) ( * )
let ex = { n = 4; qtree = Leaf 0 }
Assert.Equal(ex, res1)
Assert.Equal(ex, res2)
\ No newline at end of file
diff --git a/src/ImageProcessing/ImageProcessing.fs b/src/ImageProcessing/ImageProcessing.fs
index 653a8620..04f686ab 100644
--- a/src/ImageProcessing/ImageProcessing.fs
+++ b/src/ImageProcessing/ImageProcessing.fs
@@ -2,6 +2,9 @@ namespace ImageProcessing
open SixLabors.ImageSharp
open SixLabors.ImageSharp.PixelFormats
+open System.Threading.Tasks
+open Microsoft.FSharp.Control
+open System.IO
[]
type Image =
@@ -183,6 +186,193 @@ module ImProcessing =
|> Array.map (Array.map (fun x -> (float32 x) / + 128.0f))
+ let loadAsRgba2DA (file: string) =
+ async {
+ use fileStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize = 4096, useAsync = true)
+
+ let! img = Image.LoadAsync fileStream |> Async.AwaitTask
+ let res = Array2D.zeroCreate img.Height img.Width
+
+ for i in 0 .. img.Width - 1 do
+ for j in 0 .. img.Height - 1 do
+ res.[j, i] <- img.[i, j]
+
+ return res
+ }
+
+ let saveRgbaImageA (rgbaDataAsync: Async) file =
+ async {
+ let! rgbaData = rgbaDataAsync
+
+ let h = rgbaData.GetLength 0
+ let w = rgbaData.GetLength 1
+
+ use img = new Image(w, h)
+
+ for x in 0 .. h - 1 do
+ for y in 0 .. w - 1 do
+ img.[y, x] <- rgbaData.[x, y]
+
+ let! _ = img.SaveAsync file |> Async.AwaitTask
+ return ()
+ }
+
+ let processPixel px py (filter: float32 array) filterD (img: Rgba32[,]) imgH imgW =
+ let dataToHandle = [|
+ for i in px - filterD .. px + filterD do
+ for j in py - filterD .. py + filterD do
+ if i < 0 || i >= imgH || j < 0 || j >= imgW then
+ 0.0f, 0.0f, 0.0f
+ else
+ let pixel = img.[i, j]
+ float32 pixel.R, float32 pixel.G, float32 pixel.B
+ |]
+
+ let mutable rSum = 0.0f
+ let mutable gSum = 0.0f
+ let mutable bSum = 0.0f
+
+ Array.iteri (fun index (r, g, b) ->
+ rSum <- rSum + r * filter.[index]
+ gSum <- gSum + g * filter.[index]
+ bSum <- bSum + b * filter.[index]
+ ) dataToHandle
+
+ byte rSum, byte gSum, byte bSum // Async<[,]>
+
+ let applyFilterNoParallelismA (filter: float32[][]) (imgAsync: Async) =
+ async {
+ let! img = imgAsync
+
+ let imgH = img.GetLength 0
+ let imgW = img.GetLength 1
+
+ let filterD = Array.length filter / 2
+ let filter = Array.concat filter
+
+ let res =
+ Array2D.mapi (fun x y _ ->
+ let r, g, b = processPixel x y filter filterD img imgH imgW
+ Rgba32(r, g, b, img.[x, y].A)
+ ) img
+ return res
+ }
+
+ let applyFilterPixelParallelismA (filter: float32[][]) (imgAsync: Async) =
+ async {
+ let! img = imgAsync
+
+ let imgH = img.GetLength 0
+ let imgW = img.GetLength 1
+
+ let filterD = Array.length filter / 2
+ let filter = Array.concat filter
+
+ let res = Array2D.create imgH imgW (Rgba32(0.0f, 0.0f, 0.0f, 0.0f))
+
+ Parallel.For(0, imgH * imgW, fun k ->
+ let i = k / imgW
+ let j = k % imgW
+
+ let r, g, b = processPixel i j filter filterD img imgH imgW
+ res.[i, j] <- Rgba32(r, g, b, img.[i, j].A)
+
+ ) |> ignore
+
+ return res
+ }
+
+ let applyFilterParallelismInPartsA (filter: float32[][]) (imgAsync: Async) =
+ async {
+ let! img = imgAsync
+
+ let imgH = img.GetLength 0
+ let imgW = img.GetLength 1
+
+ let filterD = Array.length filter / 2
+ let filter = Array.concat filter
+
+ let halfImgH = imgH / 2
+ let halfImgW = imgW / 2
+
+ let res = Array2D.create imgH imgW (Rgba32(0.0f, 0.0f, 0.0f, 0.0f))
+
+ Parallel.For (0, 4, fun k ->
+ if k = 0 then
+ for i in 0 .. halfImgH - 1 do
+ for j in 0 .. halfImgW - 1 do
+ let r, g, b = processPixel i j filter filterD img imgH imgW
+ res.[i, j] <- Rgba32(r, g, b, img.[i, j].A)
+
+ elif k = 1 then
+ for i in halfImgH .. imgH - 1 do
+ for j in 0 .. halfImgW - 1 do
+ let r, g, b = processPixel i j filter filterD img imgH imgW
+ res.[i, j] <- Rgba32(r, g, b, img.[i, j].A)
+
+ elif k = 2 then
+ for i in 0 .. halfImgH - 1 do
+ for j in halfImgW .. imgW - 1 do
+ let r, g, b = processPixel i j filter filterD img imgH imgW
+ res.[i, j] <- Rgba32(r, g, b, img.[i, j].A)
+
+ else
+ for i in halfImgH .. imgH - 1 do
+ for j in halfImgW .. imgW - 1 do
+ let r, g, b = processPixel i j filter filterD img imgH imgW
+ res.[i, j] <- Rgba32(r, g, b, img.[i, j].A)
+ ) |> ignore
+
+ return res
+ }
+
+ let applyFilterRowParallelismA (filter: float32[][]) (imgAsync: Async) =
+ async {
+ let! img = imgAsync
+
+ let imgH = img.GetLength 0
+ let imgW = img.GetLength 1
+
+ let filterD = Array.length filter / 2
+ let filter = Array.concat filter
+
+ let res = Array2D.create imgH imgW (Rgba32(0.0f, 0.0f, 0.0f, 0.0f))
+
+ Parallel.For (0, imgH, fun k ->
+ for i in 0 .. imgW - 1 do
+ let r, g, b = processPixel k i filter filterD img imgH imgW
+ res.[k, i] <- Rgba32(r, g, b, img.[k, i].A)
+ ) |> ignore
+
+ return res
+ }
+
+ let applyFilterColParallelismA (filter: float32[][]) (imgAsync: Async) =
+ async {
+ let! img = imgAsync
+
+ let imgH = img.GetLength 0
+ let imgW = img.GetLength 1
+
+ let filterD = Array.length filter / 2
+ let filter = Array.concat filter
+
+ let res = Array2D.create imgH imgW (Rgba32(0.0f, 0.0f, 0.0f, 0.0f))
+
+ Parallel.For (0, imgW, fun k ->
+ for i in 0 .. imgH - 1 do
+ let r, g, b = processPixel i k filter filterD img imgH imgW
+ res.[i, k] <- Rgba32(r, g, b, img.[i, k].A)
+ ) |> ignore
+
+ return res
+ }
+
+
+
+// СИНХРОННАЯ ВЕРСИЯ ФУНКЦИЙ ВЫШЕ
+
+
let loadAsRgba2D (file: string) =
let img = Image.Load file
let res = Array2D.zeroCreate img.Height img.Width
@@ -190,12 +380,11 @@ module ImProcessing =
for i in 0 .. img.Width - 1 do
for j in 0 .. img.Height - 1 do
res.[j, i] <- img.[i, j]
-
res
let saveRgbaImage (rgbaData: Rgba32[,]) file =
- let h = rgbaData.GetLength(0)
- let w = rgbaData.GetLength(1)
+ let h = rgbaData.GetLength 0
+ let w = rgbaData.GetLength 1
use img = new Image(w, h)
@@ -203,39 +392,106 @@ module ImProcessing =
for y in 0 .. w - 1 do
img.[y, x] <- rgbaData.[x, y]
- img.Save(file)
+ img.Save file
- let applyFilter (filter: float32[][]) (img: Rgba32[,]) =
+ let applyFilterNoParallelism (filter: float32[][]) (img: Rgba32[,]) =
let imgH = img.GetLength 0
let imgW = img.GetLength 1
- let filterD = (Array.length filter) / 2
+ let filterD = Array.length filter / 2
let filter = Array.concat filter
- let processPixel px py =
- let dataToHandle = [|
- for i in px - filterD .. px + filterD do
- for j in py - filterD .. py + filterD do
- if i < 0 || i >= imgH || j < 0 || j >= imgW then
- (0.0f, 0.0f, 0.0f)
- else
- let pixel = img.[i, j]
- (float32 pixel.R, float32 pixel.G, float32 pixel.B)
- |]
-
- let mutable rSum = 0.0f
- let mutable gSum = 0.0f
- let mutable bSum = 0.0f
-
- Array.iteri (fun index (r, g, b) ->
- rSum <- rSum + r * filter.[index]
- gSum <- gSum + g * filter.[index]
- bSum <- bSum + b * filter.[index]
- ) dataToHandle
-
- (byte rSum, byte gSum, byte bSum)
-
Array2D.mapi (fun x y _ ->
- let (r, g, b) = processPixel x y
+ let r, g, b = processPixel x y filter filterD img imgH imgW
Rgba32(r, g, b, img.[x, y].A)
- ) img
\ No newline at end of file
+ ) img
+
+ let applyFilterPixelParallelism (filter: float32[][]) (img: Rgba32[,]) =
+ let imgH = img.GetLength 0
+ let imgW = img.GetLength 1
+
+ let filterD = Array.length filter / 2
+ let filter = Array.concat filter
+
+ let res = Array2D.create imgH imgW (Rgba32(0.0f, 0.0f, 0.0f, 0.0f))
+
+ Parallel.For(0, imgH * imgW, fun k ->
+ let i = k / imgW
+ let j = k % imgW
+
+ let r, g, b = processPixel i j filter filterD img imgH imgW
+ res.[i, j] <- Rgba32(r, g, b, img.[i, j].A)
+
+ ) |> ignore
+ res
+
+ let applyFilterParallelismInParts (filter: float32[][]) (img: Rgba32[,]) =
+ let imgH = img.GetLength 0
+ let imgW = img.GetLength 1
+
+ let filterD = Array.length filter / 2
+ let filter = Array.concat filter
+
+ let halfImgH = imgH / 2
+ let halfImgW = imgW / 2
+
+ let res = Array2D.create imgH imgW (Rgba32(0.0f, 0.0f, 0.0f, 0.0f))
+
+ Parallel.For (0, 4, fun k ->
+ if k = 0 then
+ for i in 0 .. halfImgH - 1 do
+ for j in 0 .. halfImgW - 1 do
+ let r, g, b = processPixel i j filter filterD img imgH imgW
+ res.[i, j] <- Rgba32(r, g, b, img.[i, j].A)
+
+ elif k = 1 then
+ for i in halfImgH .. imgH - 1 do
+ for j in 0 .. halfImgW - 1 do
+ let r, g, b = processPixel i j filter filterD img imgH imgW
+ res.[i, j] <- Rgba32(r, g, b, img.[i, j].A)
+
+ elif k = 2 then
+ for i in 0 .. halfImgH - 1 do
+ for j in halfImgW .. imgW - 1 do
+ let r, g, b = processPixel i j filter filterD img imgH imgW
+ res.[i, j] <- Rgba32(r, g, b, img.[i, j].A)
+
+ else
+ for i in halfImgH .. imgH - 1 do
+ for j in halfImgW .. imgW - 1 do
+ let r, g, b = processPixel i j filter filterD img imgH imgW
+ res.[i, j] <- Rgba32(r, g, b, img.[i, j].A)
+ ) |> ignore
+ res
+
+ let applyFilterRowParallelism (filter: float32[][]) (img: Rgba32[,]) =
+ let imgH = img.GetLength 0
+ let imgW = img.GetLength 1
+
+ let filterD = Array.length filter / 2
+ let filter = Array.concat filter
+
+ let res = Array2D.create imgH imgW (Rgba32(0.0f, 0.0f, 0.0f, 0.0f))
+
+ Parallel.For (0, imgH, fun k ->
+ for i in 0 .. imgW - 1 do
+ let r, g, b = processPixel k i filter filterD img imgH imgW
+ res.[k, i] <- Rgba32(r, g, b, img.[k, i].A)
+ ) |> ignore
+ res
+
+ let applyFilterColParallelism (filter: float32[][]) (img: Rgba32[,]) =
+ let imgH = img.GetLength 0
+ let imgW = img.GetLength 1
+
+ let filterD = Array.length filter / 2
+ let filter = Array.concat filter
+
+ let res = Array2D.create imgH imgW (Rgba32(0.0f, 0.0f, 0.0f, 0.0f))
+
+ Parallel.For (0, imgW, fun k ->
+ for i in 0 .. imgH - 1 do
+ let r, g, b = processPixel i k filter filterD img imgH imgW
+ res.[i, k] <- Rgba32(r, g, b, img.[i, k].A)
+ ) |> ignore
+ res
\ No newline at end of file
diff --git a/src/ImageProcessing/Program.fs b/src/ImageProcessing/Program.fs
index f78667ad..e191ff74 100644
--- a/src/ImageProcessing/Program.fs
+++ b/src/ImageProcessing/Program.fs
@@ -1,72 +1,163 @@
-open ImageProcessing.ImProcessing
+open System
+open System.Threading.Tasks
+open System.IO
+open ImageProcessing.ImProcessing
open Argu
-
+open SixLabors.ImageSharp.PixelFormats
type Filters =
- | gaussianBlur = 1
- | motionDiagonal135deg = 2
- | motionDiagonal315deg = 3
- | motionVertical = 4
- | motionHorizontal = 5
- | edgesHorizontal = 6
- | edgesVertical = 7
- | edgesDioganal135deg = 8
- | edgesDioganal315deg = 9
- | edgesAllDirections = 10
- | sharpen = 11
- | sharpenSoft = 12
- | sharpenWithEdges = 13
- | emboss = 14
- | embossHard = 15
+ | GaussianBlur
+ | MotionDiagonal135deg
+ | MotionDiagonal315deg
+ | MotionVertical
+ | MotionHorizontal
+ | EdgesHorizontal
+ | EdgesVertical
+ | EdgesDioganal135deg
+ | EdgesDioganal315deg
+ | EdgesAllDirections
+ | Sharpen
+ | SharpenSoft
+ | SharpenWithEdges
+ | Emboss
+ | EmbossHard
+
+
+type ParallelismTypes =
+ | NoParallelism
+ | PixelParallelism
+ | ParallelismInParts
+ | RowParallelism
+ | ColParallelism
+
type Arguments =
- | [] Input_File of string
- | [] Out_File of string
+ | [] Input_Folder of string
+ | [] Out_Folder of string
| [] Filters of list
+ | [] Parallelism of list
interface IArgParserTemplate with
member this.Usage =
match this with
- | Input_File _ -> "File to process."
- | Out_File _ -> "Where to save result."
+ | Input_Folder _ -> "Folder with images for processing."
+ | Out_Folder _ -> "Folder for processed images."
| Filters _ -> "Which filters to apply (comma-separated)."
+ | Parallelism _ -> "Type of parallelism."
+
+
+type FileProcessorMessage =
+ | ProcessImage of string * string * list * list * AsyncReplyChannel>
+ | Stop
+
+
+let createFileProcessor () =
+ let getParallelismType (parallelism: list) (filter: float32[][]) (img: Async) =
+ match parallelism.[0] with
+ | NoParallelism -> applyFilterColParallelismA filter img
+ | PixelParallelism -> applyFilterPixelParallelismA filter img
+ | ParallelismInParts -> applyFilterParallelismInPartsA filter img
+ | RowParallelism -> applyFilterRowParallelismA filter img
+ | ColParallelism -> applyFilterColParallelismA filter img
+
+ MailboxProcessor.Start(fun inbox ->
+
+ let rec loop () =
+ async {
+ let! msg = inbox.Receive()
+
+ match msg with
+ | ProcessImage (sourcePath, destinationPath, filters, parallelism, replyChannel) ->
+ try
+ let imageData = loadAsRgba2DA sourcePath
+ let! filteredImage =
+ filters |> List.fold (fun img filter ->
+ match filter with
+ | GaussianBlur -> getParallelismType parallelism gaussianBlur img
+ | MotionDiagonal135deg -> getParallelismType parallelism motionDiagonal135deg img
+ | MotionDiagonal315deg -> getParallelismType parallelism motionDiagonal315deg img
+ | MotionVertical -> getParallelismType parallelism motionVertical img
+ | MotionHorizontal -> getParallelismType parallelism motionHorizontal img
+ | EdgesHorizontal -> getParallelismType parallelism edgesHorizontal img
+ | EdgesVertical -> getParallelismType parallelism edgesVertical img
+ | EdgesDioganal135deg -> getParallelismType parallelism edgesDioganal135deg img
+ | EdgesDioganal315deg -> getParallelismType parallelism edgesDioganal315deg img
+ | EdgesAllDirections -> getParallelismType parallelism edgesAllDirections img
+ | Sharpen -> getParallelismType parallelism sharpen img
+ | SharpenSoft -> getParallelismType parallelism sharpenSoft img
+ | SharpenWithEdges -> getParallelismType parallelism sharpenWithEdges img
+ | Emboss -> getParallelismType parallelism emboss img
+ | EmbossHard -> getParallelismType parallelism embossHard img
+
+ ) imageData
+
+ do! saveRgbaImageA (async.Return filteredImage) destinationPath
+ replyChannel.Reply(Ok ())
+ return! loop ()
+ with
+ | ex ->
+ replyChannel.Reply(Error ex.Message)
+ return! loop ()
+
+ | Stop ->
+ return ()
+ }
+ loop ()
+ )
[]
let main argv =
-
+
+ let fileProcessor = createFileProcessor ()
+
+ let processImageAsync (sourcePath: string) (destinationPath: string) (filters: list) (parallelism: list) =
+ async {
+ let! reply = fileProcessor.PostAndAsyncReply (fun replyChannel -> ProcessImage(sourcePath, destinationPath, filters, parallelism, replyChannel))
+ return reply
+ }
+
let parser = ArgumentParser.Create(programName = "ImageProcessing")
let results = parser.Parse argv
- let inFile = results.GetResult Input_File
- let outFile = results.GetResult Out_File
+ let inFolder = results.GetResult Input_Folder
+ let outFolder = results.GetResult Out_Folder
let filters = results.GetResult Filters
+ let parallelisms = results.GetResult Parallelism
+
+
+ if not (Directory.Exists inFolder) then
+ printfn $"Error: Input folder '{inFolder}' does not exist."
+ 1
+ else
+ let imageFiles =
+ try
+ Directory.GetFiles(inFolder, "*.*")
+ |> Array.filter (fun file ->
+ let extension = Path.GetExtension file
+ extension.ToLower() = ".jpg" || extension.ToLower() = ".jpeg" || extension.ToLower() = ".png" || extension.ToLower() = ".bmp")
+ |> Array.toList
+ with ex ->
+ printfn $"Error getting image files from '{inFolder}': {ex.Message}"
+ []
+
+ if imageFiles.IsEmpty then
+ printfn $"Error: No images found in input folder '{inFolder}'."
+ 1
+ else
+ Directory.CreateDirectory outFolder |> ignore
+
+ let processingTasks =
+ imageFiles
+ |> List.map (fun sourcePath ->
+ let filename = Path.GetFileName sourcePath
+ let destinationPath = Path.Combine(outFolder, filename)
+ processImageAsync sourcePath destinationPath filters parallelisms
+ )
+
+ Async.AwaitTask (Task.WhenAll(processingTasks |> List.map Async.StartAsTask |> List.toArray)) |> Async.RunSynchronously |> ignore
+
+ fileProcessor.Post Stop
+
+ printfn "Processing complete."
- let inImage = loadAsRgba2D inFile
-
- let resultImage =
- filters |> List.fold (fun img filter ->
- match filter with
- | Filters.gaussianBlur -> applyFilter gaussianBlur img
- | Filters.motionDiagonal135deg -> applyFilter motionDiagonal135deg img
- | Filters.motionDiagonal315deg -> applyFilter motionDiagonal315deg img
- | Filters.motionVertical -> applyFilter motionVertical img
- | Filters.motionHorizontal -> applyFilter motionHorizontal img
- | Filters.edgesHorizontal -> applyFilter edgesHorizontal img
- | Filters.edgesVertical -> applyFilter edgesVertical img
- | Filters.edgesDioganal135deg -> applyFilter edgesDioganal135deg img
- | Filters.edgesDioganal315deg -> applyFilter edgesDioganal315deg img
- | Filters.edgesAllDirections -> applyFilter edgesAllDirections img
- | Filters.sharpen -> applyFilter sharpen img
- | Filters.sharpenSoft -> applyFilter sharpenSoft img
- | Filters.sharpenWithEdges -> applyFilter sharpenWithEdges img
- | Filters.emboss -> applyFilter emboss img
- | Filters.embossHard -> applyFilter embossHard img
- | _ ->
- printfn "Unknown filter"
- img
-
- ) inImage
-
- saveRgbaImage resultImage outFile
-
- 0
\ No newline at end of file
+ 0
\ No newline at end of file
diff --git a/src/LineralAlgebra/LineralAlgebra.fs b/src/LineralAlgebra/LineralAlgebra.fs
index 46b101cd..422f9120 100644
--- a/src/LineralAlgebra/LineralAlgebra.fs
+++ b/src/LineralAlgebra/LineralAlgebra.fs
@@ -15,15 +15,15 @@ type Matrix<'t> =
module private Private =
- let rec private toCorrectQTreePrivate qtree =
+ let rec toCorrectQTree qtree =
match qtree with
| Leaf value -> Leaf value
| Node (nw, ne, se, sw) ->
- let NW = toCorrectQTreePrivate nw
- let NE = toCorrectQTreePrivate ne
- let SE = toCorrectQTreePrivate se
- let SW = toCorrectQTreePrivate sw
+ let NW = toCorrectQTree nw
+ let NE = toCorrectQTree ne
+ let SE = toCorrectQTree se
+ let SW = toCorrectQTree sw
match NW, NE, SE, SW with
| Leaf value1,
@@ -36,14 +36,13 @@ module private Private =
| _ -> Node (NW, NE, SE, SW)
- let toCorrectQTree qtree =
- qtree |> toCorrectQTreePrivate
-
open Private
module QTrees =
+ let toCorrectQTree qtree =
+ qtree |> toCorrectQTree
let rec map func qtree =
match qtree with
@@ -129,7 +128,15 @@ module QTrees =
Array.max heights + 1
-module Matrix =
+module Matrix =
+
+ let map func (matr: Matrix<'t>) =
+ let res = QTrees.map func matr.qtree
+ { n = matr.n; qtree = res }
+
+ let map2 func (matr1: Matrix<'t>) (matr2: Matrix<'t>) =
+ let res = QTrees.map2 func matr1.qtree matr2.qtree
+ { n = max matr1.n matr2.n; qtree = res }
let rec private add qtree1 qtree2 size (opAdd: 't -> 't -> 't) (opMult: 't -> 't -> 't) =
match qtree1, qtree2 with
diff --git a/src/LineralAlgebra/LineralAlgebra.fsproj b/src/LineralAlgebra/LineralAlgebra.fsproj
index 37391835..f5bc22e4 100644
--- a/src/LineralAlgebra/LineralAlgebra.fsproj
+++ b/src/LineralAlgebra/LineralAlgebra.fsproj
@@ -4,7 +4,7 @@
net8.0
true
LineralAlgebra
- 1.0.4
+ 1.1.0
Me
Also me
This package is part of my homework that will be used in my other homework. But if you somehow stumbled upon it, here's its readme
diff --git a/src/Res/res.png b/src/Res/res.png
new file mode 100644
index 00000000..98e59e00
Binary files /dev/null and b/src/Res/res.png differ
diff --git a/src/img/NewCanvas2.png b/src/img/NewCanvas2.png
new file mode 100644
index 00000000..68717c20
Binary files /dev/null and b/src/img/NewCanvas2.png differ
diff --git a/src/img/id.png b/src/img/id.png
new file mode 100644
index 00000000..d270290e
Binary files /dev/null and b/src/img/id.png differ