小编ajc*_*ajc的帖子

Python 绑定的 RPATH 传播失败

onnxruntime我正在构建一个在底层使用的库(Ubuntu 22) 。反过来,onnxruntime使用 CUDA,动态加载一些专用的“后端”。我构建了除 CUDA 库之外的整个代码堆栈,并且没有一个库具有其RPATHRUNPATH设置(使用 进行双重检查readelf -d)。

我构建了两个应用程序,一个是 C++,并直接链接到我的库。该应用程序有其RPATH设置,一切正常。如果我运行它,LD_DEBUG=libs我会看到类似这样的内容(请注意,路径已被编辑,并且我仅显示调试输出的一小部分):

    158834:     calling init: .../install/bin/../lib/libonnxruntime_providers_cuda.so
    158834:
    158834:     find library=libcudnn_ops_infer.so.8 [0]; searching
    158834:      search path=.../install/bin/../lib         (RPATH from file .../install/bin/test)
    158834:       trying file=.../install/bin/../lib/libcudnn_ops_infer.so.8
    158834:
    158834:
    158834:     calling init: .../install/bin/../lib/libcudnn_ops_infer.so.8
    158834:
Run Code Online (Sandbox Code Playgroud)

这就是我所期待的,我很高兴。

但是,我还需要通过一些链接到它的 python 绑定来使用相同的库。为了让它工作,我需要在这种情况下设置RPATHpython 绑定(至少在我看来,它只是一个在运行时加载的共享库)。请注意,Python 可执行文件既没有RPATH也没有RUNPATH设置。这仅部分有效。也就是说,RPATH传播似乎在沿着依赖关系树向下移动时起作用,直到开始搜索 CUDA 库,此时它不再起作用。这是以相同的方式、相同的构建运行完全相同的 onnxruntime API,并在与上面相同的文件夹中使用相同的文件。唯一的区别是 python 扩展层。输出LD_DEBUG如下所示:

    159602:     find library=libonnxruntime.so.1.15.1 [0]; searching
    159602:      search path=.../install/lib/../lib …
Run Code Online (Sandbox Code Playgroud)

c++ linux rpath dlopen python-bindings

5
推荐指数
1
解决办法
291
查看次数

在 Cython 中并行化“for”循环:超越 prange

我正在努力使用 Cython 正确并行化函数。基本上,问题是对一些数据进行分类。实际代码有点长,但最终它做了这样的事情:

def bin_var(double[:] dist,
            double[:] values,
            double[:] bin_def,
            double[:] varg, long[:] count):

    dbin = (bin_def[1] - bin_def[0]) / bin_def[2]

    for n1 in range(values.size):
            if (dist[n1] < bin_def[0]) or (dist[n1] >= bin_def[1]):
                continue
            else:
                ni = int((dist - bin_def[0]) / dbin)
                count[ni] += 1
                varg[ni] += calc_something(values[ni])

    # Compute the mean
    for n1 in range(int(bin_def[2])):
        varg[ni] /= count[ni]
Run Code Online (Sandbox Code Playgroud)

该代码适合一些简单的并行化(values并且dist非常大):需要将第一个for循环拆分为单独的进程,每个进程都处理自己版本的countvarg数组。完成后,必须通过对第二个for循环(更短)之前的count和的不同版本求和来将所有内容组合在一起。varg

也就是说,我花了两天时间试图了解如何在 Cython 中有效地实现这一点,并且我开始怀疑当前版本的语言是不可能的。请注意,仅在第一个循环中使用prangefrom …

multithreading multiprocessing cython python-multiprocessing

3
推荐指数
1
解决办法
606
查看次数

Python enum.Enum 创建别名而不是新值

我刚刚注意到 pyhton 中 Enum+defaultdict 的一个非常奇怪的行为。我定义了一个这样的枚举,它收集一些默认字典:

from enum import Enum
from collections import defaultdict

class A(Enum):
     a = defaultdict(lambda: 1)
     b = defaultdict(lambda: 2)
Run Code Online (Sandbox Code Playgroud)

然后,当我查看 A 里面的内容时:

In [11]: A.a
Out[11]: <A.a: defaultdict(<function A.<lambda> at 0x7f773f03b510>, {})>

In [12]: A.b
Out[12]: <A.a: defaultdict(<function A.<lambda> at 0x7f773f03b510>, {})>
Run Code Online (Sandbox Code Playgroud)

SoA.b只是 的别名A.a。对我来说,这看起来很像一个错误,即使背后可能有一些充分的理由。任何想法?

附录

由于它出现在评论中,因此需要说明为什么要在枚举中放入字典。我发现将常量分组到命名空间中通常很有用,这样就可以访问A.a.constant1A.b.constant1等值。目前,尝试使用 Enums 执行此操作会引发AttributeError. 当然,人们可以这样做:

class A:
    class a(Enum):
        constant1 = 1
    class b(Enum):
        constant1 = 2
Run Code Online (Sandbox Code Playgroud)

然而,这并没有利用 Enum 的功能(迭代、访问__getitem__等)。

python enums alias defaultdict

3
推荐指数
1
解决办法
3583
查看次数