Message "GHC/PrimopWrappers.hs:133:29: Not in scope: `GHC.Prim.quotInteger2Exp#'" building GHC with additional primitive operation

Thorkil Naur naur at post11.tele.dk
Wed Mar 22 19:05:26 EST 2006


Hello,

Using the marvelous Haskell language and the equally marvelous GHC 
implementation, I have over the past couple of years revived my old interest 
in integer factorization. The built-in support for multi-precision integer 
arithmetic makes Haskell a fine choice for this kind of computation. And 
working with numbers with several hundreds of decimal digits, I at least hope 
that the (undoubted) overhead of GHC Haskell when compared to, say, direct 
use of C is easily drowned by the time taken by the individual arithmetic 
operations. And Haskell is so much easier to use than C.

(In addition to GHC, I use Hugs.) 

I have come to a point, however, where I wish to squeeze some additional drops 
of performance out of my programs. For that, I would like direct access to 
some selection of gmp functions, in addition to those that are available 
through the use of Integer operators. For example, to experiment with the use 
of Montgomery modular multiplication (Mathematics of Computation, volume 44, 
number 170, April 1985, pages 519-521), I would like access to the 
mpz_tdiv_q_2exp function that divides an integer by a power of 2 by efficient 
shift operations.

I have considered using FFI, but although I have not given up this idea, it 
seems hard to do in a manner that avoids some potentially significant 
additional overhead.  So, the idea that I am currently exploring is to add 
some new primitive operations to Haskell as supported by GHC.

Offhand, I would not have considered it likely that going in this direction 
would be particularly easy. So I was happy to discover that GHC already 
supports certain additional direct gmp calls. For example, the GHC.Num module 
includes the gcdInteger function that more or less directly calls mpz_gcd, 
everything in a seemingly straightforward manner.

Unfortunately, my attempt to mimic this has failed. In detail, this is what I 
have done:

1. I have expanded ghc-6.4.1-src.tar.bz2 and tried to build it (./configure +    
make). No errors detected and seemingly, this produced a working GHC    
compiler.

2. Then I changed the source as indicated in the following that compares the 
original with my changed version:

      tn at linux:~/tn/Haskell/ghc/unpack> diff -r original/ . | grep -v '^Only 
in \./ghc'
      diff -r 
original/ghc-6.4.1/ghc/compiler/prelude/primops.txt.pp ./ghc-6.4.1/ghc/compiler/prelude/primops.txt.pp
      6a7
      > -- 2006-Mar-20 20.29 / TN: Experiment with additional primitive 
operations
      429a431,435
      > primop   IntegerQuot2ExpOp   "quotInteger2Exp#" GenPrimOp
      >    Int# -> ByteArr# -> Int# -> (# Int#, ByteArr# #)
      >    {Rounds towards zero.}
      >    with out_of_line = True
      >
      diff -r 
original/ghc-6.4.1/ghc/includes/StgMiscClosures.h ./ghc-6.4.1/ghc/includes/StgMiscClosures.h
      10a11,12
      >  * 2006-Mar-21 17.05 / TN: Experiment with additional primitive 
operations
      >  *
      491a494
      > RTS_FUN(quotInteger2Expzh_fast);
      diff -r original/ghc-6.4.1/ghc/rts/Linker.c ./ghc-6.4.1/ghc/rts/Linker.c
      6a7,8
      >  * 2006-Mar-21 17.06 / TN: Experiment with additional primitive 
operations
      >  *
      535a538
      >       SymX(quotInteger2Expzh_fast)            \
      diff -r 
original/ghc-6.4.1/ghc/rts/PrimOps.cmm ./ghc-6.4.1/ghc/rts/PrimOps.cmm
      6a7,8
      >  * 2006-03-20 23.50 / TN: Experiment with additional primitive 
operations
      >  *
      29a32,36
      > quotInteger2Expzh_fast
      > {
      >     // At this point, the call of mpz_tdiv_q_2exp will eventually be 
inserted
      > }
      >
      Only in .: original
      Only in .: save
      tn at linux:~/tn/Haskell/ghc/unpack>

   With these changes, make fails with the error messages

      rm -f GHC/PrimopWrappers.o; if [ ! -d GHC/PrimopWrappers_split ]; then 
mkdir GHC/PrimopWrappers_split; else /usr/bin/find GHC/PrimopWrappers_split 
-name '*.o' -print | xargs rm -f __rm_food; fi;
      ../../ghc/compiler/ghc-inplace -H16m -O -fglasgow-exts -cpp -Iinclude 
-"#include" HsBase.h -funbox-strict-fields -ignore-package base -O 
-Rghc-timing -fgenerics  -fgenerics -split-objs    -c GHC/PrimopWrappers.hs 
-o GHC/PrimopWrappers.o  -ohi GHC/PrimopWrappers.hi

      GHC/PrimopWrappers.hs:133:29: Not in scope: `GHC.Prim.quotInteger2Exp#'
      <<ghc: 32263284 bytes, 4 GCs, 97412/97412 avg/max bytes residency (1 
samples), 16M in use, 0.00 INIT (0.00 elapsed), 0.12 MUT (0.19 elapsed), 0.02 
GC (0.04 elapsed) :ghc>>
      make[2]: *** [GHC/PrimopWrappers.o] Error 1
      make[1]: *** [all] Error 1
      make[1]: Leaving directory 
`/home/tn/tn/Haskell/ghc/unpack/ghc-6.4.1/libraries'
      make: *** [build] Error 1

So, evidently, it is not as easy to add new primitive operations as I thought. 
(Or, which is most likely, but embarrasingly, closer to the truth: I am not 
as clever as I thought I was.)

In any case, if someone is able to provide some hint that enables me to 
proceed in this matter, I would be most grateful.

For the record:

   tn at linux:~/tn/tmp/Haskell/work> gcc -v
   Using built-in specs.
   Target: i586-suse-linux
   Configured with: ../configure --enable-threads=posix --prefix=/usr 
--with-local-prefix=/usr/local --infodir=/usr/share/info 
--mandir=/usr/share/man --libdir=/usr/lib --libexecdir=/usr/lib 
--enable-languages=c,c++,objc,f95,java,ada --disable-checking 
--with-gxx-include-dir=/usr/include/c++/4.0.2 --enable-java-awt=gtk 
--disable-libjava-multilib --with-slibdir=/lib --with-system-zlib 
--enable-shared --enable-__cxa_atexit --without-system-libunwind 
--host=i586-suse-linux
   Thread model: posix
   gcc version 4.0.2 20050901 (prerelease) (SUSE Linux)
   tn at linux:~/tn/tmp/Haskell/work> ghc --version
   The Glorious Glasgow Haskell Compilation System, version 6.2
   tn at linux:~/tn/tmp/Haskell/work>  

Best regards
Thorkil Naur


More information about the Glasgow-haskell-users mailing list