Spring Break
25 Mar 2018The week prior was Spring Break.
Much of my time was spent reading through the MATLAB documentation for the function call in particular, that was causing the bug I was having. There was some ambiguity as to which library the function was being invoked from as I found multiple libraries with that function name in the documentation, and even for the ones that seemed the most likely, the function was overloaded such that it could take many different types of parameters. In addition, to this I was receiving build waring about typing, which I suspect were related.
I was at a point where I felt fairly confident that my bug was a version compatibility issue, but in order to resolve it I would need to reverse engineer the tool-box I was using and given that this could take weeks, I decided it was likely better to stop chasing this rabbit hole, and continue my exportation proof of concept with other code that was more integral to the project. As such I spoke with my team members and will continue my attempts to integrate with one of their tools.
I spent this week continuing to investigate the error I ran into last week. Initially I attempted to examine the settings of the MATLAB Runtime library, and go through the documentation relating to them, but I couldn’t find anything to resolve the error.
Eventually I went back to the figurative “drawing board”, and decided to examine my code in the MATLAB IDE so see if there was anything thing in my odd code that looked like it could be causing the error. In hindsight it feels obvious (although I spent hours before I figured it out), it turned out that since I developed much of the code I was using previously over the summer, it had been done in a previous version of MATLAB. Unsurprisingly, when I attempted to run the current in the more recent version on MATLAB (the same version as the runtime) it crashed. Okay that was a surprisingly simple explanation. The next step was to find where in my code it was crashing (and why). I had been building of off the the GLOAT toolbox, and the line in question was a built in MATLAB function, which appears to have changed the expected types of its parameters between versions.
I’ve begun to work on exporting some of the existing code, starting with the code that I wrote. The first steps were to go through it and modify it so that the return values were simply the raw results (array of classification) as opposed to manipulating those results to plot them in various ways. The idea being that the data presentation can be handled in Matplotlib, which integrates with Tkinter more easily.
From the MATLAB side of things those modifications / refactoring for modularity have been implemented. However, when I attempt to follow the same process as last week to export it, I run into the following error:
>>> import detectVoice
Exception caught during initialization of Python interface. Details: Could not find an appropriate directory for MATLAB or the MATLAB runtime in LD_LIBRARY_PATH. Details: libmwmclmcrrt.so.9.0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "detectVoice/__init__.py", line 275, in <module>
_pir.get_paths_from_os()
File "detectVoice/__init__.py", line 180, in get_paths_from_os
self.path_var, file_to_find))
RuntimeError: Could not find an appropriate directory for MATLAB or the MATLAB runtime in LD_LIBRARY_PATH. Details: libmwmclmcrrt.so.9.0
>>>
I’m not yet sure exactly what it refers to. I have a suspicion it relates to some setting of the MATLAB runtime, but am still working on figuring it out.
After over a month of struggling with the MATLAB framework and finding and importing the correct, I’ve finally managed to be able to export MATLAB code and imported it as a module that I can call from python. This path allows for MATLAB code to be exported to a collection of files that can be compiled into a python module which can be used to call MATLAB functions and run them on the MATLAB Runtime Engine. I’ve only tested this on Ubuntu, however it appears that the Runtime Engine can be installed royalty free on Mac, Windows, and Linux systems.
Consider the following simple MATLAB script “hello_world.m”:
function hello_world
fprintf('Hello, World!\n')
end
We will go through the steps required to be able to call this from python.
### Note: This process has the following dependencies:
First launch the MATLAB application “libraryCompiler”. In the pop-up window select Python Package and add the hello_world.m script to the exported functions list.
Using a terminal navigate into the produced directory and into the for_redistribution_files_only directory. In this case from my parent directory
$ cd hello_world/for_redistribution_files_only
Now install the module with the command:
$ python setup.py install
or, depending on your computer’s permissions you will likely have to sudo it.
$ sudo python setup.py install
Now we have to set the environment variable “LD_LIBRARY_PATH” on Linux (or “PATH” on Windows and “DYLD_LIBRARY_PATH”) on Mac. If these are not set we will get the following error:
>>> import hello_world
Exception caught during initialization of Python interface. Details: On Linux, you must set the environment variable "LD_LIBRARY_PATH" to a non-empty string. For more details, see the package documentation.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "hello_world/__init__.py", line 276, in <module>
_pir.get_paths_from_os()
File "hello_world/__init__.py", line 171, in get_paths_from_os
friendly_os_name, self.path_var, 'For more details, see the package documentation.'))
RuntimeError: On Linux, you must set the environment variable "LD_LIBRARY_PATH" to a non-empty string. For more details, see the package documentation.
>>>
We want to set the “LD_LIBRARY_PATH” environment variable to the path in which the MATLAB Runtime is installed. For me this became:
$ export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/MATLAB/MATLAB_Runtime/v93/runtime/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v93/bin/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v93/sys/os/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v93/sys/opengl/lib/glnxa64
Now we should be able to successfully import the module, without errors.
>>> import hello_world
>>>
We are almost able run our function. We simply need to initialize the MATLAB Runtime, which is shown in lines 2 and 3 below.
>>> import hello_world
>>> hello_world.initialize_runtime(['-nojvm', '-nodisplay'])
>>> ms = hello_world.initialize()
>>> ms.hello_world(nargout=0)
Hello, World!
>>>
Yay! Success! We can export MATLAB code to python applications. The next steps for me will be to export mine and the labs MATLAB code so that I can integrate them into the GUI I’m building.