首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ImportError: libmpi.so.12:无法打开共享对象文件:没有这样的文件或目录

ImportError: libmpi.so.12:无法打开共享对象文件:没有这样的文件或目录
EN

Stack Overflow用户
提问于 2021-11-11 15:04:12
回答 1查看 892关注 0票数 1

我想加载一个自定义Python模块dataloader,它利用了mpi4py库。我的代码会引发ImportError: libmpi.so.12: cannot open shared object file: No such file or directory

跟踪错误:

代码语言:javascript
运行
复制
> --------------------------------------------------------------------------- ImportError                               Traceback (most recent call
> last) /tmp/ipykernel_10920/2839973880.py in <module>

> ----> 6 from whole_slide_cnn.dataloader import WholeSlideDataloader, MILDataloader
> 
> ~/CODEX/whole-slide-cnn/whole_slide_cnn/dataloader.py in <module>
> ----> 3 from mpi4py import MPI
> 
> ImportError: libmpi.so.12: cannot open shared object file: No such
> file or directory

木星笔记本

代码语言:javascript
运行
复制
! conda install -c conda-forge mpi4py
from whole_slide_cnn.dataloader import WholeSlideDataloader, MILDataloader

whole_slide_cnn.dataloader.py

代码语言:javascript
运行
复制
from mpi4py import MPI

class WholeSlideDataloader(tf.keras.utils.Sequence):
    def __init__(
        self, 
        dataset,
        augment,
        shuffle,
        num_classes,
        batch_size=1,
        snapshot_path=None,
        hvd=None,
    ):
        self.dataset = dataset
        self.augment = augment
        self.shuffle = shuffle
        self.num_classes = num_classes
        self.batch_size = batch_size
        self.snapshot_path = snapshot_path
        self.hvd = hvd

        self._reinit_shuffle_list()

    def __len__(self):
        num_workers = self.hvd.size() if self.hvd != None else 1
        return len(self.dataset) // self.batch_size // num_workers

    def __getitem__(self, idx):
        begin_idx = idx * self.batch_size
        end_idx = (idx + 1) * self.batch_size

        x_batch = []
        y_batch = []
        for shuffle_list_idx in range(begin_idx, end_idx):
            dataset_idx = self.shuffle_list[shuffle_list_idx]
            loaded = False
            while not loaded:
                try:
                    img, label = self.dataset[dataset_idx]
                    loaded = True
                except Exception as e:
                    print(traceback.format_exc())
                    print(
                        "Error occurs while loading {} . Retry after 5 seconds.".format(
                            self.dataset.get_slide_path(dataset_idx)
                        )
                    )
                    time.sleep(5)

            if self.augment:
                if img.size < 4 * 1024 * 1024 * 1024:
                    img = _get_augmentor().augment_image(img)
                else:
                    # If the image is too large, imgaug will fail on affine transformation. Use PIL instead.
                    img = _get_augmentor_wo_affine().augment_image(img)
                    img = Image.fromarray(img)
                    angle = np.random.uniform(0.0, 360.0)
                    translate = tuple(np.random.randint(-220, 220, size=[2]))
                    img = img.rotate(angle, resample=Image.NEAREST, translate=translate, fillcolor=(255, 255, 255))
                    img = np.array(img)

            if self.snapshot_path != None:
                os.makedirs(self.snapshot_path, exist_ok=True)
                img_bgr = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
                cv2.imwrite(
                    os.path.join(self.snapshot_path, "dataloader_snapshot.tiff"),
                    img_bgr,
                )

            img = preprocess_input(img)
            y = np.zeros(shape=[self.num_classes])
            y[label] = 1.0
            
            x_batch.append(img)
            y_batch.append(y)

        return np.array(x_batch), np.array(y_batch)

    def on_epoch_end(self):
        self._reinit_shuffle_list()

    def get_slide_path(self, idx):
        dataset_idx = self.shuffle_list[idx]
        return self.dataset.get_slide_path(dataset_idx)

    def get_y_true(self, idx):
        dataset_idx = self.shuffle_list[idx]
        return self.dataset.get_y_true(dataset_idx)

    def get_dataset_idx(self, idx):
        return self.shuffle_list[idx]

    def _reinit_shuffle_list(self):
        self.shuffle_list = np.arange(len(self.dataset))
        if self.shuffle:
            np.random.shuffle(self.shuffle_list)
        if self.hvd != None:
            self.shuffle_list = MPI.COMM_WORLD.bcast(self.shuffle_list, root=0)

            num_workers = self.hvd.size()
            rank = self.hvd.rank()
            self.shuffle_list = [
                self.shuffle_list[idx * num_workers + rank]
                for idx in range(len(self))
            ]


class MILDataloader(WholeSlideDataloader):
    MIL_WHITE_THRESHOLD = 220
    MIL_EM_GAUSSIAN_KERNEL_SIZE = 3
    MIL_EM_P1 = 0.1
    MIL_EM_P2 = 0.05

    def __init__(
        self, 
        dataset,
        augment,
        shuffle,
        num_classes,
        mil_model,
        batch_size=1,
        snapshot_path=None,
        hvd=None,
        mil_patch_size=[224, 224],
        mil_infer_batch_size=32,
        mil_use_em=False,
        mil_k=1,
        mil_skip_white=True,
    ):
        super(MILDataloader, self).__init__(
            dataset=dataset,
            augment=augment,
            shuffle=shuffle,
            num_classes=num_classes,
            batch_size=batch_size,
            snapshot_path=snapshot_path,
            hvd=hvd,
        )
        self.mil_model = mil_model
        self.mil_patch_size = mil_patch_size
        self.mil_infer_batch_size = mil_infer_batch_size
        self.mil_use_em = mil_use_em
        self.mil_k = mil_k
        self.mil_skip_white = mil_skip_white
            
    def __getitem__(self, idx):
        x_batch_wsi, y_batch_wsi = super(MILDataloader, self).__getitem__(idx)

        x_batch = []
        y_batch = []
        for i in range(self.batch_size):
            x = x_batch_wsi[i]
            y = y_batch_wsi[i]

            num_patch_y = x.shape[0] // self.mil_patch_size[1]
            num_patch_x = x.shape[1] // self.mil_patch_size[0]

            mil_infer_dataset = []
            coords = []
            for i in range(num_patch_y):
                for j in range(num_patch_x):
                    sliced_x = x[
                        i * self.mil_patch_size[1]: (i + 1) * self.mil_patch_size[1],
                        j * self.mil_patch_size[0]: (j + 1) * self.mil_patch_size[0],
                        :,
                    ]
                    if (
                        self.mil_skip_white and 
                        np.min(sliced_x) > preprocess_input(self.MIL_WHITE_THRESHOLD)
                    ):
                        continue
                    mil_infer_dataset.append(sliced_x)
                    coords.append((j, i))
            mil_infer_dataset = np.array(mil_infer_dataset)

            mil_infer_res = []
            for begin_idx in range(0, len(mil_infer_dataset), self.mil_infer_batch_size):
                end_idx = np.minimum(len(mil_infer_dataset), begin_idx + self.mil_infer_batch_size)
                mil_infer_res.append(
                    self.mil_model.predict_on_batch(
                         mil_infer_dataset[begin_idx: end_idx]
                    )
                )
            mil_infer_res = np.concatenate(mil_infer_res, axis=0)
            benign_rate = mil_infer_res[:, 0]

            if not self.mil_use_em:
                top_k_indices = np.argsort(benign_rate)[0: self.mil_k]
                for index in top_k_indices:
                    x_batch.append(mil_infer_dataset[index])
                    y_batch.append(y)
            else:
                res_map = np.zeros([num_patch_y, num_patch_x, self.num_classes - 1]) # Excluding non-cancer
                for i in range(len(mil_infer_res)):
                    res = mil_infer_res[i]
                    coord = coords[i]
                    res_map[coord[1], coord[0], :] = res[1: ]

                res_map_blurred = cv2.GaussianBlur(
                    res_map, 
                    (self.MIL_EM_GAUSSIAN_KERNEL_SIZE, self.MIL_EM_GAUSSIAN_KERNEL_SIZE),
                    0
                )

                mil_infer_res_blurred = []
                for i in range(len(mil_infer_res)):
                    coord = coords[i]
                    res_blurred = res_map_blurred[coord[1], coord[0], :]
                    mil_infer_res_blurred.append(res_blurred)
                mil_infer_res_blurred = np.array(mil_infer_res_blurred)

                thres_p1 = np.percentile(mil_infer_res_blurred, 100.0 - self.MIL_EM_P1)

                select = None
                for class_id in range(1, self.num_classes):
                    candidates = mil_infer_res_blurred[:, class_id - 1].tolist()
                    if self.hvd != None:
                        candidates = MPI.COMM_WORLD.gather(candidates, root=0)
                        candidates = MPI.COMM_WORLD.bcast(candidates, root=0)
                        flatten = []
                        for candidate in candidates:
                            flatten += candidate
                        candidates = flatten
                    candidates = np.array(candidates)

                    thres_p2 = np.percentile(candidates, 100.0 - self.MIL_EM_P2)
                    thres = np.minimum(thres_p1, thres_p2)

                    if select is None:
                        select = mil_infer_res_blurred[:, class_id - 1] > thres
                    else:
                        select = np.logical_or(select, mil_infer_res_blurred[:, class_id - 1] > thres)

                no_selected = True
                for i in range(len(mil_infer_res_blurred)):
                    is_select = select[i]
                    if is_select:
                        x_batch.append(mil_infer_dataset[i])
                        y_batch.append(y)
                        no_selected = False

                if no_selected:
                    x_batch.append(mil_infer_dataset[np.argmin(benign_rate)])
                    y_batch.append(y)

        x_batch = np.array(x_batch) # The batch dimension is large as (self.batch_size * self.mil_k).
        y_batch = np.array(y_batch)

        if self.snapshot_path != None:
            os.makedirs(self.snapshot_path, exist_ok=True)
            img = inverse_preprocess_input(x_batch[0])
            img_bgr = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
            cv2.imwrite(
                os.path.join(self.snapshot_path, "mil_top_patch_snapshot.tiff"),
                img_bgr,
            )

        return x_batch, y_batch
EN

回答 1

Stack Overflow用户

发布于 2022-08-15 06:34:12

同样的问题,在Anaconda2021-11和使用mpi4py版本3.1.3 (通过conda安装)时,我得到

代码语言:javascript
运行
复制
Traceback (most recent call last):
  [...]
    from Utils.mpi import *
  [..]
    from mpi4py import MPI
ImportError: libmpi.so.12: cannot open shared object file: No such file or directory

但它曾经在较老的Anaconda版本下工作。似乎安装的mpi库版本(libmpi.so.40)与mpi4py想要的版本不匹配。

寻找版本12不能给我提示该做什么。

代码语言:javascript
运行
复制
$ find / -iname 'libmpi.so.*' 2>/dev/null 
find / -iname 'libmpi.so.*' 2>/dev/null 
/usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi.so.40.20.3
/usr/lib/x86_64-linux-gnu/libmpi.so.40
/usr/lib/x86_64-linux-gnu/libmpi.so.40.20.3
/home/xxx/.conda/pkgs/openmpi-4.0.2-hb1b8bf9_1/lib/libmpi.so.40
/home/xxx/.conda/envs/myy5/lib/libmpi.so.40
/home/xxx/.conda/envs/myy5/lib/libmpi.so.40.20.2
/opt/anaconda-2021.11/pkgs/mpich-3.3.2-hc856adb_0/lib/libmpi.so.12.1.8
/opt/anaconda-2021.11/pkgs/mpich-3.3.2-hc856adb_0/lib/libmpi.so.12

..that是,有一个libmpi.so.40,一些在用户安装的conda路径中(.conda/pkgs' and .conda/envs'),在系统路径中有一个正确的版本,用于我的anaconda 2021-11安装程序。

/opt/anaconda-2021.11/pkgs/mpich-3.3.2-hc856adb_0/lib/libmpi.so.12

但是,在此之前,我尝试了mpi4py的pip和conda安装(并且conda安装了系统范围和myy5环境),...so的结论在这里有点棘手。

在运行Anaconda时,仍然没有找到和加载在libmpi.so.12中找到的in库/opt/anaconda-2021.11/pkgs/mpich,而是在

/opt/anaconda-2021.11/lib

作为

代码语言:javascript
运行
复制
$ cd /opt/anaconda-2021.11/lib 
$ sudo ln -s /opt/anaconda-2021.11/pkgs/mpich-3.3.2-hc856adb_0/lib/libmpi.so.12

可能是一个临时的解决方案与警告,版本12和40可能不是100%兼容.

它曾经在我以前的设置中工作,版本-12的错误对我来说是新的(或者我忘记了之前为使它工作而应用的任何黑客.)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69930526

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档