Skip to content

Configure default value of -native-compiler#13352

Merged
coqbot-app[bot] merged 6 commits intorocq-prover:masterfrom
validsdp:cep-48
Nov 20, 2020
Merged

Configure default value of -native-compiler#13352
coqbot-app[bot] merged 6 commits intorocq-prover:masterfrom
validsdp:cep-48

Conversation

@proux01
Copy link
Copy Markdown
Contributor

@proux01 proux01 commented Nov 11, 2020

This an implementation of point 2 of rocq-prover/rfcs#48

A new boolean option -native-compiler-default-yes is added to the configure script. When set to "yes", the default value for the -native-compiler option of the produced coqc becomes "yes" (and the stdlib is still precompiled for native compute), otherwise (default) it remains "ondemand" (but the stdlib is no longer precompiled for
native compute).

@SkySkimmer
Copy link
Copy Markdown
Contributor

It may be prettier to have a new value for the -native-compiler configure option.
ie instead of -native-compiler-default-yes yes one would pass -native-compiler yes-yes (or some other string instead of yes-yes)

@ejgallego
Copy link
Copy Markdown
Contributor

It may be prettier to have a new value for the -native-compiler configure option.

+1

I'm not sure if hardcoding this is a good idea; IMHO these kind of options should be better controlled by the build system [coq_makefile or dune]. Having this kind of hardcoded values makes it the life of the build system harder due to a combinatorial explosion on possible flags values. Now the build system has to do another query to see what coqc is going to do by default, and maybe override it in case the user wants a quick build.

@proux01
Copy link
Copy Markdown
Contributor Author

proux01 commented Nov 12, 2020

It may be prettier to have a new value for the -native-compiler configure option.
ie instead of -native-compiler-default-yes yes one would pass -native-compiler yes-yes (or some other string instead of yes-yes)

Indeed, here is an offer with ondemand.

@proux01 proux01 added needs: changelog entry This should be documented in doc/changelog. needs: squashing Some commits should be squashed together. labels Nov 12, 2020
@proux01
Copy link
Copy Markdown
Contributor Author

proux01 commented Nov 12, 2020

I'm not sure if hardcoding this is a good idea; IMHO these kind of options should be better controlled by the build system [coq_makefile or dune].

To me, this always has been and definitely remains a configure option. But if you have a rationale supporting your opinion, I'd be happy to hear it.

Now the build system has to do another query to see what coqc is going to do by default,

Sorry, I din't follow you, why would you like to know the default value ?

and maybe override it in case the user wants a quick build.

If by quick you mean without native, you can just pass -native-compiler no to coqc, nothing new here.

Anyway, this PR is certainly missing a dune part. I was unable to write it because I still don't understand how the configuration phase is done in the dune build process.

@ejgallego
Copy link
Copy Markdown
Contributor

To me, this always has been and definitely remains a configure option. But if you have a rationale supporting your opinion, I'd be happy to hear it.

The example I pointed out is a good one I think: when in dev mode, you may want to skip native compilation for performance purposes, of even proofs as done in vos , so indeed you want a coqc that is able to work both ways.

Sorry, I din't follow you, why would you like to know the default value ?

The build system needs to know what object files will coqc produce, in particular to prevent stale files when building incrementally. For example if you compile a.v with native, then you compile again without native, an incremental build needs to clean the stale cmxs files.

Anyway, this PR is certainly missing a dune part. I was unable to write it because I still don't understand how the configuration phase is done in the dune build process.

Nothing to be done for dune in this tree, dune rules would have to be adapted themselves to query the configure option of coqc. This introduces a bit painful build dependency tho, as .v rules cannot be computed until the configure rule has been queried. Usually, the more static the build DAG is, the better performance you may get. This is a concern in the real world once you have 10 or 100s thousand targets [which happens when doing a composed build]

@ejgallego
Copy link
Copy Markdown
Contributor

One alternative is just to patch coq_makefile, so when the configure flag is set, it uses the right flag.

@proux01
Copy link
Copy Markdown
Contributor Author

proux01 commented Nov 12, 2020

One alternative is just to patch coq_makefile, so when the configure flag is set, it uses the right flag.

That wouldn't work for build systems other than coq_makefile.

@SkySkimmer
Copy link
Copy Markdown
Contributor

Nothing to be done for dune in this tree, dune rules would have to be adapted themselves to query the configure option of coqc.

dune could call coqc with the option always explicit, not relying on the default.

@proux01
Copy link
Copy Markdown
Contributor Author

proux01 commented Nov 12, 2020

dune could call coqc with the option always explicit, not relying on the default.

That would completely ruin the whole point of the CEP though.

@coqbot-app
Copy link
Copy Markdown
Contributor

coqbot-app bot commented Nov 12, 2020

The job library:ci-fiat_crypto_legacy has failed in allow failure mode
ping @JasonGross

@ejgallego
Copy link
Copy Markdown
Contributor

That wouldn't work for build systems other than coq_makefile

Well it is not gonna work either now as unless you patch them, they won't realize that additional files are being built.

By the way, we should converge to a single build system for Coq packages so that would be moot [and if people want to have their own DIY build system, IMHO they are on their own]

@proux01
Copy link
Copy Markdown
Contributor Author

proux01 commented Nov 12, 2020

That wouldn't work for build systems other than coq_makefile

Well it is not gonna work either now as unless you patch them, they won't realize that additional files are being built.

No, coq_makefile is working fine, whenever .coq-native are produced, they get installed,that's it.

By the way, we should converge to a single build system for Coq packages so that would be moot [and if people want to have their own DIY build system, IMHO they are on their own]

Well, we shouldn't make their life ridiculously harder though.

@ejgallego
Copy link
Copy Markdown
Contributor

No, coq_makefile is working fine, whenever .coq-native are produced, they get installed,that's it.

I was answering to your question about systems other than coq_makefile.

Well, we shouldn't make their life ridiculously harder though.

Actually this PR would make their life harder as now they have to implement a method to query Coq config options in order to know what's being built

@proux01
Copy link
Copy Markdown
Contributor Author

proux01 commented Nov 12, 2020

The build system needs to know what object files will coqc produce, in particular to prevent stale files when building incrementally. For example if you compile a.v with native, then you compile again without native, an incremental build needs to clean the stale cmxs files.

That may be a stupid question but can't we just clean the cmxs whether there is actually one or not ?

@proux01
Copy link
Copy Markdown
Contributor Author

proux01 commented Nov 12, 2020

No, coq_makefile is working fine, whenever .coq-native are produced, they get installed,that's it.

I was answering to your question about systems other than coq_makefile.

Sorry, they indeed would have to do the same (and the few cases I'm aware of do it).

@ppedrot
Copy link
Copy Markdown
Member

ppedrot commented Nov 12, 2020

I wrongly believed that the related CEP was backwards compatible, but with this PR I realize now that it requires changes to the coqc binary. Since it was its main interest, I think I should make an alternative proposal based on split compilation that is essentially a configure-agnostic way of achieving on-demand compilation.

@ejgallego
Copy link
Copy Markdown
Contributor

That may be a stupid question but can't we just clean the cmxs whether there is actually one or not ?

Well that'd result in a pretty suboptimal incremental build.

@Blaisorblade
Copy link
Copy Markdown
Contributor

By the way, we should converge to a single build system for Coq packages so that would be moot [and if people want to have their own DIY build system, IMHO they are on their own]

That discussion should happen in a separate issue — I thought we had already concluded that too many packages still rely on coq_makefile for a switch, and migrating many of them would anyway fall on coq-community. We also agreed that dune has pretty limited programmability, as long as a dhall-ocaml doesn’t get born.

I'm not sure if hardcoding this is a good idea; IMHO these kind of options should be better controlled by the build system [coq_makefile or dune]. Having this kind of hardcoded values makes it the life of the build system harder due to a combinatorial explosion on possible flags values. Now the build system has to do another query to see what coqc is going to do by default, and maybe override it in case the user wants a quick build.

That might be great when using dune, but it’s not as great when using opam. A point of the CEP was to get better behavior by default, even without changing each coq package around. Technically, that limits changes to the repos of coq, dune, and maybe opam-coq-repository. And even if everybody used dune, I’m not sure that would save much opam-packaging work — unless the result of installing an opam-dune package depends on some global flag, which IIUC you were objecting to?

I wrongly believed that the related CEP was backwards compatible, but with this PR I realize now that it requires changes to the coqc binary.

These changes seem easy enough to get in for 8.13, and they give you a better default. You said split packages would not get in before 8.14; even if your PR can be finished in time, it’s not clear the build-system changes can be done in time as well for 8.13, and ditto for the changes to all the packages.

That may be a stupid question but can't we just clean the cmxs whether there is actually one or not ?

Well that'd result in a pretty suboptimal incremental build.

Why? You could also move potential outputs out-of-the way, and restore them if needed. I’m also not sure why “asking coq for a bunch of flags” is intrinsically hard — add one coq option to dump the config in machine-readable format, and call that at the start.

@ejgallego
Copy link
Copy Markdown
Contributor

These changes seem easy enough to get in for 8.13, and they give you a better default.

You can only coq_makefile as suggested an still you get the same effect; this PR, as-is, is breaking everything else.

Why? You could also move potential outputs out-of-the way, and restore them if needed.

If you clean the cmxs files, then you need to regenerate them again at each build, all of them. To restore the outputs you need to know them, that's beyond what make can do.

I’m also not sure why “asking coq for a bunch of flags” is intrinsically hard — add one coq option to dump the config in machine-readable format, and call that at the start.

First, it adds complexity. Not having to parse anything is much much better than having to parse. Second, when you compose with coq, a common scenario for example in CI, your build rules need to get Coq configure and queried, a move from a static dependency graph to a dynamic graph. While doable, I don't think the benefits justify the added complexity.

@erikmd
Copy link
Copy Markdown
Contributor

erikmd commented Nov 13, 2020

Hi @ejgallego,

You can only coq_makefile as suggested an still you get the same effect; this PR, as-is, is breaking everything else.

by "breaking everything else", do you just mean "this PR breaks the CI currently", or "this PR is incomplete because the dune counterpart is missing in this PR"? − because as I'm not very fluent with dune, it is hard for me to see how easy it is to finalize that part…

it adds complexity. Not having to parse anything is much much better than having to parse.

But I believe the native_compiler configure option was already there… so it just amounts to a change of a bool option to a 3-valued option :)
and this increase of complexity is just due to the fact this PR currently puts forth a new default value for coqc -native-compiler, while keeping the ability to trigger the "ondemand" behavior (albeit the discussion in the CEP mentioned at some point that this "ondemand" behavior could just as well have been disabled, IIRC)

@Blaisorblade
Copy link
Copy Markdown
Contributor

You can only [change] coq_makefile as suggested an[d] still you get the same effect;

This does sound interesting, and potentially better! It doesn't help users of DIY build systems — but they can make the same choice independently.

this PR, as-is, is breaking everything else.

More accurately, I think it breaks dune and might help DIY build system; changing coq_makefile seems indeed potentially better.

Why? You could also move potential outputs out-of-the way, and restore them if needed.

If you clean the cmxs files, then you need to regenerate them again at each build, all of them. To restore the outputs you need to know them, that's beyond what make can do.

No? If you recompile a %.v->%.vo file, remove only %.cmxs. Or move it away and restore it if coq has not created the cmxs file. E.g.:

%.vo: %.v
	mv "%.cmxs" "%.cmxs-old"
	coqc ...
	[ -f "%.cmxs" ] || mv "%.cmxs-old" "%.cmxs"

Optionally, restore the old file even if the contents have not changed (à la KBuild), to restore the old timestamps, but adding features to coq_makefile is likely overkill.

I do agree that the above change might add some complexity to weigh in to this proposal, and 4 lines of untested bash don't prove it's easy.

Copy link
Copy Markdown
Contributor

@silene silene left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are supposed to modify the configure call in .gitlab-ci.yml so as to pass -native-compiler ondemand, I guess. Hopefully, our CI guys can point you to the correct place if this is not it.

Regarding the discoverability of the setting, you could add a line at the end of file lib/envars.ml.

@proux01
Copy link
Copy Markdown
Contributor Author

proux01 commented Nov 13, 2020

You can only [change] coq_makefile as suggested an[d] still you get the same effect;

This does sound interesting, and potentially better! It doesn't help users of DIY build systems — but they can make the same choice independently.

Coul you be more precise? If that means configuring coq_makefile rather than coqc, this just breaks every build sytem (but coq_makefile).

@Blaisorblade
Copy link
Copy Markdown
Contributor

this just breaks every build sytem (but coq_makefile).

Let’s assume Emilio’s proposal won’t break dune. Let coq_makefile pass the desired default setting of native_compute to coq. Why are other build-systems broken, if they'd get the same behavior as today?
I see they won't get better defaults, but the existing defaults will work as well/badly as today.
And support for alternative build systems must have some limit — keeping coqc behaviors unchanged.

@silene
Copy link
Copy Markdown
Contributor

silene commented Nov 13, 2020

keeping coqc behaviors unchanged

Note that the default behavior of coqc is not changed by this pull request. If the user does not explicitly pass -native-compiler yes to the configure script, then coqc will behave exactly the same as today (whether the -native-compiler option is passed or not).

@silene
Copy link
Copy Markdown
Contributor

silene commented Nov 13, 2020

Since there seems to be some confusion, let me stress the following point. This pull request does not change the behavior of coqc; it changes the behavior of the configure script. Rather than modifying the behavior of configure -native-compiler yes, @SkySkimmer proposed to add configure -native-compiler yes-yes instead. I tend to prefer @proux01 's solution, since it makes the correspondence between the options of configure and coqc more intuitive. But honestly, both -native-compiler variants are fine with me, as long as we finally fix the mistake done by some misguided idiot five years ago.

@proux01
Copy link
Copy Markdown
Contributor Author

proux01 commented Nov 13, 2020

The only difference in default behavior is that the stdlib is no longer precompiled for native compute (which you were interested in @Blaisorblade IIRC ;-) )

Let coq_makefile pass the desired default setting of native_compute to coq. Why are other build-systems broken, if they'd get the same behavior as today?

Because they won't get the expected behavior for native_compute users (except maybe by hacking them to discover the setting hidden in coq_makefile).

@proux01 proux01 force-pushed the cep-48 branch 4 times, most recently from acbbc05 to ed709be Compare November 19, 2020 22:33
@proux01
Copy link
Copy Markdown
Contributor Author

proux01 commented Nov 20, 2020

After implementing @SkySkimmer 's idea just above, there is no more duplicate job.

@erikmd
Copy link
Copy Markdown
Contributor

erikmd commented Nov 20, 2020

Hi @proux01!
if you need to push-force again, note that this commit validsdp@6c538ed
has a buggy hyperlink coq#48 in the commit message (it should read coq/ceps#48)

@ejgallego
Copy link
Copy Markdown
Contributor

After implementing @SkySkimmer 's idea just above, there is no more duplicate job.

Thanks a lot for your patience @proux01 ; I'd say that the PR looks good to go.

We had a failure on the test suite however:

File "./primitive/float/compare.v", line 326, characters 0-48:
Error:
Dynlink error: The module `Coq_native18246a' is already loaded (either by the main program or a previously-dynlinked library)

0m0.000000s 0m0.000000s
0m11.230000s 0m13.280000s
==========> FAILURE <==========
    primitive/float/compare.v...Error! (should be accepted)

This is not the first time I see this, and it looks quite fishy. I'll re-run the job for now.

@ejgallego
Copy link
Copy Markdown
Contributor

re-running fixed the failure, I think we can merge , @gares , do you need your comments addressed before merge?

@proux01
Copy link
Copy Markdown
Contributor Author

proux01 commented Nov 20, 2020

We had a failure on the test suite however:

File "./primitive/float/compare.v", line 326, characters 0-48:
Error:
Dynlink error: The module `Coq_native18246a' is already loaded (either by the main program or a previously-dynlinked library)

0m0.000000s 0m0.000000s
0m11.230000s 0m13.280000s
==========> FAILURE <==========
    primitive/float/compare.v...Error! (should be accepted)

This is not the first time I see this, and it looks quite fishy. I'll re-run the job for now.

We should probably have a look with a native_compute and dynlink expert at some point. I unfortunately know close to nothing on the subject.

This an implementation of point 2 of CEP rocq-prover/rfcs#48
rocq-prover/rfcs#48

Option -native-compiler of the configure script now impacts the
default value of the option -native-compiler of coqc. The
-native-compiler option of the configure script is added an ondemand
value, which becomes the default, thus preserving the previous default
behavior.

The stdlib is still precompiled when configuring with -native-compiler
yes. It is not precompiled otherwise.
A few libraries in the CI don't compile with it
(out of memory).
@proux01
Copy link
Copy Markdown
Contributor Author

proux01 commented Nov 20, 2020

I just removed equations and metacoq specific code following upstream fixes.

@gares
Copy link
Copy Markdown
Member

gares commented Nov 20, 2020

So I do need to update the pins... anyway, please merge.

@ejgallego
Copy link
Copy Markdown
Contributor

@coqbot: merge now

@coqbot-app coqbot-app bot merged commit 87a59a8 into rocq-prover:master Nov 20, 2020
@JasonGross
Copy link
Copy Markdown
Member

I'm surprised this didn't break the fiat-parsers CI, as it breaks the CI on our end because the native compiler hangs for over ten minutes trying to compile libraries to native code. Is the correct solution to this to add -arg -native-compiler -arg ondemand to _CoqProject?

@proux01
Copy link
Copy Markdown
Contributor Author

proux01 commented Dec 8, 2020

Apparently, we got the CI to pass with export COQEXTRAFLAGS='-native-compiler no' so yes, something like that should work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind: infrastructure CI, build tools, development tools. part: build The build system. part: native compiler

Projects

None yet

Development

Successfully merging this pull request may close these issues.