diff --git a/Directory.Build.props b/Directory.Build.props index 448bd2c6..dc1d21e5 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -9,5 +9,6 @@ YaccConstructor https://github.com/YaccConstructor/GraphBLAS-sharp + true diff --git a/paket.dependencies b/paket.dependencies index 954dc961..e8631d36 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -18,7 +18,7 @@ nuget System.CodeDom 4.7.0 nuget FSharp.Quotations.Evaluator 2.1.0 nuget FSharpx.Collections 2.1.3 nuget FSharpx.Text.StructuredFormat 2.3.0 -nuget Brahma.FSharp.OpenCL.WorkflowBuilder +nuget Brahma.FSharp.OpenCL.WorkflowBuilder 2.0.0-alpha4 nuget BenchmarkDotNet nuget MathNet.Numerics.FSharp diff --git a/paket.lock b/paket.lock index 43e9500e..7b2b9dd4 100644 --- a/paket.lock +++ b/paket.lock @@ -22,34 +22,34 @@ NUGET System.Threading.Tasks.Extensions (>= 4.5.2) - restriction: >= netstandard2.0 System.ValueTuple (>= 4.5) - restriction: >= netstandard2.0 BenchmarkDotNet.Annotations (0.12.1) - restriction: >= netstandard2.0 - Brahma.FSharp (2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) - Brahma.FSharp.OpenCL.Printer (>= 2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) - Brahma.FSharp.OpenCL.Translator (>= 2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) + Brahma.FSharp (2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) + Brahma.FSharp.OpenCL.Printer (>= 2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) + Brahma.FSharp.OpenCL.Translator (>= 2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) FSharp.Core (>= 4.3.4) - restriction: || (>= net461) (>= netstandard2.1) FSharp.Quotations.Evaluator (>= 2.1) - restriction: || (>= net461) (>= netstandard2.1) - YC.Brahma (>= 2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) - YC.Brahma.OpenCL (>= 2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) - YC.OpenCL.NET (>= 2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) - Brahma.FSharp.OpenCL.AST (2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) + YC.Brahma (>= 2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) + YC.Brahma.OpenCL (>= 2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) + YC.OpenCL.NET (>= 2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) + Brahma.FSharp.OpenCL.AST (2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) FSharp.Core (>= 4.3.4) - restriction: || (>= net461) (>= netstandard2.1) - Brahma.FSharp.OpenCL.Extensions (2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) + Brahma.FSharp.OpenCL.Extensions (2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) FSharp.Core (>= 4.3.4) - restriction: || (>= net461) (>= netstandard2.1) - YC.Brahma.OpenCL (>= 2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) - YC.OpenCL.NET (>= 2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) - Brahma.FSharp.OpenCL.Printer (2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) - Brahma.FSharp.OpenCL.AST (>= 2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) - Brahma.FSharp.OpenCL.Translator (>= 2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) + YC.Brahma.OpenCL (>= 2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) + YC.OpenCL.NET (>= 2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) + Brahma.FSharp.OpenCL.Printer (2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) + Brahma.FSharp.OpenCL.AST (>= 2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) + Brahma.FSharp.OpenCL.Translator (>= 2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) FSharp.Core (>= 4.3.4) - restriction: || (>= net461) (>= netstandard2.1) FSharpx.Collections (>= 2.1.3) - restriction: || (>= net461) (>= netstandard2.1) FSharpx.Text.StructuredFormat (>= 2.3) - restriction: || (>= net461) (>= netstandard2.1) - Brahma.FSharp.OpenCL.Translator (2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) - Brahma.FSharp.OpenCL.AST (>= 2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) - Brahma.FSharp.OpenCL.Extensions (>= 2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) + Brahma.FSharp.OpenCL.Translator (2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) + Brahma.FSharp.OpenCL.AST (>= 2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) + Brahma.FSharp.OpenCL.Extensions (>= 2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) FSharp.Core (>= 4.3.4) - restriction: || (>= net461) (>= netstandard2.1) FSharpx.Collections (>= 2.1.3) - restriction: || (>= net461) (>= netstandard2.1) - Brahma.FSharp.OpenCL.WorkflowBuilder (2.0.0-alpha3) - Brahma.FSharp (>= 2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) - Brahma.FSharp.OpenCL.Extensions (>= 2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) + Brahma.FSharp.OpenCL.WorkflowBuilder (2.0.0-alpha4) + Brahma.FSharp (>= 2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) + Brahma.FSharp.OpenCL.Extensions (>= 2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) FSharp.Core (>= 4.3.4) - restriction: || (>= net461) (>= netstandard2.1) Chessie (0.6) - restriction: >= netcoreapp1.0 FSharp.Core (>= 4.0.1.7-alpha) - restriction: >= netstandard1.6 @@ -521,7 +521,6 @@ NUGET System.Runtime.InteropServices (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net45) (>= netstandard1.1) (< netstandard2.0) (< win8) (< wpa81) (< xamarintvos) (< xamarinwatchos) System.Net.Http (4.3.4) - restriction: || (&& (< net45) (>= net46) (< netstandard1.4) (>= netstandard1.6)) (&& (< net45) (< netstandard1.2) (>= netstandard1.6) (< win8)) (&& (< net45) (< netstandard1.3) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.4) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (< netstandard1.5) (>= netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (>= netcoreapp5.0) (< netstandard2.0)) (&& (< netstandard1.5) (>= netstandard1.6) (>= uap10.0)) Microsoft.NETCore.Platforms (>= 1.1.1) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.6) (< win8) (< wpa81)) (>= netcoreapp5.0) - Microsoft.Win32.Primitives (>= 4.3) - restriction: && (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.6) (< win8) (< wpa81) runtime.native.System (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net45) (< netcoreapp5.0) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) runtime.native.System.Net.Http (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net45) (< netcoreapp5.0) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.2) - restriction: && (< monoandroid) (< monotouch) (< net45) (< netcoreapp5.0) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) @@ -532,7 +531,6 @@ NUGET System.Globalization (>= 4.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.6) (< win8) (< wpa81)) (>= netcoreapp5.0) System.Globalization.Extensions (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net45) (< netcoreapp5.0) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) System.IO (>= 4.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.1) (< netstandard1.3) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.6) (< win8) (< wpa81)) (>= netcoreapp5.0) - System.IO.Compression (>= 4.3) - restriction: && (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.6) (< win8) (< wpa81) System.IO.FileSystem (>= 4.3) - restriction: && (< monoandroid) (< monotouch) (< net45) (< netcoreapp5.0) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) System.Net.Primitives (>= 4.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.1) (< netstandard1.3) (< win8) (< wpa81)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.6) (< win8) (< wpa81)) (>= netcoreapp5.0) System.Resources.ResourceManager (>= 4.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.6) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.3) (< netstandard1.6) (< win8) (< wpa81)) (>= netcoreapp5.0) @@ -921,11 +919,11 @@ NUGET System.Threading (>= 4.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (>= netcoreapp5.0) System.Xml.ReaderWriter (>= 4.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (< monoandroid) (< net45) (>= netstandard1.0) (< netstandard1.3) (< win8) (< wp8) (< wpa81)) (>= netcoreapp5.0) System.Xml.XmlDocument (>= 4.3) - restriction: || (&& (< monoandroid) (< monotouch) (< net45) (>= netstandard1.3) (< win8) (< wpa81) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (>= netcoreapp5.0) - YC.Brahma (2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) - YC.Brahma.OpenCL (2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) - YC.Brahma (>= 2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) - YC.OpenCL.NET (>= 2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) - YC.OpenCL.NET (2.0.0-alpha3) - restriction: || (>= net461) (>= netstandard2.1) + YC.Brahma (2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) + YC.Brahma.OpenCL (2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) + YC.Brahma (>= 2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) + YC.OpenCL.NET (>= 2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) + YC.OpenCL.NET (2.0.0-alpha4) - restriction: || (>= net461) (>= netstandard2.1) ExtraConstraints.Fody (>= 1.14) - restriction: >= netstandard2.0 Microsoft.Build.Framework (>= 16.6) - restriction: >= netstandard2.0 System.CodeDom (>= 4.7) - restriction: >= netstandard2.0 diff --git a/src/GraphBLAS-sharp/Abstracts.fs b/src/GraphBLAS-sharp/Abstracts.fs index 4dd52049..bafa0d2f 100644 --- a/src/GraphBLAS-sharp/Abstracts.fs +++ b/src/GraphBLAS-sharp/Abstracts.fs @@ -1,5 +1,7 @@ namespace GraphBLAS.FSharp +open Brahma.FSharp.OpenCL.WorkflowBuilder.Evaluation + [] type Matrix<'a when 'a : struct and 'a : equality>(nrow: int, ncol: int) = abstract RowCount: int @@ -7,77 +9,81 @@ type Matrix<'a when 'a : struct and 'a : equality>(nrow: int, ncol: int) = default this.RowCount = nrow default this.ColumnCount = ncol - abstract Mask: Mask2D option - abstract Complemented: Mask2D option - - abstract Item: Mask2D option -> Matrix<'a> with get, set - abstract Item: Mask1D option * int -> Vector<'a> with get, set - abstract Item: int * Mask1D option -> Vector<'a> with get, set - abstract Item: int * int -> Scalar<'a> with get, set - abstract Fill: Mask2D option -> Scalar<'a> with set - abstract Fill: Mask1D option * int -> Scalar<'a> with set - abstract Fill: int * Mask1D option -> Scalar<'a> with set - - abstract Mxm: Matrix<'a> -> Mask2D option -> Semiring<'a> -> Matrix<'a> - abstract Mxv: Vector<'a> -> Mask1D option -> Semiring<'a> -> Vector<'a> - abstract EWiseAdd: Matrix<'a> -> Mask2D option -> Monoid<'a> -> Matrix<'a> - abstract EWiseMult: Matrix<'a> -> Mask2D option -> Monoid<'a> -> Matrix<'a> - abstract Apply: Mask1D option -> UnaryOp<'a, 'b> -> Matrix<'b> - abstract ReduceIn: Mask1D option -> Monoid<'a> -> Vector<'a> - abstract ReduceOut: Mask1D option -> Monoid<'a> -> Vector<'a> - abstract Reduce: Monoid<'a> -> Scalar<'a> - abstract T: Matrix<'a> + abstract Clear: unit -> OpenCLEvaluation + abstract Copy: unit -> OpenCLEvaluation> + abstract Resize: int -> int -> OpenCLEvaluation> + abstract GetNNZ: unit -> OpenCLEvaluation + abstract GetTuples: unit -> OpenCLEvaluation<{| Rows: int[]; Columns: int[]; Values: 'a[] |}> + abstract GetMask: ?isComplemented: bool -> OpenCLEvaluation + + abstract Extract: Mask2D option -> OpenCLEvaluation> + abstract Extract: (Mask1D option * int) -> OpenCLEvaluation> + abstract Extract: (int * Mask1D option) -> OpenCLEvaluation> + abstract Extract: (int * int) -> OpenCLEvaluation> + abstract Assign: Mask2D option * Matrix<'a> -> OpenCLEvaluation + abstract Assign: (Mask1D option * int) * Vector<'a> -> OpenCLEvaluation + abstract Assign: (int * Mask1D option) * Vector<'a> -> OpenCLEvaluation + abstract Assign: (int * int) * Scalar<'a> -> OpenCLEvaluation + abstract Assign: Mask2D option * Scalar<'a> -> OpenCLEvaluation + abstract Assign: (Mask1D option * int) * Scalar<'a> -> OpenCLEvaluation + abstract Assign: (int * Mask1D option) * Scalar<'a> -> OpenCLEvaluation + + abstract Mxm: Matrix<'a> -> Mask2D option -> Semiring<'a> -> OpenCLEvaluation> + abstract Mxv: Vector<'a> -> Mask1D option -> Semiring<'a> -> OpenCLEvaluation> + abstract EWiseAdd: Matrix<'a> -> Mask2D option -> Semiring<'a> -> OpenCLEvaluation> + abstract EWiseMult: Matrix<'a> -> Mask2D option -> Semiring<'a> -> OpenCLEvaluation> + abstract Apply: Mask2D option -> UnaryOp<'a, 'b> -> OpenCLEvaluation> + abstract Prune: Mask2D option -> UnaryOp<'a, bool> -> OpenCLEvaluation> + abstract ReduceIn: Mask1D option -> Monoid<'a> -> OpenCLEvaluation> + abstract ReduceOut: Mask1D option -> Monoid<'a> -> OpenCLEvaluation> + abstract Reduce: Monoid<'a> -> OpenCLEvaluation> + abstract Transpose: unit -> OpenCLEvaluation> + abstract Kronecker: Matrix<'a> -> Mask2D option -> Semiring<'a> -> OpenCLEvaluation> static member inline (+) (x: Matrix<'a>, y: Matrix<'a>) = x.EWiseAdd y static member inline (*) (x: Matrix<'a>, y: Matrix<'a>) = x.EWiseMult y static member inline (@.) (x: Matrix<'a>, y: Matrix<'a>) = x.Mxm y static member inline (@.) (x: Matrix<'a>, y: Vector<'a>) = x.Mxv y -and [] Vector<'a when 'a : struct and 'a : equality>(length: int) = - abstract Length: int - default this.Length = length - abstract AsArray: 'a[] - abstract Clear: unit -> unit +and [] Vector<'a when 'a : struct and 'a : equality>(size: int) = + abstract Size: int + default this.Size = size - abstract Mask: Mask1D option - abstract Complemented: Mask1D option + abstract Clear: unit -> OpenCLEvaluation + abstract Copy: unit -> OpenCLEvaluation> + abstract Resize: int -> OpenCLEvaluation> + abstract GetNNZ: unit -> OpenCLEvaluation + abstract GetTuples: unit -> OpenCLEvaluation<{| Indices: int[]; Values: 'a[] |}> + abstract GetMask: ?isComplemented: bool -> OpenCLEvaluation - abstract Item: Mask1D option -> Vector<'a> with get, set - abstract Item: int -> Scalar<'a> with get, set - abstract Fill: Mask1D option -> Scalar<'a> with set + abstract Extract: Mask1D option -> OpenCLEvaluation> + abstract Extract: int -> OpenCLEvaluation> + abstract Assign: Mask1D option * Vector<'a> -> OpenCLEvaluation + abstract Assign: int * Scalar<'a> -> OpenCLEvaluation + abstract Assign: Mask1D option * Scalar<'a> -> OpenCLEvaluation - abstract Vxm: Matrix<'a> -> Mask1D option -> Semiring<'a> -> Vector<'a> - abstract EWiseAdd: Vector<'a> -> Mask1D option -> Monoid<'a> -> Vector<'a> - abstract EWiseMult: Vector<'a> -> Mask1D option -> Monoid<'a> -> Vector<'a> - abstract Apply: Mask1D option -> UnaryOp<'a, 'b> -> Vector<'b> - abstract Reduce: Monoid<'a> -> Scalar<'a> + abstract Vxm: Matrix<'a> -> Mask1D option -> Semiring<'a> -> OpenCLEvaluation> + abstract EWiseAdd: Vector<'a> -> Mask1D option -> Semiring<'a> -> OpenCLEvaluation> + abstract EWiseMult: Vector<'a> -> Mask1D option -> Semiring<'a> -> OpenCLEvaluation> + abstract Apply: Mask1D option -> UnaryOp<'a, 'b> -> OpenCLEvaluation> + abstract Prune: Mask1D option -> UnaryOp<'a, bool> -> OpenCLEvaluation> + abstract Reduce: Monoid<'a> -> OpenCLEvaluation> static member inline (+) (x: Vector<'a>, y: Vector<'a>) = x.EWiseAdd y static member inline (*) (x: Vector<'a>, y: Vector<'a>) = x.EWiseMult y static member inline (@.) (x: Vector<'a>, y: Matrix<'a>) = x.Vxm y -and Mask1D(indices: int[], length: int, isComplemented: bool) = + +and Mask1D(indices: int[], size: int, isComplemented: bool) = member this.Indices = indices - member this.Length = length + member this.Size = size member this.IsComplemented = isComplemented - member this.Item - with get (idx: int) : bool = - this.Indices - |> Array.exists ((=) idx) - |> (<>) this.IsComplemented -and Mask2D(indices: (int * int)[], rowCount: int, columnCount: int, isComplemented: bool) = - member this.Rows = indices |> Array.unzip |> fst - member this.Columns = indices |> Array.unzip |> snd +and Mask2D(rowIndices: int[], columnIndices: int[], rowCount: int, columnCount: int, isComplemented: bool) = + member this.RowIndices = rowIndices + member this.ColumnIndices = columnIndices member this.RowCount = rowCount member this.ColumnCount = columnCount member this.IsComplemented = isComplemented - - member this.Item - with get (rowIdx: int, colIdx: int) : bool = - (this.Rows, this.Columns) - ||> Array.zip - |> Array.exists ((=) (rowIdx, colIdx)) - |> (<>) this.IsComplemented diff --git a/src/GraphBLAS-sharp/Algorithms/BFS.fs b/src/GraphBLAS-sharp/Algorithms/BFS.fs index 07ec3eb5..09c5b705 100644 --- a/src/GraphBLAS-sharp/Algorithms/BFS.fs +++ b/src/GraphBLAS-sharp/Algorithms/BFS.fs @@ -3,23 +3,27 @@ namespace GraphBLAS.FSharp.Algorithms open GraphBLAS.FSharp.Predefined open GraphBLAS.FSharp.Helpers open GraphBLAS.FSharp +open Brahma.FSharp.OpenCL.WorkflowBuilder.Basic +open Brahma.FSharp.OpenCL.WorkflowBuilder.Evaluation [] module BFS = - let levelBFS (matrix: Matrix) (source: int) : Vector = + let levelBFS (matrix: Matrix) (source: int) : OpenCLEvaluation> = let vertexCount = matrix.RowCount - let levels = DenseVector(Array.zeroCreate vertexCount, IntegerMonoid.add) - - let frontier = SparseVector(vertexCount, [source, true]) - - let mutable currentLevel = 1 - while !> (frontier.Reduce BooleanMonoid.any) && currentLevel < vertexCount do - levels.Fill(frontier.Mask) <- Scalar currentLevel - frontier.Clear() - frontier.[levels.Complemented] <- (frontier @. matrix) levels.Complemented BooleanSemiring.anyAll - currentLevel <- currentLevel + 1 - - upcast levels + let levels = Vector.Dense(Array.zeroCreate vertexCount, IntegerMonoid.add) + let frontier = Vector.Sparse(vertexCount, [source, true]) + + opencl { + let mutable currentLevel = 1 + while currentLevel < vertexCount do + let! frontierMask = frontier.GetMask() + do! levels.Assign(frontierMask, Scalar currentLevel) + let! levelsComplemented = levels.GetMask(isComplemented = true) + let! frontier = (frontier @. matrix) levelsComplemented BooleanSemiring.anyAll + currentLevel <- currentLevel + 1 + + return levels + } // let parentBFS (matrix: Matrix) (source: int) : Vector = // let vertexCount = matrix.RowCount diff --git a/src/GraphBLAS-sharp/Algorithms/SSSP.fs b/src/GraphBLAS-sharp/Algorithms/SSSP.fs index 24a42148..ec053e95 100644 --- a/src/GraphBLAS-sharp/Algorithms/SSSP.fs +++ b/src/GraphBLAS-sharp/Algorithms/SSSP.fs @@ -2,14 +2,19 @@ namespace GraphBLAS.FSharp.Algorithms open GraphBLAS.FSharp.Predefined open GraphBLAS.FSharp +open Brahma.FSharp.OpenCL.WorkflowBuilder.Basic +open Brahma.FSharp.OpenCL.WorkflowBuilder.Evaluation [] module SSSP = - let SSSP (matrix: Matrix) (source: int) : Vector = + let SSSP (matrix: Matrix) (source: int) : OpenCLEvaluation> = let vertexCount = matrix.RowCount - let distance = SparseVector(vertexCount, [source, 0.]) + let distance = Vector.Sparse(vertexCount, [source, 0.]) - for _ in 1 .. vertexCount - 1 do - distance.[None] <- (distance @. matrix) None FloatSemiring.minAdd + opencl { + for _ in 1 .. vertexCount - 1 do + let! step = (distance @. matrix) None FloatSemiring.minAdd + do! distance.Assign(None, step) - upcast distance + return distance + } diff --git a/src/GraphBLAS-sharp/Algorithms/TriangleCounting.fs b/src/GraphBLAS-sharp/Algorithms/TriangleCounting.fs index d1596751..b169a906 100644 --- a/src/GraphBLAS-sharp/Algorithms/TriangleCounting.fs +++ b/src/GraphBLAS-sharp/Algorithms/TriangleCounting.fs @@ -2,13 +2,21 @@ namespace GraphBLAS.FSharp.Algorithms open GraphBLAS.FSharp.Predefined open GraphBLAS.FSharp +open Brahma.FSharp.OpenCL.WorkflowBuilder.Basic +open Brahma.FSharp.OpenCL.WorkflowBuilder.Evaluation [] module TriangleCounting = - let sandiaTriangleCount (lowerTriangular: Matrix) = + // скорее всего, тут не скаляр возвращать нужно, а инт + let sandiaTriangleCount (lowerTriangular: Matrix) : OpenCLEvaluation> = let bool2int = function | true -> 1 | false -> 0 - let convertedMatrix = lowerTriangular.Apply None (UnaryOp <@ bool2int @>) - let result = (convertedMatrix @. convertedMatrix.T) lowerTriangular.Mask IntegerSemiring.addMult - result.Reduce IntegerMonoid.add + + opencl { + let! convertedMatrix = lowerTriangular.Apply None (UnaryOp <@ bool2int @>) + let! convertedTransposed = convertedMatrix.Transpose() + let! lowerTriangularMask = lowerTriangular.GetMask() + let! result = (convertedMatrix @. convertedTransposed) lowerTriangularMask IntegerSemiring.addMult + return! result.Reduce IntegerMonoid.add + } diff --git a/src/GraphBLAS-sharp/FodyWeavers.xml b/src/GraphBLAS-sharp/FodyWeavers.xml deleted file mode 100644 index 20aae2eb..00000000 --- a/src/GraphBLAS-sharp/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/GraphBLAS-sharp/FodyWeavers.xsd b/src/GraphBLAS-sharp/FodyWeavers.xsd deleted file mode 100644 index 686bf548..00000000 --- a/src/GraphBLAS-sharp/FodyWeavers.xsd +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/src/GraphBLAS-sharp/Implementations.fs b/src/GraphBLAS-sharp/Implementations.fs index 37e82fe7..0eee848a 100644 --- a/src/GraphBLAS-sharp/Implementations.fs +++ b/src/GraphBLAS-sharp/Implementations.fs @@ -29,10 +29,10 @@ type CSRMatrix<'a when 'a : struct and 'a : equality>(csrTuples: CSRFormat<'a>) let rowCount = base.RowCount let columnCount = base.ColumnCount - let spMV (vector: Vector<'a>) (mask: Mask1D) (semiring: Semiring<'a>) : Vector<'a> = + let spMV (vector: DenseVector<'a>) (mask: Mask1D) (semiring: Semiring<'a>) : OpenCLEvaluation> = let csrMatrixRowCount = rowCount let csrMatrixColumnCount = columnCount - let vectorLength = vector.Length + let vectorLength = vector.Size if csrMatrixColumnCount <> vectorLength then invalidArg "vector" @@ -67,114 +67,104 @@ type CSRMatrix<'a when 'a : struct and 'a : equality>(csrTuples: CSRFormat<'a>) csrTuples.Values csrTuples.Columns csrTuples.RowPointers - vector.AsArray + vector.Values - let eval = opencl { + opencl { do! RunCommand command binder - return! ToHost resultVector + return upcast DenseVector(resultVector, semiring.PlusMonoid) } - upcast DenseVector(oclContext.RunSync eval, semiring.PlusMonoid) + // Not Implemented + new(rows: int[], columns: int[], values: 'a[]) = CSRMatrix(CSRFormat.CreateEmpty()) member this.Values = csrTuples.Values member this.Columns = csrTuples.Columns member this.RowPointers = csrTuples.RowPointers - override this.Mask = failwith "Not implemented" - override this.Complemented = failwith "Not implemented" - - override this.Item - with get (mask: Mask2D option) : Matrix<'a> = failwith "Not Implemented" - and set (mask: Mask2D option) (value: Matrix<'a>) = failwith "Not Implemented" - override this.Item - with get (vectorMask: Mask1D option, colIdx: int) : Vector<'a> = failwith "Not Implemented" - and set (vectorMask: Mask1D option, colIdx: int) (value: Vector<'a>) = failwith "Not Implemented" - override this.Item - with get (rowIdx: int, vectorMask: Mask1D option) : Vector<'a> = failwith "Not Implemented" - and set (rowIdx: int, vectorMask: Mask1D option) (value: Vector<'a>) = failwith "Not Implemented" - override this.Item - with get (rowIdx: int, colIdx: int) : Scalar<'a> = failwith "Not Implemented" - and set (rowIdx: int, colIdx: int) (value: Scalar<'a>) = failwith "Not Implemented" - override this.Fill - with set (mask: Mask2D option) (value: Scalar<'a>) = failwith "Not Implemented" - override this.Fill - with set (vectorMask: Mask1D option, colIdx: int) (value: Scalar<'a>) = failwith "Not Implemented" - override this.Fill - with set (rowIdx: int, vectorMask: Mask1D option) (value: Scalar<'a>) = failwith "Not Implemented" + override this.Clear () = failwith "Not Implemented" + override this.Copy () = failwith "Not Implemented" + override this.Resize a b = failwith "Not Implemented" + override this.GetNNZ () = failwith "Not Implemented" + override this.GetTuples () = failwith "Not Implemented" + override this.GetMask(?isComplemented: bool) = + let isComplemented = defaultArg isComplemented false + failwith "Not Implemented" + + override this.Extract (mask: Mask2D option) : OpenCLEvaluation> = failwith "Not Implemented" + override this.Extract (colMask: Mask1D option * int) : OpenCLEvaluation> = failwith "Not Implemented" + override this.Extract (rowMask: int * Mask1D option) : OpenCLEvaluation> = failwith "Not Implemented" + override this.Extract (idx: int * int) : OpenCLEvaluation> = failwith "Not Implemented" + override this.Assign (mask: Mask2D option, value: Matrix<'a>) : OpenCLEvaluation = failwith "Not Implemented" + override this.Assign (colMask: Mask1D option * int, value: Vector<'a>) : OpenCLEvaluation = failwith "Not Implemented" + override this.Assign (rowMask: int * Mask1D option, value: Vector<'a>) : OpenCLEvaluation = failwith "Not Implemented" + override this.Assign (idx: int * int, value: Scalar<'a>) : OpenCLEvaluation = failwith "Not Implemented" + override this.Assign (mask: Mask2D option, value: Scalar<'a>) : OpenCLEvaluation = failwith "Not Implemented" + override this.Assign (colMask: Mask1D option * int, value: Scalar<'a>) : OpenCLEvaluation = failwith "Not Implemented" + override this.Assign (rowMask: int * Mask1D option, value: Scalar<'a>) : OpenCLEvaluation = failwith "Not Implemented" override this.Mxm a b c = failwith "Not Implemented" override this.Mxv a b c = failwith "Not Implemented" override this.EWiseAdd a b c = failwith "Not Implemented" override this.EWiseMult a b c = failwith "Not Implemented" override this.Apply a b = failwith "Not Implemented" + override this.Prune a b = failwith "Not Implemented" override this.ReduceIn a b = failwith "Not Implemented" override this.ReduceOut a b = failwith "Not Implemented" override this.Reduce a = failwith "Not Implemented" - override this.T = failwith "Not Implemented" - -and SparseVector<'a when 'a : struct and 'a : equality>(size: int, listOfNonzeroes: (int * 'a) list) = - inherit Vector<'a>(size) - - member this.AsList: (int * 'a) list = listOfNonzeroes - - override this.AsArray = failwith "Not Implemented" - override this.Clear() = failwith "Not Implemented" + override this.Transpose () = failwith "Not Implemented" + override this.Kronecker a b c = failwith "Not Implemented" - override this.Mask = failwith "Not implemented" - override this.Complemented = failwith "Not implemented" - override this.Item - with get (mask: Mask1D option) : Vector<'a> = failwith "Not Implemented" - and set (mask: Mask1D option) (value: Vector<'a>) = failwith "Not Implemented" - override this.Item - with get (idx: int) : Scalar<'a> = failwith "Not Implemented" - and set (idx: int) (value: Scalar<'a>) = failwith "Not Implemented" - override this.Fill - with set (mask: Mask1D option) (value: Scalar<'a>) = failwith "Not Implemented" +and SparseVector<'a when 'a : struct and 'a : equality>(size: int, indices: int[], values: 'a[]) = + inherit Vector<'a>(size) - override this.Vxm (matrix: Matrix<'a>) (mask: Mask1D option) (semiring: Semiring<'a>) : Vector<'a> = failwith "Not Implemented" + override this.Clear () = failwith "Not Implemented" + override this.Copy () = failwith "Not Implemented" + override this.Resize a = failwith "Not Implemented" + override this.GetNNZ () = failwith "Not Implemented" + override this.GetTuples () = failwith "Not Implemented" + override this.GetMask(?isComplemented: bool) = + let isComplemented = defaultArg isComplemented false + failwith "Not Implemented" + + override this.Extract (mask: Mask1D option) : OpenCLEvaluation> = failwith "Not Implemented" + override this.Extract (idx: int) : OpenCLEvaluation> = failwith "Not Implemented" + override this.Assign (mask: Mask1D option, vector: Vector<'a>) : OpenCLEvaluation = failwith "Not Implemented" + override this.Assign (idx: int, Scalar (value: 'a)) : OpenCLEvaluation = failwith "Not Implemented" + override this.Assign (mask: Mask1D option, Scalar (value: 'a)) : OpenCLEvaluation = failwith "Not Implemented" + + override this.Vxm (matrix: Matrix<'a>) (mask: Mask1D option) (semiring: Semiring<'a>) : OpenCLEvaluation> = failwith "Not Implemented" override this.EWiseAdd a b c = failwith "Not Implemented" override this.EWiseMult a b c = failwith "Not Implemented" override this.Apply a b = failwith "Not Implemented" + override this.Prune a b = failwith "Not Implemented" override this.Reduce (monoid: Monoid<'a>) = failwith "Not Implemented" + and DenseVector<'a when 'a : struct and 'a : equality>(vector: 'a[], monoid: Monoid<'a>) = inherit Vector<'a>(vector.Length) - // Not Implemented - new(monoid: Monoid<'a>) = DenseVector(Array.zeroCreate<'a> 0, monoid) - // Not Implemented - new(listOfIndices: int list, monoid: Monoid<'a>) = DenseVector(Array.zeroCreate<'a> 0, monoid) - member this.Monoid = monoid - member this.Values = vector - - override this.AsArray = failwith "Not Implemented" - override this.Clear() = failwith "Not Implemented" - - override this.Mask = - let indices = - [| for i in 0 .. this.Length - 1 do - if this.Values.[i] <> this.Monoid.Zero then yield i |] - Some <| Mask1D(indices, this.Length, false) - - override this.Complemented = - let indices = - [| for i in 0 .. this.Length - 1 do - if this.Values.[i] <> this.Monoid.Zero then yield i |] - Some <| Mask1D(indices, this.Length, true) - - override this.Item - with get (mask: Mask1D option) : Vector<'a> = failwith "Not Implemented" - and set (mask: Mask1D option) (value: Vector<'a>) = failwith "Not Implemented" - override this.Item - with get (idx: int) : Scalar<'a> = failwith "Not Implemented" - and set (idx: int) (value: Scalar<'a>) = failwith "Not Implemented" - override this.Fill - with set (mask: Mask1D option) (value: Scalar<'a>) = failwith "Not Implemented" + member this.Values: 'a[] = vector + + override this.Clear () = failwith "Not Implemented" + override this.Copy () = failwith "Not Implemented" + override this.Resize a = failwith "Not Implemented" + override this.GetNNZ () = failwith "Not Implemented" + override this.GetTuples () = failwith "Not Implemented" + override this.GetMask(?isComplemented: bool) = + let isComplemented = defaultArg isComplemented false + failwith "Not Implemented" + + override this.Extract (mask: Mask1D option) : OpenCLEvaluation> = failwith "Not Implemented" + override this.Extract (idx: int) : OpenCLEvaluation> = failwith "Not Implemented" + override this.Assign (mask: Mask1D option, vector: Vector<'a>) : OpenCLEvaluation = failwith "Not Implemented" + override this.Assign (idx: int, Scalar (value: 'a)) : OpenCLEvaluation = failwith "Not Implemented" + override this.Assign (mask: Mask1D option, Scalar (value: 'a)) : OpenCLEvaluation = failwith "Not Implemented" override this.Vxm a b c = failwith "Not Implemented" override this.EWiseAdd a b c = failwith "Not Implemented" override this.EWiseMult a b c = failwith "Not Implemented" override this.Apply a b = failwith "Not Implemented" + override this.Prune a b = failwith "Not Implemented" override this.Reduce (monoid: Monoid<'a>) = failwith "Not Implemented" diff --git a/src/GraphBLAS-sharp/Matrix.fs b/src/GraphBLAS-sharp/Matrix.fs index a85848b8..dc2a29c9 100644 --- a/src/GraphBLAS-sharp/Matrix.fs +++ b/src/GraphBLAS-sharp/Matrix.fs @@ -1,14 +1,21 @@ namespace GraphBLAS.FSharp module MatrixBackend = - // можно убрать перегрузку и добавить возможность partitial application type Matrix<'a when 'a : struct and 'a : equality> with static member Build(denseMatrix: 'T[,], zero: 'T, matrixType: MatrixBackendFormat) : Matrix<'T> = failwith "Not Implemented" + + static member Build(rows: int[], columns: int[], values: 'T[], matrixType: MatrixBackendFormat) : Matrix<'T> = + match matrixType with + | CSR -> upcast CSRMatrix(rows, columns, values) + | _ -> failwith "Not Implemented" + static member Build(pathToMatrix: string, matrixType: MatrixBackendFormat) : Matrix<'T> = failwith "Not Implemented" + static member Build(rowCount: int, columnCount: int, initializer: int -> int -> 'T, matrixType: MatrixBackendFormat) : Matrix<'T> = failwith "Not Implemented" + static member ZeroCreate(rowCount: int, columnCount: int, matrixType: MatrixBackendFormat) : Matrix<'T> = failwith "Not Implemented" @@ -18,10 +25,16 @@ module MatrixExtensions = type Matrix<'a when 'a : struct and 'a : equality> with static member Build(denseMatrix: 'T[,], zero: 'T) : Matrix<'T> = Matrix.Build(denseMatrix, zero, matrixBackendFormat) + + static member Build(rows: int[], columns: int[], values: 'T[]) : Matrix<'T> = + Matrix.Build(rows, columns, values) + static member Build(pathToMatrix: string) : Matrix<'T> = Matrix.Build(pathToMatrix, matrixBackendFormat) + static member Build(rowCount: int, columnCount: int, initializer: int -> int -> 'T) : Matrix<'T> = Matrix.Build(rowCount, columnCount, initializer, matrixBackendFormat) + static member ZeroCreate(rowCount: int, columnCount: int) : Matrix<'T> = Matrix.ZeroCreate(rowCount, columnCount) diff --git a/src/GraphBLAS-sharp/Vector.fs b/src/GraphBLAS-sharp/Vector.fs index 7c35c247..d4157037 100644 --- a/src/GraphBLAS-sharp/Vector.fs +++ b/src/GraphBLAS-sharp/Vector.fs @@ -5,17 +5,26 @@ module VectorExtensions = type Vector<'a when 'a : struct and 'a : equality> with static member Sparse(denseVector: 'T[], zero: 'T) : Vector<'T> = failwith "Not Implemented" + + static member Sparse(length: int, values: (int * 'T) list) : Vector<'T> = + failwith "Not Implemented" + static member Sparse(length: int, initializer: int -> 'T) : Vector<'T> = failwith "Not Implemented" + static member ZeroSparse(length: int) : Vector<'T> = - failwith "Not Implemented" + upcast SparseVector(length, Array.zeroCreate 0, Array.zeroCreate<'T> 0) + static member Dense(denseVector: 'T[], monoid: Monoid<'T>) : Vector<'T> = - failwith "Not Implemented" + upcast DenseVector(denseVector, monoid) + static member Dense(length: int, initializer: int -> 'T, monoid: Monoid<'T>) : Vector<'T> = - failwith "Not Implemented" + upcast DenseVector(Array.init length initializer, monoid) + static member ZeroDense(length: int, monoid: Monoid<'T>) : Vector<'T> = - failwith "Not Implemented" + upcast DenseVector(Array.create length monoid.Zero, monoid) + [] module Vector = diff --git a/tests/GraphBLAS-sharp.Tests/FodyWeavers.xml b/tests/GraphBLAS-sharp.Tests/FodyWeavers.xml deleted file mode 100644 index 20aae2eb..00000000 --- a/tests/GraphBLAS-sharp.Tests/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/tests/GraphBLAS-sharp.Tests/FodyWeavers.xsd b/tests/GraphBLAS-sharp.Tests/FodyWeavers.xsd deleted file mode 100644 index 686bf548..00000000 --- a/tests/GraphBLAS-sharp.Tests/FodyWeavers.xsd +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/tests/GraphBLAS-sharp.Tests/OperationsTests/VxmTests.fs b/tests/GraphBLAS-sharp.Tests/OperationsTests/VxmTests.fs index 04320660..a5bf6215 100644 --- a/tests/GraphBLAS-sharp.Tests/OperationsTests/VxmTests.fs +++ b/tests/GraphBLAS-sharp.Tests/OperationsTests/VxmTests.fs @@ -4,6 +4,8 @@ open Expecto open FsCheck open GraphBLAS.FSharp open MathNet.Numerics +open Brahma.FSharp.OpenCL.WorkflowBuilder.Basic +open GlobalContext type OperationCase = { VectorCase: VectorType @@ -106,14 +108,24 @@ module VxmTests = let emptyVector = zeroVectorConstructor vectorSize Expect.throwsT - (fun () -> (emptyVector @. emptyMatrix) mask stdSemiring |> ignore) + (fun () -> + opencl { + return! (emptyVector @. emptyMatrix) mask stdSemiring + } + |> oclContext.RunSync + |> ignore + ) (sprintf "1x%i @ %ix%i\n case:\n %A" vectorSize matrixRowCount matrixColumnCount case) testPropertyWithConfig config "Operation should have correct semantic" <| fun (denseMatrix: float[,]) (denseVector: float[]) -> let matrix = Matrix.Build(denseMatrix, 0., matrixBackend) let vector = vectorConstructor denseVector - let result = (vector @. matrix) mask stdSemiring + let result = + opencl { + return! (vector @. matrix) mask stdSemiring + } + |> oclContext.RunSync let a = LinearAlgebra.DenseMatrix.ofArray2 denseMatrix let b = LinearAlgebra.DenseVector.ofArray denseVector let c = b * a