peterwittek / somoclu

Massively parallel self-organizing maps: accelerate training on multicore CPUs, GPUs, and clusters
https://peterwittek.github.io/somoclu/
MIT License
268 stars 70 forks source link

errors importing native C library (python 3.8.6 & swig 4.0.1) #159

Closed tomcucinotta closed 3 years ago

tomcucinotta commented 3 years ago

Hi, I'm recompiling somoclu on Ubuntu 20.10, with python 3.8.6, and I'm having this problem

$ find /usr/local/lib/python3.8/dist-packages/ | grep somoclu /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/somoclu /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/somoclu/train.py /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/somoclu/init.py /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/somoclu/pycache /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/somoclu/pycache/init.cpython-38.pyc /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/somoclu/pycache/train.cpython-38.pyc /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/somoclu/pycache/somoclu_wrap.cpython-38.pyc /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/somoclu/somoclu_wrap.py /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/_somoclu_wrap.cpython-38-x86_64-linux-gnu.so /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/_somoclu_wrap.py /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/EGG-INFO /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/EGG-INFO/not-zip-safe /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/EGG-INFO/PKG-INFO /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/EGG-INFO/native_libs.txt /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/EGG-INFO/top_level.txt /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/EGG-INFO/dependency_links.txt /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/EGG-INFO/requires.txt /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/EGG-INFO/SOURCES.txt /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/pycache /usr/local/lib/python3.8/dist-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/pycache/_somoclu_wrap.cpython-38.pyc

tomcucinotta commented 3 years ago

tracked down to swig (4.0.1-5build1) generating a somoclu_wrap.py with these lines

# Import the low-level C/C++ module
if __package__ or "." in __name__:
    from . import _somoclu_wrap
else:
    import _somoclu_wrap

if I get rid of the "from ." and just do "import __somoclu_wrap", then I can import somoclu from python.

But this is not an area I'm familiar with, at all!

tomcucinotta commented 3 years ago

Ubuntu 20.10 has a means for downgrading swig:

sudo apt-get purge swig*
sudo apt-get install swig3.0

# this is needed otherwise make python won't find swig
sudo ln -s /usr/bin/swig3.0 /usr/bin/swig

then, after recompiling (make python) and installing (sudo make python_install), it imports correctly.

The code to find the native C library in the same auto-generated somoclu_wrap.py is now a hell of code:

from sys import version_info as _swig_python_version_info
if _swig_python_version_info >= (2, 7, 0):
    def swig_import_helper():
        import importlib
        pkg = __name__.rpartition('.')[0]
        mname = '.'.join((pkg, '_somoclu_wrap')).lstrip('.')
        try:
            return importlib.import_module(mname)
        except ImportError:
            return importlib.import_module('_somoclu_wrap')
    _somoclu_wrap = swig_import_helper()
    del swig_import_helper
elif _swig_python_version_info >= (2, 6, 0):
    def swig_import_helper():
        from os.path import dirname
        import imp
        fp = None
        try:
            fp, pathname, description = imp.find_module('_somoclu_wrap', [dirname(__file__)])
        except ImportError:
            import _somoclu_wrap
            return _somoclu_wrap
        try:
            _mod = imp.load_module('_somoclu_wrap', fp, pathname, description)
        finally:
            if fp is not None:
                fp.close()
        return _mod
    _somoclu_wrap = swig_import_helper()
    del swig_import_helper
else:
    import _somoclu_wrap

Any clue as to how to get this working on the latest swig and avoid this nightmare on recent distros ?

Thanks!

xgdgsc commented 3 years ago

I tested in a anaconda python 3.8 env with swig 4 installed from anaconda in ubuntu 20.04. After building and installing. cd /home/user/anaconda3/envs/p38/lib/python3.8/site-packages/somoclu-1.7.5-py3.8-linux-x86_64.egg/ and cp _somoclu_wrap.cpython-38-x86_64-linux-gnu.so _somoclu_wrap.py somoclu seems to work (only when cd in this directory).

xgdgsc commented 3 years ago

From digging some swig github issues I found this seems to work. You can test.