允许在 python、pypar 和 mpich2 中对 shelve 对象进行 pickle

发布于 2024-10-21 02:49:46 字数 199 浏览 2 评论 0原文

我有一些遗留的 python 代码,使用 pypar 和 mpich2 在多个节点之间传输数据。由于某种原因,数据保存在架子中,并且 pypar 希望对架子进行 pickle 以将其发送到其他节点。不允许酸洗货架。所以我想从搁置转换为可以通过 pypar 发送的东西,在发送到其他节点之前将其腌制。有什么建议吗?我可以将 shelve 转换为 json 并对其进行 pickle 吗?

I have some legacy python code that using pypar and mpich2 to transmit data between multiple nodes. For some reason the data is kept in shelves and pypar wants to pickle the shelve to send it to other nodes. Pickling shelves is not allowed. So I want to convert from shelve to something I can send via pypar which pickles it before sending to other nodes. Any suggestions? Could I convert the shelve to json and pickle that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

后来的我们 2024-10-28 02:49:46

尝试将架子转换为 dict(),然后对其进行腌制:

sdb = shelve.open('foo.db')
sdb['abc'] = {'a': 1, 'b': 2}
tmp = cPickle.dumps(dict(sdb), 2)
print cPickle.loads(tmp)
{'abc': {'a': 1, 'b': 2}}

更新:(回复评论中的问题):dict 可以复制来自任何映射对象的键值,因此如果该对象实现了 keys__getitem__ 方法,它将起作用。由于 shelve 是一个映射对象,因此 dict 复制构造函数可以从 shelve 读取键值,然后您可以 pickle 生成的 dict 并将其发送到其他主机。

下面的示例显示了复制对象所需的最小接口 dict

class Foo(object):

    def __init__(self):
        self.value = 0

    def keys(self):
        return ['a', 'b']

    def __getitem__(self, key):
        v = self.value
        self.value += 1
        return self.value

foo = Foo()
print dict(foo)
print dict(foo)

输出

{'a': 1, 'b': 2}
{'a': 3, 'b': 4}

Update:要将 dict 的内容添加回架子,请使用 update() :

d = {'a': 1, 'b': 2}
s = shelve.open('foo.db')
s.update(d)
print s
{'a': 1, 'b': 2}

Try converting the shelve to a dict() and then pickling it:

sdb = shelve.open('foo.db')
sdb['abc'] = {'a': 1, 'b': 2}
tmp = cPickle.dumps(dict(sdb), 2)
print cPickle.loads(tmp)
{'abc': {'a': 1, 'b': 2}}

Updated: (Response to a question in comments): A dict can copy the key-values from any mapping object, so if that object implements the methods keys and __getitem__ it will work. Since a shelve is a mapping object, the dict copy constructor can read the key-values from the shelve, then you can pickle the resulting dict and ship it to other hosts.

The example below shows the minimal interface dict requires to copy an object:

class Foo(object):

    def __init__(self):
        self.value = 0

    def keys(self):
        return ['a', 'b']

    def __getitem__(self, key):
        v = self.value
        self.value += 1
        return self.value

foo = Foo()
print dict(foo)
print dict(foo)

Output

{'a': 1, 'b': 2}
{'a': 3, 'b': 4}

Update: To add the contents of a dict back to a shelve, use update():

d = {'a': 1, 'b': 2}
s = shelve.open('foo.db')
s.update(d)
print s
{'a': 1, 'b': 2}
岁月静好 2024-10-28 02:49:46

@samplebias 的建议< /a> 将你的 shelve 对象转换为 dict 将会起作用。

但是,(这可能不太可能,但是)考虑到您的数据已经搁置到数据库文件中,可能值得检查让其他节点从搁置文件加载数据是否更快进行 MPI 发送。我假设所有节点都可以访问相同的文件系统,因为您使用 MPI 运行它们。

老实说,我希望 MPI 发送速度更快,尤其是在共享内存系统上运行时,因为许多 MPI 实现将回退到内存副本。然而,一旦将发送的重新酸洗和取消酸洗的开销包括在内,比赛可能会很接近!

我怀疑这将取决于您运行它的节点数量以及您的通信模式。

@samplebias's suggestion of converting your shelve object to a dict will work.

However, (this may be a long shot but) considered your data is already shelved to a db file, it might be worth checking if it is faster to have the other nodes load data off the shelve file instead of doing MPI sends. I'm assuming all nodes have access to the same filesystem since you're running them using MPI.

To be honest, I'd expect the MPI send to be faster especially if you're running on a shared-memory system since many MPI implementations will fallback to a memory copy. However, once you include the overheads of repickling and unpickling for the send, the race might be close!

I suspect it will be down to the number of nodes you're running it on, and your communication pattern.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文