Start GAP with prescribed package versions - #6057
Conversation
|
I like the idea. I wonder if at least a warning (and honestly, I'd be tempted to abort GAP, if the point is to ensure reproducability), if one of the package versions we expect to find is missing? Otherwise if someone loads a list of required packages and are missing one of the correct versions, that package just won't exist -- but that might not stop their calculation, just slow it down, if that package was optional. |
|
@ChrisJefferson The proposed code turns the prescribed packages (in the prescribed versions, since all other versions lying around get ignored) into needed packages of GAP. Thus one gets an error as soon as the first such package turns out to be not loadable. This is the error which one gets already now if for example the |
|
Ah, thanks. I think I didn't read carefully, I thought the packages still got loaded later when requested. |
It is not clear what we really want in this respect. The currently proposed code removes all information about packages that are not in the list of prescribed package versions. It is still possible to add a new package directory later in the GAP session, and then to load packages which can be found there. Shall we forbid this? Or shall we argue that adding a package directory does not happen silently, and users who do this can add other packages on top of the prescribed ones? |
|
A few years ago I would have said don't bother, but now I do have quite a bit of code that tries using PackageManager to install packages, and people have and maintain multiple package directories, and it might be nice to catch that. However, I don't think that's required from day one, and we can't stop people doing bad things if they really want to in GAP. |
|
@james-d-mitchell You had mentioned in a discussion during the recent GAP Days that you would like to get a better control of the loaded GAP packages. Is the current pull request helpful in this respect, and what else would you like to get? |
|
I think this is a really useful feature to add, thanks @ThomasBreuer I've tried playing around with this locally, and perhaps I am doing something wrong, but I see the following behaviour. I did: Added the line: Restarting GAP: It seems that maybe the order the packages are loaded is getting messed up? Not sure.
I think this is a good compromise.
Yes, this would be really useful. We've had numerous instances where students had multiple versions of package installed and this cased issues. If we could specify which copy of a package to use, this would simplify things enormously.
I think the only thing it would be good to see (other than fixing whatever is going wrong in the example above) would be to document how to use the feature:
|
|
@james-d-mitchell Thanks for your comments.
|
In order to reproduce computations from a GAP session, it is desirable to start GAP with a given set of GAP packages whose exact version numbers are prescribed. The idea is as follows. - In a GAP session, use the new function `PackagesLoaded` for collecting the names and version numbers of the currently loaded GAP packages. - Write this description to a file. - Set the new user preference `PrescribedPackageVersions`, with value the name of that file. - Start a new GAP session. The user preference will modify the autoload process such that exactly the GAP packages listed in the file will be loaded, with exactly the listed versions.
When one wants to start a GAP session with the same package versions loaded as in the previous session, it can make a difference if these packages are loaded in a different order. The information about the order in which packages have been read in the current session is available via the log messages in `GAPInfo.PackageLoadingMessages`. This commit changes `PackagesLoaded` and the format of the value for the proposed user preference `PrescribedPackageVersions` such that the loading order is respected when the user preference is active. Note that the `OnlyNeeded` option is set (and logged) only per `LoadPackage` call, and sets of dependent packages get loaded together via one `LoadPackage` call. Thus we get the intended loading order by storing the packages for which `LoadPackage` was called, in the right order, and together with the `OnlyNeeded` value that was set in the reference GAP session. Thus we cannot simply set `OnleNeeded` to `true` when loading the packages. (In the list created by `PackagesLoaded()`, the indirectly loaded packages do not have entries concerning when they get loaded and which `OnlyNeeded` value is valid for them.)
348aa1e to
c6bd7cd
Compare
|
@james-d-mitchell I have updated the pull request such that Achieving this is quite tricky. Since GAP loads each set of interdependent packages together, with only one |
|
My previous comment may give the impression that it is a very complicated procedure to prescribe exact package version. However, the aim of the intended feature was to write down such a list in order to get reproducible behaviour. In this sense, we do not have to force the same behaviour as in some GAP session where the packages were loaded in a particular order that is perhaps "natural" but that is not really necessary for the thousand GAP sessions we want to compare with each other. So which feature are we interested in: the complicated one that respects the loading order, or the simpler one that doesn't care about the loading order? |
|
@james-d-mitchell Could you have another look at this? |
@ThomasBreuer I'll have a look today, thanks for the ping! |
| ## and <C>version</C> is its version. | ||
| ## <P/> | ||
| ## One can print this string to a file and set the user preference | ||
| ## <C>"PrescribedPackageVersions"</C> to the name of this file, |
There was a problem hiding this comment.
| ## <C>"PrescribedPackageVersions"</C> to the name of this file, | |
| ## <C>"PrescribedPackageVersions"</C> to the name of this file. |
| UserPreference( "PrescribedPackageVersions" ) ); | ||
| if exact <> fail then | ||
| # Store the list of prescribed package version, | ||
| # including the informtion about ordering and 'OnlyNeeded' option. |
There was a problem hiding this comment.
| # including the informtion about ordering and 'OnlyNeeded' option. | |
| # including the information about ordering and 'OnlyNeeded' option. |
| # including the informtion about ordering and 'OnlyNeeded' option. | ||
| GAPInfo.PrescribedPackageVersions:= exact; | ||
| exact:= List( exact, x -> x{ [ 1, 2 ] } ); | ||
| GAPInfo.PackagesInfo:= Filtered( GAPInfo.PackagesInfo, |
There was a problem hiding this comment.
What happens here if the UserPreference contains nonsense? Is there any reasonable way to parse it, and give a meaningful error if it is somehow not well-formed?
There was a problem hiding this comment.
Sorry, I should have read further, I see this is resolved below.
| exact:= List( exact, x -> x{ [ 1, 2 ] } ); | ||
| GAPInfo.PackagesInfo:= Filtered( GAPInfo.PackagesInfo, | ||
| r -> [ LowercaseString( r.PackageName ), r.Version ] in exact ); | ||
| fi; |
There was a problem hiding this comment.
Semi-relatedly, shouldn't there be some sort of warning or something if there's a mismatch between the initial value of GAPInfo.PackagesInfo and exact? What if there things in exact not in GAPInfo.PackagesInfo for example?
| fi; | ||
| fi; | ||
| fi; | ||
| return fail; |
There was a problem hiding this comment.
Related to the comments above would it be possible to maybe give an info warning or error in the case that the file exists but fails the parsing above, to indicate what's wrong?
| ## One can print this string to a file and set the user preference | ||
| ## <C>"PrescribedPackageVersions"</C> to the name of this file, | ||
| ## Then starting &GAP; anew will load exactly the same packages. | ||
| ## </Description> |
There was a problem hiding this comment.
Might be a good idea here to give an explicit example of how you might do this, and to specify that the absolute path of the file is required also.
james-d-mitchell
left a comment
There was a problem hiding this comment.
I think this looks good, and it appears to work reasonably well. There are three comments:
- When I do
gap -Aafter adding
SetUserPreference("PrescribedPackageVersions", "/Users/jdm3/Library/Preferences/GAP/prescribed.txt");to mygap.inifile, and that file contains the output ofPackagesLoaded();I get the info warning#I Options stack is already empty - When this fails, it does so silently, it'd be better if it did it loudly, so that one could easily see what has gone wrong and why (in my case I first specified the relative path to the file
prescribed.txtwhich didn't work). - The process of writing to a file the currently loaded packages, adding that to user preference somewhere, etc, might be difficult for beginners, and we could do somethings to make this easier (such as an analogue of
WriteGAPIniFileor similar). This could be done after this PR is merged though and is probably out of scope for now.
In order to reproduce computations from a GAP session, it is desirable to start GAP with a given set of GAP packages whose exact version numbers are prescribed.
The idea is as follows.
In a GAP session, use the new function
PackagesLoadedfor collecting the names and version numbers of the currently loaded GAP packages.Write this description to a file.
Set the new user preference
PrescribedPackageVersions, with value the name of that file.Start a new GAP session. The user preference will modify the autoload process such that exactly the GAP packages listed in the file will be loaded, with exactly the listed versions.
This is just a first proposal. There are things to discuss for example:
(One motivation is a remark in oscar-system/GAP.jl/issues/1189.)