Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 31 additions & 0 deletions benchmark/autofill.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Autofill around paths, first with coarse grid, then with fine grid
function coarse_and_fine_autofill()
cs = CoordinateSystem("autofill_bench", nm)
pa = Path(nm)
pa.metadata = SemanticMeta(:metal_negative)
bspline!(pa, [Point(1000μm, 1000μm)], 90°, Paths.SimpleCPW(10μm, 6μm))
meander!(pa, 6000μm, 500μm, 200μm, -180°)
bspline!(pa, [Point(4000μm, 0μm)], 0°)
# Place two copies of paths, one rotated
addref!(cs, pa)
addref!(cs, pa, Point(-500μm, 0μm), rot=90°)

# Autofill grids
coarse_grid_x = (-3000:250:5000)μm
coarse_grid_y = (-1000:250:5000)μm
fine_grid_x = (-3000:25:5000)μm
fine_grid_y = (-1000:25:5000)μm

# Coordinate systems holding "dummy" geometry (the thing filling space)
coarse_dummy = CoordinateSystem("coarse", nm)
place!(coarse_dummy, centered(Rounded(Rectangle(100μm, 100μm), 50μm)), :metal_negative)
fine_dummy = CoordinateSystem("fine", nm)
place!(fine_dummy, centered(Rounded(Rectangle(10μm, 10μm), 5μm)), :metal_negative)

# Autofill
autofill!(cs, coarse_dummy, coarse_grid_x, coarse_grid_y, make_halo(150μm))
autofill!(cs, fine_dummy, fine_grid_x, fine_grid_y, make_halo(50μm))
return
end

SUITE["autofill"] = @benchmarkable coarse_and_fine_autofill()
14 changes: 11 additions & 3 deletions benchmark/benchmarks.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
using Test, BenchmarkTools
const SUITE = BenchmarkGroup()

using DeviceLayout, Pkg, FileIO, Unitful, DeviceLayout.PreferredUnits
using DeviceLayout.SchematicDrivenLayout
import Random: default_rng, rand, seed!

const um = μm
const SUITE = BenchmarkGroup()

include(joinpath(@__DIR__, "clipping.jl"))
include("autofill.jl")
include("bounds.jl")
include("clipping.jl")
include("curves.jl")
include("intersect.jl")
include("polygons.jl")
include("schematic.jl")
53 changes: 53 additions & 0 deletions benchmark/bounds.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
SUITE["bounds"] = BenchmarkGroup()
SUITE["flatten"] = BenchmarkGroup()

rng = seed!(default_rng(), 111)
# Generate rectangles from random points
num_rects = 1_000
p1s = reinterpret(Point{Int}, rand(Int, 2, num_rects))
p2s = reinterpret(Point{Int}, rand(Int, 2, num_rects))
random_rectangles = [Rectangle(p1, p2) for (p1, p2) in zip(p1s, p2s)]
# Circles around points
random_circles = [circle_polygon(1.0, 10°) for p1 in p1s]

# Cell with same circle coordinate system referenced many times at top level
c_shallow = Cell{Float64}("shallow")
c_circ = Cell{Float64}("circle")
render!(c_circ, circle_polygon(10.0, 10°))
rots = rand(num_rects) * 2π
for (p1, rot) in zip(p1s, rots)
addref!(c_shallow, c_circ, p1, rot=rot)
end

# Cell with reference to a circle coordinate systems holding a reference to another
# and so on to `num_rects` depth
c_nested = Cell{Float64}("nested")
rots = rand(num_rects) * 2π
nextcell = c_nested
for (p1, rot) in zip(p1s, rots)
global nextcell
c = Cell{Float64}(uniquename("nested"))
addref!(nextcell, c, p1, rot=rot)
nextcell = c
render!(nextcell, circle_polygon(10.0, 10°))
end

# Array reference with around 1000 circles
c_arrayed = Cell{Float64}("arrayed")
addarr!(
c_arrayed,
c_circ,
numrows=31,
numcols=31,
deltarow=Point(0.0, 10.0),
deltacol=Point(10.0, 0.0)
)

SUITE["bounds"]["random_rectangles"] = @benchmarkable bounds($random_rectangles)
SUITE["bounds"]["random_circles"] = @benchmarkable bounds($random_circles)
SUITE["bounds"]["shallow_references"] = @benchmarkable bounds($c_shallow)
SUITE["bounds"]["nested_references"] = @benchmarkable bounds($c_nested)

SUITE["flatten"]["shallow_references"] = @benchmarkable flatten($c_shallow)
SUITE["flatten"]["nested_references"] = @benchmarkable flatten($c_nested)
SUITE["flatten"]["array_reference"] = @benchmarkable flatten($c_arrayed)
15 changes: 15 additions & 0 deletions benchmark/clipping.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
SUITE["clipping"] = BenchmarkGroup()
SUITE["clipping"]["difference2d"] = BenchmarkGroup()

# Differences using various pregenerated square arrays
for name in [
:difference2d_100_square,
:difference2d_961_square,
Expand All @@ -27,3 +28,17 @@ c = element_metadata(difference2d_8000_skew)
a = splice!(b, findall(m -> m == GDSMeta(0, 0), c))

SUITE["clipping"]["difference2d"]["8000_skew"] = @benchmarkable difference2d($(a), $(b))

# Offset a hexagon then take the difference across some overlapping copies
function offset_difference()
c = Cell{Float64}("test")
poly = circle_polygon(1.5, 60°)
render!(c, poly)
ref = aref(c, Point(-3.0, 5.0), nc=4, deltacol=Point(2.0, 0.0))
els = [poly; elements(flatten(ref))]
off = offset(els, 0.2)
boo = difference2d(off, els)
return render!(c, boo, GDSMeta(1)) # Render to force interiorcuts
end

SUITE["clipping"]["difference2d_offset"] = @benchmarkable offset_difference()
47 changes: 47 additions & 0 deletions benchmark/curves.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
SUITE["curves"] = BenchmarkGroup()

# Build and render turns
function turns()
c = Cell{Float64}("test")
turn_path = Path{Float64}()
for i = 1:10
turn!(turn_path, 45°, 20.0 * i, Paths.CPW(10.0, 6.0))
turn!(turn_path, -45°, 20.0 * i)
end
return render!(c, turn_path, GDSMeta())
end

# Build and render B-splines
function bsplines()
c = Cell{Float64}("test")
bspline_path = Path{Float64}()
for i = 1:10
bspline!(
bspline_path,
[p0(bspline_path) + Point(20 * i, 10 * i)],
0°,
Paths.CPW(10.0, 6.0),
endpoints_speed=20.0 * i
)
end
return render!(c, bspline_path, GDSMeta())
end

# Approximate offset curves with B-splines
function offset_bspline_approx()
bspline_path = Path{Float64}()
for i = 1:10
bspline!(
bspline_path,
[p0(bspline_path) + Point(20 * i, 10 * i^2)],
0°,
Paths.CPW(10.0, 6.0),
endpoints_speed=20.0 * i
)
Paths.bspline_approximation(Paths.offset(bspline_path[end].seg, 11.0))
end
end

SUITE["curves"]["turns_render"] = @benchmarkable turns()
SUITE["curves"]["bsplines_render"] = @benchmarkable bsplines()
SUITE["curves"]["offset_bspline_approximation"] = @benchmarkable offset_bspline_approx()
12 changes: 12 additions & 0 deletions benchmark/intersect.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Crossing vertical and horizontal paths
paths_vert = [Path(i * 0.1mm, (-1)^(i + 1) * (1mm), α0=(-1)^i * π / 2) for i = -5:5]
paths_horiz = [Path((-1)^(i) * (1mm), i * 0.1mm, α0=(-1)^i * π / 2 + π / 2) for i = -5:5]

sty = Paths.SimpleCPW(10μm, 6μm)
straight!.(paths_vert, 2mm, Ref(sty))
straight!.(paths_horiz, 2mm, Ref(sty))
all_paths = vcat(paths_vert, paths_horiz)

SUITE["intersection"] = BenchmarkGroup()
SUITE["intersection"]["straight_lines"] =
@benchmarkable Intersect.prepared_intersections($all_paths)
81 changes: 81 additions & 0 deletions benchmark/polygons.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
SUITE["polygons"] = BenchmarkGroup()
SUITE["polygons"]["circles"] = BenchmarkGroup()
SUITE["polygons"]["rectangles"] = BenchmarkGroup()

# Render and optionally export n rectangles
function rectangles(n; output_dir=nothing)
c = Cell{Float64}("rectangles")
for i = 1:n
render!(c, Rectangle(Point(i, 0.0), Point(i + 1, 1.0)))
end
return !isnothing(output_dir) && save(joinpath(output_dir, "$(n)_rectangles.gds"), c)
end

# As above but with units
function rectangles_units(n, unit; output_dir=nothing)
um = uconvert(unit, DeviceLayout.onemicron(1unit))
c = Cell{typeof(1.0nm)}("rectangles") # coordinatetype(c) may or may not be same as unit
for i = 1:n
render!(c, Rectangle(Point(i * um, 0 * um), Point((i + 1) * um, 1 * um)))
end
return !isnothing(output_dir) &&
save(joinpath(output_dir, "$(n)_rectangles_units.gds"), c)
end

# Render circles using `circle_polygon` to calculate polygon points directly
# (use ~maxiumum number of points for single GDSII polygon -- other extreme from rectangles)
function circles_direct(n; output_dir=nothing)
c = Cell{Float64}("circles")
for i = 1:n
render!(c, Point(i, 0.0) + circle_polygon(1, 2π / 8000))
end
return !isnothing(output_dir) && save(joinpath(output_dir, "$(n)_circles.gds"), c)
end

# As above but with units
function circles_direct_units(n, unit; output_dir=nothing)
um = uconvert(unit, DeviceLayout.onemicron(1unit))
c = Cell{typeof(1.0nm)}("circles") # coordinatetype(c) may or may not be same as unit
for i = 1:n
render!(c, Point(i * um, 0.0 * um) + circle_polygon(1 * um, 2π / 8000))
end
return !isnothing(output_dir) && save(joinpath(output_dir, "$(n)_circles_units.gds"), c)
end

# Render circles using `Circle` entity and `Δθ` keyword option for discretization
function circles_entity_delta(n; output_dir=nothing)
c = Cell{Float64}("circles")
for i = 1:n
render!(c, Circle(Point(i, 0.0), 1.0), Δθ=2π / 8000)
end
return !isnothing(output_dir) && save(joinpath(output_dir, "$(n)_circles_delta.gds"), c)
end

# As above but using `atol` for discretization with the same number of points
function circles_entity_atol(n; output_dir=nothing)
c = Cell{Float64}("circles")
for i = 1:n
render!(c, Circle(Point(i, 0.0), 1.0), atol=4e-7)#, atol=7.714e-8) # 7999 points
end
return !isnothing(output_dir) && save(joinpath(output_dir, "$(n)_circles_atol.gds"), c)
end

dir = mktempdir()
SUITE["polygons"]["rectangles"]["render"] = @benchmarkable rectangles(10_000)
SUITE["polygons"]["rectangles"]["render_gds"] =
@benchmarkable rectangles(10_000, output_dir=$dir)
SUITE["polygons"]["rectangles"]["render_units"] =
@benchmarkable rectangles_units(10_000, $nm)
SUITE["polygons"]["rectangles"]["render_units_gds"] =
@benchmarkable rectangles_units(10_000, $nm, output_dir=$dir)
SUITE["polygons"]["rectangles"]["render_convertunits"] =
@benchmarkable rectangles_units(10_000, $μm)
SUITE["polygons"]["circles"]["direct"] = @benchmarkable circles_direct(1_000)
SUITE["polygons"]["circles"]["direct_gds"] =
@benchmarkable circles_direct(1_000, output_dir=$dir)
SUITE["polygons"]["circles"]["direct_units"] =
@benchmarkable circles_direct_units(1_000, $nm)
SUITE["polygons"]["circles"]["direct_units_gds"] =
@benchmarkable circles_direct_units(1_000, $nm, output_dir=$dir)
SUITE["polygons"]["circles"]["entity_delta"] = @benchmarkable circles_entity_delta(1_000)
SUITE["polygons"]["circles"]["entity_atol"] = @benchmarkable circles_entity_atol(1_000)
14 changes: 14 additions & 0 deletions benchmark/schematic.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Schematic with chain of spacers rotated at 45 degrees
g = SchematicGraph("test")
lastnode = add_node!(g, Spacer{Float64}(p1=Point(10.0, 10.0)))
for i = 1:100
global lastnode
lastnode = fuse!(
g,
lastnode => :p1_east,
Spacer{Float64}(p1=Point(10.0, 10.0)) => :p0_southwest
)
end

SUITE["schematic"] = BenchmarkGroup()
SUITE["schematic"]["plan"] = @benchmarkable plan($g; log_dir=nothing)
2 changes: 1 addition & 1 deletion benchmark/tune.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[{"Julia":"1.6.0-rc2","BenchmarkTools":"0.4.3"},[["BenchmarkGroup",{"data":{"clipping":["BenchmarkGroup",{"data":{"difference2d":["BenchmarkGroup",{"data":{"100_square":["BenchmarkTools.Parameters",{"gctrial":true,"time_tolerance":0.05,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"3600_square":["BenchmarkTools.Parameters",{"gctrial":true,"time_tolerance":0.05,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"961_square":["BenchmarkTools.Parameters",{"gctrial":true,"time_tolerance":0.05,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"19881_square":["BenchmarkTools.Parameters",{"gctrial":true,"time_tolerance":0.05,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"8000_skew":["BenchmarkTools.Parameters",{"gctrial":true,"time_tolerance":0.05,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"10000_square":["BenchmarkTools.Parameters",{"gctrial":true,"time_tolerance":0.05,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}]},"tags":[]}]},"tags":[]}]]]
[{"Julia":"1.12.0","BenchmarkTools":{"major":1,"minor":6,"patch":2,"prerelease":[],"build":[]}},[["BenchmarkGroup",{"data":{"schematic":["BenchmarkGroup",{"data":{"plan":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}],"curves":["BenchmarkGroup",{"data":{"turns_render":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"bsplines_render":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"offset_bspline_approximation":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}],"polygons":["BenchmarkGroup",{"data":{"rectangles":["BenchmarkGroup",{"data":{"render_units":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"render":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"render_units_gds":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"render_convertunits":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"render_gds":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}],"circles":["BenchmarkGroup",{"data":{"direct":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"entity_delta":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"direct_units_gds":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"direct_units":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"entity_atol":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"direct_gds":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}]},"tags":[]}],"flatten":["BenchmarkGroup",{"data":{"shallow_references":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"array_reference":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"nested_references":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}],"clipping":["BenchmarkGroup",{"data":{"difference2d_offset":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"difference2d":["BenchmarkGroup",{"data":{"100_square":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"3600_square":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"961_square":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"19881_square":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"8000_skew":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"10000_square":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}]},"tags":[]}],"bounds":["BenchmarkGroup",{"data":{"random_rectangles":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"shallow_references":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"random_circles":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"nested_references":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}],"intersection":["BenchmarkGroup",{"data":{"straight_lines":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}],"autofill":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}]]]