Bodigrim / bitvec

Bit vectors: 8x less memory, up to 3500x faster than Vector Bool
https://hackage.haskell.org/package/bitvec
BSD 3-Clause "New" or "Revised" License
73 stars 7 forks source link

GHC Linking-Error: Unknown symbol when newtype deriving #87

Open bruderj15 opened 3 months ago

bruderj15 commented 3 months ago

Hello all,

i have been playing around with Bit and made a type-level length- and sign-indexed version.

newtype Bitvector (n :: Nat) (b :: Bool) = Bitvector { unsign :: Vector n Bit.Bit }
  deriving stock (Eq, Ord)
  deriving newtype (Show, Bits)

However, deriving Bits for the newtype always ends up in a GHC linking error.

ghc-9.6.5.exe:  | C:\Users\Julian.Bruder\AppData\Roaming\stack\snapshots\5937a04a\lib\x86_64-windows-ghc-9.6.5\bitvec-1.1.5.0-FeYjI9fYzTYHldeafWMV7y\libHSbitvec-1.1.5.0-FeYjI9fYzTYHldeafWMV7y.a: unknown symbol `__cpu_model'
ghc-9.6.5.exe:  | C:\Users\Julian.Bruder\AppData\Roaming\stack\snapshots\5937a04a\lib\x86_64-windows-ghc-9.6.5\bitvec-1.1.5.0-FeYjI9fYzTYHldeafWMV7y\libHSbitvec-1.1.5.0-FeYjI9fYzTYHldeafWMV7y.a: unknown symbol `_hs_bitvec_select_bits'
ghc-9.6.5.exe: ^^ Could not load 'bitveczm1zi1zi5zi0zmFeYjI9fYzzTYHldeafWMV7y_DataziBitziImmutable_zdfBitsVector_closure', dependency unresolved. See top entry above.

GHC.ByteCode.Linker.lookupCE
During interactive linking, GHCi couldn't find the following symbol:
  bitveczm1zi1zi5zi0zmFeYjI9fYzzTYHldeafWMV7y_DataziBitziImmutable_zdfBitsVector_closure

Is this related to the C SIMD-optimizations? This is on Win 11.

konsumlamm commented 3 months ago

Is this related to the C SIMD-optimizations?

Possibly. I suspect it is because of __builtin_cpu_supports. What C compiler do you have?

As a workaround, try disabling the simd flag.

Bodigrim commented 3 months ago

@bruderj15 please raise an issue at https://gitlab.haskell.org/ghc/ghc/-/issues, this is fundamentally a GHC issue. (Tell me if you need an account activation at https://gitlab.haskell.org)

Bodigrim commented 2 months ago

@bruderj15 any news on this?

bruderj15 commented 2 months ago

@Bodigrim Apologies for not answering. I have not yet reported the problem. For now I wrote the instance myself.

Will investigate further and then issue a ticket at ghc as soon as there is some spare time.

Bodigrim commented 2 months ago

@bruderj15 could you please share a self-contained reproducer?

bruderj15 commented 2 months ago

Surely. Repl below module with: cabal repl --build-depends "bitvec" --build-depends "vector-sized" GHC is 9.6.5.

{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralisedNewtypeDeriving #-}

module BitvecNewTypeDerivingLinkingError where

import Data.Bit as Bit
import Data.Bits
import GHC.TypeNats
import qualified Data.Vector.Unboxed.Sized as V

newtype Bitvector (n :: Nat) = Bitvector { unsign :: V.Vector n Bit.Bit }
  deriving stock (Eq, Ord)
  deriving newtype (Show, Bits)

main :: IO ()
main = putStrLn "Hello World!"

The module compiles successfully. However, when running main, we get the following error:

ghci> main
ghc-9.6.5.exe:| C:\cabal\store\ghc-9.6.5\bitvec-1.1.5.0-505e12042e6d0bd4f1d718085478e089a7c3bbe0\lib\libHSbitvec-1.1.5.0-505e12042e6d0bd4f1d718085478e089a7c3bbe0.a: unknown symbol `__cpu_model'
ghc-9.6.5.exe:| C:\cabal\store\ghc-9.6.5\bitvec-1.1.5.0-505e12042e6d0bd4f1d718085478e089a7c3bbe0\lib\libHSbitvec-1.1.5.0-505e12042e6d0bd4f1d718085478e089a7c3bbe0.a: unknown symbol `_hs_bitvec_select_bits'
ghc-9.6.5.exe: ^^ Could not load 'bitveczm1zi1zi5zi0zm505e12042e6d0bd4f1d718085478e089a7c3bbe0_DataziBitziImmutable_zdfBitsVector_closure', dependency unresolved. See top entry above.

GHC.ByteCode.Linker.lookupCE
During interactive linking, GHCi couldn't find the following symbol:
  bitveczm1zi1zi5zi0zm505e12042e6d0bd4f1d718085478e089a7c3bbe0_DataziBitziImmutable_zdfBitsVector_closure

Removing the newtype-derived Bits instance makes it work.

This problem only seems to occur on Win 11, works fine on Linux. As @konsumlamm mentioned, maybe this is due to the C compiler. I will check later. If it is, we would rather want some more descriptive error message i guess.

bruderj15 commented 2 months ago

Disabling simd by repling with cabal repl --build-depends "bitvec" --build-depends "vector-sized" --flags="-simd" yields the same error.

Bodigrim commented 2 months ago

I reproduced the issue on Windows with GHC 9.10.1, so it's unlikely to be fixed already.

Disabling simd by repling with cabal repl --build-depends "bitvec" --build-depends "vector-sized" --flags="-simd" yields the same error.

This is not a right syntax, I think. cabal repl --build-depends "bitvec" --build-depends "vector-sized" --constraint 'bitvec -simd' works for me on Windows, so the issue is definitely related to C code.

Bodigrim commented 2 months ago

I raised https://gitlab.haskell.org/ghc/ghc/-/issues/25080.

Bodigrim commented 1 month ago

Judging from GHC tracker, the simplest solution is to avoid __builtin_cpu_supports and do CPU feature detection by hand, as in text. PR is welcome.