Skip to content
Open
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
182b0c4
Compilable version of Maggs-Plotkin MST.
gsvgit May 29, 2026
6ac040e
Tests on Maggs-Plotkin MST.
gsvgit May 29, 2026
588f407
Formatted
gsvgit May 29, 2026
ac44fe0
Maggs-Plotkin: handle edges with identical weights correctly.
gsvgit May 31, 2026
8bcd91a
MST tests fixed. In progress.
gsvgit May 31, 2026
86b2e89
Simple test on Boruvka to investigate what goes wrong.
gsvgit May 31, 2026
1937a67
Fixed cycles in Boruvka MST
gsvgit May 31, 2026
0243914
Added information about Maggs-Plotkin MSF.
gsvgit May 31, 2026
069d6b9
First vrsion of parent BFS.
gsvgit May 31, 2026
a8f2a7a
Fixed vxmi.
gsvgit Jun 1, 2026
98aa4b2
More tests on BFS.
gsvgit Jun 1, 2026
1b6479e
Added Parent-BFS
gsvgit Jun 1, 2026
a09b299
Formatted.
gsvgit Jun 1, 2026
43047ed
add slice in Vector.fs and Matrix.fs, add reduceRows and reduceCols i…
Brulevich-Nikita May 8, 2026
f62ef2f
add Kronecker product to Matrix.fs with tests, fix tests, duplicate h…
Brulevich-Nikita May 18, 2026
a8c2df2
fix: returned failwith to benchmarks, fix SSSP, LinearAlgebra, MST, B…
Brulevich-Nikita Jun 3, 2026
5feffed
add Benchmarks, their results, fix: slice logic
Brulevich-Nikita Jun 10, 2026
54a24ad
refactor benchmarks
Brulevich-Nikita Jun 13, 2026
fbf3454
add fantomas to refactored benchmarks
Brulevich-Nikita Jun 13, 2026
c5f8bcb
refactor: Vector and Matrix functions and Benchmarks
Brulevich-Nikita Aug 4, 2026
8ae0c1f
refactor: Kronecker, Benchmarks
Brulevich-Nikita Aug 29, 2026
3d493fc
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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ну и так про все бенчи. Тут уже лучше ронять, чтобы было видно, что что-то пошло не так.

| 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