将非内存连续的c / c ++数据包装为numpy数组

时间:2014-03-20 21:11:11

标签: python c++ arrays numpy swig

我有一个C ++类,为许多“粒子”提供数据接口(上下文是物理模拟)。每个粒子的数据都存储在一个结构中,该类有一个指向结构的指针数组。我真的不想搞乱这种存储方案,因为:

  • 数据以二进制格式存储在磁盘上,这不是我自己设计的,并且编写一个新函数来将文件读入其他存储结构并不简单。
  • 我有大量围绕相同数据存储方案设计的其他C / C ++代码,如果存储结构发生变化,这些代码将无法使用或需要进行大修。

现在,我想使用python进行一些可视化。理想的情况是可以访问我的数据作为numpy数组,所以我可以使用各种numpy函数(直方图,排序,分级,统计等)。我有一个使用SWIG的工作解决方案将我的类包装到Python中。缺点是我需要制作数据的部分副本(从埋在C ++类中的结构到numpy数组)。随着我对这些模拟工作的进展,我正在推动我的硬件施加的限制,这意味着我想将粒子数量推到数据占据可用内存的很大一部分的位置。因此,不惜一切代价避免复制。

有没有办法将numpy数组映射到这一堆混乱的数据上?一些探讨似乎指向一个“不”的答案,但如果我放松一点“无副本”要求并允许一些摆动空间来创建一个额外的指针数组怎么办?我会勾勒出我在想的东西:

struct particle_data
{
  double x[3];
  double vx[3];
  //more data
}

class Snap
{
  struct particle_data *P; //this gets allocated, so data is accessed as P[i].x[j] and so on
  //a bunch of other functions, flags, etc.
}

我在想的是我可以创建一个指针数组,例如

double **x0;
//of course allocate some memory for the array here...
for(int i=0; i<max; i++)
{
  x0 = &P[i].x[0]
}

并希望以某种方式让它在python中很好地发挥作为一个numpy数组的双打。如果我特别幸运的话,可以避免制作类似的数组x1和x2,因为x0 [i] +1 = x1 [i]和x0 [i] +2 = x2 [i]。

我不知道这是否可能或如何设置它。在一个完美的世界里,我可以坚持使用SWIG,但我有一种预感,如果可能的话,这将涉及自己写一些包装。

1 个答案:

答案 0 :(得分:1)

我会通过确定如何将C ++对象存储为数组来实现此目的。如果你能找到一种方法,那么通过SWIG将它暴露给Python将很容易。如果你甚至不能在C ++级别(可能没有办法做你想做的事情),那么你就无法继续前进。但是,您似乎认为应该有一个可用于表示数据的数组结构,因此首先在C ++中向该方向推送。一旦解决,大部分的战斗进入都会获胜。