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

Is it possible to change settings when reading model from json? #42

Open
mipals opened this issue Jun 4, 2024 · 8 comments
Open

Is it possible to change settings when reading model from json? #42

mipals opened this issue Jun 4, 2024 · 8 comments

Comments

@mipals
Copy link
Contributor

mipals commented Jun 4, 2024

Hi there,

In rust you can simply override the settings, but using this interface the same does not seem possible. At least I can not figure out how.

My problem initially came since I wanted to try out the faer-solver, but my json model came from Julia which do not support that (Turns out that you can actually export to the faer solver from Julia by setting direct_solve_method=:faer, since it does not check if the field is an actual available solver). However, I would like to avoid having a json file for each solver.

Best,
Mikkel

@goulart-paul
Copy link
Member

The issue is that the read_from_file function reads the JSON file and converts it immediately to a solver object. All of the internal data structures are allocated when creating that solver object, including the internal KKT solver with its choice of LDL subsolver. Once that happens you can't change your mind about which linear solver to use.

I guess the solution is to just let you load the JSON file and get all of the data fields without the solver step. That functionality already exists in the code here, it's just not part of the public interface.

It's easy enough to make this part of the public interface in rust or julia, i.e. something like read_from_file_raw or whatever. Doing so in C or C++ would be kind of a PITA but also doable.

@goulart-paul
Copy link
Member

Note you can also directly edit the JSON file after you export it to replace the solver option there. Something like perl -pi -e 's/qdldl/faer/g' <yourfile>.json edits it in place.

I would agree that that's not a good long term solution though.

@mipals
Copy link
Contributor Author

mipals commented Jun 4, 2024

Okay, I can see that the price to pay for using the interface is that the data is not as closely available. I guess you could technically pass user defined settings when reading in the JSON file that overrides the ones in the file, but maybe that would just be unnecessary complexity.

Now I wonder if my way of overriding the settings in Rust is okay then? What I get from what you're saying is that I should instead copy the data (P, q, A, b, and cones) and create a new solver with the new settings so that the internal data structures match up? I've done similar things in Julia before where i just change settings using set_attribute, but I am not sure if things get recomputed internally there.

I initially updated manually the JSON files, but since I had a lot of models it was easier to just export from Julia with a different setting.

@goulart-paul
Copy link
Member

I think what you are doing is: create a solver object via Julia, then update the settings.direct_solve_method to some solver of your choice, then export to a file. The effect of that is:

  1. The Julia object itself will ignore that change of setting, since the direct_solve_method is only examined once at object creating. IOW, you can't create a solver object, solve your problem, then change LDL option, then solve again and end up using the new LDL solver.

  2. The export to JSON format will be fine, since it is just dumping its problem data and current settings to a text file. There is no need to make multiple solvers to create different JSON files -- just change the settings and dump to as many different files as you like.

All that (2) is doing though is changing one string in the output file though, which you could also do manually or via some script like the perl above.

If we extend the interface to allow you to pass your own settings, my preference would be to just allow direct access to the data that was loaded rather than trying to pass an optional list of settings. Julia and C++ are fine with having different variations of the same function with different signatures, but rust not so much, and I would like to keep the interfaces as similar as possible. This means you would have to do it in two steps though, i.e. load the file directly and then pass all of the data to the problem constructor yourself.

@mipals
Copy link
Contributor Author

mipals commented Jun 4, 2024

I guess technically you can do (1), but it would just be wrong / have some undefined behaviour. Good to know.

Related to (2), then I guess the same could be done in Rust for now, i.e. change settings and then write the new model to a new file and then read in that new file. It is little much for something that is simply just a change of a single string.

I agree that just having access to the data would be preferred. It would at give you some more room to experiment with the models that is loaded from JSON instead of having hardcoded settings (i get that hardcoded settings is good for reproducibility just not as much for experimenting).

@goulart-paul
Copy link
Member

I will see what I can do about providing access to the data directly without forming a solver. I assume that this relates to the C or C++ interface, yes?

The hardcoded settings are indeed mostly about reproducibility. I had this in mind more as a mechanism for people to easily report problems to us without having to provide a lot of code to reproduce their problem data. This way they can just dump it to a file regardless of how it was generated.

@mipals
Copy link
Contributor Author

mipals commented Jun 4, 2024

Yes, its only C/ C++ where this is giving some issues. In Rust and Julia you can at least get around the issue fairly easy as you have access to the data through the solver object.

That makes sense. It could maybe make sense to include the version number to the JSON file then?

@goulart-paul
Copy link
Member

Another option (for C++ at least) is to just read the JSON file directly since it is in a standard format, then pass the data directly to the solver constructor yourself. Something like this : https://github.com/nlohmann/json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants