Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
af0357b
Compilable version of Maggs-Plotkin MST.
gsvgit May 29, 2026
9cb6b1e
Tests on Maggs-Plotkin MST.
gsvgit May 29, 2026
c0dcef1
Formatted
gsvgit May 29, 2026
2bf90ff
Maggs-Plotkin: handle edges with identical weights correctly.
gsvgit May 31, 2026
7ac73ce
MST tests fixed. In progress.
gsvgit May 31, 2026
2a4c757
Simple test on Boruvka to investigate what goes wrong.
gsvgit May 31, 2026
9ce3bd4
Fixed cycles in Boruvka MST
gsvgit May 31, 2026
56e18ef
Added information about Maggs-Plotkin MSF.
gsvgit May 31, 2026
8f9a425
First vrsion of parent BFS.
gsvgit May 31, 2026
d83962d
Fixed vxmi.
gsvgit Jun 1, 2026
64fb06e
More tests on BFS.
gsvgit Jun 1, 2026
a44e451
Added Parent-BFS
gsvgit Jun 1, 2026
1dbe80f
Formatted.
gsvgit Jun 1, 2026
1ec2aae
add slice in Vector.fs and Matrix.fs, add reduceRows and reduceCols i…
Brulevich-Nikita May 8, 2026
2ae01e4
add Kronecker product to Matrix.fs with tests, fix tests, duplicate h…
Brulevich-Nikita May 18, 2026
8c015a0
fix: returned failwith to benchmarks, fix SSSP, LinearAlgebra, MST, B…
Brulevich-Nikita Jun 3, 2026
46959c9
add Benchmarks, their results, fix: slice logic
Brulevich-Nikita Jun 10, 2026
4bc87b4
refactor benchmarks
Brulevich-Nikita Jun 13, 2026
2c9e35c
add fantomas to refactored benchmarks
Brulevich-Nikita Jun 13, 2026
b119e6b
refactor: Vector and Matrix functions and Benchmarks
Brulevich-Nikita Aug 4, 2026
2f0f92e
refactor: Kronecker, Benchmarks
Brulevich-Nikita Aug 29, 2026
6dac273
add: matricies for ReduceComparison benchmark, translate errors to En…
Brulevich-Nikita Sep 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions QuadTree.Benchmark/BFS.fs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,25 @@ type Benchmark() =

let mutable matrix = Unchecked.defaultof<Matrix.SparseMatrix<double>>


[<Params("494_bus.mtx", "arc130.mtx")>]
member val MatrixName = "" with get, set

[<GlobalSetup>]
member this.LoadMatrix() =
matrix <- readMtx (System.IO.Path.Combine(DIR_WITH_MATRICES, this.MatrixName)) false
matrix <-
match readMtx (System.IO.Path.Combine(DIR_WITH_MATRICES, this.MatrixName)) false with
| Ok m -> m
| Error msg -> failwith $"Failed to load matrix {this.MatrixName}: {msg}"

[<Benchmark>]
member this.BFS() =
let startVertices =
let startVerticesResult =
Vector.CoordinateList((uint64 matrix.ncols) * 1UL<Vector.dataLength>, [ 0UL<Vector.index>, 1UL ])
|> Vector.fromCoordinateList

let startVertices =
match startVerticesResult with
| Ok v -> v
| Error msg -> failwith $"Failed to create start vertices: {msg}"

Graph.BFS.bfs_level matrix startVertices
53 changes: 53 additions & 0 deletions QuadTree.Benchmark/Kronecker.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
namespace QuadTree.Benchmarks.Kronecker

open System
open BenchmarkDotNet.Attributes
open QuadTree.Benchmarks.Utils

[<Config(typeof<MyConfig>)>]
[<MemoryDiagnoser>]
type Benchmark() =

[<Params(150, 200, 250, 300)>]
member val SizeA = 0 with get, set

[<Params(150, 200, 250, 300)>]
member val SizeB = 0 with get, set

[<Params(0.005, 0.01, 0.05, 0.1)>]
member val DensityB = 0.0 with get, set

[<Params(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)>]
member val Seed = 0 with get, set

member val A = Unchecked.defaultof<Matrix.SparseMatrix<double>> with get, set
member val B = Unchecked.defaultof<Matrix.SparseMatrix<double>> with get, set

member private this.GenerateMatrix(size: int, density: float, rng: Random) =
let coords =
[ for i in 0 .. size - 1 do
for j in 0 .. size - 1 do
if rng.NextDouble() < density then
let value = double (rng.Next(1, 4))
yield (uint64 i * 1UL<Matrix.rowindex>, uint64 j * 1UL<Matrix.colindex>, value) ]

match
Matrix.fromCoordinateList (
Matrix.CoordinateList(uint64 size * 1UL<Matrix.nrows>, uint64 size * 1UL<Matrix.ncols>, coords)
)
with
| Ok m -> m
| Error msg -> failwithf "Failed to create matrix: %s" msg

[<GlobalSetup>]
member this.Setup() =
let rng = Random(this.Seed)
this.A <- this.GenerateMatrix(this.SizeA, 0.01, rng)
this.B <- this.GenerateMatrix(this.SizeB, this.DensityB, rng)

[<Benchmark>]
member this.Kronecker() =
match Matrix.kroneckerProduct this.A this.B (fun a b -> Some(a * b)) with
| Ok res -> res
| Error msg -> failwithf "Kronecker failed: %s" msg
|> ignore
8 changes: 7 additions & 1 deletion QuadTree.Benchmark/Main.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ let main argv =
BenchmarkSwitcher
[| typeof<QuadTree.Benchmarks.BFS.Benchmark>
typeof<QuadTree.Benchmarks.SSSP.Benchmark>
typeof<QuadTree.Benchmarks.Triangles.Benchmark> |]
typeof<QuadTree.Benchmarks.Triangles.Benchmark>
typeof<QuadTree.Benchmarks.ReduceComparison.Benchmark>
typeof<QuadTree.Benchmarks.VectorSlice.Benchmark>
typeof<QuadTree.Benchmarks.MatrixSlice.Benchmark>
typeof<QuadTree.Benchmarks.Kronecker.Benchmark>
typeof<QuadTree.Benchmarks.MatrixSliceAlign.Benchmark>
typeof<QuadTree.Benchmarks.VectorSliceAlign.Benchmark> |]

benchmarks.Run argv |> ignore
0
59 changes: 59 additions & 0 deletions QuadTree.Benchmark/MatrixSlice.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
namespace QuadTree.Benchmarks.MatrixSlice

open System
open BenchmarkDotNet.Attributes
open BenchmarkDotNet.Configs
open BenchmarkDotNet.Jobs
open QuadTree.Benchmarks.Utils

type RealConfig() =
inherit ManualConfig()
do base.AddJob(Job.Default.WithWarmupCount(5).WithIterationCount(10)) |> ignore

[<Config(typeof<RealConfig>)>]
[<MemoryDiagnoser>]
type Benchmark() =

[<Params(1000, 2000, 3000, 4000, 5000, 6000, 7000)>]
member val Size = 0 with get, set

[<Params(0.001, 0.005, 0.01, 0.05, 0.1, 0.5)>]
member val Density = 0.0 with get, set

[<Params(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)>]
member val Seed = 0 with get, set

member val Matrix = Unchecked.defaultof<Matrix.SparseMatrix<double>> with get, set

member private this.GenerateMatrix(size: int, density: float, rng: Random) =
let coords =
[ for i in 0 .. size - 1 do
for j in 0 .. size - 1 do
if rng.NextDouble() < density then
let value = double (rng.Next(1, 4))
yield (uint64 i * 1UL<Matrix.rowindex>, uint64 j * 1UL<Matrix.colindex>, value) ]

match
Matrix.fromCoordinateList (
Matrix.CoordinateList(uint64 size * 1UL<Matrix.nrows>, uint64 size * 1UL<Matrix.ncols>, coords)
)
with
| Ok m -> m
| Error msg -> failwithf "Failed to create matrix: %s" msg

[<GlobalSetup>]
member this.Setup() =
let rng = Random(this.Seed)
this.Matrix <- this.GenerateMatrix(this.Size, this.Density, rng)

member private this.SliceMiddle(m: Matrix.SparseMatrix<double>) =
let n = int m.nrows
let start = n / 4
let last = 3 * n / 4 - 1

match Matrix.slice m start last start last with
| Ok res -> res
| Error msg -> failwithf "Slice failed: %s" msg

[<Benchmark>]
member this.Slice() = this.SliceMiddle(this.Matrix) |> ignore
65 changes: 65 additions & 0 deletions QuadTree.Benchmark/MatrixSliceAlign.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
namespace QuadTree.Benchmarks.MatrixSliceAlign

open System
open BenchmarkDotNet.Attributes
open QuadTree.Benchmarks.Utils
open Matrix
open QuadTree

[<Config(typeof<MyConfig>)>]
[<MemoryDiagnoser>]
type Benchmark() =

[<Params(4096)>]
member val Size = 0 with get, set

[<Params(0.001, 0.005, 0.01, 0.05, 0.1, 0.5)>]
member val Density = 0.0 with get, set

[<Params(0)>]
member val Seed = 0 with get, set

[<Params(2048)>]
member val SliceSize = 0 with get, set

[<Params(0, 512, 1024, 1536, 2048, 1)>]
member val StartOffset = 0 with get, set

member val Matrix = Unchecked.defaultof<Matrix.SparseMatrix<double>> with get, set

member private this.GenerateMatrix(size: int, density: float, rng: Random) =
let coords =
[ for i in 0 .. size - 1 do
for j in 0 .. size - 1 do
if rng.NextDouble() < density then
let value = double (rng.Next(1, 4))
yield (uint64 i * 1UL<Matrix.rowindex>, uint64 j * 1UL<Matrix.colindex>, value) ]

match
Matrix.fromCoordinateList (
Matrix.CoordinateList(uint64 size * 1UL<Matrix.nrows>, uint64 size * 1UL<Matrix.ncols>, coords)
)
with
| Ok m -> m
| Error msg -> failwithf "Failed to create matrix: %s" msg

[<GlobalSetup>]
member this.Setup() =
let rng = Random(this.Seed)
this.Matrix <- this.GenerateMatrix(this.Size, this.Density, rng)

member private this.SliceWithOffset(m: Matrix.SparseMatrix<double>) =
let n = int m.nrows
let start = this.StartOffset
let last = start + this.SliceSize - 1

if last >= n then
failwithf "Slice out of bounds: start=%d, last=%d, n=%d" start last n

match Matrix.slice m start last start last with
| Ok res -> res
| Error msg -> failwithf "Slice failed: %s" msg

[<Benchmark>]
member this.Slice() =
this.SliceWithOffset(this.Matrix) |> ignore
8 changes: 7 additions & 1 deletion QuadTree.Benchmark/QuadTree.Benchmark.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
<Compile Include="BFS.fs"/>
<Compile Include="SSSP.fs"/>
<Compile Include="Triangles.fs"/>
<Compile Include="ReduceComparison.fs"/>
<Compile Include="VectorSlice.fs"/>
<Compile Include="MatrixSlice.fs"/>
<Compile Include="Kronecker.fs"/>
<Compile Include="MatrixSliceAlign.fs"/>
<Compile Include="VectorSliceAlign.fs"/>
<Compile Include="Main.fs"/>
</ItemGroup>

Expand All @@ -22,4 +28,4 @@
<ProjectReference Include="..\QuadTree\QuadTree.fsproj" />
</ItemGroup>

</Project>
</Project>
110 changes: 110 additions & 0 deletions QuadTree.Benchmark/ReduceComparison.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
namespace QuadTree.Benchmarks.ReduceComparison

open System
open System.IO
open BenchmarkDotNet.Attributes
open QuadTree.Benchmarks.Utils

[<Config(typeof<MyConfig>)>]
[<MemoryDiagnoser>]
type Benchmark() =

let add x y =
match x, y with
| Some a, Some b -> Some(a + b)
| Some a, None
| None, Some a -> Some a
| _ -> None

[<Params("bcsstk01",
"bcsstk02",
"bcsstk03",
"bcsstk04",
"bcsstk05",
"bcsstk06",
"bcsstk07",
"bcsstk08",
"bcsstk09",
"bcsstk10",
"bcsstk11",
"bcsstk12",
"bcsstk13",
"bcsstk14",
"bcsstk15",
"bcsstk16",
"bcsstk17",
"bcsstk18",
"bcsstk29",
"bcsstk30",
"bcsstk31",
"cavity01",
"cavity05",
"cavity10",
"mesh2e1",
"mesh3em5",
"pwt",
"shuttle_eddy",
"tandem_vtx",
"email-Eu-core")>]
member val MatrixName = "" with get, set
Comment thread
Danil-Zaripov marked this conversation as resolved.

member val Matrix = Unchecked.defaultof<Matrix.SparseMatrix<double>> with get, set
member val Size = 0 with get, set
member val Density = 0.0 with get, set
member val IsSymmetric = false with get, set

member private this.CheckSymmetric(m: Matrix.SparseMatrix<double>) =
let coo = Matrix.toCoordinateList m
let dict = System.Collections.Generic.Dictionary<string, double>()

for (i, j, v) in coo.list do
let key = $"{uint64 i},{uint64 j}"
dict.[key] <- v

let mutable sym = true

for (i, j, v) in coo.list do
let key = $"{uint64 j},{uint64 i}"

match dict.TryGetValue(key) with
| true, v2 when v = v2 -> ()
| _ -> sym <- false

sym

[<GlobalSetup>]
member this.Setup() =
let rec findProjectRoot (dir: string) =
if Directory.Exists(Path.Combine(dir, "data")) then
dir
else
let parent = Directory.GetParent(dir)

if parent = null then
failwith "Project root not found (data directory is missing)"
else
findProjectRoot parent.FullName

let projectRoot = findProjectRoot __SOURCE_DIRECTORY__

let path =
Path.Combine(projectRoot, "data", this.MatrixName, $"{this.MatrixName}.mtx")

if not (File.Exists path) then
failwithf "File not found: %s\nSearched in: %s" path projectRoot

match QuadTree.Benchmarks.Utils.readMtx path false with
| Ok m ->
this.Matrix <- m
this.Size <- int m.nrows
this.Density <- float m.nvals / (float m.nrows * float m.ncols)
this.IsSymmetric <- this.CheckSymmetric(m)
| Error msg -> failwithf "Failed to load %s: %s" this.MatrixName msg

[<Benchmark>]
member this.ReduceCols_Original() = Matrix.reduceCols add this.Matrix

[<Benchmark>]
member this.ReduceCols_ViaTranspose() =
let transposed = Matrix.transpose this.Matrix
Matrix.reduceRows add transposed
6 changes: 4 additions & 2 deletions QuadTree.Benchmark/SSSP.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ open QuadTree.Benchmarks.Utils
type Benchmark() =
let mutable matrix = Unchecked.defaultof<Matrix.SparseMatrix<double>>


[<Params("494_bus.mtx", "arc130.mtx")>]
member val MatrixName = "" with get, set

[<GlobalSetup>]
member this.LoadMatrix() =
matrix <- readMtx (System.IO.Path.Combine(DIR_WITH_MATRICES, this.MatrixName)) false
matrix <-
match readMtx (System.IO.Path.Combine(DIR_WITH_MATRICES, this.MatrixName)) false with
| Ok m -> m
Comment thread
Brulevich-Nikita marked this conversation as resolved.
| Error e -> failwith $"Failed to load matrix {this.MatrixName}: {e}"

[<Benchmark>]
member this.SSSP() = Graph.SSSP.sssp matrix 0UL
5 changes: 4 additions & 1 deletion QuadTree.Benchmark/Triangles.fs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ type Benchmark() =

[<GlobalSetup>]
member this.LoadMatrix() =
matrix <- readMtx (System.IO.Path.Combine(DIR_WITH_MATRICES, this.MatrixName)) false
matrix <-
match readMtx (System.IO.Path.Combine(DIR_WITH_MATRICES, this.MatrixName)) false with
| Ok m -> m
| Error msg -> failwith $"Failed to load matrix {this.MatrixName}: {msg}"

[<Benchmark>]
member this.TriangleCount() =
Expand Down
Loading
Loading