Skip to content

Commit 6f3bb31

Browse files
authored
Merge pull request #104 from Juice-jl/compressed-io
Support for `read` and `write` of circuits to *.gz compressed files
2 parents 97ad299 + 98290d8 commit 6f3bb31

File tree

10 files changed

+104
-45
lines changed

10 files changed

+104
-45
lines changed

.github/workflows/slow_tests.yml

Lines changed: 0 additions & 36 deletions
This file was deleted.

Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ version = "0.3.1"
66
[deps]
77
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
88
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
9+
CodecZlib = "944b1d66-785c-5afd-91f1-9de20f533193"
910
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
1011
DirectedAcyclicGraphs = "1e6dae5e-d6e2-422d-9af3-452e7a3785ee"
1112
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
@@ -23,6 +24,7 @@ TikzGraphs = "b4f28e30-c73f-5eaf-a395-8a9db949a742"
2324
[compat]
2425
CSV = "0.7, 0.8, 0.9"
2526
CUDA = "3"
27+
CodecZlib = "0.7"
2628
DataFrames = "1.1, 1.2"
2729
DirectedAcyclicGraphs = "0.1.1"
2830
Graphs = "1.4"

src/Utils/misc.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ export issomething,
1818
never,
1919
uniform,
2020
logsumexp,
21-
noop,
22-
map_values,
23-
groupby
21+
noop
2422

2523

2624
using CUDA: CuArray, CuVector, CuMatrix, CUDA

src/io/io.jl

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
using LazyArtifacts
22
using Lerche: Lerche, Lark, Transformer, @rule, @inline_rule
3+
using CodecZlib: GzipDecompressorStream, GzipCompressorStream
34

4-
export FileFormat
5+
export FileFormat, GzipFormat
56

67
# version of model zoo to grab files from
78
const zoo_version = "/Circuit-Model-Zoo-0.1.4"
@@ -13,6 +14,10 @@ Lerche.visit_tokens(t::JuiceTransformer) = false
1314
# file formats supported by this package
1415
abstract type FileFormat end
1516

17+
struct GzipFormat <: FileFormat
18+
inner_format::FileFormat
19+
end
20+
1621
# usual comment format for DIMACS-based file formats
1722
const dimacs_comments = raw"""
1823
COMMENT : ("c" | "cc") (_WS /[^\n]/*)? (_NL | /$/)
@@ -32,7 +37,11 @@ include("plot.jl")
3237
# if no logic circuit file format is given on read, infer file format from extension
3338

3439
function file2logicformat(file)
35-
if endswith(file,".jlc")
40+
if endswith(file,".gz")
41+
file_inner, _ = splitext(file)
42+
format_inner = file2logicformat(file_inner)
43+
GzipFormat(format_inner)
44+
elseif endswith(file,".jlc")
3645
JlcFormat()
3746
elseif endswith(file,".sdd")
3847
SddFormat()
@@ -83,6 +92,10 @@ Base.parse(::Type{LogicCircuit}, args...) =
8392
Base.read(io::IO, ::Type{LogicCircuit}, args...) =
8493
read(io, PlainLogicCircuit, args...)
8594

95+
Base.read(io::IO, ::Type{LogicCircuit}, f::GzipFormat) =
96+
# avoid method ambiguity
97+
read(io, PlainLogicCircuit, f)
98+
8699
# when asked to parse/read as `StructLogicCircuit`, default to `PlainStructLogicCircuit`
87100

88101
Base.parse(::Type{StructLogicCircuit}, args...) =
@@ -91,9 +104,17 @@ Base.parse(::Type{StructLogicCircuit}, args...) =
91104
Base.read(io::IO, ::Type{StructLogicCircuit}, args...) =
92105
read(io, PlainStructLogicCircuit, args...)
93106

107+
Base.read(io::IO, ::Type{StructLogicCircuit}, f::GzipFormat) =
108+
# avoid method ambiguity
109+
read(io, PlainStructLogicCircuit, f)
110+
94111
Base.read(ios::Tuple{IO,IO}, ::Type{StructLogicCircuit}, args...) =
95112
read(ios, PlainStructLogicCircuit, args...)
96113

114+
Base.read(ios::Tuple{IO,IO}, ::Type{StructLogicCircuit}, f::Tuple{GzipFormat,VtreeFormat}) =
115+
# avoid method ambiguity
116+
read(ios, PlainStructLogicCircuit, f)
117+
97118
# copy read/write API for tuples of files
98119

99120
function Base.read(files::Tuple{AbstractString, AbstractString}, ::Type{C}, args...) where C <: StructLogicCircuit
@@ -111,4 +132,28 @@ function Base.write(files::Tuple{AbstractString,AbstractString},
111132
write((io1, io2), circuit, args...)
112133
end
113134
end
114-
end
135+
end
136+
137+
# (de)compress Gzip streams
138+
139+
Base.read(io::IO, circuit_type, f::GzipFormat) =
140+
read(GzipDecompressorStream(io), circuit_type, f.inner_format)
141+
142+
Base.write(io::IO, circuit, f::GzipFormat) = begin
143+
iogz = GzipCompressorStream(io)
144+
write(iogz, circuit, f.inner_format)
145+
close(iogz)
146+
end
147+
148+
Base.read(ios::Tuple{IO,IO}, circuit_type, f::Tuple{GzipFormat,VtreeFormat}) = begin
149+
ios = (GzipDecompressorStream(ios[1]), ios[2])
150+
formats = (f[1].inner_format, f[2])
151+
read(ios, circuit_type, formats)
152+
end
153+
154+
Base.write(io::Tuple{IO,IO}, circuit, f::Tuple{GzipFormat,VtreeFormat}) = begin
155+
iosgz = (GzipCompressorStream(io[1]), io[2])
156+
formats = (f[1].inner_format, f[2])
157+
write(iosgz, circuit, formats)
158+
close(iosgz[1])
159+
end
File renamed without changes.

test/io/fnf_io_test.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,16 @@ using LogicCircuits
3535
cnf_orig = zoo_cnf("easy/C17_mince.cnf")
3636
@test_nowarn write("$tmp/temp.cnf", cnf_orig)
3737
cnf_new = read("$tmp/temp.cnf", LogicCircuit)
38+
3839
@test num_variables(cnf_orig) == num_variables(cnf_new)
3940
@test all(x isa Plain⋁Node || x isa PlainLiteralNode for x in cnf_new.children)
4041
@test all(all(x isa PlainLiteralNode for x in or_node.children) for or_node in or_nodes(cnf_new))
4142
@test tree_formula_string(cnf_orig) == tree_formula_string(cnf_new)
4243

44+
@test_nowarn write("$tmp/temp.cnf.gz", cnf_orig)
45+
cnf_new = read("$tmp/temp.cnf.gz", LogicCircuit)
46+
@test tree_formula_string(cnf_orig) == tree_formula_string(cnf_new)
47+
4348
end
4449

4550
end
@@ -66,6 +71,10 @@ end
6671
circuit2 = read(temp_path, LogicCircuit)
6772
test8(circuit2)
6873

74+
write("$temp_path.gz", circuit)
75+
circuit2 = read("$temp_path.gz", LogicCircuit)
76+
test8(circuit2)
77+
6978
end
7079

7180
end

test/io/jlc_io_test.jl

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,17 @@ include("../helper/little_circuits.jl")
1717
jlc2 = read(jlc_path, LogicCircuit, JlcFormat())
1818

1919
@test jlc2 isa PlainLogicCircuit
20-
2120
@test num_nodes(sdd) == num_nodes(jlc2)
2221
@test prob_equiv(sdd, jlc2, 10)
2322

23+
# write/read as an instructured logic circuit, compressed
24+
write("$jlc_path.gz", sdd)
25+
jlc2 = read("$jlc_path.gz", LogicCircuit)
26+
27+
@test jlc2 isa PlainLogicCircuit
28+
@test num_nodes(sdd) == num_nodes(jlc2)
29+
@test prob_equiv(sdd, jlc2, 10)
30+
2431
# write with vtree
2532
vtree_path = "$tmp/example.vtree"
2633
paths = (jlc_path, vtree_path)
@@ -31,10 +38,18 @@ include("../helper/little_circuits.jl")
3138
jlc3 = read(paths, StructLogicCircuit, formats)
3239

3340
@test jlc3 isa PlainStructLogicCircuit
34-
3541
@test num_nodes(sdd) == num_nodes(jlc3)
3642
@test prob_equiv(sdd, jlc3, 10)
43+
@test Vtree(mgr(sdd)) == vtree(jlc3)
3744

45+
# write/read with vtree, compressed
46+
pathsgz = ("$jlc_path.gz", vtree_path)
47+
write(pathsgz, sdd)
48+
jlc3 = read(pathsgz, StructLogicCircuit)
49+
50+
@test jlc3 isa PlainStructLogicCircuit
51+
@test num_nodes(sdd) == num_nodes(jlc3)
52+
@test prob_equiv(sdd, jlc3, 10)
3853
@test Vtree(mgr(sdd)) == vtree(jlc3)
3954

4055
end

test/io/nnf_io_test.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ include("../helper/little_circuits.jl")
4646

4747
@test prob_equiv(circuit, circuit2, 10)
4848

49+
write("$temp_path.gz", circuit)
50+
51+
circuit2 = read("$temp_path.gz", LogicCircuit)
52+
53+
test_circuit(circuit2)
54+
55+
@test prob_equiv(circuit, circuit2, 10)
56+
4957
end
5058
end
5159

@@ -62,5 +70,13 @@ end
6270
@test num_nodes(circuit) == num_nodes(circuit2)
6371
@test num_edges(circuit) == num_edges(circuit2)
6472
@test prob_equiv(circuit, circuit2, 10)
73+
74+
write("$temp_path.gz", circuit)
75+
76+
circuit2 = read("$temp_path.gz", LogicCircuit)
77+
78+
@test num_nodes(circuit) == num_nodes(circuit2)
79+
@test num_edges(circuit) == num_edges(circuit2)
80+
@test prob_equiv(circuit, circuit2, 10)
6581
end
6682
end

test/io/sdd_io_test.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ end
6666

6767
@test Vtree(mgr(sdd)) == Vtree(mgr(sdd4))
6868

69+
# write/read compressed
70+
paths = ("$sdd_path.gz", vtree_path)
71+
write(paths, sdd)
72+
sdd4 = read(paths, StructLogicCircuit)
73+
74+
@test sdd4 isa PlainStructLogicCircuit
75+
@test num_nodes(sdd) == num_nodes(sdd4)
76+
@test prob_equiv(sdd, sdd4, 10)
77+
@test Vtree(mgr(sdd)) == vtree(sdd4)
78+
6979
end
7080

7181
mktempdir() do tmp

test/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
using Jive
44

5-
runtests(@__DIR__, skip=["runtests.jl", "helper/", "_manual_/", "build/"])
5+
runtests(@__DIR__, skip=["runtests.jl", "helper/", "build/"])

0 commit comments

Comments
 (0)