From 146b17fa885906a1128244dbfa9fd575e63f80d2 Mon Sep 17 00:00:00 2001 From: ArtiomPatov Date: Tue, 21 Mar 2023 23:01:37 +0300 Subject: [PATCH 1/9] add: Matrix.map --- .../GraphBLAS-sharp.Backend.fsproj | 2 + .../Matrix/COOMatrix/Map.fs | 117 ++++++++++ .../Matrix/COOMatrix/Matrix.fs | 2 + .../Matrix/CSRMatrix/Map.fs | 155 +++++++++++++ .../Matrix/CSRMatrix/Matrix.fs | 2 + src/GraphBLAS-sharp.Backend/Matrix/Matrix.fs | 15 ++ .../GraphBLAS-sharp.Tests.fsproj | 1 + tests/GraphBLAS-sharp.Tests/Matrix/Map.fs | 206 ++++++++++++++++++ tests/GraphBLAS-sharp.Tests/Program.fs | 3 + 9 files changed, 503 insertions(+) create mode 100644 src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map.fs create mode 100644 src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs create mode 100644 tests/GraphBLAS-sharp.Tests/Matrix/Map.fs diff --git a/src/GraphBLAS-sharp.Backend/GraphBLAS-sharp.Backend.fsproj b/src/GraphBLAS-sharp.Backend/GraphBLAS-sharp.Backend.fsproj index affc7f5a..b3d7f503 100644 --- a/src/GraphBLAS-sharp.Backend/GraphBLAS-sharp.Backend.fsproj +++ b/src/GraphBLAS-sharp.Backend/GraphBLAS-sharp.Backend.fsproj @@ -37,9 +37,11 @@ + + diff --git a/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map.fs b/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map.fs new file mode 100644 index 00000000..4ff9a1e5 --- /dev/null +++ b/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map.fs @@ -0,0 +1,117 @@ +namespace GraphBLAS.FSharp.Backend.Matrix.COO + +open Brahma.FSharp +open GraphBLAS.FSharp.Backend.Matrix +open Microsoft.FSharp.Quotations +open GraphBLAS.FSharp.Backend.Objects +open GraphBLAS.FSharp.Backend +open GraphBLAS.FSharp.Backend.Objects.ClMatrix +open GraphBLAS.FSharp.Backend.Objects.ClContext + + +module Map = + let preparePositions<'a, 'b> (clContext: ClContext) workGroupSize opAdd = + + let preparePositions (op: Expr<'a option -> 'b option>) = + <@ fun (ndRange: Range1D) rowCount columnCount valuesLength (values: ClArray<'a>) (rowPointers: ClArray) (columns: ClArray) (resultBitmap: ClArray) (resultValues: ClArray<'b>) (resultRows: ClArray) (resultColumns: ClArray) -> + + let gid = ndRange.GlobalID0 + + if gid < rowCount * columnCount then + + let columnIndex = gid % columnCount + let rowIndex = gid / columnCount + + let index = + (uint64 rowIndex <<< 32) ||| (uint64 columnIndex) + + let value = + (%Map2.binSearch) valuesLength index rowPointers columns values + + match (%op) value with + | Some resultValue -> + resultValues.[gid] <- resultValue + resultRows.[gid] <- rowIndex + resultColumns.[gid] <- columnIndex + + resultBitmap.[gid] <- 1 + | None -> resultBitmap.[gid] <- 0 @> + + + let kernel = + clContext.Compile <| preparePositions opAdd + + fun (processor: MailboxProcessor<_>) rowCount columnCount (values: ClArray<'a>) (rowPointers: ClArray) (columns: ClArray) -> + + let (resultLength: int) = columnCount * rowCount + + let resultBitmap = + clContext.CreateClArrayWithSpecificAllocationMode(DeviceOnly, resultLength) + + let resultRows = + clContext.CreateClArrayWithSpecificAllocationMode(DeviceOnly, resultLength) + + let resultColumns = + clContext.CreateClArrayWithSpecificAllocationMode(DeviceOnly, resultLength) + + let resultValues = + clContext.CreateClArrayWithSpecificAllocationMode<'b>(DeviceOnly, resultLength) + + let ndRange = + Range1D.CreateValid(resultLength, workGroupSize) + + let kernel = kernel.GetKernel() + + processor.Post( + Msg.MsgSetArguments + (fun () -> + kernel.KernelFunc + ndRange + rowCount + columnCount + values.Length + values + rowPointers + columns + resultBitmap + resultValues + resultRows + resultColumns) + ) + + processor.Post(Msg.CreateRunMsg<_, _> kernel) + + resultBitmap, resultValues, resultRows, resultColumns + + + let run<'a, 'b when 'a: struct and 'b: struct and 'b: equality> + (clContext: ClContext) + (opAdd: Expr<'a option -> 'b option>) + workGroupSize + = + + let map = + preparePositions clContext workGroupSize opAdd + + let setPositions = + Common.setPositions<'b> clContext workGroupSize + + fun (queue: MailboxProcessor<_>) allocationMode (matrix: ClMatrix.COO<'a>) -> + + let bitmap, values, rows, columns = + map queue matrix.RowCount matrix.ColumnCount matrix.Values matrix.Rows matrix.Columns + + let resultRows, resultColumns, resultValues, _ = + setPositions queue allocationMode rows columns values bitmap + + queue.Post(Msg.CreateFreeMsg<_>(bitmap)) + queue.Post(Msg.CreateFreeMsg<_>(values)) + queue.Post(Msg.CreateFreeMsg<_>(rows)) + queue.Post(Msg.CreateFreeMsg<_>(columns)) + + { Context = clContext + RowCount = matrix.RowCount + ColumnCount = matrix.ColumnCount + Rows = resultRows + Columns = resultColumns + Values = resultValues } diff --git a/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Matrix.fs b/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Matrix.fs index b7714251..d4ef9174 100644 --- a/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Matrix.fs +++ b/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Matrix.fs @@ -8,6 +8,8 @@ open GraphBLAS.FSharp.Backend.Objects open GraphBLAS.FSharp.Backend.Objects.ClMatrix module Matrix = + let map = Map.run + let map2 = Map2.run ///. diff --git a/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs b/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs new file mode 100644 index 00000000..bbd5098a --- /dev/null +++ b/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs @@ -0,0 +1,155 @@ +namespace GraphBLAS.FSharp.Backend.Matrix.CSR + +open Brahma.FSharp +open FSharp.Quotations +open GraphBLAS.FSharp.Backend +open GraphBLAS.FSharp.Backend.Matrix +open GraphBLAS.FSharp.Backend.Matrix.COO +open GraphBLAS.FSharp.Backend.Objects +open GraphBLAS.FSharp.Backend.Objects.ClMatrix +open GraphBLAS.FSharp.Backend.Objects.ClContext + +module Map = + let binSearch<'a> = + <@ fun startIndex nnzInRow sourceColumn (columnIndices: ClArray) (values: ClArray<'a>) -> + + let mutable leftEdge = startIndex + let mutable rightEdge = startIndex + nnzInRow - 1 + + let mutable result = None + + while leftEdge <= rightEdge do + let middleIdx = (leftEdge + rightEdge) / 2 + + let currentColumn = columnIndices.[middleIdx] + + if sourceColumn = currentColumn then + result <- Some values.[middleIdx] + + rightEdge <- -1 // TODO() break + elif sourceColumn < currentColumn then + rightEdge <- middleIdx - 1 + else + leftEdge <- middleIdx + 1 + + result @> + + let preparePositions<'a, 'b> (clContext: ClContext) workGroupSize opAdd = + + let preparePositions (op: Expr<'a option -> 'b option>) = + <@ fun (ndRange: Range1D) rowCount columnCount (values: ClArray<'a>) (rowPointers: ClArray) (columns: ClArray) (resultBitmap: ClArray) (resultValues: ClArray<'b>) (resultRows: ClArray) (resultColumns: ClArray) -> + + let gid = ndRange.GlobalID0 + + if gid < rowCount * columnCount then + + let columnIndex = gid % columnCount + let rowIndex = gid / columnCount + + let nnzInRow = + rowPointers.[rowIndex + 1] + - rowPointers.[rowIndex] + + let value = + (%binSearch) rowPointers.[rowIndex] nnzInRow columnIndex columns values + + match (%op) value with + | Some resultValue -> + resultValues.[gid] <- resultValue + resultRows.[gid] <- rowIndex + resultColumns.[gid] <- columnIndex + + resultBitmap.[gid] <- 1 + | None -> resultBitmap.[gid] <- 0 @> + + let kernel = + clContext.Compile <| preparePositions opAdd + + fun (processor: MailboxProcessor<_>) rowCount columnCount (values: ClArray<'a>) (rowPointers: ClArray) (columns: ClArray) -> + + let (resultLength: int) = columnCount * rowCount + + let resultBitmap = + clContext.CreateClArrayWithSpecificAllocationMode(DeviceOnly, resultLength) + + let resultRows = + clContext.CreateClArrayWithSpecificAllocationMode(DeviceOnly, resultLength) + + let resultColumns = + clContext.CreateClArrayWithSpecificAllocationMode(DeviceOnly, resultLength) + + let resultValues = + clContext.CreateClArrayWithSpecificAllocationMode<'b>(DeviceOnly, resultLength) + + let ndRange = + Range1D.CreateValid(resultLength, workGroupSize) + + let kernel = kernel.GetKernel() + + processor.Post( + Msg.MsgSetArguments + (fun () -> + kernel.KernelFunc + ndRange + rowCount + columnCount + values + rowPointers + columns + resultBitmap + resultValues + resultRows + resultColumns) + ) + + processor.Post(Msg.CreateRunMsg<_, _> kernel) + + resultBitmap, resultValues, resultRows, resultColumns + + + let runToCOO<'a, 'b when 'a: struct and 'b: struct and 'b: equality> + (clContext: ClContext) + (opAdd: Expr<'a option -> 'b option>) + workGroupSize + = + + let map = + preparePositions clContext workGroupSize opAdd + + let setPositions = + Common.setPositions<'b> clContext workGroupSize + + fun (queue: MailboxProcessor<_>) allocationMode (matrix: ClMatrix.CSR<'a>) -> + + let bitmap, values, rows, columns = + map queue matrix.RowCount matrix.ColumnCount matrix.Values matrix.RowPointers matrix.Columns + + let resultRows, resultColumns, resultValues, _ = + setPositions queue allocationMode rows columns values bitmap + + queue.Post(Msg.CreateFreeMsg<_>(bitmap)) + queue.Post(Msg.CreateFreeMsg<_>(values)) + queue.Post(Msg.CreateFreeMsg<_>(rows)) + queue.Post(Msg.CreateFreeMsg<_>(columns)) + + { Context = clContext + RowCount = matrix.RowCount + ColumnCount = matrix.ColumnCount + Rows = resultRows + Columns = resultColumns + Values = resultValues } + + let run<'a, 'b when 'a: struct and 'b: struct and 'b: equality> + (clContext: ClContext) + (opAdd: Expr<'a option -> 'b option>) + workGroupSize + = + + let elementwiseToCOO = runToCOO clContext opAdd workGroupSize + + let toCSRInplace = + Matrix.toCSRInplace clContext workGroupSize + + fun (queue: MailboxProcessor<_>) allocationMode (matrix: ClMatrix.CSR<'a>) -> + elementwiseToCOO queue allocationMode matrix + |> toCSRInplace queue allocationMode diff --git a/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Matrix.fs b/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Matrix.fs index c639135b..a5bf0cb2 100644 --- a/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Matrix.fs +++ b/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Matrix.fs @@ -90,6 +90,8 @@ module Matrix = Columns = matrix.Columns Values = matrix.Values } + let map = CSR.Map.run + let map2<'a, 'b, 'c when 'a: struct and 'b: struct and 'c: struct and 'c: equality> (clContext: ClContext) (opAdd: Expr<'a option -> 'b option -> 'c option>) diff --git a/src/GraphBLAS-sharp.Backend/Matrix/Matrix.fs b/src/GraphBLAS-sharp.Backend/Matrix/Matrix.fs index 5adc3cd1..3fac746a 100644 --- a/src/GraphBLAS-sharp.Backend/Matrix/Matrix.fs +++ b/src/GraphBLAS-sharp.Backend/Matrix/Matrix.fs @@ -191,6 +191,21 @@ module Matrix = .ToCSC |> ClMatrix.CSC + let map (clContext: ClContext) (opAdd: Expr<'a option -> 'b option>) workGroupSize = + let mapCOO = + COO.Matrix.map clContext opAdd workGroupSize + + let mapCSR = + CSR.Matrix.map clContext opAdd workGroupSize + + fun (processor: MailboxProcessor<_>) allocationMode matrix -> + match matrix with + | ClMatrix.COO m -> mapCOO processor allocationMode m |> ClMatrix.COO + | ClMatrix.CSR m -> mapCSR processor allocationMode m |> ClMatrix.CSR + | ClMatrix.CSC m -> + (mapCSR processor allocationMode m.ToCSR).ToCSC + |> ClMatrix.CSC + let map2 (clContext: ClContext) (opAdd: Expr<'a option -> 'b option -> 'c option>) workGroupSize = // TODO() let map2COO = COO.Matrix.map2 clContext opAdd workGroupSize diff --git a/tests/GraphBLAS-sharp.Tests/GraphBLAS-sharp.Tests.fsproj b/tests/GraphBLAS-sharp.Tests/GraphBLAS-sharp.Tests.fsproj index 14bbf3ff..d5c43eaa 100644 --- a/tests/GraphBLAS-sharp.Tests/GraphBLAS-sharp.Tests.fsproj +++ b/tests/GraphBLAS-sharp.Tests/GraphBLAS-sharp.Tests.fsproj @@ -45,6 +45,7 @@ + diff --git a/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs b/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs new file mode 100644 index 00000000..64a478cc --- /dev/null +++ b/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs @@ -0,0 +1,206 @@ +module GraphBLAS.FSharp.Tests.Backend.Matrix.Map + +open Expecto +open Expecto.Logging +open Expecto.Logging.Message +open Microsoft.FSharp.Collections +open GraphBLAS.FSharp.Backend +open GraphBLAS.FSharp.Backend.Matrix +open GraphBLAS.FSharp.Backend.Objects +open GraphBLAS.FSharp.Backend.Objects.ClContext +open GraphBLAS.FSharp.Tests +open GraphBLAS.FSharp.Tests.Backend +open GraphBLAS.FSharp.Tests.TestCases +open GraphBLAS.FSharp.Objects +open GraphBLAS.FSharp.Objects.MatrixExtensions + +let logger = Log.create "Map.Tests" + +let config = Utils.defaultConfig +let wgSize = Utils.defaultWorkGroupSize + +let getCorrectnessTestName case datatype = + $"Correctness on %s{datatype}, %A{case}" + +let checkResult isEqual op zero (baseMtx: 'a [,]) (actual: Matrix<'a>) = + let rows = Array2D.length1 baseMtx + let columns = Array2D.length2 baseMtx + Expect.equal columns actual.ColumnCount "The number of columns should be the same." + Expect.equal rows actual.RowCount "The number of rows should be the same." + + let expected2D = Array2D.create rows columns zero + + for i in 0 .. rows - 1 do + for j in 0 .. columns - 1 do + expected2D.[i, j] <- op baseMtx.[i, j] + + let actual2D = Array2D.create rows columns zero + + match actual with + | Matrix.COO actual -> + for i in 0 .. actual.Columns.Length - 1 do + if isEqual zero actual.Values.[i] then + failwith "Resulting zeroes should be filtered." + + actual2D.[actual.Rows.[i], actual.Columns.[i]] <- actual.Values.[i] + | _ -> failwith "Resulting matrix should be converted to COO format." + + "Arrays must be the same" + |> Utils.compare2DArrays isEqual actual2D expected2D + +let correctnessGenericTest + zero + op + (addFun: MailboxProcessor<_> -> AllocationFlag -> ClMatrix<'a> -> ClMatrix<'b>) + toCOOFun + (isEqual: 'a -> 'a -> bool) + q + (case: OperationCase) + (matrix: 'a [,]) + = + + let mtx = + Utils.createMatrixFromArray2D case.Format matrix (isEqual zero) + + if mtx.NNZ > 0 then + try + let m = mtx.ToDevice case.TestContext.ClContext + + let res = addFun q HostInterop m + + m.Dispose q + + let (cooRes: ClMatrix<'a>) = toCOOFun q HostInterop res + let actual = cooRes.ToHost q + + cooRes.Dispose q + res.Dispose q + + logger.debug ( + eventX "Actual is {actual}" + >> setField "actual" (sprintf "%A" actual) + ) + + checkResult isEqual op zero matrix actual + with + | ex when ex.Message = "InvalidBufferSize" -> () + | ex -> raise ex + +let createTestMap case (zero: 'a) op isEqual opQ map = + let getCorrectnessTestName = getCorrectnessTestName case + + let context = case.TestContext.ClContext + let q = case.TestContext.Queue + + let map = map context opQ wgSize + + let toCOO = Matrix.toCOO context wgSize + + case + |> correctnessGenericTest zero op map toCOO isEqual q + |> testPropertyWithConfig config (getCorrectnessTestName $"{typeof<'a>}") + +let testFixturesMapNot case = + [ let context = case.TestContext.ClContext + let q = case.TestContext.Queue + q.Error.Add(fun e -> failwithf "%A" e) + + let notQ = + <@ fun x -> + match x with + | Some true -> None + | _ -> Some true @> + + createTestMap case false not (=) notQ Matrix.map ] + +let notTests = + operationGPUTests "Backend.Matrix.map not tests" testFixturesMapNot + +let testFixturesMapAdd case = + [ let context = case.TestContext.ClContext + let q = case.TestContext.Queue + q.Error.Add(fun e -> failwithf "%A" e) + + let addFloat64Q = + <@ fun x -> + let mutable res = 0.0 + + match x with + | Some v -> res <- (v + 10.0) + | None -> res <- 10.0 + + if res = 0.0 then None else Some res @> + + let addFloat32Q = + <@ fun x -> + let mutable res = 0.0f + + match x with + | Some v -> res <- (v + 10.0f) + | None -> res <- 10.0f + + if res = 0.0f then None else Some res @> + + let addByte = + <@ fun x -> + let mutable res = 0uy + + match x with + | Some v -> res <- (v + 10uy) + | None -> res <- 10uy + + if res = 0uy then None else Some res @> + + if Utils.isFloat64Available context.ClDevice then + createTestMap case 0.0 ((+) 10.0) Utils.floatIsEqual addFloat64Q Matrix.map + + createTestMap case 0.0f ((+) 10.0f) Utils.float32IsEqual addFloat32Q Matrix.map + createTestMap case 0uy ((+) 10uy) (=) addByte Matrix.map ] + +let addTests = + operationGPUTests "Backend.Matrix.map add tests" testFixturesMapAdd + +let testFixturesMapMul case = + [ let context = case.TestContext.ClContext + let q = case.TestContext.Queue + q.Error.Add(fun e -> failwithf "%A" e) + + let mulFloat64Q = + <@ fun x -> + let mutable res = 0.0 + + match x with + | Some v -> res <- (v * 10.0) + | _ -> () + + if res = 0.0 then None else Some res @> + + let mulFloat32Q = + <@ fun x -> + let mutable res = 0.0f + + match x with + | Some v -> res <- (v * 10.0f) + | _ -> () + + if res = 0.0f then None else Some res @> + + + let mulByte = + <@ fun x -> + let mutable res = 0uy + + match x with + | Some v -> res <- (v * 10uy) + | _ -> () + + if res = 0uy then None else Some res @> + + if Utils.isFloat64Available context.ClDevice then + createTestMap case 0.0 ((*) 10.0) Utils.floatIsEqual mulFloat64Q Matrix.map + + createTestMap case 0.0f ((*) 10.0f) Utils.float32IsEqual mulFloat32Q Matrix.map + createTestMap case 0uy ((*) 10uy) (=) mulByte Matrix.map ] + +let mulTests = + operationGPUTests "Backend.Matrix.map mul tests" testFixturesMapMul diff --git a/tests/GraphBLAS-sharp.Tests/Program.fs b/tests/GraphBLAS-sharp.Tests/Program.fs index 2514a8ff..94a4787d 100644 --- a/tests/GraphBLAS-sharp.Tests/Program.fs +++ b/tests/GraphBLAS-sharp.Tests/Program.fs @@ -9,6 +9,9 @@ let matrixTests = Matrix.Map2.addAtLeastOneTests Matrix.Map2.mulAtLeastOneTests Matrix.Map2.addAtLeastOneToCOOTests + Matrix.Map.notTests + Matrix.Map.addTests + Matrix.Map.mulTests Matrix.Mxm.tests Matrix.Transpose.tests ] |> testSequenced From 5571002e3008abfc8356b7a985139bb972f4ca81 Mon Sep 17 00:00:00 2001 From: ArtiomPatov Date: Thu, 23 Mar 2023 07:02:43 +0300 Subject: [PATCH 2/9] refactor: tests, binSearch --- .../GraphBLAS-sharp.Backend.fsproj | 1 + .../Matrix/COOMatrix/Map.fs | 9 +-- .../Matrix/COOMatrix/Map2.fs | 31 +------- .../Matrix/CSRMatrix/Map.fs | 39 ++-------- .../Quotes/Arithmetic.fs | 16 ++++ .../Quotes/BinSearch.fs | 55 ++++++++++++++ tests/GraphBLAS-sharp.Tests/Matrix/Map.fs | 74 ++----------------- 7 files changed, 94 insertions(+), 131 deletions(-) create mode 100644 src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs diff --git a/src/GraphBLAS-sharp.Backend/GraphBLAS-sharp.Backend.fsproj b/src/GraphBLAS-sharp.Backend/GraphBLAS-sharp.Backend.fsproj index b3d7f503..76c665c3 100644 --- a/src/GraphBLAS-sharp.Backend/GraphBLAS-sharp.Backend.fsproj +++ b/src/GraphBLAS-sharp.Backend/GraphBLAS-sharp.Backend.fsproj @@ -26,6 +26,7 @@ + diff --git a/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map.fs b/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map.fs index 4ff9a1e5..7352785d 100644 --- a/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map.fs +++ b/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map.fs @@ -2,6 +2,7 @@ open Brahma.FSharp open GraphBLAS.FSharp.Backend.Matrix +open GraphBLAS.FSharp.Backend.Quotes open Microsoft.FSharp.Quotations open GraphBLAS.FSharp.Backend.Objects open GraphBLAS.FSharp.Backend @@ -9,11 +10,11 @@ open GraphBLAS.FSharp.Backend.Objects.ClMatrix open GraphBLAS.FSharp.Backend.Objects.ClContext -module Map = +module internal Map = let preparePositions<'a, 'b> (clContext: ClContext) workGroupSize opAdd = let preparePositions (op: Expr<'a option -> 'b option>) = - <@ fun (ndRange: Range1D) rowCount columnCount valuesLength (values: ClArray<'a>) (rowPointers: ClArray) (columns: ClArray) (resultBitmap: ClArray) (resultValues: ClArray<'b>) (resultRows: ClArray) (resultColumns: ClArray) -> + <@ fun (ndRange: Range1D) rowCount columnCount valuesLength (values: ClArray<'a>) (rows: ClArray) (columns: ClArray) (resultBitmap: ClArray) (resultValues: ClArray<'b>) (resultRows: ClArray) (resultColumns: ClArray) -> let gid = ndRange.GlobalID0 @@ -26,7 +27,7 @@ module Map = (uint64 rowIndex <<< 32) ||| (uint64 columnIndex) let value = - (%Map2.binSearch) valuesLength index rowPointers columns values + (%BinSearch.searchCOO) valuesLength index rows columns values match (%op) value with | Some resultValue -> @@ -37,7 +38,6 @@ module Map = resultBitmap.[gid] <- 1 | None -> resultBitmap.[gid] <- 0 @> - let kernel = clContext.Compile <| preparePositions opAdd @@ -83,7 +83,6 @@ module Map = resultBitmap, resultValues, resultRows, resultColumns - let run<'a, 'b when 'a: struct and 'b: struct and 'b: equality> (clContext: ClContext) (opAdd: Expr<'a option -> 'b option>) diff --git a/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map2.fs b/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map2.fs index d3d2e0d1..cccef30a 100644 --- a/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map2.fs +++ b/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map2.fs @@ -5,36 +5,11 @@ open GraphBLAS.FSharp.Backend.Matrix open Microsoft.FSharp.Quotations open GraphBLAS.FSharp.Backend.Objects open GraphBLAS.FSharp.Backend +open GraphBLAS.FSharp.Backend.Quotes open GraphBLAS.FSharp.Backend.Objects.ClMatrix open GraphBLAS.FSharp.Backend.Objects.ClContext module internal Map2 = - let binSearch<'a> = - <@ fun lenght sourceIndex (rowIndices: ClArray) (columnIndices: ClArray) (values: ClArray<'a>) -> - - let mutable leftEdge = 0 - let mutable rightEdge = lenght - 1 - - let mutable result = None - - while leftEdge <= rightEdge do - let middleIdx = (leftEdge + rightEdge) / 2 - - let currentIndex: uint64 = - ((uint64 rowIndices.[middleIdx]) <<< 32) - ||| (uint64 columnIndices.[middleIdx]) - - if sourceIndex = currentIndex then - result <- Some values.[middleIdx] - - rightEdge <- -1 // TODO() break - elif sourceIndex < currentIndex then - rightEdge <- middleIdx - 1 - else - leftEdge <- middleIdx + 1 - - result @> - let preparePositions<'a, 'b, 'c> (clContext: ClContext) workGroupSize opAdd = let preparePositions (op: Expr<'a option -> 'b option -> 'c option>) = @@ -51,10 +26,10 @@ module internal Map2 = (uint64 rowIndex <<< 32) ||| (uint64 columnIndex) let leftValue = - (%binSearch) leftValuesLength index leftRows leftColumns leftValues + (%BinSearch.searchCOO) leftValuesLength index leftRows leftColumns leftValues let rightValue = - (%binSearch) rightValuesLength index rightRows rightColumn rightValues + (%BinSearch.searchCOO) rightValuesLength index rightRows rightColumn rightValues match (%op) leftValue rightValue with | Some value -> diff --git a/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs b/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs index bbd5098a..1ce83e79 100644 --- a/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs +++ b/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs @@ -3,37 +3,14 @@ open Brahma.FSharp open FSharp.Quotations open GraphBLAS.FSharp.Backend +open GraphBLAS.FSharp.Backend.Quotes open GraphBLAS.FSharp.Backend.Matrix open GraphBLAS.FSharp.Backend.Matrix.COO open GraphBLAS.FSharp.Backend.Objects open GraphBLAS.FSharp.Backend.Objects.ClMatrix open GraphBLAS.FSharp.Backend.Objects.ClContext -module Map = - let binSearch<'a> = - <@ fun startIndex nnzInRow sourceColumn (columnIndices: ClArray) (values: ClArray<'a>) -> - - let mutable leftEdge = startIndex - let mutable rightEdge = startIndex + nnzInRow - 1 - - let mutable result = None - - while leftEdge <= rightEdge do - let middleIdx = (leftEdge + rightEdge) / 2 - - let currentColumn = columnIndices.[middleIdx] - - if sourceColumn = currentColumn then - result <- Some values.[middleIdx] - - rightEdge <- -1 // TODO() break - elif sourceColumn < currentColumn then - rightEdge <- middleIdx - 1 - else - leftEdge <- middleIdx + 1 - - result @> - +module internal Map = let preparePositions<'a, 'b> (clContext: ClContext) workGroupSize opAdd = let preparePositions (op: Expr<'a option -> 'b option>) = @@ -46,12 +23,11 @@ module Map = let columnIndex = gid % columnCount let rowIndex = gid / columnCount - let nnzInRow = - rowPointers.[rowIndex + 1] - - rowPointers.[rowIndex] + let startIndex = rowPointers.[rowIndex] + let lastIndex = rowPointers.[rowIndex + 1] - 1 let value = - (%binSearch) rowPointers.[rowIndex] nnzInRow columnIndex columns values + (%BinSearch.searchInRange) startIndex lastIndex columnIndex columns values match (%op) value with | Some resultValue -> @@ -106,7 +82,6 @@ module Map = resultBitmap, resultValues, resultRows, resultColumns - let runToCOO<'a, 'b when 'a: struct and 'b: struct and 'b: equality> (clContext: ClContext) (opAdd: Expr<'a option -> 'b option>) @@ -145,11 +120,11 @@ module Map = workGroupSize = - let elementwiseToCOO = runToCOO clContext opAdd workGroupSize + let mapToCOO = runToCOO clContext opAdd workGroupSize let toCSRInplace = Matrix.toCSRInplace clContext workGroupSize fun (queue: MailboxProcessor<_>) allocationMode (matrix: ClMatrix.CSR<'a>) -> - elementwiseToCOO queue allocationMode matrix + mapToCOO queue allocationMode matrix |> toCSRInplace queue allocationMode diff --git a/src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs b/src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs index 1432510f..e5c2d7a9 100644 --- a/src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs +++ b/src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs @@ -3,6 +3,16 @@ open GraphBLAS.FSharp.Backend.Objects module ArithmeticOperations = + let inline mkOpWithConst zero op constant = + <@ fun x -> + let mutable res = zero + + match x with + | Some v -> res <- (op v constant) + | None -> res <- constant + + if res = zero then None else Some res @> + let inline mkNumericSum zero = <@ fun (x: 't option) (y: 't option) -> let mutable res = zero @@ -98,3 +108,9 @@ module ArithmeticOperations = let byteMulAtLeastOne = mkNumericMulAtLeastOne 0uy let floatMulAtLeastOne = mkNumericMulAtLeastOne 0.0 let float32MulAtLeastOne = mkNumericMulAtLeastOne 0f + + let notQ = + <@ fun x -> + match x with + | Some true -> None + | _ -> Some true @> diff --git a/src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs b/src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs new file mode 100644 index 00000000..422fd48e --- /dev/null +++ b/src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs @@ -0,0 +1,55 @@ +namespace GraphBLAS.FSharp.Backend.Quotes + +open Brahma.FSharp + +module BinSearch = + let searchInRange<'a> = + <@ fun leftEdge rightEdge sourceIndex (indices: ClArray) (values: ClArray<'a>) -> + + let mutable leftEdge = leftEdge + let mutable rightEdge = rightEdge + + let mutable result = None + + while leftEdge <= rightEdge do + let middleIdx = (leftEdge + rightEdge) / 2 + + let currentColumn = indices.[middleIdx] + + if sourceIndex = currentColumn then + result <- Some values.[middleIdx] + + rightEdge <- -1 // TODO() break + elif sourceIndex < currentColumn then + rightEdge <- middleIdx - 1 + else + leftEdge <- middleIdx + 1 + + result @> + + let searchCOO<'a> = + <@ fun lenght sourceIndex (rowIndices: ClArray) (columnIndices: ClArray) (values: ClArray<'a>) -> + + let mutable leftEdge = 0 + let mutable rightEdge = lenght - 1 + + let mutable result = None + + while leftEdge <= rightEdge do + let middleIdx = (leftEdge + rightEdge) / 2 + + let currentIndex: uint64 = + ((uint64 rowIndices.[middleIdx]) <<< 32) + ||| (uint64 columnIndices.[middleIdx]) + + if sourceIndex = currentIndex then + result <- Some values.[middleIdx] + + rightEdge <- -1 // TODO() break + elif sourceIndex < currentIndex then + rightEdge <- middleIdx - 1 + else + leftEdge <- middleIdx + 1 + + result @> + diff --git a/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs b/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs index 64a478cc..b8b8578c 100644 --- a/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs +++ b/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs @@ -5,6 +5,7 @@ open Expecto.Logging open Expecto.Logging.Message open Microsoft.FSharp.Collections open GraphBLAS.FSharp.Backend +open GraphBLAS.FSharp.Backend.Quotes open GraphBLAS.FSharp.Backend.Matrix open GraphBLAS.FSharp.Backend.Objects open GraphBLAS.FSharp.Backend.Objects.ClContext @@ -105,13 +106,7 @@ let testFixturesMapNot case = let q = case.TestContext.Queue q.Error.Add(fun e -> failwithf "%A" e) - let notQ = - <@ fun x -> - match x with - | Some true -> None - | _ -> Some true @> - - createTestMap case false not (=) notQ Matrix.map ] + createTestMap case false not (=) ArithmeticOperations.notQ Matrix.map ] let notTests = operationGPUTests "Backend.Matrix.map not tests" testFixturesMapNot @@ -121,35 +116,9 @@ let testFixturesMapAdd case = let q = case.TestContext.Queue q.Error.Add(fun e -> failwithf "%A" e) - let addFloat64Q = - <@ fun x -> - let mutable res = 0.0 - - match x with - | Some v -> res <- (v + 10.0) - | None -> res <- 10.0 - - if res = 0.0 then None else Some res @> - - let addFloat32Q = - <@ fun x -> - let mutable res = 0.0f - - match x with - | Some v -> res <- (v + 10.0f) - | None -> res <- 10.0f - - if res = 0.0f then None else Some res @> - - let addByte = - <@ fun x -> - let mutable res = 0uy - - match x with - | Some v -> res <- (v + 10uy) - | None -> res <- 10uy - - if res = 0uy then None else Some res @> + let addFloat64Q = ArithmeticOperations.mkOpWithConst 0.0 (+) 10.0 + let addFloat32Q = ArithmeticOperations.mkOpWithConst 0.0f (+) 10.0f + let addByte = ArithmeticOperations.mkOpWithConst 0uy (+) 10uy if Utils.isFloat64Available context.ClDevice then createTestMap case 0.0 ((+) 10.0) Utils.floatIsEqual addFloat64Q Matrix.map @@ -165,36 +134,9 @@ let testFixturesMapMul case = let q = case.TestContext.Queue q.Error.Add(fun e -> failwithf "%A" e) - let mulFloat64Q = - <@ fun x -> - let mutable res = 0.0 - - match x with - | Some v -> res <- (v * 10.0) - | _ -> () - - if res = 0.0 then None else Some res @> - - let mulFloat32Q = - <@ fun x -> - let mutable res = 0.0f - - match x with - | Some v -> res <- (v * 10.0f) - | _ -> () - - if res = 0.0f then None else Some res @> - - - let mulByte = - <@ fun x -> - let mutable res = 0uy - - match x with - | Some v -> res <- (v * 10uy) - | _ -> () - - if res = 0uy then None else Some res @> + let mulFloat64Q = ArithmeticOperations.mkOpWithConst 0.0 (*) 10.0 + let mulFloat32Q = ArithmeticOperations.mkOpWithConst 0.0f (*) 10.0f + let mulByte = ArithmeticOperations.mkOpWithConst 0uy (*) 10uy if Utils.isFloat64Available context.ClDevice then createTestMap case 0.0 ((*) 10.0) Utils.floatIsEqual mulFloat64Q Matrix.map From 7349c1dcdba14a61f481e9bdcfc7ddd9a6ba7c9c Mon Sep 17 00:00:00 2001 From: ArtiomPatov Date: Thu, 23 Mar 2023 07:12:15 +0300 Subject: [PATCH 3/9] refactor: formatting --- .../Quotes/Arithmetic.fs | 10 ++++----- .../Quotes/BinSearch.fs | 1 - tests/GraphBLAS-sharp.Tests/Matrix/Map.fs | 22 ++++++++++++++----- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs b/src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs index e5c2d7a9..da8730d7 100644 --- a/src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs +++ b/src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs @@ -5,13 +5,13 @@ open GraphBLAS.FSharp.Backend.Objects module ArithmeticOperations = let inline mkOpWithConst zero op constant = <@ fun x -> - let mutable res = zero + let mutable res = zero - match x with - | Some v -> res <- (op v constant) - | None -> res <- constant + match x with + | Some v -> res <- (op v constant) + | None -> res <- constant - if res = zero then None else Some res @> + if res = zero then None else Some res @> let inline mkNumericSum zero = <@ fun (x: 't option) (y: 't option) -> diff --git a/src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs b/src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs index 422fd48e..4bde7c67 100644 --- a/src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs +++ b/src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs @@ -52,4 +52,3 @@ module BinSearch = leftEdge <- middleIdx + 1 result @> - diff --git a/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs b/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs index b8b8578c..0b45b6dd 100644 --- a/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs +++ b/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs @@ -116,9 +116,14 @@ let testFixturesMapAdd case = let q = case.TestContext.Queue q.Error.Add(fun e -> failwithf "%A" e) - let addFloat64Q = ArithmeticOperations.mkOpWithConst 0.0 (+) 10.0 - let addFloat32Q = ArithmeticOperations.mkOpWithConst 0.0f (+) 10.0f - let addByte = ArithmeticOperations.mkOpWithConst 0uy (+) 10uy + let addFloat64Q = + ArithmeticOperations.mkOpWithConst 0.0 (+) 10.0 + + let addFloat32Q = + ArithmeticOperations.mkOpWithConst 0.0f (+) 10.0f + + let addByte = + ArithmeticOperations.mkOpWithConst 0uy (+) 10uy if Utils.isFloat64Available context.ClDevice then createTestMap case 0.0 ((+) 10.0) Utils.floatIsEqual addFloat64Q Matrix.map @@ -134,9 +139,14 @@ let testFixturesMapMul case = let q = case.TestContext.Queue q.Error.Add(fun e -> failwithf "%A" e) - let mulFloat64Q = ArithmeticOperations.mkOpWithConst 0.0 (*) 10.0 - let mulFloat32Q = ArithmeticOperations.mkOpWithConst 0.0f (*) 10.0f - let mulByte = ArithmeticOperations.mkOpWithConst 0uy (*) 10uy + let mulFloat64Q = + ArithmeticOperations.mkOpWithConst 0.0 (*) 10.0 + + let mulFloat32Q = + ArithmeticOperations.mkOpWithConst 0.0f (*) 10.0f + + let mulByte = + ArithmeticOperations.mkOpWithConst 0uy (*) 10uy if Utils.isFloat64Available context.ClDevice then createTestMap case 0.0 ((*) 10.0) Utils.floatIsEqual mulFloat64Q Matrix.map From c89e1b91037721aff7ee19a4b72e6cb5eb8fd191 Mon Sep 17 00:00:00 2001 From: artemiipatov Date: Thu, 23 Mar 2023 21:18:46 +0300 Subject: [PATCH 4/9] add: CSR.map2 --- .../GraphBLAS-sharp.Backend.fsproj | 3 +- .../Matrix/CSRMatrix/Map.fs | 5 +- .../Matrix/CSRMatrix/Map2.fs | 151 ++++++++++++++++++ .../Matrix/CSRMatrix/Matrix.fs | 26 +-- .../Quotes/Arithmetic.fs | 6 +- .../Quotes/BinSearch.fs | 16 ++ tests/GraphBLAS-sharp.Tests/Matrix/Map.fs | 15 +- 7 files changed, 182 insertions(+), 40 deletions(-) create mode 100644 src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map2.fs diff --git a/src/GraphBLAS-sharp.Backend/GraphBLAS-sharp.Backend.fsproj b/src/GraphBLAS-sharp.Backend/GraphBLAS-sharp.Backend.fsproj index 76c665c3..59c03eff 100644 --- a/src/GraphBLAS-sharp.Backend/GraphBLAS-sharp.Backend.fsproj +++ b/src/GraphBLAS-sharp.Backend/GraphBLAS-sharp.Backend.fsproj @@ -26,7 +26,7 @@ - + @@ -40,6 +40,7 @@ + diff --git a/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs b/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs index 1ce83e79..c61cf19f 100644 --- a/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs +++ b/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs @@ -11,7 +11,7 @@ open GraphBLAS.FSharp.Backend.Objects.ClMatrix open GraphBLAS.FSharp.Backend.Objects.ClContext module internal Map = - let preparePositions<'a, 'b> (clContext: ClContext) workGroupSize opAdd = + let preparePositions<'a, 'b> (clContext: ClContext) workGroupSize op = let preparePositions (op: Expr<'a option -> 'b option>) = <@ fun (ndRange: Range1D) rowCount columnCount (values: ClArray<'a>) (rowPointers: ClArray) (columns: ClArray) (resultBitmap: ClArray) (resultValues: ClArray<'b>) (resultRows: ClArray) (resultColumns: ClArray) -> @@ -38,8 +38,7 @@ module internal Map = resultBitmap.[gid] <- 1 | None -> resultBitmap.[gid] <- 0 @> - let kernel = - clContext.Compile <| preparePositions opAdd + let kernel = clContext.Compile <| preparePositions op fun (processor: MailboxProcessor<_>) rowCount columnCount (values: ClArray<'a>) (rowPointers: ClArray) (columns: ClArray) -> diff --git a/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map2.fs b/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map2.fs new file mode 100644 index 00000000..cc0883d4 --- /dev/null +++ b/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map2.fs @@ -0,0 +1,151 @@ +namespace GraphBLAS.FSharp.Backend.Matrix.CSR + +open Brahma.FSharp +open Microsoft.FSharp.Quotations +open GraphBLAS.FSharp.Backend +open GraphBLAS.FSharp.Backend.Matrix +open GraphBLAS.FSharp.Backend.Quotes +open GraphBLAS.FSharp.Backend.Objects +open GraphBLAS.FSharp.Backend.Objects.ClMatrix +open GraphBLAS.FSharp.Backend.Objects.ClContext +open GraphBLAS.FSharp.Backend.Matrix.COO + +module internal Map2 = + let preparePositions<'a, 'b, 'c> (clContext: ClContext) workGroupSize opAdd = + + let preparePositions (op: Expr<'a option -> 'b option -> 'c option>) = + <@ fun (ndRange: Range1D) rowCount columnCount (leftValues: ClArray<'a>) (leftRowPointers: ClArray) (leftColumns: ClArray) (rightValues: ClArray<'b>) (rightRowPointers: ClArray) (rightColumn: ClArray) (resultBitmap: ClArray) (resultValues: ClArray<'c>) (resultRows: ClArray) (resultColumns: ClArray) -> + + let gid = ndRange.GlobalID0 + + if gid < rowCount * columnCount then + + let columnIndex = gid % columnCount + let rowIndex = gid / columnCount + + let leftStartIndex = leftRowPointers.[rowIndex] + let leftLastIndex = leftRowPointers.[rowIndex + 1] - 1 + + let rightStartIndex = rightRowPointers.[rowIndex] + let rightLastIndex = rightRowPointers.[rowIndex + 1] - 1 + + let leftValue = + (%BinSearch.searchInRange) leftStartIndex leftLastIndex columnIndex leftColumns leftValues + + let rightValue = + (%BinSearch.searchInRange) rightStartIndex rightLastIndex columnIndex rightColumn rightValues + + match (%op) leftValue rightValue with + | Some value -> + resultValues.[gid] <- value + resultRows.[gid] <- rowIndex + resultColumns.[gid] <- columnIndex + + resultBitmap.[gid] <- 1 + | None -> resultBitmap.[gid] <- 0 @> + + let kernel = + clContext.Compile <| preparePositions opAdd + + fun (processor: MailboxProcessor<_>) rowCount columnCount (leftValues: ClArray<'a>) (leftRows: ClArray) (leftColumns: ClArray) (rightValues: ClArray<'b>) (rightRows: ClArray) (rightColumns: ClArray) -> + + let (resultLength: int) = columnCount * rowCount + + let resultBitmap = + clContext.CreateClArrayWithSpecificAllocationMode(DeviceOnly, resultLength) + + let resultRows = + clContext.CreateClArrayWithSpecificAllocationMode(DeviceOnly, resultLength) + + let resultColumns = + clContext.CreateClArrayWithSpecificAllocationMode(DeviceOnly, resultLength) + + let resultValues = + clContext.CreateClArrayWithSpecificAllocationMode<'c>(DeviceOnly, resultLength) + + let ndRange = + Range1D.CreateValid(resultLength, workGroupSize) + + let kernel = kernel.GetKernel() + + processor.Post( + Msg.MsgSetArguments + (fun () -> + kernel.KernelFunc + ndRange + rowCount + columnCount + leftValues + leftRows + leftColumns + rightValues + rightRows + rightColumns + resultBitmap + resultValues + resultRows + resultColumns) + ) + + processor.Post(Msg.CreateRunMsg<_, _> kernel) + + resultBitmap, resultValues, resultRows, resultColumns + + ///. + ///. + ///Should be a power of 2 and greater than 1. + let runToCOO<'a, 'b, 'c when 'a: struct and 'b: struct and 'c: struct and 'c: equality> + (clContext: ClContext) + (opAdd: Expr<'a option -> 'b option -> 'c option>) + workGroupSize + = + + let map2 = + preparePositions clContext workGroupSize opAdd + + let setPositions = + Common.setPositions<'c> clContext workGroupSize + + fun (queue: MailboxProcessor<_>) allocationMode (matrixLeft: ClMatrix.CSR<'a>) (matrixRight: ClMatrix.CSR<'b>) -> + + let bitmap, values, rows, columns = + map2 + queue + matrixLeft.RowCount + matrixLeft.ColumnCount + matrixLeft.Values + matrixLeft.RowPointers + matrixLeft.Columns + matrixRight.Values + matrixRight.RowPointers + matrixRight.Columns + + let resultRows, resultColumns, resultValues, _ = + setPositions queue allocationMode rows columns values bitmap + + queue.Post(Msg.CreateFreeMsg<_>(bitmap)) + queue.Post(Msg.CreateFreeMsg<_>(values)) + queue.Post(Msg.CreateFreeMsg<_>(rows)) + queue.Post(Msg.CreateFreeMsg<_>(columns)) + + { Context = clContext + RowCount = matrixLeft.RowCount + ColumnCount = matrixLeft.ColumnCount + Rows = resultRows + Columns = resultColumns + Values = resultValues } + + let run<'a, 'b, 'c when 'a: struct and 'b: struct and 'c: struct and 'c: equality> + (clContext: ClContext) + (opAdd: Expr<'a option -> 'b option -> 'c option>) + workGroupSize + = + + let map2ToCOO = runToCOO clContext opAdd workGroupSize + + let toCSRInplace = + Matrix.toCSRInplace clContext workGroupSize + + fun (queue: MailboxProcessor<_>) allocationMode (matrixLeft: ClMatrix.CSR<'a>) (matrixRight: ClMatrix.CSR<'b>) -> + map2ToCOO queue allocationMode matrixLeft matrixRight + |> toCSRInplace queue allocationMode diff --git a/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Matrix.fs b/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Matrix.fs index a5bf0cb2..d9c96445 100644 --- a/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Matrix.fs +++ b/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Matrix.fs @@ -92,31 +92,7 @@ module Matrix = let map = CSR.Map.run - let map2<'a, 'b, 'c when 'a: struct and 'b: struct and 'c: struct and 'c: equality> - (clContext: ClContext) - (opAdd: Expr<'a option -> 'b option -> 'c option>) - workGroupSize - = - - let firstToCOO = toCOO clContext workGroupSize - - let secondToCOO = toCOO clContext workGroupSize - - let COOMap2 = - COO.Matrix.map2 clContext opAdd workGroupSize - - let toCSR = - COO.Matrix.toCSRInplace clContext workGroupSize - - fun (processor: MailboxProcessor<_>) allocationMode (leftMatrix: ClMatrix.CSR<'a>) (rightMatrix: ClMatrix.CSR<'b>) -> - let leftCOOMatrix = - firstToCOO processor DeviceOnly leftMatrix - - let rightCOOMatrix = - secondToCOO processor DeviceOnly rightMatrix - - COOMap2 processor DeviceOnly leftCOOMatrix rightCOOMatrix - |> toCSR processor allocationMode + let map2 = Map2.run let map2AtLeastOneToCOO<'a, 'b, 'c when 'a: struct and 'b: struct and 'c: struct and 'c: equality> (clContext: ClContext) diff --git a/src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs b/src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs index da8730d7..d71dd456 100644 --- a/src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs +++ b/src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs @@ -3,13 +3,13 @@ open GraphBLAS.FSharp.Backend.Objects module ArithmeticOperations = - let inline mkOpWithConst zero op constant = + let inline mkUnaryOp zero unaryOp = <@ fun x -> let mutable res = zero match x with - | Some v -> res <- (op v constant) - | None -> res <- constant + | Some v -> res <- (%unaryOp) v + | None -> res <- (%unaryOp) zero if res = zero then None else Some res @> diff --git a/src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs b/src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs index 4bde7c67..2dcf421f 100644 --- a/src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs +++ b/src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs @@ -3,6 +3,15 @@ open Brahma.FSharp module BinSearch = + /// + /// Searches a section of the array of indices, bounded by the given left and right edges, for an index, using a binary search algorithm. + /// In case searched section contains source index, the value at the same position in the array of values is returned. + /// + /// + /// Searched section of index array should be sorted in ascending order. + /// The index array should have the same length as the array of values. + /// left edge and right edge should be less than the length of the index array. + /// let searchInRange<'a> = <@ fun leftEdge rightEdge sourceIndex (indices: ClArray) (values: ClArray<'a>) -> @@ -27,6 +36,13 @@ module BinSearch = result @> + /// + /// Searches matrix in COO format for a value, using a binary search algorithm. + /// In case there is a value at the given position, it is returned. + /// + /// + /// Position is uint64 and it should be written in such format: first 32 bits is row, second 32 bits is column. + /// let searchCOO<'a> = <@ fun lenght sourceIndex (rowIndices: ClArray) (columnIndices: ClArray) (values: ClArray<'a>) -> diff --git a/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs b/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs index 0b45b6dd..659bf888 100644 --- a/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs +++ b/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs @@ -102,8 +102,7 @@ let createTestMap case (zero: 'a) op isEqual opQ map = |> testPropertyWithConfig config (getCorrectnessTestName $"{typeof<'a>}") let testFixturesMapNot case = - [ let context = case.TestContext.ClContext - let q = case.TestContext.Queue + [ let q = case.TestContext.Queue q.Error.Add(fun e -> failwithf "%A" e) createTestMap case false not (=) ArithmeticOperations.notQ Matrix.map ] @@ -117,13 +116,13 @@ let testFixturesMapAdd case = q.Error.Add(fun e -> failwithf "%A" e) let addFloat64Q = - ArithmeticOperations.mkOpWithConst 0.0 (+) 10.0 + ArithmeticOperations.mkUnaryOp 0.0 <@ fun x -> x + 10.0 @> let addFloat32Q = - ArithmeticOperations.mkOpWithConst 0.0f (+) 10.0f + ArithmeticOperations.mkUnaryOp 0.0f <@ fun x -> x + 10.0f @> let addByte = - ArithmeticOperations.mkOpWithConst 0uy (+) 10uy + ArithmeticOperations.mkUnaryOp 0uy <@ fun x -> x + 10uy @> if Utils.isFloat64Available context.ClDevice then createTestMap case 0.0 ((+) 10.0) Utils.floatIsEqual addFloat64Q Matrix.map @@ -140,13 +139,13 @@ let testFixturesMapMul case = q.Error.Add(fun e -> failwithf "%A" e) let mulFloat64Q = - ArithmeticOperations.mkOpWithConst 0.0 (*) 10.0 + ArithmeticOperations.mkUnaryOp 0.0 <@ fun x -> x * 10.0 @> let mulFloat32Q = - ArithmeticOperations.mkOpWithConst 0.0f (*) 10.0f + ArithmeticOperations.mkUnaryOp 0.0f <@ fun x -> x * 10.0f @> let mulByte = - ArithmeticOperations.mkOpWithConst 0uy (*) 10uy + ArithmeticOperations.mkUnaryOp 0uy <@ fun x -> x * 10uy @> if Utils.isFloat64Available context.ClDevice then createTestMap case 0.0 ((*) 10.0) Utils.floatIsEqual mulFloat64Q Matrix.map From f223b97f5d8e6985977f954fa815ec5254c773c2 Mon Sep 17 00:00:00 2001 From: artemiipatov Date: Fri, 24 Mar 2023 14:48:00 +0300 Subject: [PATCH 5/9] refactor: Map.tests, float32 generator shift --- .../Quotes/Arithmetic.fs | 12 +++++++ tests/GraphBLAS-sharp.Tests/Generators.fs | 11 ++++--- tests/GraphBLAS-sharp.Tests/Matrix/Map.fs | 32 +++++-------------- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs b/src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs index d71dd456..8aa72db5 100644 --- a/src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs +++ b/src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs @@ -66,6 +66,12 @@ module ArithmeticOperations = if res then Some true else None @> + let inline addLeftConst zero constant = + mkUnaryOp zero <@ fun x -> constant + x @> + + let inline addRightConst zero constant = + mkUnaryOp zero <@ fun x -> x + constant @> + let intSum = mkNumericSum 0 let byteSum = mkNumericSum 0uy let floatSum = mkNumericSum 0.0 @@ -89,6 +95,12 @@ module ArithmeticOperations = if res then Some true else None @> + let inline mulLeftConst zero constant = + mkUnaryOp zero <@ fun x -> constant * x @> + + let inline mulRightConst zero constant = + mkUnaryOp zero <@ fun x -> x * constant @> + let intMul = mkNumericMul 0 let byteMul = mkNumericMul 0uy let floatMul = mkNumericMul 0.0 diff --git a/tests/GraphBLAS-sharp.Tests/Generators.fs b/tests/GraphBLAS-sharp.Tests/Generators.fs index 2183d0b9..4182b57a 100644 --- a/tests/GraphBLAS-sharp.Tests/Generators.fs +++ b/tests/GraphBLAS-sharp.Tests/Generators.fs @@ -47,12 +47,15 @@ module Generators = let rec normalFloat32Generator (random: System.Random) = gen { - let result = random.NextSingle() + let rawValue = random.NextSingle() - if System.Single.IsNormal result then - return result + if System.Single.IsNormal rawValue then + let sign = float32 <| sign rawValue + let processedValue = ((+) 1.0f) <| (abs <| rawValue) + + return processedValue * sign else - return! normalFloat32Generator random + return 0.0f } let genericSparseGenerator zero valuesGen handler = diff --git a/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs b/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs index 659bf888..afa8d5f2 100644 --- a/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs +++ b/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs @@ -115,20 +115,12 @@ let testFixturesMapAdd case = let q = case.TestContext.Queue q.Error.Add(fun e -> failwithf "%A" e) - let addFloat64Q = - ArithmeticOperations.mkUnaryOp 0.0 <@ fun x -> x + 10.0 @> - - let addFloat32Q = - ArithmeticOperations.mkUnaryOp 0.0f <@ fun x -> x + 10.0f @> - - let addByte = - ArithmeticOperations.mkUnaryOp 0uy <@ fun x -> x + 10uy @> - if Utils.isFloat64Available context.ClDevice then - createTestMap case 0.0 ((+) 10.0) Utils.floatIsEqual addFloat64Q Matrix.map + createTestMap case 0.0 ((+) 10.0) Utils.floatIsEqual (ArithmeticOperations.addLeftConst 0.0 10.0) Matrix.map + + createTestMap case 0.0f ((+) 10.0f) Utils.float32IsEqual (ArithmeticOperations.addLeftConst 0.0f 10.0f) Matrix.map - createTestMap case 0.0f ((+) 10.0f) Utils.float32IsEqual addFloat32Q Matrix.map - createTestMap case 0uy ((+) 10uy) (=) addByte Matrix.map ] + createTestMap case 0uy ((+) 10uy) (=) (ArithmeticOperations.addLeftConst 0uy 10uy) Matrix.map ] let addTests = operationGPUTests "Backend.Matrix.map add tests" testFixturesMapAdd @@ -138,20 +130,12 @@ let testFixturesMapMul case = let q = case.TestContext.Queue q.Error.Add(fun e -> failwithf "%A" e) - let mulFloat64Q = - ArithmeticOperations.mkUnaryOp 0.0 <@ fun x -> x * 10.0 @> - - let mulFloat32Q = - ArithmeticOperations.mkUnaryOp 0.0f <@ fun x -> x * 10.0f @> - - let mulByte = - ArithmeticOperations.mkUnaryOp 0uy <@ fun x -> x * 10uy @> - if Utils.isFloat64Available context.ClDevice then - createTestMap case 0.0 ((*) 10.0) Utils.floatIsEqual mulFloat64Q Matrix.map + createTestMap case 0.0 ((*) 10.0) Utils.floatIsEqual (ArithmeticOperations.mulLeftConst 0.0 10.0) Matrix.map + + createTestMap case 0.0f ((*) 10.0f) Utils.float32IsEqual (ArithmeticOperations.mulLeftConst 0.0f 10.0f) Matrix.map - createTestMap case 0.0f ((*) 10.0f) Utils.float32IsEqual mulFloat32Q Matrix.map - createTestMap case 0uy ((*) 10uy) (=) mulByte Matrix.map ] + createTestMap case 0uy ((*) 10uy) (=) (ArithmeticOperations.mulLeftConst 0uy 10uy) Matrix.map ] let mulTests = operationGPUTests "Backend.Matrix.map mul tests" testFixturesMapMul From 4f2b965d86bc20d4e611f53ba1c9cb298958a76b Mon Sep 17 00:00:00 2001 From: artemiipatov Date: Sat, 25 Mar 2023 11:27:53 +0300 Subject: [PATCH 6/9] refactor: map tests --- tests/GraphBLAS-sharp.Tests/Matrix/Map.fs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs b/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs index afa8d5f2..07c05f30 100644 --- a/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs +++ b/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs @@ -87,25 +87,28 @@ let correctnessGenericTest | ex when ex.Message = "InvalidBufferSize" -> () | ex -> raise ex -let createTestMap case (zero: 'a) op isEqual opQ map = +let createTestMap case (zero: 'a) (constant: 'a) binOp isEqual opQ = let getCorrectnessTestName = getCorrectnessTestName case let context = case.TestContext.ClContext let q = case.TestContext.Queue - let map = map context opQ wgSize + let unaryOp = binOp constant + let unaryOpQ = opQ zero constant + + let map = Matrix.map context unaryOpQ wgSize let toCOO = Matrix.toCOO context wgSize case - |> correctnessGenericTest zero op map toCOO isEqual q + |> correctnessGenericTest zero unaryOp map toCOO isEqual q |> testPropertyWithConfig config (getCorrectnessTestName $"{typeof<'a>}") let testFixturesMapNot case = [ let q = case.TestContext.Queue q.Error.Add(fun e -> failwithf "%A" e) - createTestMap case false not (=) ArithmeticOperations.notQ Matrix.map ] + createTestMap case false true (fun _ -> not) (=) (fun _ _ -> ArithmeticOperations.notQ) ] let notTests = operationGPUTests "Backend.Matrix.map not tests" testFixturesMapNot @@ -116,11 +119,11 @@ let testFixturesMapAdd case = q.Error.Add(fun e -> failwithf "%A" e) if Utils.isFloat64Available context.ClDevice then - createTestMap case 0.0 ((+) 10.0) Utils.floatIsEqual (ArithmeticOperations.addLeftConst 0.0 10.0) Matrix.map + createTestMap case 0.0 10.0 (+) Utils.floatIsEqual ArithmeticOperations.addLeftConst - createTestMap case 0.0f ((+) 10.0f) Utils.float32IsEqual (ArithmeticOperations.addLeftConst 0.0f 10.0f) Matrix.map + createTestMap case 0.0f 10.0f (+) Utils.float32IsEqual ArithmeticOperations.addLeftConst - createTestMap case 0uy ((+) 10uy) (=) (ArithmeticOperations.addLeftConst 0uy 10uy) Matrix.map ] + createTestMap case 0uy 10uy (+) (=) ArithmeticOperations.addLeftConst ] let addTests = operationGPUTests "Backend.Matrix.map add tests" testFixturesMapAdd @@ -131,11 +134,11 @@ let testFixturesMapMul case = q.Error.Add(fun e -> failwithf "%A" e) if Utils.isFloat64Available context.ClDevice then - createTestMap case 0.0 ((*) 10.0) Utils.floatIsEqual (ArithmeticOperations.mulLeftConst 0.0 10.0) Matrix.map + createTestMap case 0.0 10.0 (*) Utils.floatIsEqual ArithmeticOperations.mulLeftConst - createTestMap case 0.0f ((*) 10.0f) Utils.float32IsEqual (ArithmeticOperations.mulLeftConst 0.0f 10.0f) Matrix.map + createTestMap case 0.0f 10.0f (*) Utils.float32IsEqual ArithmeticOperations.mulLeftConst - createTestMap case 0uy ((*) 10uy) (=) (ArithmeticOperations.mulLeftConst 0uy 10uy) Matrix.map ] + createTestMap case 0uy 10uy (*) (=) ArithmeticOperations.mulLeftConst ] let mulTests = operationGPUTests "Backend.Matrix.map mul tests" testFixturesMapMul From 953be9b25eaf7ec1fce2c288a6fdb7cc19218436 Mon Sep 17 00:00:00 2001 From: artemiipatov Date: Sat, 25 Mar 2023 15:45:39 +0300 Subject: [PATCH 7/9] refactor: rename functions in binSearch module --- src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map.fs | 3 +-- src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map2.fs | 4 ++-- src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs | 2 +- src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map2.fs | 4 ++-- src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs | 4 ++-- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map.fs b/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map.fs index 7352785d..26df8f65 100644 --- a/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map.fs +++ b/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map.fs @@ -9,7 +9,6 @@ open GraphBLAS.FSharp.Backend open GraphBLAS.FSharp.Backend.Objects.ClMatrix open GraphBLAS.FSharp.Backend.Objects.ClContext - module internal Map = let preparePositions<'a, 'b> (clContext: ClContext) workGroupSize opAdd = @@ -27,7 +26,7 @@ module internal Map = (uint64 rowIndex <<< 32) ||| (uint64 columnIndex) let value = - (%BinSearch.searchCOO) valuesLength index rows columns values + (%BinSearch.byKey2D) valuesLength index rows columns values match (%op) value with | Some resultValue -> diff --git a/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map2.fs b/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map2.fs index cccef30a..adf5fdeb 100644 --- a/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map2.fs +++ b/src/GraphBLAS-sharp.Backend/Matrix/COOMatrix/Map2.fs @@ -26,10 +26,10 @@ module internal Map2 = (uint64 rowIndex <<< 32) ||| (uint64 columnIndex) let leftValue = - (%BinSearch.searchCOO) leftValuesLength index leftRows leftColumns leftValues + (%BinSearch.byKey2D) leftValuesLength index leftRows leftColumns leftValues let rightValue = - (%BinSearch.searchCOO) rightValuesLength index rightRows rightColumn rightValues + (%BinSearch.byKey2D) rightValuesLength index rightRows rightColumn rightValues match (%op) leftValue rightValue with | Some value -> diff --git a/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs b/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs index c61cf19f..c75daf90 100644 --- a/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs +++ b/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map.fs @@ -27,7 +27,7 @@ module internal Map = let lastIndex = rowPointers.[rowIndex + 1] - 1 let value = - (%BinSearch.searchInRange) startIndex lastIndex columnIndex columns values + (%BinSearch.inRange) startIndex lastIndex columnIndex columns values match (%op) value with | Some resultValue -> diff --git a/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map2.fs b/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map2.fs index cc0883d4..e65c870e 100644 --- a/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map2.fs +++ b/src/GraphBLAS-sharp.Backend/Matrix/CSRMatrix/Map2.fs @@ -30,10 +30,10 @@ module internal Map2 = let rightLastIndex = rightRowPointers.[rowIndex + 1] - 1 let leftValue = - (%BinSearch.searchInRange) leftStartIndex leftLastIndex columnIndex leftColumns leftValues + (%BinSearch.inRange) leftStartIndex leftLastIndex columnIndex leftColumns leftValues let rightValue = - (%BinSearch.searchInRange) rightStartIndex rightLastIndex columnIndex rightColumn rightValues + (%BinSearch.inRange) rightStartIndex rightLastIndex columnIndex rightColumn rightValues match (%op) leftValue rightValue with | Some value -> diff --git a/src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs b/src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs index 2dcf421f..c645f2af 100644 --- a/src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs +++ b/src/GraphBLAS-sharp.Backend/Quotes/BinSearch.fs @@ -12,7 +12,7 @@ module BinSearch = /// The index array should have the same length as the array of values. /// left edge and right edge should be less than the length of the index array. /// - let searchInRange<'a> = + let inRange<'a> = <@ fun leftEdge rightEdge sourceIndex (indices: ClArray) (values: ClArray<'a>) -> let mutable leftEdge = leftEdge @@ -43,7 +43,7 @@ module BinSearch = /// /// Position is uint64 and it should be written in such format: first 32 bits is row, second 32 bits is column. /// - let searchCOO<'a> = + let byKey2D<'a> = <@ fun lenght sourceIndex (rowIndices: ClArray) (columnIndices: ClArray) (values: ClArray<'a>) -> let mutable leftEdge = 0 From 02b702fdce6c11489c7fa26a901ead6e7d554fd8 Mon Sep 17 00:00:00 2001 From: artemiipatov Date: Sat, 25 Mar 2023 15:46:31 +0300 Subject: [PATCH 8/9] add: map tests for integer support --- tests/GraphBLAS-sharp.Tests/Matrix/Map.fs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs b/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs index 07c05f30..fb4dbf28 100644 --- a/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs +++ b/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs @@ -118,6 +118,8 @@ let testFixturesMapAdd case = let q = case.TestContext.Queue q.Error.Add(fun e -> failwithf "%A" e) + createTestMap case 0 10 (+) (=) ArithmeticOperations.addLeftConst + if Utils.isFloat64Available context.ClDevice then createTestMap case 0.0 10.0 (+) Utils.floatIsEqual ArithmeticOperations.addLeftConst @@ -133,6 +135,8 @@ let testFixturesMapMul case = let q = case.TestContext.Queue q.Error.Add(fun e -> failwithf "%A" e) + createTestMap case 0 10 (+) (=) ArithmeticOperations.mulLeftConst + if Utils.isFloat64Available context.ClDevice then createTestMap case 0.0 10.0 (*) Utils.floatIsEqual ArithmeticOperations.mulLeftConst From edfa3ff672913e1bc7509cfce89ef8c65b28022c Mon Sep 17 00:00:00 2001 From: artemiipatov Date: Sat, 25 Mar 2023 16:28:11 +0300 Subject: [PATCH 9/9] fix: map tests --- tests/GraphBLAS-sharp.Tests/Matrix/Map.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs b/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs index fb4dbf28..229271b7 100644 --- a/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs +++ b/tests/GraphBLAS-sharp.Tests/Matrix/Map.fs @@ -135,7 +135,7 @@ let testFixturesMapMul case = let q = case.TestContext.Queue q.Error.Add(fun e -> failwithf "%A" e) - createTestMap case 0 10 (+) (=) ArithmeticOperations.mulLeftConst + createTestMap case 0 10 (*) (=) ArithmeticOperations.mulLeftConst if Utils.isFloat64Available context.ClDevice then createTestMap case 0.0 10.0 (*) Utils.floatIsEqual ArithmeticOperations.mulLeftConst