美文网首页
Make it works(4) Matlab编译为python

Make it works(4) Matlab编译为python

作者: 默而识之者 | 来源:发表于2020-05-03 20:56 被阅读0次

    0. 准备

    本文只讨论将matlab封装成python,并在docker中运行python脚本的情况

    要让matlab运行在docker里,你需要:

    • 在本机,你需要安装matlab和对应版本的matlab compiler runtime(简称mcc),在这里下载

    • 需要准备一个和你本机的matlab版本相同的MCC的Docker镜像,所幸有现成的,在这里

    1. 将matlab函数编译为python

    我的matlab运行于mac环境中,版本为2019b

    1. 封装函数

    没什么好说的,我在这里封装了一个名为algorithm的函数,再编写一个调用这个函数的脚本:


    2. 编译

    命令窗口输入deploytool,选择Library Compiler

    1. 选则TYPE框内的Python Package
    2. 点击EXPORTED FUNCTIONS框的➕,添加所需的函数(不要添加脚本,会提示错误)
    3. 在下方的Samples框内点击Add Existing Sample,添加编写的调用脚本(不添加sample不会影响生成,就是没有调用参考了,也没有生成编译后脚本的单元测试了)
    4. 点击Package按钮开始编译,一定要安装MCC才行,编译成功会自动打开成果文件夹,编译失败则会在在编译见面有惊叹号.

    3. 修改编译成果

    mcc在docker运行时需要LD_LIBRARY_PATH这个环境变量为/opt/mcr/v97/runtime/glnxa64:/opt/mcr/v97/bin/glnxa64:/opt/mcr/v97/sys/os/glnxa64:/opt/mcr/v97/extern/bin/glnxa64(matlab2019b),然而这个设置是侵入性的,这个环境变量会让相当数量的常用工具无法使用,所以需要修改一下生成的文件:
    在生成的包中__init__.py文件下,修改:

    PLATFORM_DICT = {'Windows': ['PATH','dll',''], 'Linux': ['LD_LIBRARY_PATH','so','libmw'], 'Darwin': ['DYLD_LIBRARY_PATH','dylib','libmw']}
    

    PLATFORM_DICT = {'Windows': ['PATH','dll',''], 'Linux': ['MYLD_LIBRARY_PATH','so','libmw'], 'Darwin': ['DYLD_LIBRARY_PATH','dylib','libmw']}
    

    就是把该环境变量指向一个我们自定义的位置

    2. 让编译后的脚本再docker下可用

    1. 文件结构

    • alogrithm/setup.py和alogrithm/alogrithm是编译后的包和其安装脚本
    • run.py是如何调用该包的脚本
    • run.sh是调用run.py的脚本

    2. Dockerfile

    FROM demartis/matlab-runtime:R2019b
    # 将所需的文件拷到指定目录,我这为了方便拷到了根目录
    COPY ./algorithm/  /
    # 给MYLD_LIBRARY_PATH这个我们自定义的环境变量赋值,供脚本安装时使用
    ENV MYLD_LIBRARY_PATH /opt/mcr/v97/runtime/glnxa64:/opt/mcr/v97/bin/glnxa64:/opt/mcr/v97/sys/os/glnxa64:/opt/mcr/v97/extern/bin/glnxa64
    # 将LD_LIBRARY_PATH指向正确的位置
    ENV LD_LIBRARY_PATH=/usr/lib
    # 1. 修改为国内源,并添加了一个源,里面有高版本python
    # 2. 一定要安装libpython3.7,否则无法运行脚本
    # 3. 最后一步因为安装了多个版本的python(2.7,3.7,3.8),所以要指定版本,因为matlab2019b不支持python3.8
    RUN sed -i s@/security.debian.org/@/mirrors.163.com/@g /etc/apt/sources.list && \
        sed -i s@/deb.debian.org/@/mirrors.163.com/@g /etc/apt/sources.list && \
        echo "deb http://mirrors.163.com/debian/ testing main">>/etc/apt/sources.list && \
        apt-get update && \
        apt-get install python3-distutils -y && \
        apt install --reinstall libpython3.7 && \
        apt-get clean && \
        rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \
        python3.7 /setup.py install
    

    3. 运行脚本

    run.py的内容与自动生成的sample内容一致

    import algorithm
    import matlab
    my_algorithm = algorithm.initialize()
    my_algorithm.algorithm("xxxx.xxx", nargout=0)
    my_algorithm.terminate()
    

    run.sh

    # 运行前先切换回来
    export LD_LIBRARY_PATH=/opt/mcr/v97/runtime/glnxa64:/opt/mcr/v97/bin/glnxa64:/opt/mcr/v97/sys/os/glnxa64:/opt/mcr/v97/extern/bin/glnxa64 && \
    python3.7 /run.py && \
    # 运行后再换回去
    export LD_LIBRARY_PATH=/usr/lib
    # ...做其他的事
    

    因为编译后的脚本调用的二进制库在使用时会用到LD_LIBRARY_PATH的内容,所以在调用脚本时需要换回来,调用结束后再恢复.

    相关文章

      网友评论

          本文标题:Make it works(4) Matlab编译为python

          本文链接:https://www.haomeiwen.com/subject/byvjghtx.html