Skip to content

GSoC 2015 Abinash Meher: Ruby bindings for CSymPy

Abinash Meher edited this page Mar 23, 2015 · 14 revisions

Ruby bindings to the CSymPy C++ symbolic library

Motivation

The motivation was to have a computer algebra system for Ruby. At the beginning, the idea was to use ruby wrapper for sage which uses Pynac, based on GiNaC, because it is much faster.
However, from the benchmarks, CSymPy is much faster than Pynac. The reason Pynac is slower is probably because it uses Sage's GMP functionality. In case of CSymPy there is no Python being called from the C++ code. The code is entirely in C++. It was for this reason that there's no need to worry about any potential Python overhead. It also allows us to use it from other languages, with the help of wrappers.
Another option was to wrap GiNaC directly, but CSymPy also seems to be a bit faster than GiNaC itself by now. The code has been designed in such a way so that one can play with various data structures and really make sure the code is fast.
There is one small limitation however. Compared to GiNaC, CSymPy is missing specialized polynomial manipulation and series expansion and pattern matching, all of which are being worked on and will get the functionality soon. Most part of it might get completed during this summer as part of GSoC projects. Execution

  1. Tool to generate the wrappers
    There were many choices like Ruby inline, Rice, FFI, SWIG and manually using Ruby C API . From the first 3 FFI seems to be the fastest as benchmarked in this link. However, with the FFI method, we get a segfault at runtime while running Ruby tests (which we will be adding whatever tool we use). Here manual method is advantageous since it is compiled, so we immediately get a compile error on Travis if we change an interface in CSymPy, so we know we have to fix it, while merging the patch. It will be a huge comfort. Also, the manual method is preferred while dealing with a lot of pointers in the C++ code. Because either way we would end up doing as much work. Also the code is clearer in the manual method. With SWIG, C++ references are supported, but SWIG transforms them back into pointers, as mentioned here. It's a feature that we might be needing some time later. So, going with the manual method seems the wisest.

  2. File structure
    Currently all the python wrappers are in a folder csympy under the root folder. The idea is to keep all the wrapper code at a single place, i.e. inside the src in separate folders like src/c, src/python and src/ruby. The same logic can be applied to other languages later like src/julia, etc.
    Each folder can then be configured to a ready to install package like the python wrappers as a pip-package and the ruby wrappers as a gem.

  3. Exposing the C++ functions with extern Ruby provides interfacing to only C functions. For that we need to expose the C++ code through extern. The functions can now be called from C. It needs to be done to use the C API of Ruby.

  4. Writing the extensions I will be following the documentation for this from README.EXT. Also the Chris Lalance's blog.

  5. Making this a gem
    So that it's easier to install. User will have the choice if he wants to install along with csympy or only the wrappers. A check can be included to automate this. Also a functionality to compile the extensions separately.

Tools I am going to use

I am using a system dual-booted with Ubuntu 14.04.2 LTS and Windows 8.1. Following are the configurations on my machine

abinashmeher999@JARVIS:~$ ruby --version
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]
abinashmeher999@JARVIS:~$ gem --version
1.8.23
abinashmeher999@JARVIS:~$ rake --version
rake, version 10.0.4
abinashmeher999@JARVIS:~$ rspec --version
3.2.2
abinashmeher999@JARVIS:~$ bundle --version
Bundler version 1.3.5
abinashmeher999@JARVIS:~$ rdoc --version
rdoc 3.9.5

I will be using vim as my primary text editor. Apart from that I will be using the following

  • Rake-compiler
    rake-compiler is a set of rake tasks for automating extension building. Rake eases the process of making extensions by its 'rake/extensiontask'. If a proper project structure is followed, generating extensions requires only a few lines of code.
  • RSpec
    RSpec tests it the way a developer would like it to, to make sure all works as he intended them. More like the unit tests. Whereas, Cucumber tests it the way a client/consumer would expect from the software. Like the integration tests. Most of the places, people suggest that both go hand in hand. But since the underlying C++ code is tested elsewhere, integration testing won't be needed.
  • Bundler
    Bundler provides a consistent environment for Ruby projects by tracking and installing the exact gems and versions that are needed. It ensures that the gems you need are present in development, staging, and production.
  • RDoc
    For documentation of code and tests.

Timeline (tentative)

Community Bonding period (27th April - 24th May) and Week 1, 2 and 3

I don't know everybody yet, neither did I get enough time to know at least a few developers in the community before the application. This will be a great time to get to know everybody and the fellow students. My summer vacation will start from 29th of April and I can get up to speed by reading the documentation and getting to know the practices followed in the community. I will also use this time to read the documentation for the tools I will be using, so that I am aware of the best way to achieve the result and make informed decisions.

Week 4

  • Writing the C wrappers with extern.

Week 5, 6 and 7

  • Writing the source code for the wrappers.
  • Documenting it on the go.

Week 8

  • Reviewing what was done in week 4, 5, 6 and 7

Testing and Week 9 and 10

  • Writing and carrying out tests using RSpec
  • Might need to go back to make some changes to accommodate the coding style in ruby

Week 11

  • Packaging the code
  • Make it ready for publication

Buffer Period and Week 12 and 13

  • cleaning up the code, fixing bugs, documentation
  • addition of more tests, examples and everything that's pending
  • Make sure the installation works on all systems

Relevant Issues/ Discussions and References


Clone this wiki locally