Improving the C Interface
03 Jul 2015 GSoC-2015 · SymEngineHello! I am halfway through my project. I can’t say that I achieved what I aimed to, but all the things that pushed this further weren’t delays, they needed to be done. The few things that were delays taught me a lot. They were worth the effort to lay a strong foundation. It has been an amazing learning experience, and makes me even more excited for what’s to come.
Anyways, I will summarize what I did this week.
Improved C Interface
While the plan was to develop and add the feature for Integer
and Rational
and automating memory leak checks, it took a turn towards improving the current C
interface. While writing the c wrapper code for the function SymEngine::free_symbols
, the task was to transfer the information that was in C++ datatype to something in C so that is accessible in C. The return type of the C++ functions were a std::vector
in one case and std::set
in other. The obvious idea that came to my mind was to map them to an array of pointers that pointed to these data. This idea was also a result of us using reinterpret_cast
to change the pointer type to another while transfering from C++
to C
and back to C++
. This was obviously not a good approach as there were too many pointers and they created very hard to correct errors in the code.
Ondrej came across this link. And suggested we adopt this method, as it was a really elegant solution for this.
The C interface now is lot more simplified. We declare the struct in the header file whereas the definition is done in the source file. The source file can indeed use C++
. The header file is like this
//File: cwrapper.h
typedef struct Ctypename Ctypename;
void typename_func(Ctypename *self);
And the source file is like this
//File: cwrapper.cpp
extern "C" {
struct Ctypename {
Cpptype data;
}
void typename_func(Ctypename *self) {
self->data.func_call();
}
Elegant! Isn’t it?
You can find the details of our implementation by my mentor, Ondrej Certik here.
IRuby notebook
I have also prepared an IRuby notebook that will serve as a beginner notebook to get familiar with the gem. You can find it here. It contains only what the gem supports right now. I will add more notebooks as I add more features.
Checking for memory leaks
As I had mentioned in my plan for the last week, I did search for ways to automate checking for memory leaks. I have come across many tools for checking for memory leaks in Ruby, but for testing the C
extensions, Valgrind
and gdb
are the ones that almost all of the blogs suggest. I have explained how I plan to proceed in the issue Checking Ruby C Extensions for memory leaks. #501.
It is really difficult to check for memory leaks even by ourselves, after seeing the output. I came to the conclusion that it will be very difficult to write a script that can check for memory leaks during the Continuous-Integration using Travis-CI, which was part of the initial plan. So, I have decided to automate checking of memory leaks by Valgrind
and gdb
from rake
, and this will only ease the plan of launching the debugging session. This way developer will have to launch the tasks and manually go through the report to debug it, before pushing the code to be assured that it is free of memory leaks.
Integration of other ruby gems
I also have plans to integrate the ruby bindings for gmp
, mpfr
and mpc
libraries, that are already available as gems, with ruby bindings for our library. I have created an issue here. Feel free to drop any suggestions.
Next week
The plan for the next week includes complete refactoring of the Ruby C API according to the new improved interface, setting up of rake tasks to detect memory leaks and add support for Integer
and Rational
classes.
Commits
- Added a beginner IRuby notebook
- Removed IRuby dependency from gemspec
- Added the
#to_iruby
method - Added C wrapper for free_symbols
- Added Ruby wrapper for
#free_symbols
- Added C wrapper for Basic::get_args
- Refactored CRCPBasic in C wrappers and tests
comments powered by Disqus