Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Julia interface #232

Merged
merged 33 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
5af726d
[GALAHAD.jl] Regenerate the Julia wrappers
amontoison Jan 21, 2024
e94c216
Update test_structures.jl
amontoison Jan 21, 2024
0e5cf0d
Remove the empty C interface of dlp
amontoison Jan 21, 2024
f5a4af1
Fix a typo in the C files of UGO
amontoison Jan 21, 2024
35e932a
[GALAHAD.jl] Update README.md
amontoison Jan 21, 2024
0f0818d
[GALAHAD.jl] Update the gen folder
amontoison Jan 21, 2024
b2acb82
[GALAHAD.jl] Add Accessors in the Poject.toml
amontoison Jan 21, 2024
a7c4903
[GALAHAD.jl] Update the Julia tests
amontoison Jan 21, 2024
403db8d
[CI] Update JULIA_GALAHAD_LIBRARY_PATH for Windows
amontoison Jan 22, 2024
0cd272c
[GALAHAD.jl] Continue to test the Julia interfaces
amontoison Jan 22, 2024
55329e6
[GALAHAD.jl] More Julia tests...
amontoison Jan 23, 2024
4cbae35
[GALAHAD.jl] Don't test bqpb on Windows
amontoison Jan 23, 2024
cfb52e4
[GALAHAD.jl] Test the pakages bllsb, clls and presolve
amontoison Jan 24, 2024
ea461b2
wip
amontoison Feb 7, 2024
916ec67
Update the generator in Julia wrappers for the new C headers
amontoison Feb 12, 2024
939e2d7
Add a function galahad_linear_solver
amontoison Feb 12, 2024
0a07832
More tests for the Julia interfaces
amontoison Feb 12, 2024
fe09a21
Add OpenBLAS32_jll as a dependency of GALAHAD.jl
amontoison Feb 12, 2024
54c96cd
Update Project.tml
amontoison Feb 12, 2024
3e3d601
Try to debug test_llsr.jl with CI
amontoison Feb 13, 2024
a7fb27a
debug llsr
amontoison Feb 13, 2024
cb34dad
debug llst
amontoison Feb 13, 2024
781f77d
debug llst
amontoison Feb 13, 2024
15b2115
Add a Julia test for all GALAHAD packages
amontoison Feb 13, 2024
4af5669
wip
amontoison Feb 13, 2024
4d2e98d
Fix the structures of some packages
amontoison Feb 13, 2024
7576cba
More working tests!
amontoison Feb 13, 2024
dfdc9e7
Clean examples
amontoison Feb 13, 2024
5db7de8
Clean examples
amontoison Feb 13, 2024
95a992f
Fix test_bgo.jl
amontoison Feb 13, 2024
0671e03
Last examples
amontoison Feb 13, 2024
d76b772
Test all Julia interfaces with CI
amontoison Feb 14, 2024
4d0f38e
Update GALAHAD.jl/gen/README.md
amontoison Feb 14, 2024
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
4 changes: 3 additions & 1 deletion .github/workflows/meson.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,18 @@ jobs:
shell: bash
run: |
echo "GALAHAD=$GITHUB_WORKSPACE" >> $GITHUB_ENV
echo "JULIA_GALAHAD_LIBRARY_PATH=$GITHUB_WORKSPACE/galahad/lib" >> $GITHUB_ENV
echo "DEPS=$GITHUB_WORKSPACE/.." >> $GITHUB_ENV
if [[ "${{matrix.os}}" == "ubuntu-latest" ]]; then
echo "LIBDIR=lib" >> $GITHUB_ENV
echo "JULIA_GALAHAD_LIBRARY_PATH=$GITHUB_WORKSPACE/galahad/lib" >> $GITHUB_ENV
fi
if [[ "${{matrix.os}}" == "macos-latest" ]]; then
echo "LIBDIR=lib" >> $GITHUB_ENV
echo "JULIA_GALAHAD_LIBRARY_PATH=$GITHUB_WORKSPACE/galahad/lib" >> $GITHUB_ENV
fi
if [[ "${{matrix.os}}" == "windows-latest" ]]; then
echo "LIBDIR=bin" >> $GITHUB_ENV
echo "JULIA_GALAHAD_LIBRARY_PATH=$GITHUB_WORKSPACE/galahad/bin" >> $GITHUB_ENV
fi

- name: Install dependencies
Expand Down
5 changes: 4 additions & 1 deletion GALAHAD.jl/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ version = "0.1.0"
[deps]
GALAHAD_jll = "1621ace8-c1f0-5e32-a05d-ca786afa56c2"
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
OpenBLAS32_jll = "656ef2d0-ae68-5445-9ca0-591084a874a2"

[compat]
julia = "1.9"

[extras]
Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "Printf"]
test = ["Test", "Printf", "Accessors"]
4 changes: 1 addition & 3 deletions GALAHAD.jl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,5 @@ permanently in the shell's startup file, or in

## Documentation

Documentation is available online from

https://ralna.github.io/galahad_docs/html/Julia
Documentation is available online from [https://ralna.github.io/galahad_docs/html/Julia](https://ralna.github.io/galahad_docs/html/Julia).

26 changes: 26 additions & 0 deletions GALAHAD.jl/gen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,29 @@ include("wrappers/abcd.jl")

Now, the Julia wrappers for the `abcd` package are accessible upon
loading the Julia interface with `using GALAHAD`.

# Tests

The file `examples.jl` aids in generating Julia tests based on the
C tests within a GALAHAD package. To facilitate the translation of a C
test `GALAHAD/src/abcd/C/abcdtf.c` into a Julia test, follow these steps:

Add the following entry to `examples.jl`:

```julia
(name == "abcd") && examples("abcd", "tf")
```

Replace `"tf"` with `"t"` if translating a test from `abcdt.c`, or use `""` if no corresponding C test exists.

After including `examples.jl`, invoking `main("abcd")` will generate the file `test_abcd.jl` in the
directory `GALAHAD.jl/test`, along with a symbolic link pointing to this file in `GALAHAD/src/abcd/Julia`.

After manual modifications to ensure the Julia test works correctly, you can utilize `clean_example("abcd")`
to format the file.

To test the new package named `abcd` alongside other packages, insert the following line in `GALAHAD.jl/test/runtests.jl`:

```julia
include("test_abcd.jl")
```
204 changes: 123 additions & 81 deletions GALAHAD.jl/gen/examples.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
using JuliaFormatter

function examples(package::String, example::String)
if example == ""
text = "# test_" * package * ".jl\n# Simple code to test the Julia interface to " * uppercase(package) * "\n"
text = "# test_" * package * ".jl\n# Simple code to test the Julia interface to " * uppercase(package) * "\n\n"
text = text * "using GALAHAD\nusing Test\n\nfunction test_$package()\n"
text = text * " data = Ref{Ptr{Cvoid}}()\n"
text = text * " control = Ref{$(package)_control_type{Float64}}()\n"
text = text * " inform = Ref{$(package)_inform_type{Float64}}()\n\n"
text = text * " status = Ref{Cint}()\n"
text = text * " $(package)_initialize(data, control, status)\n"
text = text * " $(package)_information(data, inform, status)\n"
text = text * " $(package)_terminate(data, control, inform)\n\n"
text = text * " return 0\n"
else
src = "../../src/$package/C/" * package * example * ".c"
text = read(src, String)
end
dst = "../test/test_" * package * ".jl"
text = replace(text, " " => "")
text = replace(text, "int main(void) {\n\n" => "# test_$package.jl\n# Simple code to test the Julia interface to " * uppercase(package) * "\n\nusing GALAHAD\nusing Printf\n\n")
text = replace(text, "int main(void) {\n\n" => "# test_$package.jl\n# Simple code to test the Julia interface to " * uppercase(package) * "\n\nusing GALAHAD\nusing Test\nusing Printf\nusing Accessors\n\nfunction test_$package()\n")
text = replace(text, "\" i_ipc_ \"" => "i")
text = replace(text, "\" d_ipc_ \"" => "d")
text = replace(text, "ipc_" => "int")
text = replace(text, "rpc_" => "real_wp_")
text = replace(text, "//" => "#")
text = replace(text, ";" => "")
text = replace(text, "&" => "")
Expand All @@ -16,35 +31,47 @@ function examples(package::String, example::String)
text = replace(text, "printf" => "@printf")
text = replace(text, "else if" => "elseif")
text = replace(text, "}else{" => "else")
text = replace(text, "}elseif" => "elseif")
text = replace(text, "} else {" => "else")
text = replace(text, "void *data" => "data = [Ptr{Ptr{Cvoid}}()]")
text = replace(text, "struct $(package)_control_type control" => "control = $(package)_control_type{Float64}()")
text = replace(text, "struct $(package)_inform_type inform" => "inform = $(package)_inform_type{Float64}()")
text = replace(text, "void *data" => "data = Ref{Ptr{Cvoid}}()")
text = replace(text, "struct $(package)_control_type control" => "control = Ref{$(package)_control_type{Float64}}()")
text = replace(text, "struct $(package)_inform_type inform" => "inform = Ref{$(package)_inform_type{Float64}}()")
text = replace(text, "control." => "control[].")
text = replace(text, "inform." => "inform[].")
text = replace(text, "} #" => "] #")
text = replace(text, "} #" => "] #")
text = replace(text, "} #" => "] #")
for var in ("f", "power", "weight", "shift", "radius", "half_radius")
text = replace(text, "real_wp_ $var =" => "$var =")
end
for var in ("A_val", "A_dense", "b", "c", "c_l", "c_u", "x_l", "x_u", "y_l", "y_u", "z_l", "z_u", "g", "x_0",
"w", "x", "y", "z", "val", "dense", "rhs", "rhst", "sol", "H_val", "H_dense")
"w", "x", "y", "z", "val", "dense", "rhs", "rhst", "sol", "H_val", "H_dense", "C_val",
"C_dense", "H_diag", "C_diag", "H_scid", "C_scid", "Ao_val", "r", "M_val", "M_dense",
"M_diag", "y", "W", "Ao_dense")
text = replace(text, "real_wp_ $var[] = {" => "$var = Float64[")
end
for var in ("n", "ne", "m", "A_ne", "A_dense_ne", "H_ne", "H_dense_ne")
for var in ("f", "power", "weight", "shift", "radius", "half_radius", "x_l", "x_u", "sigma", "rho_g", "rho_b")
text = replace(text, "real_wp_ $var =" => "$var =")
end
for var in ("n", "ne", "m", "A_ne", "A_dense_ne", "H_ne", "H_dense_ne", "C_dense_ne",
"C_ne", "dense_ne", "o", "Ao_ne", "Ao_ptr_ne", "A_ptr_ne", "m_equal",
"M_ne", "M_dense_ne", "j_ne", "h_ne", "p_ne", "Ao_dense_ne")
text = replace(text, "int $var =" => "$var =")
end
for var in ("A_row", "A_col", "A_ptr", "row", "col", "ptr", "c_stat", "x_stat", "H_row", "H_col", "H_ptr")
for var in ("A_row", "A_col", "A_ptr", "row", "col", "ptr", "c_stat", "x_stat", "H_row", "H_col", "H_ptr",
"C_row", "C_col", "C_ptr", "Ao_col", "Ao_ptr", "Ao_row", "M_row",
"M_col", "M_ptr", "J_row", "J_col", "J_ptr", "P_row", "P_ptr")
text = replace(text, "int $var[] = {" => "$var = Cint[")
end
for val in ("3", "5", "6", "n")
for val in ("1", "3", "5", "6", "7", "n", "n+m")
text = replace(text, "for( int d=1 d <= $val d++){" => "for d = 1:$val")
text = replace(text, "for(int d=1 d <= $val d++){" => "for d = 1:$val")
end
for index in ("unit_m", "new_radius")
for index in ("unit_m", "new_radius", "a_is", "m_is")
text = replace(text, "for( int $index=0 $index <= 1 $index++){" => "for $index = 0:1")
text = replace(text, "for(int $index=0 $index <= 1 $index++){" => "for $index = 0:1")
end
for val in ("c", "g", "u", "v", "x", "r", "vector", "h_vector")
for val in ("c", "g", "u", "v", "x", "w", "z", "x_l", "x_u", "r", "vector", "h_vector", "error")
text = replace(text, "real_wp_ $val[n]" => "$val = zeros(Float64, n)")
text = replace(text, "real_wp_ $val[m]" => "$val = zeros(Float64, m)")
text = replace(text, "real_wp_ $val[o]" => "$val = zeros(Float64, o)")
end
for val in ("x_stat", "c_stat", "index_nz_u", "index_nz_v", "depen")
text = replace(text, "int $val[n]" => "$val = zeros(Cint, n)")
Expand All @@ -57,7 +84,7 @@ function examples(package::String, example::String)
text = replace(text, ")\n}" => ")\n")
text = replace(text, "\n\n\n" => "\n")
text = replace(text, "}\n" => "]\n")
text = replace(text, "NULL" => "Cint[]")
text = replace(text, "NULL" => "C_NULL")
text = replace(text, "char st" => "st = ' '")
text = replace(text, "int status" => "status = Ref{Cint}()")
text = replace(text, "int n_depen" => "n_depen = Ref{Cint}()")
Expand All @@ -80,82 +107,97 @@ function examples(package::String, example::String)
text = replace(text, "while(true)" => "while true")
text = replace(text, "for( int i = 0 i < n i++)" => "for i = 1:n")
text = replace(text, "for( int i = 0 i < m i++)" => "for i = 1:m")
text = replace(text, "for( int i = 1 i < n i++)" => "for i = 2:n")
text = replace(text, "for( int i = 1 i < m i++)" => "for i = 2:m")
text = replace(text, "for( int i = 2 i < n i++)" => "for i = 3:n")
text = replace(text, "for( int i = 2 i < m i++)" => "for i = 3:m")
text = replace(text, "constrastatus = Ref{Cint}()" => "constraint status")
text = replace(text, "}#" => "] #")
text = replace(text, "#for" => "# for")
text = replace(text, "#@" => "# @")
text = replace(text, "# for i = 1:n @" => "# for i = 1:n\n# @")
text = replace(text, "( " => "(")
text = replace(text, " )" => ")")
text = replace(text, "switch(d)\n" => "")
text = replace(text, "for(i=0 i<n i++)" => "for i = 1:n\n")
text = replace(text, "}\n" => "end\n")
for var in ("x", "u", "v", "hval", "g")
text = replace(text, "const real_wp_ $var[]" => "var::Vector{Float64}")
text = replace(text, "real_wp_ $var[]" => "$var::Vector{Float64}")
end
text = text * "end\n\n@testset \"" * uppercase(package) * "\" begin\n @test test_$package() == 0\nend\n"
write(dst, text)
(example == "") && clean_example(package)

# Generate a symbolic link for the Julia tests
current_folder = pwd()
cd("../../src/$package")
!isdir("Julia") && mkdir("Julia")
cd("Julia")
rm("test_$package.jl", force=true)
symlink("../../../GALAHAD.jl/test/test_$package.jl", "test_$package.jl")
cd(current_folder)
end
current_folder = pwd()
cd("../../src/$package")
!isdir("Julia") && mkdir("Julia")
cd("Julia")
rm("test_$package.jl", force=true)
symlink("../../../GALAHAD.jl/test/test_$package.jl", "test_$package.jl")
cd(current_folder)
end

function main(name::String="all")
(name == "all" || name == "arc") && examples("arc" , "tf")
(name == "all" || name == "bgo") && examples("bgo" , "tf")
(name == "all" || name == "blls") && examples("blls" , "tf")
(name == "all" || name == "bllsb") && examples("bllsb" , "tf")
(name == "all" || name == "bqp") && examples("bqp" , "tf")
(name == "all" || name == "bqpb") && examples("bqpb" , "tf")
(name == "all" || name == "bsc") && examples("bsc" , "" )
(name == "all" || name == "ccqp") && examples("ccqp" , "tf")
(name == "all" || name == "clls") && examples("clls" , "tf")
(name == "all" || name == "convert") && examples("convert" , "" )
(name == "all" || name == "cqp") && examples("cqp" , "tf")
(name == "all" || name == "cro") && examples("cro" , "tf")
(name == "all" || name == "dgo") && examples("dgo" , "tf")
(name == "all" || name == "dps") && examples("dps" , "tf")
(name == "all" || name == "dqp") && examples("dqp" , "tf")
(name == "all" || name == "eqp") && examples("eqp" , "tf")
(name == "all" || name == "fdc") && examples("fdc" , "tf")
(name == "all" || name == "fit") && examples("fit" , "" )
(name == "all" || name == "glrt") && examples("glrt" , "t" )
(name == "all" || name == "gls") && examples("gls" , "" )
(name == "all" || name == "gltr") && examples("gltr" , "t" )
(name == "all" || name == "hash") && examples("hash" , "" )
(name == "all" || name == "ir") && examples("ir" , "" )
(name == "all" || name == "l2rt") && examples("l2rt" , "t" )
(name == "all" || name == "lhs") && examples("lhs" , "t" )
(name == "all" || name == "llsr") && examples("llsr" , "tf")
(name == "all" || name == "llst") && examples("llst" , "tf")
(name == "all" || name == "lms") && examples("lms" , "" )
(name == "all" || name == "lpa") && examples("lpa" , "tf")
(name == "all" || name == "lpb") && examples("lpb" , "tf")
(name == "all" || name == "lsqp") && examples("lsqp" , "tf")
(name == "all" || name == "lsrt") && examples("lsrt" , "t" )
(name == "all" || name == "lstr") && examples("lstr" , "t" )
(name == "all" || name == "nls") && examples("nls" , "tf")
(name == "all" || name == "presolve") && examples("presolve", "tf")
(name == "all" || name == "psls") && examples("psls" , "tf")
(name == "all" || name == "qpa") && examples("qpa" , "tf")
(name == "all" || name == "qpb") && examples("qpb" , "tf")
(name == "all" || name == "roots") && examples("roots" , "" )
(name == "all" || name == "rpd") && examples("rpd" , "tf")
(name == "all" || name == "rqs") && examples("rqs" , "tf")
(name == "all" || name == "sbls") && examples("sbls" , "tf")
(name == "all" || name == "scu") && examples("scu" , "" )
(name == "all" || name == "sec") && examples("sec" , "" )
(name == "all" || name == "sha") && examples("sha" , "" )
(name == "all" || name == "sils") && examples("sils" , "" )
(name == "all" || name == "slls") && examples("slls" , "tf")
(name == "all" || name == "sls") && examples("sls" , "tf")
(name == "all" || name == "trb") && examples("trb" , "tf")
(name == "all" || name == "trs") && examples("trs" , "tf")
(name == "all" || name == "tru") && examples("tru" , "tf")
(name == "all" || name == "ugo") && examples("ugo" , "t" )
(name == "all" || name == "uls") && examples("uls" , "tf")
(name == "all" || name == "wcp") && examples("wcp" , "tf")
function main(name::String)
(name == "arc") && examples("arc" , "tf")
(name == "bgo") && examples("bgo" , "tf")
(name == "blls") && examples("blls" , "tf")
(name == "bllsb") && examples("bllsb" , "tf")
(name == "bqp") && examples("bqp" , "tf")
(name == "bqpb") && examples("bqpb" , "tf")
(name == "bsc") && examples("bsc" , "" )
(name == "ccqp") && examples("ccqp" , "tf")
(name == "clls") && examples("clls" , "tf")
(name == "convert") && examples("convert" , "" )
(name == "cqp") && examples("cqp" , "tf")
(name == "cro") && examples("cro" , "tf")
(name == "dgo") && examples("dgo" , "tf")
(name == "dps") && examples("dps" , "tf")
(name == "dqp") && examples("dqp" , "tf")
(name == "eqp") && examples("eqp" , "tf")
(name == "fdc") && examples("fdc" , "tf")
(name == "fit") && examples("fit" , "" )
(name == "glrt") && examples("glrt" , "t" )
(name == "gls") && examples("gls" , "" )
(name == "gltr") && examples("gltr" , "t" )
(name == "hash") && examples("hash" , "" )
(name == "ir") && examples("ir" , "" )
(name == "l2rt") && examples("l2rt" , "t" )
(name == "lhs") && examples("lhs" , "t" )
(name == "llsr") && examples("llsr" , "tf")
(name == "llst") && examples("llst" , "tf")
(name == "lms") && examples("lms" , "" )
(name == "lpa") && examples("lpa" , "tf")
(name == "lpb") && examples("lpb" , "tf")
(name == "lsqp") && examples("lsqp" , "tf")
(name == "lsrt") && examples("lsrt" , "t" )
(name == "lstr") && examples("lstr" , "t" )
(name == "nls") && examples("nls" , "tf")
(name == "presolve") && examples("presolve", "tf")
(name == "psls") && examples("psls" , "tf")
(name == "qpa") && examples("qpa" , "tf")
(name == "qpb") && examples("qpb" , "tf")
(name == "roots") && examples("roots" , "" )
(name == "rpd") && examples("rpd" , "tf")
(name == "rqs") && examples("rqs" , "tf")
(name == "sbls") && examples("sbls" , "tf")
(name == "scu") && examples("scu" , "" )
(name == "sec") && examples("sec" , "" )
(name == "sha") && examples("sha" , "" )
(name == "sils") && examples("sils" , "" )
(name == "slls") && examples("slls" , "tf")
(name == "sls") && examples("sls" , "tf")
(name == "trb") && examples("trb" , "tf")
(name == "trs") && examples("trs" , "tf")
(name == "tru") && examples("tru" , "tf")
(name == "ugo") && examples("ugo" , "t" )
(name == "uls") && examples("uls" , "tf")
(name == "wcp") && examples("wcp" , "tf")
end

# If we want to use the file as a script with `julia wrapper.jl`
if abspath(PROGRAM_FILE) == @__FILE__
main()
function clean_example(package::String)
path = "../test/test_" * package * ".jl"
isfile(path) || error("The file test_$package.jl doesn't exist.")
format_file(path, YASStyle(), indent=2)
end
Loading
Loading