安装Yosemite后,我不得不升级numpy,PyOpenGL等。
现在,一个以前工作的程序给了我以下堆栈跟踪:
file "latebind.pyx", line 44, in OpenGL_accelerate.latebind.Curry.__call__ (src/latebind.c:1201)
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/OpenGL/GL/VERSION/GL_1_5.py", line 89, in glBufferData
return baseOperation( target, size, data, usage )
File "latebind.pyx", line 32, in OpenGL_accelerate.latebind.LateBind.__call__ (src/latebind.c:989)
File "wrapper.pyx", line 314, in OpenGL_accelerate.wrapper.Wrapper.__call__ (src/wrapper.c:6505)
File "wrapper.pyx", line 311, in OpenGL_accelerate.wrapper.Wrapper.__call__ (src/wrapper.c:6439)
ctypes.ArgumentError: ("argument 3: <class 'OpenGL.error.CopyError'>: from_param received a non-contiguous array! []", (GL_ARRAY_BUFFER, 0, array([],
dtype=[('time', '<f8'), ('data', [('cluster_index', '<i4'), ('delta_diag_out', '<f8')])]), GL_STREAM_DRAW))
看起来PyOpenGL希望我的数组是连续的。查看PyOpenGL中numpy_formathandler.pyx中的源代码:
if not PyArray_ISCARRAY( instance ):
raise CopyError(
"""from_param received a non-contiguous array! %s"""%(
working,
)
)
和PyArray_ISCARRAY(arr)“如果arr的数据区域是C风格连续的,并且PyArray_ISBEHAVED(arr)为真,则求值为true。”因此“PyArray_ISBEHAVED(arr) 如果arr的数据区域是对齐且可写的,则根据其描述符以机器字节顺序进行评估。“
但是,推送到OpenGL的数组的flags
属性是:
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : False
WRITEABLE : True
ALIGNED : False
UPDATEIFCOPY : False
也许我需要对齐阵列?但是将numpy.require
与requirements={'ALIGNED': True}
一起使用似乎不起作用。
我看了numpy 1.9中的变化,表明:
有一个新的编译时环境变量 NPY_RELAXED_STRIDES_CHECKING。如果此变量设置为1,则为numpy 将更多的数组视为C-或F-连续 - 例如,它 变得可能有一个被认为是C-的列向量 并且F-连续同时。新定义更准确, 允许更快的代码,减少不必要的副本,以及 在内部简化numpy的代码。但是,它也可能会破裂 第三方图书馆对此做出过于强烈的假设 C和F连续阵列的步幅值。 (现在也是 已知这将使用内存视图中断Cython代码,这将是 在Cython中修复。)这将成为未来发布的默认,所以 请您现在测试您的代码以防止错误:
NPY_RELAXED_STRIDES_CHECKING = 1个python setup.py install
你可以检查一下 是否通过运行NPY_RELAXED_STRIDES_CHECKING生效:
np.ones((10,1),order =“C”)。flags.f_contiguous
如果是,那将是真的 启用轻松步幅检查,否则返回False。典型的 到目前为止我们看到的问题是与C-contiguous一起使用的C代码 数组,并假设可以通过查看来访问itemsize PyArray_STRIDES(arr)数组中的最后一个元素。放松的时候 大步是有效的,这不是真的(事实上,它从来没有 在某些角落情况下是真的)。相反,请使用PyArray_ITEMSIZE(arr)。
但是,np.ones((10, 1), order="C").flags.f_contiguous
在我的系统上为False。所以我很难过。改变了什么导致opengl认为我发送的数组不是连续的和对齐的?有没有办法用力对齐数组?