Message "GHC/PrimopWrappers.hs:133:29: Not in scope: `GHC.Prim.quotInteger2Exp#'" building GHC with additional primitive operation
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@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@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@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@linux:~/tn/tmp/Haskell/work> ghc --version The Glorious Glasgow Haskell Compilation System, version 6.2 tn@linux:~/tn/tmp/Haskell/work> Best regards Thorkil Naur
Thorkil Naur wrote:
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.)
I think you probably just haven't recompiled enough stuff after adding the primop. I can't tell immediately whether it's the compiler that is out of date, or an interface file in libraries/base. To be on the safe side, you could 'make clean' in ghc/compiler and libraries/base, then rebuild both. Cheers, Simon
On Thursday 23 March 2006 17:51, Simon Marlow wrote:
I think you probably just haven't recompiled enough stuff after adding the primop. I can't tell immediately whether it's the compiler that is out of date, or an interface file in libraries/base.
To be on the safe side, you could 'make clean' in ghc/compiler and libraries/base, then rebuild both.
Cheers, Simon
Hello, Thanks a lot, that removed some obstacles. Unfortunately, not all. Following successful "make clean" and "make all" in "ghc/compiler" and "libraries/base", a "make all" in the top-level directory reported: ../../ghc/compiler/stage1/ghc-inplace -o stage2/ghc-6.4.1 -H16m -O -istage2/utils -istage2/basicTypes -istage2/types -istage2/hsSyn -istage2/prelude -istage2/rename -istage2/typecheck -istage2/deSugar -istage2/coreSyn -istage2/specialise -istage2/simplCore -istage2/stranal -istage2/stgSyn -istage2/simplStg -istage2/codeGen -istage2/main -istage2/profiling -istage2/parser -istage2/cprAnalysis -istage2/compMan -istage2/ndpFlatten -istage2/iface -istage2/cmm -istage2/nativeGen -istage2/ghci -Istage2 -DGHCI -package template-haskell -package readline -DUSE_READLINE -cpp -fglasgow-exts -fno-generics -Rghc-timing -I. -IcodeGen -InativeGen -Iparser -package unix -package Cabal -recomp -Rghc-timing -H16M '-#include "hschooks.h"' -no-link-chk stage2/basicTypes/BasicTypes.o stage2/basicTypes/DataCon.o stage2/basicTypes/Demand.o stage2/basicTypes/FieldLabel.o stage2/basicTypes/Id.o stage2/basicTypes/IdInfo.o stage2/basicTypes/Literal.o stage2/basicTypes/MkId.o stage2/basicTypes/Module.o stage2/basicTypes/Name.o stage2/basicTypes/NameEnv.o stage2/basicTypes/NameSet.o stage2/basicTypes/NewDemand.o stage2/basicTypes/OccName.o stage2/basicTypes/RdrName.o stage2/basicTypes/SrcLoc.o stage2/basicTypes/UniqSupply.o stage2/basicTypes/Unique.o stage2/basicTypes/Var.o stage2/basicTypes/VarEnv.o stage2/basicTypes/VarSet.o stage2/cmm/CLabel.o stage2/cmm/Cmm.o stage2/cmm/CmmLex.o stage2/cmm/CmmLint.o stage2/cmm/CmmParse.o stage2/cmm/CmmUtils.o stage2/cmm/MachOp.o stage2/cmm/PprC.o stage2/cmm/PprCmm.o stage2/codeGen/Bitmap.o stage2/codeGen/CgBindery.o stage2/codeGen/CgCallConv.o stage2/codeGen/CgCase.o stage2/codeGen/CgClosure.o stage2/codeGen/CgCon.o stage2/codeGen/CgExpr.o stage2/codeGen/CgForeignCall.o stage2/codeGen/CgHeapery.o stage2/codeGen/CgInfoTbls.o stage2/codeGen/CgLetNoEscape.o stage2/codeGen/CgMonad.o stage2/codeGen/CgParallel.o stage2/codeGen/CgPrimOp.o stage2/codeGen/CgProf.o stage2/codeGen/CgStackery.o stage2/codeGen/CgTailCall.o stage2/codeGen/CgTicky.o stage2/codeGen/CgUtils.o stage2/codeGen/ClosureInfo.o stage2/codeGen/CodeGen.o stage2/codeGen/SMRep.o stage2/compMan/CompManager.o stage2/coreSyn/CoreFVs.o stage2/coreSyn/CoreLint.o stage2/coreSyn/CorePrep.o stage2/coreSyn/CoreSubst.o stage2/coreSyn/CoreSyn.o stage2/coreSyn/CoreTidy.o stage2/coreSyn/CoreUnfold.o stage2/coreSyn/CoreUtils.o stage2/coreSyn/ExternalCore.o stage2/coreSyn/MkExternalCore.o stage2/coreSyn/PprCore.o stage2/coreSyn/PprExternalCore.o stage2/cprAnalysis/CprAnalyse.o stage2/deSugar/Check.o stage2/deSugar/Desugar.o stage2/deSugar/DsArrows.o stage2/deSugar/DsBinds.o stage2/deSugar/DsCCall.o stage2/deSugar/DsExpr.o stage2/deSugar/DsForeign.o stage2/deSugar/DsGRHSs.o stage2/deSugar/DsListComp.o stage2/deSugar/DsMeta.o stage2/deSugar/DsMonad.o stage2/deSugar/DsUtils.o stage2/deSugar/Match.o stage2/deSugar/MatchCon.o stage2/deSugar/MatchLit.o stage2/ghci/ByteCodeAsm.o stage2/ghci/ByteCodeFFI.o stage2/ghci/ByteCodeGen.o stage2/ghci/ByteCodeInstr.o stage2/ghci/ByteCodeItbls.o stage2/ghci/ByteCodeLink.o stage2/ghci/InteractiveUI.o stage2/ghci/Linker.o stage2/ghci/ObjLink.o stage2/hsSyn/Convert.o stage2/hsSyn/HsBinds.o stage2/hsSyn/HsDecls.o stage2/hsSyn/HsExpr.o stage2/hsSyn/HsImpExp.o stage2/hsSyn/HsLit.o stage2/hsSyn/HsPat.o stage2/hsSyn/HsSyn.o stage2/hsSyn/HsTypes.o stage2/hsSyn/HsUtils.o stage2/iface/BinIface.o stage2/iface/BuildTyCl.o stage2/iface/IfaceEnv.o stage2/iface/IfaceSyn.o stage2/iface/IfaceType.o stage2/iface/LoadIface.o stage2/iface/MkIface.o stage2/iface/TcIface.o stage2/main/CmdLineOpts.o stage2/main/CodeOutput.o stage2/main/Config.o stage2/main/Constants.o stage2/main/DriverFlags.o stage2/main/DriverMkDepend.o stage2/main/DriverPhases.o stage2/main/DriverPipeline.o stage2/main/DriverState.o stage2/main/DriverUtil.o stage2/main/ErrUtils.o stage2/main/Finder.o stage2/main/GetImports.o stage2/main/HscMain.o stage2/main/HscStats.o stage2/main/HscTypes.o stage2/main/Main.o stage2/main/PackageConfig.o stage2/main/Packages.o stage2/main/ParsePkgConf.o stage2/main/SysTools.o stage2/main/TidyPgm.o stage2/nativeGen/AsmCodeGen.o stage2/nativeGen/MachCodeGen.o stage2/nativeGen/MachInstrs.o stage2/nativeGen/MachRegs.o stage2/nativeGen/NCGMonad.o stage2/nativeGen/PositionIndependentCode.o stage2/nativeGen/PprMach.o stage2/nativeGen/RegAllocInfo.o stage2/nativeGen/RegisterAlloc.o stage2/ndpFlatten/FlattenInfo.o stage2/ndpFlatten/FlattenMonad.o stage2/ndpFlatten/Flattening.o stage2/ndpFlatten/NDPCoreUtils.o stage2/ndpFlatten/PArrAnal.o stage2/parser/Ctype.o stage2/parser/LexCore.o stage2/parser/Lexer.o stage2/parser/Parser.o stage2/parser/ParserCore.o stage2/parser/ParserCoreUtils.o stage2/parser/RdrHsSyn.o stage2/prelude/ForeignCall.o stage2/prelude/PrelInfo.o stage2/prelude/PrelNames.o stage2/prelude/PrelRules.o stage2/prelude/PrimOp.o stage2/prelude/TysPrim.o stage2/prelude/TysWiredIn.o stage2/profiling/CostCentre.o stage2/profiling/SCCfinal.o stage2/rename/RnBinds.o stage2/rename/RnEnv.o stage2/rename/RnExpr.o stage2/rename/RnHsSyn.o stage2/rename/RnNames.o stage2/rename/RnSource.o stage2/rename/RnTypes.o stage2/simplCore/CSE.o stage2/simplCore/FloatIn.o stage2/simplCore/FloatOut.o stage2/simplCore/LiberateCase.o stage2/simplCore/OccurAnal.o stage2/simplCore/SAT.o stage2/simplCore/SATMonad.o stage2/simplCore/SetLevels.o stage2/simplCore/SimplCore.o stage2/simplCore/SimplEnv.o stage2/simplCore/SimplMonad.o stage2/simplCore/SimplUtils.o stage2/simplCore/Simplify.o stage2/simplStg/SRT.o stage2/simplStg/SimplStg.o stage2/simplStg/StgStats.o stage2/specialise/Rules.o stage2/specialise/SpecConstr.o stage2/specialise/Specialise.o stage2/stgSyn/CoreToStg.o stage2/stgSyn/StgLint.o stage2/stgSyn/StgSyn.o stage2/stranal/DmdAnal.o stage2/stranal/SaAbsInt.o stage2/stranal/SaLib.o stage2/stranal/StrictAnal.o stage2/stranal/WorkWrap.o stage2/stranal/WwLib.o stage2/typecheck/Inst.o stage2/typecheck/TcArrows.o stage2/typecheck/TcBinds.o stage2/typecheck/TcClassDcl.o stage2/typecheck/TcDefaults.o stage2/typecheck/TcDeriv.o stage2/typecheck/TcEnv.o stage2/typecheck/TcExpr.o stage2/typecheck/TcForeign.o stage2/typecheck/TcGenDeriv.o stage2/typecheck/TcHsSyn.o stage2/typecheck/TcHsType.o stage2/typecheck/TcInstDcls.o stage2/typecheck/TcMType.o stage2/typecheck/TcMatches.o stage2/typecheck/TcPat.o stage2/typecheck/TcRnDriver.o stage2/typecheck/TcRnMonad.o stage2/typecheck/TcRnTypes.o stage2/typecheck/TcRules.o stage2/typecheck/TcSimplify.o stage2/typecheck/TcSplice.o stage2/typecheck/TcTyClsDecls.o stage2/typecheck/TcTyDecls.o stage2/typecheck/TcType.o stage2/typecheck/TcUnify.o stage2/types/Class.o stage2/types/FunDeps.o stage2/types/Generics.o stage2/types/InstEnv.o stage2/types/Kind.o stage2/types/TyCon.o stage2/types/Type.o stage2/types/TypeRep.o stage2/types/Unify.o stage2/utils/Bag.o stage2/utils/Binary.o stage2/utils/BitSet.o stage2/utils/Digraph.o stage2/utils/FastMutInt.o stage2/utils/FastString.o stage2/utils/FastTypes.o stage2/utils/FiniteMap.o stage2/utils/IOEnv.o stage2/utils/ListSetOps.o stage2/utils/Maybes.o stage2/utils/OrdList.o stage2/utils/Outputable.o stage2/utils/Panic.o stage2/utils/Pretty.o stage2/utils/PrimPacked.o stage2/utils/StringBuffer.o stage2/utils/UnicodeUtil.o stage2/utils/UniqFM.o stage2/utils/UniqSet.o stage2/utils/Util.o stage2/parser/hschooks.o /home/tn/tn/Haskell/ghc/unpack/ghc-6.4.1/ghc/rts/libHSrts.a(Linker.o): (.data+0x41c): undefined reference to `quotInteger2Expzh_fast' collect2: ld returned 1 exit status <<ghc: 14519528 bytes, 3 GCs, 172816/172816 avg/max bytes residency (1 samples), 15M in use, 0.01 INIT (0.00 elapsed), 0.01 MUT (36.43 elapsed), 0.02 GC (0.02 elapsed) :ghc>> make[2]: *** [stage2/ghc-6.4.1] Error 1 make[2]: Leaving directory `/home/tn/tn/Haskell/ghc/unpack/ghc-6.4.1/ghc/compiler' make[1]: *** [stage2] Error 2 make[1]: Leaving directory `/home/tn/tn/Haskell/ghc/unpack/ghc-6.4.1' make: *** [bootstrap2] Error 2 And that message persisted, even when I tried "make clean" and "make all" in the top-level directory. I have tried a few things, groping in the darkness I would call it, trying to get around this. And I was actually able produce a compiler by temporarily removing the quotInteger2Expzh_fast reference in ghc/rts/Linker.c. But the produced compiler (including GHCi) complained about missing the symbol quotInteger2Expzh_fast. The file libraries/base/GHC/Base.lhs contains the tantalizing remarks GHC.Prim Has no implementation. It defines built-in things, and by importing it you bring them into scope. The source file is GHC.Prim.hi-boot, which is just copied to make GHC.Prim.hi but I have not been able to find anything that relates to this. So I am again at a loss, aksing for help to proceed. Thanks a lot in advance. Best regards Thorkil Naur
Thorkil Naur wrote:
Thanks a lot, that removed some obstacles. Unfortunately, not all. Following successful "make clean" and "make all" in "ghc/compiler" and "libraries/base", a "make all" in the top-level directory reported:
../../ghc/compiler/stage1/ghc-inplace -o stage2/ghc-6.4.1 -H16m -O ... snip... /home/tn/tn/Haskell/ghc/unpack/ghc-6.4.1/ghc/rts/libHSrts.a(Linker.o): (.data+0x41c): undefined reference to `quotInteger2Expzh_fast' collect2: ld returned 1 exit status
And that message persisted, even when I tried "make clean" and "make all" in the top-level directory.
quotInteger2Expzh_fast is the function you are adding to PrimOps.cmm to implement the primop. The patch in your original message indicated that you had added a stub for this function, so it should link ok. I don't understand what has gone wrong. You could check that indeed ghc/rts/PrimOps.o contains a definition for this symbol (nm ghc/rts/PrimOps.o), and also check that the symbol is defined in ghc/rts/libHSrts.a. Cheers, Simon
Hello Simon, Monday, March 27, 2006, 2:57:47 PM, you wrote:
quotInteger2Expzh_fast is the function you are adding to PrimOps.cmm to
Thorkil, i can't understand why you can't just use FFI to import functions you required? why you need to patch the PrimOps list? -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com
On Monday 27 March 2006 16:33, Bulat Ziganshin wrote:
Thorkil, i can't understand why you can't just use FFI to import functions you required? why you need to patch the PrimOps list? Hello,
As I wrote earlier, using FFI is also a candidate for getting access to additional GMP functions. However, presently, I am not aware of a method of doing this that does not involve some potentially significant additional overhead. After all, Haskell Integers are not directly supported in C, so some sort of marshalling and/or intricate access to internal GHC Haskell structures would seem to be required. But, as you have perhaps seen (my reply to Simon Marlow a few minutes ago on the same matter), adding primitive operations turned out to be easy (at least if you know exactly what you are doing). In addition, I have found that this method with very little effort allows me to continue to write code that can be used both via Hugs and GHC without change. Thanks and regards Thorkil
Hello Thorkil, Wednesday, March 29, 2006, 2:15:05 AM, you wrote:
Thorkil, i can't understand why you can't just use FFI to import functions you required? why you need to patch the PrimOps list? As I wrote earlier, using FFI is also a candidate for getting access to additional GMP functions. However, presently, I am not aware of a method of doing this that does not involve some potentially significant additional overhead. After all, Haskell Integers are not directly supported in C, so some sort of marshalling and/or intricate access to internal GHC Haskell structures would seem to be required.
primitives work with just the same internal structures. i thinl that only real advantage of adding primop instead of adding FFI import is that PrimOps.cmm contains already implemented wrappers for calling GMP functions while for FFI you should implement them from scratch -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com
Bulat Ziganshin wrote:
Hello Thorkil,
Wednesday, March 29, 2006, 2:15:05 AM, you wrote:
Thorkil, i can't understand why you can't just use FFI to import functions you required? why you need to patch the PrimOps list?
As I wrote earlier, using FFI is also a candidate for getting access to additional GMP functions. However, presently, I am not aware of a method of doing this that does not involve some potentially significant additional overhead. After all, Haskell Integers are not directly supported in C, so some sort of marshalling and/or intricate access to internal GHC Haskell structures would seem to be required.
primitives work with just the same internal structures. i thinl that only real advantage of adding primop instead of adding FFI import is that PrimOps.cmm contains already implemented wrappers for calling GMP functions while for FFI you should implement them from scratch
And primops can be constant folded (probably not important in this case, though). Also, because GMP operations need to allocate on the heap, special considerations apply in a multithreaded setting. You can't call allocation routines from a foreign call in general without either having a Capability (allocateLocal()), or taking the storage manager lock (allocate()). The primops have direct access to the current Capability, so they can just call allocateLocal() and don't need any locking operations. Cheers, Simon
On Wednesday 29 March 2006 01:35, Bulat Ziganshin wrote:
primitives work with just the same internal structures. i thinl that only real advantage of adding primop instead of adding FFI import is that PrimOps.cmm contains already implemented wrappers for calling GMP functions while for FFI you should implement them from scratch
Hello, You could very well be right. In fact, the main advantage that I see of solving my problem by adding a new GHC primitive operation is simply that this solution worked for me. I have so far not been able to concoct another solution that uses FFI. Quite possibly for simple lack of insight. But the "adding a new primitive operation"-method is not, of course, without its disadvantages. For example, now I have some additional work whenever I wish to use a new GHC version. And I also have to become fluent in generating GHC for Windows, because I also use the Windows version. All in all, I have not at all given up the idea of solving my problem of interfacing directly with the GMP functions using the FFI. But, as I have said, I have not been able to come up with such a solution. But perhaps you can help me out here. Suppose, for the example, that I wish to call the mpz_gcdext function. That function takes two integers as input and returns three. Here are some questions: 1. How should I declare the C (wrapper) function in Haskell? 2. What would a call of this function look like? 3. What circumstances would the implementing C (wrapper) function have to deal with? In particular, how would it access the two Integer input parameters? And how would it return the resulting three Integer results? I should tell you that I have studied the FFI document "The Haskell 98 Foreign Function Interface 1.0 An Addendum to the Haskell 98 Report (Release Candidate 14)" in detail, not finding it particularly easy going. I am also familiar with the properties of the FFI as implemented by GHC. In fact, I have tried to call a (very simple) C function from Haskell and it actually worked. Unfortunately, the solution to the main problem, that of passing Haskell Integer typed values back and forth between Haskell and C, still eludes me. (I have also seen Simon Marlow's comments to your letter. The sort of things that he talks about there ring bells, sure, but the details are completely unknown to me.) Thank you very much for any help that you provide in this matter. Regards Thorkil
On Monday 27 March 2006 12:57, Simon Marlow wrote:
quotInteger2Expzh_fast is the function you are adding to PrimOps.cmm to implement the primop. The patch in your original message indicated that you had added a stub for this function, so it should link ok. I don't understand what has gone wrong.
You could check that indeed ghc/rts/PrimOps.o contains a definition for this symbol (nm ghc/rts/PrimOps.o), and also check that the symbol is defined in ghc/rts/libHSrts.a. Hello,
The symbol quotInteger2Expzh_fast was indeed not defined in ghc/rts/PrimOps.o. It turned out that simply adding some "real" code to the body of quotInteger2Expzh_fast and recompiling caused a definition of the symbol to be added to PrimOps.o. So, apparently, the definition of a symbol for an empty Cmm body is (sometimes?) discarded. In any case, I managed to define suitable new primitive operations for my Haskell programs. Thanks a lot for your generous help. Best regards Thorkil
participants (3)
-
Bulat Ziganshin -
Simon Marlow -
Thorkil Naur