我已经在一定程度上成功地将一个软件储存库(KPConv)进行了对接,我计划使用并扩展以下Dockerfile
FROM tensorflow/tensorflow:1.12.0-devel-gpu-py3
# Install other required python stuff
RUN apt-get update && apt install -y --fix-missing --no-install-recommends\
python3-setuptools python3-pip python3-tk
RUN pip install --upgrade pip
RUN pip3 install numpy scikit-learn psutil matplotlib pyqt5 laspy
# Compile the custom operations and CPP wrappers
# For some reason this must be done within container, cannot access libcuda.so during docker build
# Ref: https://stackoverflow.com/questions/66575232
#COPY . /kpconv
#WORKDIR /kpconv/tf_custom_ops
#RUN sh compile_op.sh
#WORKDIR /kpconv/cpp_wrappers
#RUN sh compile_wrappers.sh
# Set the working directory to kpconv
WORKDIR /kpconv
# Set root user password so we can su/sudo later if need be
RUN echo "root:pass" | chpasswd
# Create a user and group akin to the host within the container
ARG USER_ID
ARG GROUP_ID
RUN addgroup --gid $GROUP_ID user
RUN adduser --disabled-password --gecos '' --uid $USER_ID --gid $GROUP_ID user
USER user
#Build
#sudo docker build -t kpconv-test \
# --build-arg USER_ID=$(id -u) \
# --build-arg GROUP_ID=$(id -g) \
# .在这个Dockerfile的末尾,我遵循了post 在这里发现的,它描述了一种正确设置容器中生成的文件的权限的方法,这样主机/用户就可以访问它们,而不必更改文件权限。
此外,这个软件库使用自定义tensorflow操作 in C++ (运维)和Python用于定制C++代码(包装纸)。KPConv的作者Thomas提供了一个bash脚本,它编译每个脚本以生成各种.so文件。
如果我在构建过程(COPY . /kpconv)期间将存储库放入映像中,启动容器,调用两个编译bash脚本,然后运行代码,然后Python正确地加载C++包装器(生成的.so grid_subsampling.cpython-35m-x86_64-linux-gnu.so),并开始按预期/预期的方式运行软件。
$ sudo docker run -it \
> -v /<myhostpath>/data_sets:/data \
> -v /<myhostpath>/_output:/output \
> --runtime=nvidia kpconv-test /bin/bash
user@eec8553dcb5d:/kpconv$ cd tf_custom_ops
user@eec8553dcb5d:/kpconv/tf_custom_ops$ sh compile_op.sh
user@eec8553dcb5d:/kpconv/tf_custom_ops$ cd ..
user@eec8553dcb5d:/kpconv$ cd cpp_wrappers/
user@eec8553dcb5d:/kpconv/cpp_wrappers$ sh compile_wrappers.sh
running build_ext
building 'grid_subsampling' extension
<Redacted for brevity>
user@eec8553dcb5d:/kpconv/cpp_wrappers$ cd ..
user@eec8553dcb5d:/kpconv$ python training_ModelNet40.py
Dataset Preparation
*******************
Loading training points
1620.2 MB loaded in 0.6s
Loading test points
411.6 MB loaded in 0.2s
<Redacted for brevity>这是很好的工作,并允许我运行KPConv软件。
另外,为了以后的工作,.so文件有哈希
user@eec8553dcb5d:/kpconv/cpp_wrappers/cpp_subsampling$ sha1sum grid_subsampling.cpython-35m-x86_64-linux-gnu.so
a17eef453f6d2370a15bc2a0e6714c978390c5c3 grid_subsampling.cpython-35m-x86_64-linux-gnu.so它还具有以下权限
user@eec8553dcb5d:/kpconv/cpp_wrappers/cpp_subsampling$ ls -al grid_subsampling.cpython-35m-x86_64-linux-gnu.so
-rwxr-xr-x 1 user user 561056 Mar 14 02:16 grid_subsampling.cpython-35m-x86_64-linux-gnu.so虽然它产生了一个难以快速编辑和软件的工作流程,但为了我的目的,并在容器中快速运行它。对代码的每一项更改都需要新的映像构建。因此,我更愿意在运行时将KPConv代码从主机加载/卷到容器中,然后编辑在容器中运行时处于“活动”状态。
这样做,并使用帖子顶部的Dockerfile (不包括COPY . /kpconv)编译映像,执行相同的编译步骤,并运行代码
$ sudo docker run -it \
> -v /<myhostpath>/data_sets:/data \
> -v /<myhostpath>/KPConv_Tensorflow:/kpconv \
> -v /<myhostpath>/_output:/output \
> --runtime=nvidia kpconv-test /bin/bash
user@a82e2c1af21a:/kpconv$ cd tf_custom_ops/
user@a82e2c1af21a:/kpconv/tf_custom_ops$ sh compile_op.sh
user@a82e2c1af21a:/kpconv/tf_custom_ops$ cd ..
user@a82e2c1af21a:/kpconv$ cd cpp_wrappers/
user@a82e2c1af21a:/kpconv/cpp_wrappers$ sh compile_wrappers.sh
running build_ext
building 'grid_subsampling' extension
<Redacted for brevity>
user@a82e2c1af21a:/kpconv/cpp_wrappers$ cd ..
user@a82e2c1af21a:/kpconv$ python training_ModelNet40.py 我收到下面的Python ImportError
user@a82e2c1af21a:/kpconv$ python training_ModelNet40.py
Traceback (most recent call last):
File "training_ModelNet40.py", line 36, in <module>
from datasets.ModelNet40 import ModelNet40Dataset
File "/kpconv/datasets/ModelNet40.py", line 40, in <module>
from datasets.common import Dataset
File "/kpconv/datasets/common.py", line 29, in <module>
import cpp_wrappers.cpp_subsampling.grid_subsampling as cpp_subsampling
ImportError: /kpconv/cpp_wrappers/cpp_subsampling/grid_subsampling.cpython-35m-x86_64-linux-gnu.so: failed to map segment from shared object为什么C++的这个Python包装器只能在将代码复制到坞库映像时使用,而不能通过卷挂载?
此.so文件具有与第一次描述的情况相同的哈希和权限。
user@a82e2c1af21a:/kpconv/cpp_wrappers/cpp_subsampling$ sha1sum grid_subsampling.cpython-35m-x86_64-linux-gnu.so
a17eef453f6d2370a15bc2a0e6714c978390c5c3 grid_subsampling.cpython-35m-x86_64-linux-gnu.so
user@a82e2c1af21a:/kpconv/cpp_wrappers/cpp_subsampling$ ls -al grid_subsampling.cpython-35m-x86_64-linux-gnu.so
-rwxr-xr-x 1 user user 561056 Mar 14 02:19 grid_subsampling.cpython-35m-x86_64-linux-gnu.so在我的主机上,该文件具有以下权限(它位于主机上,因为/kpconv是作为卷挂载的)(由于某种原因,容器将来也是如此,请检查时间戳)
$ ls -al grid_subsampling.cpython-35m-x86_64-linux-gnu.so
-rwxr-xr-x 1 <myusername> <myusername> 561056 Mar 13 21:19 grid_subsampling.cpython-35m-x86_64-linux-gnu.so在对错误消息进行了一些研究之后,看起来每个结果都是特定于某一情况的。尽管大多数人似乎都提到了错误是某种权限问题的结果。
我认为这个Unix&Linux堆栈回答为实际问题提供了答案。但是,我在大学里和C++一起实习的日子太远了,我不知道如何用它来解决这个问题。但我认为问题在于容器和主机之间以及用户对每个用户之间的权限(即容器上的根,容器上的user (Dockerfile),主机上的根,主机上的<myusername> )。
我还试图首先使用Dockerfile中创建的根密码来提升容器中的权限,然后编译代码并运行软件。但这也导致了同样的问题。我还尝试将代码编译为容器中的user,但将软件作为root运行,同样存在同样的问题。
因此,我发现并提供的另一条线索是,当编译“仅在”容器内(没有.so )和在--volume中编译它时(因此我试图比较文件哈希)时,似乎与--volume有一些不同。所以,可能不是那么多的权限,但是内核是如何在容器中加载.so的,或者它在--volume中的位置如何影响加载过程?
编辑:对于SSCCE,您应该能够将链接的存储库克隆到您的计算机上,并使用相同的文件。您不需要指定/data或/output卷,也不需要以任何方式更改代码(它试图在加载数据之前加载.so (这只会导致错误并结束执行))
如果您没有GPU或不想使用nvidia-runtime,您应该能够将Dockerfile基映像更改为tensorflow:1.12.0-devel-py3并在CPU上运行代码。
发布于 2021-03-14 05:36:42
您的问题是由试图动态加载库的链接器造成的。这可能有几个根本原因:
noexec安装也会阻止加载库。ldd grid_subsampling.cpython-35m-x86_64-linux-gnu.so和ldd -r -d -v grid_subsampling.cpython-35m-x86_64-linux-gnu.so检查所有链接的库。https://stackoverflow.com/questions/66620589
复制相似问题