Looking for support for adding new features of clustering algorithms in python-igraph

Dear all,

I am currently implementing new features based on an existing clustering algorithm in python-igraph. As I want to test and compare with original algorithm, I have to modify the python-igraph package.

I have added new c++ clustering function in vender/source/igraph/src and in vendor/source/igraph/include/igraph_community.h, but I am having problems with the graphobject.c file by adding new clustering function there.

Can I get any help regarding to wrapping c++ files into python-igraph package and any other files are linking python object with igraph object besides graphobject.c?

Thank you very much in advance.

Sofia

In principle you could copy and edit other clustering functions in graphobject.c. is there anything specific that is unclear in this file? Note that new functions should also be included in the header. Finally, functions are exposed in the actual graph object in __init__.py.

Thank you for your answer vtraag.

My question is not so clearly to the problem that I face with, one issue is that I have a PyObject *a = Py_False (a can be taken as False or True in Python function) and I want to change it into a igraph_bool_t object in graphobject.c, I don’t know how I can change Py_False/Py_True objects into igraph_bool_t;

another issue is that when the python function takes None as an input as a ATTRIBUTE_TYPE_VERTEX, then I got the error

python3: ../../../source/igraph/src/vector.pmt:923: igraph_vector_resize: Assertion `v != NULL' failed.

It might be useful to look at how to program C extensions for Python: see https://docs.python.org/3/c-api/index.html for the full reference.

There is no wrapper being used to wrap C code in Python; the C code is all manually integrated in Python. This may change in the future, but for now, it all has to be manually programmed. As said, most of it is in graphobject.c, but there are also some other files that you need to change.

igraph_bool_t is defined to be an int, so you need to use PyLong_AsLong to convert from a Python object to a long (and cast to igraph_bool_t). It might be more suitable to actually use PyBool_Check. Note that python-igraph also defines PyLong_AsInt, which explicitly checks whether the result fits an int, and if not raises an overflow error. If it is just argument passing, you may simply specify an int using i, see https://docs.python.org/3/c-api/arg.html.

I don’t fully understand your question regarding ATTRIBUTE_TYPE_VERTEX. It is defined to be 1: it is simply an argument to the attribute interface to either get/set vertex attributes or edge attributes.

Thanks for your reply vtraag. I am changing the clustering algorithm. I have done the changes in function c files and its related files also changed igraph_community.h and graphobject.c + init.py.

After I changed those files, I still have some issue with graphobject.c, one is that I added an new input parameter as PyObject *a = Py_False changed it into a igraph_bool_t, when I am debugging it in gdb, I have error in terms of igraph_vector_resize(), but it seems a bit weird for me, casting the igraph_bool_t into an igraph_vector_t. Maybe there are some files that I haven’t changed properly, I cannot figure it out. May I have some support on which functions are needed to modify for any changing the python-igraph?

I have done the same with igraph R package, my clustering function is working as expected. I think my problem with python-igraph is really on how the python interface is done which is still not clear to me.

Perhaps it would be useful if you point me to the exact code that you use? If you have it in GitHub (or another git repo) somewhere, that might make it easier to take a closer look.

Indeed, casting an igraph_bool_t to an igraph_vector_t is not expected to work.

I am still not very clear about how igraph c core files are linked with python interface. I have made changes on the C files in python-igraph/vendor/build/igraph and run make to compile all the igraph C files successfully.

1st question is after compiled igraph C source files, how to check and make sure that the python interface is linked with the latest compiled igraph files?

2nd question is regarding the debug of python-igraph. I have also changed the python calling functions in __init__.py, graphobject.c. I am running into errors shown in gdb python3, but I want to further debug in the C level, I am not sure what I should change in Makefile in /vendor/build/igraph/, "CFLAGS = -fPIC -I/usr/include/libxml2 -O3" or "CXXFLAGS = -fPIC -O3" or others for further showing errors of functions written in C or C++ in igraph.

3rd question is for re-build and re-install the modified python-igraph package, I just want to make sure I have the command correctly, I am using python3 setup.py build, and python3 setup.py install --user.

Thank you for your suggestions and help on my questions.

There are two ways to compile the Python interface for igraph:

  1. You compiled using the vendored igraph source files (i.e. located in vendor/source/igraph), which is the default. When you run python setup.py build it automatically builds the igraph library from the vendored igraph source files in the background.

  2. You compile the igraph library separately yourself, and then build the python-igraph library separately and link it to the separate igraph library. If you compiled and installed the igraph library separately (using the typical ./configure, make and make install steps) you should be able to build python-igraph by running python setup.py build --use-pkg-config. This force the Python interface to link to the provided library using pkg-config (assuming you have this installed).

It might make sense to first make sure that you are able to compile the provided source packages yourself, before seeing how you can make changes to this package? It is difficult to answer your second question with a bit more details. But first making sure that you compile/build the source package, might clarify a number of these issues.

Following @vtraag instruction for the installation. Here I write down a bit more detailed steps for those who may be interested in locally installation without changing anything in the shared environment for the development:

Step 1. C source compilation on local stored python package directory:
./configure --exec-prefix=/loc/dir/python-packages --prefix=/loc/dir/python-packages
make
make install

Step 2.
export PKG_CONFIG_PATH=/loc/dir/python-packages/lib/pkgconfig
pkg-config --cflags --libs igraph (make sure you have a folder called lib/pkgconfig under the local python package directory)

Step 3. build python-igraph
python3 setup.py build --use-pkg-config
python3 setup.py install --user (not sudo user)

Thank you for the detailed information on the igraph C compilation and python-igraph building. It is very helpful. Finally, I managed to successfully install both C source and python-igraph.

Now, it comes to the questions about debug. When I added new parameters of a clustering algorithm in graphobject.c file, how to check if the input parameters have been interpreted from Python interface to C objects used in igraph C source file?

For example, I am trying to print out the igraph_vector_t *v_ws values in graphobject.c:
PyObject *v_weights = Py_None;
igraph_vector_t *v_ws = NULL;

for (int i= 0; i < igraph_vcount(&self->g); i++){
printf(VECTOR(*v_ws)[i]);
}

if (igraphmodule_attrib_to_vector_t(v_weights, self, &v_ws, ATTRIBUTE_TYPE_VERTEX)){
igraph_vector_destroy(&membership);
igraphmodule_handle_igraph_error();
return NULL;
}

I got an error of “/igraph_vector_pmt.h:61:19: error: incompatible type for argument 1 of ‘printf’ #define VECTOR(v) ((v).stor_begin)”;

It would be very helpful to have any suggestions or information on the process of debugging.