Skip to content

Commit 1ccf976

Browse files
committed
Support parallel decoding of the SIF files
1 parent 1a41838 commit 1ccf976

File tree

3 files changed

+61
-53
lines changed

3 files changed

+61
-53
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Printf = "1.10"
3030
Quadmath = "0.5.10"
3131
REPL = "1.10"
3232
Random = "1.10"
33-
SIFDecode_jll = "2.6.1"
33+
SIFDecode_jll = "2.6.3"
3434
SparseArrays = "1.10"
3535
Test = "1.10"
3636
julia = "1.10"

src/model.jl

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,17 @@ function CUTEstModel{T}(
113113
end
114114
end
115115

116-
precision = (T == Float32) ? :single : (T == Float64) ? :double : :quadruple
116+
if T == Float32
117+
precision = :single
118+
elseif T == Float64
119+
precision = :double
120+
elseif T == Float128
121+
precision = :quadruple
122+
else
123+
error("The precision $T is not supported.")
124+
end
117125
pname, sif = basename(name) |> splitext
118-
outsdif = "OUTSDIF_$(pname)_$precision.d"
126+
outsdif = _name_outsdif(pname, precision)
119127
libsif = C_NULL
120128

121129
funit = rand(1000:10000) |> Ref{Cint}
@@ -125,10 +133,10 @@ function CUTEstModel{T}(
125133
libsif_name = "lib$(pname)_$(precision)"
126134
if !decode
127135
isfile(outsdif) || error("CUTEst: no decoded problem found")
128-
isfile("$(libsif_name).$dlext") || error("CUTEst: lib not found; decode problem first")
136+
isfile("$libsif_name.$dlext") || error("CUTEst: $libsif_name.$dlext not found; decode problem first")
129137
else
130-
sifdecoder(path_sifname, args..., verbose = verbose, outsdif = outsdif, precision = precision)
131-
build_libsif(path_sifname, precision = precision)
138+
sifdecoder(path_sifname, args...; verbose, precision)
139+
build_libsif(path_sifname; precision)
132140
end
133141
libsif = Libdl.dlopen(libsif_name, Libdl.RTLD_NOW | Libdl.RTLD_DEEPBIND | Libdl.RTLD_GLOBAL)
134142
fopen(T, libsif, funit, outsdif, status)

src/sifdecoder.jl

Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,34 @@ function list_sif_problems()
4040
return problems
4141
end
4242

43+
function _suffix_precision(precision::Symbol)
44+
if precision == :single
45+
return "_s"
46+
elseif precision == :double
47+
return ""
48+
elseif precision == :quadruple
49+
return "_q"
50+
else
51+
error("The $precision precision is not supported.")
52+
end
53+
end
54+
55+
function _decoder_precision(precision::Symbol)
56+
if precision == :single
57+
return "-sp"
58+
elseif precision == :double
59+
return "-dp"
60+
elseif precision == :quadruple
61+
return "-qp"
62+
else
63+
error("The $precision precision is not supported.")
64+
end
65+
end
66+
4367
function _name_outsdif(name::String, precision::Symbol)
4468
sifname, extension = basename(name) |> splitext
45-
name = "OUTSDIF_$(sifname)_$(precision).d"
69+
suffix = _suffix_precision(precision)
70+
name = "OUTSDIF_$(sifname)$(suffix).d"
4671
return name
4772
end
4873

@@ -57,7 +82,6 @@ Decodes a SIF problem, converting it into a format suitable for further processi
5782
- `args...`: Additional arguments passed directly to the SIF decoder. Relevant for problems with variable sizes.
5883
- `verbose::Bool`: If `true`, enables verbose output during the decoding process. Defaults to `false`.
5984
- `precision::Symbol`: The desired precision for the problem. Can be `:single`, `:double` (default), or `:quadruple`.
60-
- `outsdif::String`: The name of the file `OUTSDIF.d` required for automatic differentiation. Defaults to `"OUTSDIF_sifname_precision.d"`, where `sifname` and `precision` are replaced with the problem name and chosen precision.
6185
- `libsif_folder::String`: The directory where the generated files (`*.f` and `*.d`) will be stored. Defaults to `libsif_path`.
6286
6387
```julia
@@ -71,21 +95,12 @@ function sifdecoder(
7195
args...;
7296
verbose::Bool = false,
7397
precision::Symbol = :double,
74-
outsdif::String = _name_outsdif(name, precision),
7598
libsif_folder::String = libsif_path,
7699
)
77-
if precision == :single
78-
prec = "-sp"
79-
suffix = "_s"
80-
elseif precision == :double
81-
prec = "-dp"
82-
suffix = ""
83-
elseif precision == :quadruple
84-
prec = "-qp"
85-
suffix = "_q"
86-
else
87-
error("The $precision precision is not supported.")
88-
end
100+
outsdif = _name_outsdif(name, precision)
101+
prec = _decoder_precision(precision)
102+
suffix = _suffix_precision(precision)
103+
pname, sif = basename(name) |> splitext
89104

90105
if length(name) < 4 || name[(end - 3):end] != ".SIF"
91106
name = "$name.SIF"
@@ -102,11 +117,12 @@ function sifdecoder(
102117
outlog = tempname()
103118
errlog = tempname()
104119
cd(libsif_folder) do
105-
delete_temp_files(suffix)
120+
delete_temp_files(pname, suffix)
121+
isfile(outsdif) && rm(outsdif, force = true)
106122
run(
107123
pipeline(
108124
Cmd(
109-
`$(SIFDecode_jll.sifdecoder_standalone()) $(args) $(prec) $(path_sifname)`,
125+
`$(SIFDecode_jll.sifdecoder_standalone()) $(args) $(prec) -suffix $(path_sifname)`,
110126
ignorestatus = true,
111127
),
112128
stdout = outlog,
@@ -122,7 +138,6 @@ function sifdecoder(
122138
output_str = read(outlog, String)
123139
println(output_str)
124140
end
125-
isfile("OUTSDIF.d") && mv("OUTSDIF.d", outsdif, force = true)
126141
end
127142
rm(outlog)
128143
rm(errlog)
@@ -153,27 +168,13 @@ function build_libsif(
153168
precision::Symbol = :double,
154169
libsif_folder::String = libsif_path,
155170
)
156-
if precision == :single
157-
prec = "-sp"
158-
suffix = "_s"
159-
library = "cutest_single"
160-
elseif precision == :double
161-
prec = "-dp"
162-
suffix = ""
163-
library = "cutest_double"
164-
elseif precision == :quadruple
165-
prec = "-qp"
166-
suffix = "_q"
167-
library = "cutest_quadruple"
168-
else
169-
error("The $precision precision is not supported.")
170-
end
171-
172171
pname, sif = basename(name) |> splitext
173172
libsif_name = "lib$(pname)_$(precision)"
173+
suffix = _suffix_precision(precision)
174+
libcutest = joinpath(libcutest_path, "libcutest_$precision.a")
174175

175176
cd(libsif_folder) do
176-
if isfile("ELFUN$suffix.f")
177+
if isfile("ELFUN_$pname$suffix.f")
177178
object_files = String[]
178179
for file in (
179180
"ELFUN",
@@ -187,45 +188,45 @@ function build_libsif(
187188
"EXTER",
188189
"EXTERA",
189190
)
190-
if isfile("$file$suffix.f")
191+
fname = "$(file)_$pname$suffix"
192+
if isfile("$fname.f")
191193
@static if Sys.iswindows()
192194
mingw = Int == Int64 ? "mingw64" : "mingw32"
193195
gfortran = joinpath(artifact"mingw-w64", mingw, "bin", "gfortran.exe")
194-
run(`$gfortran -O3 -c -fPIC $file$suffix.f`)
196+
run(`$gfortran -O3 -c -fPIC $fname.f`)
195197
else
196-
run(`gfortran -O3 -c -fPIC $file$suffix.f`)
198+
run(`gfortran -O3 -c -fPIC $fname.f`)
197199
end
198-
push!(object_files, "$file$suffix.o")
200+
push!(object_files, "$fname.o")
199201
end
200202
end
201203
if Sys.isapple()
202-
libcutest = joinpath(libcutest_path, "lib$library.a")
203204
run(
204205
`gfortran -dynamiclib -o $(libsif_name).$dlext $(object_files) -Wl,-all_load $libcutest`,
205206
)
206207
elseif Sys.iswindows()
207208
@static if Sys.iswindows()
208209
mingw = Int == Int64 ? "mingw64" : "mingw32"
209210
gfortran = joinpath(artifact"mingw-w64", mingw, "bin", "gfortran.exe")
210-
libcutest = joinpath(libcutest_path, "lib$library.a")
211211
run(
212212
`$gfortran -shared -o $(libsif_name).$dlext $(object_files) -Wl,--whole-archive $libcutest -Wl,--no-whole-archive`,
213213
)
214214
end
215215
else
216-
libcutest = joinpath(libcutest_path, "lib$library.a")
217216
run(
218217
`gfortran -shared -o $(libsif_name).$dlext $(object_files) -Wl,--whole-archive $libcutest -Wl,--no-whole-archive`,
219218
)
220219
end
221-
delete_temp_files(suffix)
220+
delete_temp_files(pname, suffix)
221+
else
222+
error("The file $pname.SIF was not decoded in the folder $libsif_folder.")
222223
end
223224
end
224225
return nothing
225226
end
226227

227-
function delete_temp_files(suffix::String)
228-
for f in (
228+
function delete_temp_files(pname::String, suffix::String)
229+
for file in (
229230
"ELFUN",
230231
"ELFUNF",
231232
"ELFUND",
@@ -238,11 +239,10 @@ function delete_temp_files(suffix::String)
238239
"EXTERA",
239240
)
240241
for ext in ("f", "o")
241-
fname = "$f$suffix.$ext"
242+
fname = "$(file)_$pname$suffix.$ext"
242243
isfile(fname) && rm(fname, force = true)
243244
end
244245
end
245-
isfile("OUTSDIF.d") && rm("OUTSDIF.d", force = true)
246246
nothing
247247
end
248248

0 commit comments

Comments
 (0)