Interfacing Mathemagix with C++ Joris van der Hoeven, Grégoire Lecerf
To cite this version:
Joris van der Hoeven, Grégoire Lecerf. Interfacing Mathemagix with C++. 2013. hal-00771214
HAL Id: hal-00771214 https://hal.archives-ouvertes.fr/hal-00771214 Preprint submitted on 8 Jan 2013
HAL is a multi-disciplinary open access L’archive ouverte pluridisciplinaire HAL, est archive for the deposit and dissemination of sci- destinée au dépôt et à la diffusion de documents entific research documents, whether they are pub- scientifiques de niveau recherche, publiés ou non, lished or not. The documents may come from émanant des établissements d’enseignement et de teaching and research institutions in France or recherche français ou étrangers, des laboratoires abroad, or from public or private research centers. publics ou privés. Interfacing Mathemagix with C++∗
Joris van der Hoeven Grégoire Lecerf Laboratoire d’Informatique Laboratoire d’Informatique UMR 7161 CNRS UMR 7161 CNRS Campus de l’École polytechnique Campus de l’École polytechnique 91128 Palaiseau Cedex 91128 Palaiseau Cedex France France Email: [email protected] Email: [email protected]
Preliminary version of January 8, 2013
Abstract system would evolve. This has discouraged many of the programmers who did care about the novel programming In this paper, we give a detailed description of the inter- language concepts in these systems. face between the Mathemagix language and C++. In In our opinion, this has led to an unpleasant current particular, we describe the mechanism which allows us to situation in computer algebra: there is a dramatic lack of import a C++ template library (which only permits static a modern, sound and fast general purpose programming tm instantiation) as a fully generic Mathemagix template language. The major systems Mathematica [31] and tm library. Maple [20] are both interpreted, weakly typed, besides being proprietary and expensive. The Sage system [26] Keywords: Mathemagix, C++, generic programming, relies on Python and merely contents itself to glue template library together various existing libraries and other software com- A.M.S. subject classification: 68W30 ponents. The absence of modern languages for computer algebra 1 Introduction is even more critical whenever performance is required. Nowadays, many important computer algebra libraries 1.1 Motivation behind Mathemagix (such as Gmp [10], Mpfr [6], Flint [12], FGb [5], etc.) are directly written in C or C++. Performance issues Until the mid nineties, the development of computer are also important whenever computer algebra is used in algebra systems tended to exploit advances in the area combination with numerical algorithms. We would like to of programming languages, and sometimes even influenced emphasize that high level ideas can be important even the design of new languages. The Formac system [2] for traditionally low level applications. For instance, in was developed shortly after the introduction of Fortran. a suitable high level language it should be easy to operate Symbolic algebra was an important branch of the arti- on SIMD vectors of, say, 256 bit floating point num- ficial intelligence project at Mit during the sixties. During bers. Unfortunately, Mpfr would have to be completely a while, the Macsyma system [21, 23, 25] was the largest redesigned in order to make such a thing possible. program written in Lisp, and motivated the development For these reasons, we have started the design of a new of better Lisp compilers. software, Mathemagix [14, 15], based on a compiled and The Scratchpad system [11, 16] was at the origin of strongly typed language, featuring signatures, dependent yet another interesting family of computer algebra sys- types, and overloading. Mathemagix is intended as a gen- tems, especially after the introduction of domains and eral purpose language, which supports both functional and categories as function values and dependent types in imperative programming styles. Although the design has Modlisp and Scratchpad II [17, 19, 27]. These devel- greatly been influenced by Scratchpad II and its succes- opments were at the forefront of language design and type sors Axiom and Aldor, the type system of Mathemagix theory [9, 22, 24]. Scratchpad later evolved into the contains several novel aspects, as described in [13]. Math- Axiom system [1, 18]. In the A# project [29, 30], later emagix is also a free software, which can be downloaded renamed into Aldor, the language and compiler were from http://www.mathemagix.org. redesigned from scratch and further purified. After this initial period, computer algebra systems 1.2 Interfacing Mathemagix with C++ have been less keen on exploiting new ideas in language design. One important reason is that a good language One major design goal of the Mathemagix compiler is for computer algebra is more important for developers to admit a good compatibility with existing program- than for end users. Indeed, typical end users tend to use ming languages. For the moment, we have focussed on C computer algebra systems as enhanced pocket calculators, and C++. Indeed, on the one hand, in parallel with the and rarely write programs of substantial complexity them- development of the compiler, we have written several high selves. Another reason is specific to the family of systems performance C++ template libraries for various basic that grew out of Scratchpad: after IBM’s decision to mathematical structures (polynomials, matrices, series, no longer support the development, there has been a long etc.). On the other hand, the compiler currently gener- period of uncertainty for developers and users on how the ates C++ code.
∗. This work has been partly supported by the Digiteo 2009-36HD grant of the Région Ile-de-France.
1 We already stated that Mathemagix was inspired 2 Basic interface principles to C++ by Axiom and Aldor in many respects. Some early work on interfacing with C++ was done in the context 2.1 Preparing imports from C++ of Aldor [4, 7]. There are two major differences between Different programming languages have different conven- C++ and Aldor which are important in this context. tions for compiling programs, organizing projects into On the one hand, Aldor provides support for gen- libraries, and mechanisms for separate compilation. uine generic functional programming: not only functions, C++ is particularly complex, since the language does but also data types can be passed as function arguments. not provide any direct support for the management of big For instance, one may write a routine which takes a ring projects. Instead, this task is delegated to separate con- R and an integer n on input and which returns the ring figuration and Makefile systems, which are responsible for
R[X1] [Xn]. The language also provides support for the detection and specification of external and internal dependent types: a function may very well take a ring R dependencies, and the determination of the correct com- together with an instance x of R as its arguments or return pilation flags. Although these tasks may be facilitated up value. to a certain extent when using integrated development tm On the other hand, C++ provides support for tem- environments such as Eclipse (trademark of Eclipse tm plates. We may write a routine cube which takes an Foundation, Inc.), Xcode (trademark of Apple Inc.), tm instance x of an arbitrary type R on input and returns or C++ Builder (trademark of Embarcadero Tech- x*x*x. However, and even though there is some work in nologies, Inc.), they usually remain non trivial for projects this direction [8], it is currently not possible to add the of a certain size. requirement that R must be a ring when declaring the tem- Mathemagix uses a different philosophy for managing plate cube. Hence, the correctness of the template body big projects. Roughly speaking, any source file contains x*x*x can only be checked at the moment when the tem- all information which is necessary for building the cor- plate is instantiated for a particular type R. Furthermore, responding binary. Consequently, there is no need for only a finite number of these instantiations can occur in external configuration or Makefile systems. a program or library, and template parameters cannot be Whenever we import functionality from C++ into passed to functions as objects. Mathemagix, our design philosophy implies that we have In Aldor, there is no direct equivalent of templates. to specify the necessary instructions for compiling and/or Mathemagix Nevertheless, it is possible to implement a function cube linking the imported code. To this effect, which takes a ring R and an instance x of R on input, provides special primitives cpp_flags, cpp_libs and cpp_include and which returns x*x*x. It thus makes sense to consider for specifying the compilation and linking the importation of C++ template libraries into Aldor. flags, and C++ header files to be included. numerix Mathemagix Although [4, 7] contain a precise strategy for realizing such For instance, the library of interfacing, part of the interface still had to be written by contains implementation for various numerical types. In particular, it contains wrappers for the Gmp and hand. Mpfr libraries [6, 10] with implementations of arbitrary Mathemagix features two main novelties with respect precision integers, rational numbers and floating point to the previous work which was done in the context of numbers. The Mathemagix interface for importing the Axiom and Aldor. First of all, the language itself admits wrapper for arbitrary precision integers starts as follows: full support for templates with typed parameters; see our paper [13] on the type system for more details. Secondly, foreign cpp import { C++ template libraries can be imported into Math- cpp_flags "`numerix-config --cppflags`"; emagix in a straightforward way, without the need to cpp_libs "`numerix-config --libs`"; write any non trivial parts of the interface by hand. cpp_include "numerix/integer.hpp"; The ability to transform a C++ template library which ... } only permits static instantiation into a fully generic tem- plate library is somewhat surprising. Part of the magic On installation of the numerix library, a special script occurs in the specification of the interface itself. Indeed, numerix-config is installed in the user’s path. In the the interface should in particular provide the missing type above example, we use this script in order to retrieve information about the parameters of the C++ templates. the compilation and linking flags. Notice also that In this paper, we will describe in more details how this numerix/integer.hpp is the C++ header file for basic mechanism works. We think that similar techniques can arbitrary precision integer arithmetic. be applied for the generic importation of C++ templates into other languages such as Aldor or OCaml. It might 2.2 Importing simple classes and functions also be useful for future extensions of C++ itself. Ideally speaking, the bulk of an interface between Math- The paper is organized as follows. In Section 2, we emagix and a foreign language is simply a dictionary describe how to import and export non templated classes which specifies how concepts in one system should be and functions from and to C++. In Section 3, we briefly mapped into the other one. For ordinary classes, functions recall how genericity works in Mathemagix, and we and constants, there is a direct correspondence between describe what kind of C++ code is generated by the com- Mathemagix and C++, so the interface is very simple piler for generic classes and functions. The core of the in this case. paper is Section 4, where we explain how C++ templates Assume for instance that we want to map the C++ are imported into Mathemagix. In Section 5 we sum- class integer from integer.hpp into the Mathemagix marize the main C++ libraries that have been interfaced class Integer, and import the basic constructors and to Mathemagix, and Section 6 contains a conclusion and arithmetic operations on integers. This is done by com- several ideas for future extensions. pleting the previous example into:
2 foreign cpp import { The first compulsory operator is flatten: T -> cpp_flags "`numerix-config --cppflags`"; Syntactic, which converts instances of type T into syn- cpp_libs "`numerix-config --libs`"; tactic expression trees which can then be printed in cpp_include "numerix/integer.hpp"; several formats (ASCII, Lisp,TEXMACS, etc.). The other compulsory operators are three types of equality (and class Integer == integer; inequality) tests and the corresponding hash functions. literal_integer: Literal -> Integer == Indeed, Mathemagix distinguishes between “semantic” make_literal_integer; equality, exact “syntactic” equality and “hard” pointer equality. Finally, any C++ type should provide a default prefix -: Integer -> Integer == prefix -; infix +: (Integer, Integer) -> Integer == infix +; constructor with no arguments. infix -: (Integer, Integer) -> Integer == infix -; infix *: (Integer, Integer) -> Integer == infix *; 2.5 Exporting basic functionality to C++ Simple Mathemagix classes and functions can be ... } exported to C++ in a similar way as C++ classes and functions are imported. Assume for instance that we wrote The special constructor literal_integer allows us to a Mathemagix class Point with a constructor, accessors, write literal integer constants such as 12345678987654321 and a few operations on points. Then we may export this using the traditional notation. This literal constructor cor- functionality to C++ as follows: responds to the C++ routine foreign cpp export { integer make_literal_integer (const literal&); class Point == point; point: (Double, Double) -> Point == where literal is a special C++ class for string symbols. keyword constructor; postfix .x: Point -> Double == get_x; postfix .y: Point -> Double == get_y; 2.3 Syntactic sugar middle: (Point, Point) -> Point == middle; } The syntax of C++ is quite rigid and often directly related to implementation details. For instance, in C++ the nota- tion p.x necessarily presupposes the definition of a class 3 Categories and genericity in Mathemagix or structure with a field x. In Mathemagix, the operator postfix .x can be defined anywhere. More generally, the Before we discuss the importation of C++ template language provides a lot of syntactic sugar which allows for libraries into Mathemagix, let us first describe how to a flexible mapping of C++ functionality to Mathemagix. define generic classes and functions in Mathemagix, and Another example is type inheritance. In C++, type how such generic declarations are reflected on the C++ inheritance can only be done at the level of class defini- side. tions. Furthermore, type inheritance induces a specific low Mathemagix provides the forall construct for the level representation in memory for the corresponding class declaration of generic functions. For instance, a simple instances. In Mathemagix, we may declare any type T to generic function for the computation of a cube is the fol- inherit from a type U by defining an operator downgrade: lowing: T -> U. This operator really acts as a converter with the special property that for any second converter X -> T, forall (M: Monoid) cube (x: M): M == x*x*x; Mathemagix automatically generates the converter X -> This function can be applied to any element x whose type U. This allows for a more high level view of type inher- M is a monoid. For instance, we may write itance. Mathemagix also provides a few built-in type con- c: Int == cube 3; structors: Alias T provides a direct equivalent for the C++ reference types, the type Tuple T can be used The parameters of generic functions are necessarily typed. for writing functions with an arbitrary number of argu- In our example, the parameter M is a type itself and the ments of the same type T, and Generator T corresponds type of M a category. The category Monoid specifies the to a stream of coefficients of type T. The built-in types requirements which are made upon the type M, and a typ- Alias T, Tuple T and Generator T are automatically ical declaration would be the following: mapped to the C++ types T&, mmx::vector
3 template
Notice that we did not generate any specific instantiation One of the most interesting aspects of our interface of cube for the Int type. This may lead to significantly between Mathemagix and C++ is its ability to import smaller executables with respect to C++ when the func- C++ template classes and functions. This makes it pos- tion cube is applied to objects of many different types. sible to provide a fully generic Mathemagix interface on Indeed, in the case of C++, a separate instantiation of top of an existing C++ template library. We notice that the function needs to be generated for each of these types. the interface between Aldor and C++ [4, 7] also provided In particular, the function can only be applied to a finite a strategy for the importation of templates. However, the number of types in the course of a program. bulk of the actual work still had to be done by hand.
4 4.1 Example of a generic C++ import Indeed, whenever a function returns a ring object, we should be able to determine the underlying ring R from Before coming to the technical details, let us first give the input arguments. In the case of a function such as a small example of how to import part of the univariate postfix []: (Pol R, Int) -> R, this means that R has polynomial arithmetic from the C++ template library to be read off from the coefficients of the input polynomial. algebramix, which is shipped with Mathemagix: But the most straightforward implementation of the zero polynomial does not have any coefficients! In principle, it foreign cpp import { is possible to tweak all C++ containers so as to guarantee ... the ability to determine the underlying generic parameters class Pol (R: Ring) == polynomial R; from actual instances. We have actually implemented this idea, but it required a lot of work, and it violates the forall (R: Ring){ principle that writing a Mathemagix interface for a C++ pol: Tuple R -> Pol R == keyword constructor; upgrade: R -> Pol R == keyword constructor; template library should essentially be trivial. The second approach is to store the ring R in a deg: Pol R -> Int == deg; global variable, whose value will frequently be changed postfix []: (Pol R, Int) -> R == postfix []; in the course of actual computations. In fact, certain templates might carry more than one parameter of type prefix -: Pol R -> Pol R == prefix -; Ring, in which case we need more than one global ring. infix +: (Pol R, Pol R) -> Pol R == infix +; For this reason, we chose to implement a container infix -: (Pol R, Pol R) -> Pol R == infix -; instance
5 template
5.1 Mathemagix libraries 4.3 Importing C++ templates C++ libraries of the Mathemagix project provide the Now that we have a way to represent arbitrary Math- user with usual data types and mathematical objects. emagix classes R with the structure of a Ring by a C++ We have already mentioned the basix library which is type instance
6 6 Conclusion and future extensions Compiling and running this program in a textual terminal yields: The current mechanism for importing C++ template libraries has been tested for the standard mathematical f= 1.0000 + 1.0000 * z + 0.50000 * z^2 libraries which are shipped with Mathemagix. For this purpose, it has turned out to be very user friendly, flexible + 0.16667 * z^3 + 0.041667 * z^4 + O (z^5) and robust. We think that other languages may develop f (1)= 2.7183 facilities for the importation of C++ template libraries f (1 + z)= 2.7183 + 2.7183 * z + 1.3591 * z^2 along similar lines. In the future, our approach may even + 0.45305 * z^3 + 0.11326 * z^4 + O (z^5) be useful for adding more genericity to C++ itself. A few points deserve to be developed further: Exporting Mathemagix containers and tem- 5.2 External libraries plates So far, we have focussed on the importation of C++ containers and templates, and Mathemagix only Importing a library that is completely external to the allows for the exportation of simple, non generic functions Mathemagix project involves several issues. First of all, and non parameterized classes. Nevertheless, it should not as mentioned in Section 2.4, all the data types to be be hard to add support for the more general exportation imported should satisfy mild conditions in order to be of generic functions and parameterized classes. Of course, properly usable from Mathemagix. Usually, these con- the types of the template parameters would be lost in ditions can easily be satisfied by writing a C++ wrapper this process and the resulting templates will only allow whenever necessary. for static instantiation. However, when introducing new types and functions, one usually wants them to interact naturally with other Multi-threading The main disadvantage of relying on librairies. For instance, if several libraries have their own global variables for storing the current values of template arbitrarily long integer type, straightforward interfaces parameters is that this strategy is not thread-safe. In order introduce several Mathemagix types of such integers, to allow generic code to be run simultaneously by several leaving to the user the responsibility of the conversions threads, the global variables have to be replaced by fast in order to use functions of different librairies within a lookup tables which determine the current values of tem- single program. plate parameters as a function of the current thread. For C and C++ libraries involving only a finite number Non class parameters The current interface only of types, we prefer to design lower level interfaces to the allows for the importation of C++ templates with type C++ libraries of Mathemagix. In this way, we focus parameters. This is not a big limitation, because tem- on writing efficient converters between external and C++ plates with value parameters are only supported for built- Mathemagix objects, and then on interfacing new func- in types and they can only be instantiated for constant tions at the Mathemagix language level. This is the way values. Nevertheless, it is possible to define auxiliary we did for instance with lattice reduction of the Fplll classes for storing mutable static variables, and use these library [3], where we mainly had to write converters for instead as our template parameters; notice that this is integer matrices. Similarly the interface with FGb [5] exactly the purpose of the instance
7 Bibliography [13] J. van der Hoeven. Overview of the Mathemagix type system. In Electronic proc. ASCM ’12 , Beijing, China, October 2012. Available from http://hal.archives-ouvertes.fr/hal-00702634. [1] Axiom computer algebra system. Software available from [14] J. van der Hoeven, G. Lecerf, B. Mourrain, et al. Mathemagix, http://wiki.axiom-developer.org. 2002. Software available from http://www.mathemagix.org. [2] E. Bond, M. Auslander, S. Grisoff, R. Kenney, M. Myszewski, [15] J. van der Hoeven, G. Lecerf, B. Mourrain, Ph. Trébuchet, J. Sammet, R. Tobey, and S. Zilles. FORMAC an experi- J. Berthomieu, D. Diatta, and A. Manzaflaris. Mathemagix, mental formula manipulation compiler. In Proceedings of the the quest of modularity and efficiency for symbolic and certi- 1964 19th ACM national conference, ACM ’64, pages 112.101– fied numeric computation. ACM Commun. Comput. Algebra, 112.1019, New York, NY, USA, 1964. ACM. 45(3/4):186–188, 2012. [3] D. Cade, X. Pujol, and D. Stehlé. Fplll, library for LLL- [16] R. D. Jenks. The SCRATCHPAD language. SIGPLAN Not., reduction of Euclidean lattices. Software available from 9(4):101–111, 1974. http://perso.ens-lyon.fr/damien.stehle/fplll, 1998. [17] R. D. Jenks. MODLISP – an introduction (invited). In [4] Y. Chicha, F. Defaix, and S. M. Watt. Automation of Proceedings of the International Symposium on Symbolic the Aldor/C++ interface: User’s guide. Technical Report and Algebraic Computation, EUROSAM ’79, pages 466–480, Research Report D2.2.2c, FRISCO Consoritum, 1999. Available London, UK, UK, 1979. Springer-Verlag. from http://www.csd.uwo.ca/~watt/pub/reprints/1999-frisco- [18] R. D. Jenks and R. Sutor. AXIOM: the scientific computa- aldorcpp-ug.pdf. tion system. Springer-Verlag, New York, NY, USA, 1992. [5] J.-C. Faugère. FGb: A Library for Computing Gröbner Bases. [19] R. D. Jenks and B. M. Trager. A language for computational In K. Fukuda, J. van der Hoeven, M. Joswig, and N. Takayama, algebra. SIGPLAN Not., 16(11):22–29, 1981. editors, Mathematical Software - ICMS 2010, Third Inter- [20] Maple user manual. Toronto: Maplesoft, a national Congress on Mathematical Software, Kobe, Japan, division of Waterloo Maple Inc., 2005–2012. Maple is a trade- September 13-17, 2010, volume 6327 of Lecture Notes in Com- mark of Waterloo Maple Inc. http://www.maplesoft.com/prod- puter Science, pages 84–87. Springer Berlin / Heidelberg, 2010. ucts/maple. [6] L. Fousse, G. Hanrot, V. Lefèvre, P. Pélissier, and P. Zim- [21] W. A. Martin and R. J. Fateman. The MACSYMA system. mermann. MPFR: A multiple-precision binary floating-point In Proceedings of the second ACM symposium on symbolic and library with correct rounding. ACM Transactions on Math- algebraic manipulation, SYMSAC ’71, pages 59–75, New York, ematical Software, 33(2), 2007. Software available from NY, USA, 1971. ACM. http://www.mpfr.org. [22] P. Martin-Löf. Constructive mathematics and computer pro- [7] M. Gaëtano and S. M. Watt. An object model corre- gramming. Logic, Methodology and Philosophy of Science VI , spondence for Aldor and C++. Technical Report Research pages 153–175, 1979. Report D2.2.1, FRISCO Consortium, 1997. Available from [23] Maxima, a computer algebra system (free version). Software http://www.csd.uwo.ca/~watt/pub/reprints/1997-frisco- available from http://maxima.sourceforge.net, 2011. aldorcppobs.pdf. [24] R. Milner. A theory of type polymorphism in programming. [8] R. Garcia, J. Järvi, A. Lumsdaine, J. G. Siek, and J. Willcock. Journal of Computer and System Sciences, 17:348–375, 1978. A comparative study of language support for generic program- [25] J. Moses. Macsyma: A personal history. Journal of Symbolic ming. In Proceedings of the 2003 ACM SIGPLAN conference Computation, 47(2):123–130, 2012. on Object-oriented programming, systems, languages, and [26] W. A. Stein et al. Sage Mathematics Software. The applications (OOPSLA’03), October 2003. Sage Development Team, 2004. Software available from [9] J. Y. Girard. Une extension de l’interprétation de Gödel à http://www.sagemath.org. l’analyse, et son application à l’élimination de coupures dans [27] R. S. Sutor and R. D. Jenks. The type inference and coer- l’analyse et la théorie des types. In J. E. Fenstad, editor, Pro- cion facilities in the Scratchpad II interpreter. SIGPLAN Not., ceedings of the Second Scandinavian Logic Symposium, pages 22(7):56–63, 1987. 63–92. North-Holland Publishing Co., 1971. [28] The PARI Group, Bordeaux. PARI/GP, 2012. Software avail- [10] T. Granlund and the GMP development team. GNU MP: The able from http://pari.math.u-bordeaux.fr. GNU Multiple Precision Arithmetic Library. Software available [29] S. Watt, P. A. Broadbery, S. S. Dooley, P. Iglio, S. C. Mor- from http://gmplib.org, 1991. rison, J. M. Steinbach, and R. S. Sutor. A first report on the [11] J. H. Griesmer, R. D. Jenks, and D. Y. Y. Yun. A# compiler. In Proceedings of the international symposium SCRATCHPAD User’s Manual. Computer Science Depart- on symbolic and algebraic computation, ISSAC ’94, pages 25– ment monograph series. IBM Research Division, 1975. 31, New York, NY, USA, 1994. ACM. [12] W. Hart. An introduction to Flint. In K. Fukuda, J. van der [30] S. Watt et al. Aldor programming language. Software avail- Hoeven, M. Joswig, and N. Takayama, editors, Mathemat- able from http://www.aldor.org, 1994. ical Software - ICMS 2010, Third International Congress on [31] S. Wolfram. Mathematica: A System for Doing Mathe- Mathematical Software, Kobe, Japan, September 13-17, 2010 , matics by Computer. Addison-Wesley, second edition, 1991. volume 6327 of Lecture Notes in Computer Science, pages 88– Mathematica is a trademark of Wolfram Research, Inc. 91. Springer Berlin / Heidelberg, 2010. http://www.wolfram.com/mathematica.
8