haskell.nix icon indicating copy to clipboard operation
haskell.nix copied to clipboard

How to use the new (GHC 9+) native ghc-bignum backend?

Open ramirez7 opened this issue 4 years ago • 12 comments

# default.nix
let
  pkgs = import ./nix/pkgs.nix;
in pkgs.haskell-nix.project {
  src = "<elided>";
  compiler-nix-name = "ghc901";

  modules = [
    {
      packages.ghc-bignum.components.library.configureFlags = ["-f native"];
    }
  ];
}

ghc-pkg describe ghc-bignum still includes hidden-modules: GHC.Num.Backend.GMP, which makes me think it didn't work. But maybe I'm misunderstanding how to validate it?

I also tried setting the flag in my cabal.project file and it also didn't work.

ramirez7 avatar Sep 28 '21 19:09 ramirez7

I did some more investigating of this (now on ghc922):

When I pass -f native to modules and x-compile to Windows..

  • libgmp DLLs are automatically included by haskell.nix
  • If I delete them, the program still runs. Implying they aren't necessary.
  • I think that's due to me not actually using ghc-bignum..if I don't do -f native, the program still runs with deleted dlls.

On a Linux build, ldd still claims I have a dep on gmp:

$ ldd result/bin/ld50 | grep gmp
        libgmp.so.10 => /nix/store/d98pqy6b8graar18kwq0zba010xy0ihn-gmp-6.2.1/lib/libgmp.so.10 (0x00007fd2c7248000)

ramirez7 avatar May 24 '22 20:05 ramirez7

Same here, it looks to me like flags passed to ghc-bignum are having no effect.

It's strange since flags for other packages seem to work fine--for example, I disable GMP in cryptonite like this: packages.cryptonite.configureFlags = [''-f -integer-gmp''];.

I'm wondering if ghc-bignum is different because it's treated specially as one of the "core" GHC libraries.

EDIT: further evidence that ghc-bignum is special:

> nix-build . -A cryptonite.components.library
...builds
> nix-build . -A ghc-bignum.components.library
error: the expression selected by the selection path 'ghc-bignum.components.library' should be a set but is null

@michaelpj I saw you were doing some integer-simple work with https://github.com/Bodigrim/mod/issues/13, any chance you know what this is about? Thanks!

thomasjm avatar Jul 13 '22 01:07 thomasjm

Because ghc-bignum is a dependency of integer-simple and integer-gmp it is included in the default nonReinstallablePkgs here https://github.com/input-output-hk/haskell.nix/blob/112669d1ba96fa2a1c75478d12d6f38ee2bd3ee6/modules/component-driver.nix#L63-L65

It is also in bootPkgs (I am not sure why).

The best way to fix this issue is probably to find a way to make ghc-bignum, integer-simple and integer-gmp reinstallable. If that is not possible we should allow the the appropriate flags to be specified in derivation that builds GHC.

hamishmack avatar Sep 29 '22 07:09 hamishmack

What does making those packages "reinstallable" mean exactly? Where does that happen?

ramirez7 avatar Sep 29 '22 18:09 ramirez7

They are packages that are built during the GHC boot process (so the are available in the GHC derivation itself). Reinstalling them means haskell.nix ignoring that version and building them again. This is necessary if we want the configuration of the package to differ from what was built when GHC was built.

I just noticed that base itself depends on ghc-bignum. That might be tricky to reinstall. We might need to add an option to build GHC with the native flag set in ghc-bignum. Most likely by adding it to somewhere in https://github.com/input-output-hk/haskell.nix/blob/master/compiler/ghc/default.nix.

hamishmack avatar Sep 29 '22 23:09 hamishmack

Makes sense. I'll send a PR with the GHC option (probably in the next couple weeks). I already do some GHC rebuilding anyways, so I don't mind the ramifications of that :)

Thanks for the pointer ✌️

ramirez7 avatar Sep 30 '22 01:09 ramirez7

We might need to add an option to build GHC with the native flag set in ghc-bignum

Is there not already such a flag? https://github.com/input-output-hk/haskell.nix/blob/fd7b85d34f78f9944878f87fb57e2ed7bd3b80fa/compiler/ghc/default.nix#L36

This flag sets BIGNUM_BACKEND=native in the .mk file when building GHC. It was added in https://github.com/input-output-hk/haskell.nix/pull/1569.

The same PR made another change in overlays/ghc.nix which I'm having trouble understanding:

https://github.com/input-output-hk/haskell.nix/blob/master/overlays/ghc.nix#L7-L9

Shouldn't line 8 say enableNativeBignum = true instead?

thomasjm avatar Oct 05 '22 06:10 thomasjm

Thanks for merging #1784! I guess we can close this now, unless it's still tracking the effort to do this in a reinstallable way?

It's probably worth noting that as of this change, the native bignum flag will be used automatically on GHC 9+. Also, is there any way for a user to get the previous behavior if they should want to? AFAIK the GMP backend is still the most performant.

thomasjm avatar Nov 18 '22 09:11 thomasjm

It's probably worth noting that as of this change, the native bignum flag will be used automatically on GHC 9+.

This sounds promising, but could someone please clarify, regarding #1784, what exactly "when available" means?

georgefst avatar Nov 28 '22 00:11 georgefst

Also, after #1784, the DLLs are still present on Windows, but can be safely deleted (similarly to https://github.com/input-output-hk/haskell.nix/issues/1254#issuecomment-1136405540, although in this the Linux build is successful, with ldd not referencing GMP).

georgefst avatar Nov 28 '22 14:11 georgefst

what exactly "when available" means?

In the code, it's when the following returns true: hasNativeBignum = name: !lib.hasPrefix "ghc8" name;

thomasjm avatar Nov 28 '22 20:11 thomasjm

In the code, it's when the following returns true: hasNativeBignum = name: !lib.hasPrefix "ghc8" name;

Aha, cool, thanks. I was worried it'd be something more complicated.

georgefst avatar Dec 01 '22 10:12 georgefst