我想创建numpy.ndarray包含复杂整数值的对象.NumPy确实内置了复杂的支持,但仅适用于浮点格式(float和double); 例如,我可以创建一个ndarraywith dtype='cfloat',但没有类似的东西dtype='cint16'.我希望能够创建包含使用8位或16位整数表示的复数值的数组.
我从2007年发现了这个邮件列表帖子,有人询问了这种支持.他们建议的唯一解决方法是定义一个dtype包含整数对的new .这似乎将每个数组元素表示为2个值的元组,但是为了使得到的数据类型与算术函数无缝地工作,还不清楚还需要做些什么工作.
我还考虑了另一种基于用NumPy 注册用户定义类型的方法.如果它能够正常工作,那么去C API进行设置我没有问题.但是,类型描述符结构的文档似乎表明类型的kind字段仅支持有符号/无符号整数,浮点和复杂浮点数字类型.目前尚不清楚我是否能够在任何地方尝试定义复杂的整数类型.
关于可行的方法的任何建议?
编辑:还有一件事; 我选择的任何方案都必须适合包装现有的复数整数缓冲区而不执行复制.也就是说,我希望能够使用PyArray_SimpleNewFromData()将缓冲区暴露给Python,而不必首先复制缓冲区.缓冲区已经是交错的实/虚格式,并且可以是int8_t或的数组int16_t.
在可用于创建空Python列表/词典的两种语法形式之间是否存在任何明显的差异,即
l = list()
l = []
Run Code Online (Sandbox Code Playgroud)
和:
d = dict()
d = {}
Run Code Online (Sandbox Code Playgroud)
我想知道使用一个是否优于另一个.
我遇到了一个错误导致使用clang 3.4,3.5和3.6 trunk生成错误代码的错误.实际触发问题的来源非常复杂,但我已经能够将其减少到这个自包含的示例:
#include <iostream>
#include <immintrin.h>
#include <string.h>
struct simd_pack
{
enum { num_vectors = 1 };
__m256i _val[num_vectors];
};
simd_pack load_broken(int8_t *p)
{
simd_pack pack;
for (int i = 0; i < simd_pack::num_vectors; ++i) pack._val[i] = _mm256_loadu_si256(reinterpret_cast<__m256i *>(p + i * 32));
return pack;
}
void store_broken(int8_t *p, simd_pack pack)
{
for (int i = 0; i < simd_pack::num_vectors; ++i) _mm256_storeu_si256(reinterpret_cast<__m256i *>(p + i * 32), pack._val[i]);
}
void test_broken(int8_t *out, int8_t *in1, size_t n)
{
size_t i …Run Code Online (Sandbox Code Playgroud) 我有一个QGLWidget在Qt应用程序中呈现OpenGL场景.我想添加一些覆盖在其上的半透明Qt小部件QGLWidget.这比标准小部件更难,因为OpenGL绘图上下文对于Qt的画家类是未知的.因此,如果我只是做了明显的事情并在QGLWidget例如顶部放置一个透明工具栏,则工具栏的透明部分将呈现黑色(绘制时无法访问OpenGL帧缓冲区).
似乎处理此类事情的推荐方法是在绘制OpenGL场景后重绘2D内容.只要您只是绘制简单的形状,链接的示例似乎非常简单.相反,我想要做的是推迟绘制一些子QWidget对象的绘画,以便在绘画事件中完成QGLWidget.
所以,我的问题归结为:
QWidget在正常的2D上下文中绘制.QGLWidget绘制构成背景的3D场景后绘制叠加层.这个列表中的第二项似乎很简单:我可以QWidget::render()在QGLWidget绘图事件中使用在视口顶部绘制所需的小部件.这很好用.
第一项更棘手:我需要一种方法来阻止小部件在正常的事件过程中绘画,并且只在QGLWidget油漆处理程序中绘制它们.一个显而易见的方法是使用隐藏叠加层QWidget::hide().这允许我按照我的意愿在OpenGL场景上绘制小部件.但是,由于窗口小部件是隐藏的,因此它们不响应鼠标或键盘事件.作为一个例子,我使用了一个QToolBar带有几个按钮,工具栏被正确绘制,但是没有功能(没有一个按钮响应点击).因此,如果沿着这条路走下去,似乎我需要一种方法来强制小部件仍然响应事件,即使它是隐藏的.
我尝试过的另一种方法是QToolBar使用事件过滤器拦截绘制事件,目的是阻止工具栏自行绘制.但是,工具栏仍然呈现; 我假设这是因为工具栏上的各种按钮都是仍然绘制的子窗口小部件,即使我拦截了父级的绘制事件.
关于我可以实现目标的方式的任何想法?
我有一个函数,它接受特定模板类型的参数; 简化版可能如下所示:
#include <type_traits>
template <typename T>
struct foo
{
// default constructor
foo() { }
// simple copy constructor that can construct a foo<T> from a foo<T>
// or foo<const T>
foo(const foo<typename std::remove_const<T>::type> &) { }
};
Run Code Online (Sandbox Code Playgroud)
在功能上,foo行为类似于a shared_ptr<T>,具有与此问题无关的一些其他插件功能.该函数的语义规定它更喜欢接受a foo<const T>.foo<const T>是隐式可构造的foo<T>,所以我希望能够做如下的事情:
template <typename T>
void bar(foo<const T> f) { }
int main()
{
bar(foo<const int>()); // fine
bar(foo<int>()); // compile error
}
Run Code Online (Sandbox Code Playgroud)
这失败了,因为没有匹配的重载,bar因为a foo<int>(即使a foo<const int> …
我正在尝试使用cuFFT的回调功能来动态执行输入格式转换(例如,计算8位整数输入数据的FFT,而不先对输入缓冲区进行显式转换float).在我的许多应用程序中,我需要计算输入缓冲区上的重叠 FFT,如前面的SO问题所述.通常,相邻的FFT可能重叠FFT长度的1/4到1/8.
cuFFT具有类似FFTW的接口,通过函数的idist参数cufftPlanMany()显式支持.具体来说,如果我想计算大小为32768的FFT,并且在连续输入之间重叠4096个样本,我会设置idist = 32768 - 4096.这不,因为它得到正确的输出感正常工作.
但是,当我以这种方式使用cuFFT时,我看到了奇怪的性能下降.我设计了一个测试,它以两种不同的方式实现这种格式转换和重叠:
明确告诉cuFFT有关输入的重叠性质:idist = nfft - overlap如上所述设置.安装负载回调函数只是没有从转换int8_t到float根据需要提供给所述回叫缓冲指数.
不要告诉cuFFT关于输入的重叠性质; 对它说谎idist = nfft.然后,让回调函数通过计算应为每个FFT输入读取的正确索引来处理重叠.
这个GitHub要点提供了一个测试程序,该程序通过时序和等效测试实现这两种方法.为简洁起见,我没有在这里重现所有内容.该程序计算一批1024个32768点FFT,重叠4096个样本; 输入数据类型是8位整数.当我在我的机器上运行它(使用Geforce GTX 660 GPU,在Ubuntu 16.04上使用CUDA 8.0 RC)时,我得到以下结果:
executing method 1...done in 32.523 msec
executing method 2...done in 26.3281 msec
Run Code Online (Sandbox Code Playgroud)
方法2明显更快,我不指望.看一下回调函数的实现:
方法1:
template <typename T>
__device__ cufftReal convert_callback(void * inbuf, size_t fft_index,
void *, void *)
{
return (cufftReal)(((const T …Run Code Online (Sandbox Code Playgroud) 我有一个密钥算法,其中大部分运行时用于计算密集矩阵产品:
A*A'*Y, where: A is an m-by-n matrix,
A' is its conjugate transpose,
Y is an m-by-k matrix
Typical characteristics:
- k is much smaller than both m or n (k is typically < 10)
- m in the range [500, 2000]
- n in the range [100, 1000]
Run Code Online (Sandbox Code Playgroud)
基于这些维度,根据矩阵链乘法问题的教训,很明显,在运算数意义上将计算结构化为最优A*(A'*Y).我当前的实现就是这样做的,而只是强迫关联性到表达式的性能提升是显而易见的.
我的应用程序是用C++编写的,用于x86_64平台.我正在使用Eigen线性代数库,英特尔的数学核心库作为后端.Eigen能够使用IMKL的BLAS接口来执行乘法,并且从我的Sandy Bridge机器上移动到Eigen的原生SSE2实现到Intel优化的基于AVX的实现的提升也很重要.
然而,表达式A * (A.adjoint() * Y)(用Eigen的说法)被分解为两个通用的矩阵 - 矩阵乘积(调用xGEMMBLAS例程),在它们之间创建一个临时矩阵.我想知道,通过一次专门的实现来一次评估整个表达式,我可以得到一个比我现在的通用更快的实现.一些让我相信这一点的观察结果是:
使用上述典型尺寸,输入矩阵A通常不适合缓存.因此,用于计算三矩阵乘积的特定存储器访问模式将是关键.显然,避免为部分产品创建临时矩阵也是有利的.
A 并且它的共轭转置显然具有非常相关的结构,可以利用它来改善整体表达的存储器访问模式.
是否有任何标准技术以缓存友好的方式实现这种表达式?我发现的矩阵乘法的大多数优化技术都是针对标准A*B情况而不是更大的表达式.我对这个问题的微优化方面很满意,例如转换成适当的SIMD指令集,但是我正在寻找任何可以用尽可能最友好的方式打破这个结构的引用.
编辑: …
我有一个C++应用程序,我有时需要一个POD类型的大缓冲区(例如一个25 b illion floats 的数组)在一个连续的块中同时保存在内存中.这个特定的内存组织是由应用程序使用一些对数据进行操作的C API这一事实驱动的.因此,不同的安排(例如像std::deque使用的较小的存储器块的列表)是不可行的.
该应用程序有一个以流式方式在阵列上运行的算法; 想想这样的事情:
std::vector<float> buf(<very_large_size>);
for (size_t i = 0; i < buf.size(); ++i) do_algorithm(buf[i]);
Run Code Online (Sandbox Code Playgroud)
该特定算法是已应用于数据集的早期处理步骤的流水线的结论.因此,一旦我的算法通过了i数组中的-th元素,应用程序就不再需要它了.
因此,从理论上讲,我可以释放内存,以便在浏览数据时减少应用程序的内存占用.但是,做类似于realloc()(或a std::vector<T>::shrink_to_fit())的操作会效率低下,因为我的应用程序必须花费时间在重新分配时将未使用的数据复制到新的位置.
我的应用程序在兼容POSIX的操作系统(例如Linux,OS X)上运行.是否有任何接口可以让操作系统从内存块的前面仅释放指定的区域?这似乎是最有效的方法,因为我可以通知内存管理器,例如,一旦我完成了内存块的前2 GB就可以被回收.
这与我今天早些时候提出的问题非常相似。但是,我在该问题中引用的示例是不正确的。错误地,我查看的是错误的源文件,而不是实际出现我所描述的错误的文件。无论如何,这是我的问题的一个示例:
struct base { };
struct child1 : base { };
struct child2 : base { };
child1 *c1;
child2 *c2;
// Goal: iterate over a few derived class pointers using a range-based for loop.
// initializer_lists are convenient for this, but we can't just use { c1, c2 }
// here because the compiler can't deduce what the type of the initializer_list
// should be. Therefore, we have to explicitly spell out that we want …Run Code Online (Sandbox Code Playgroud) 我的 Linux 应用程序需要以每秒约 600,000 个数据包的速率接收具有适度大小的数据包 (~1 KB) 的单个 UDP 流。我当前的实现很幼稚:它有一个线程,只需recv()重复调用,将接收到的数据放入队列中以供另一个线程处理。因此,接收者线程只负责拉入数据包。
在我所做的一些初始测试中,在线程充分利用其 CPU 核心之前,我每秒只能接收 200,000-300,000 个数据包。这显然不足以满足每秒 600,000 个数据包的目标。
\n\n理想情况下,我会找到某种方法在多个线程之间分配数据包接收负载。在寻找问题的解决方案时,我遇到了SO_REUSEPORT套接字选项,它允许多个 TCP/UDP 线程绑定到相同的 IP/端口组合。起初,这似乎正是我想要的。
不过,文章也指出了这个细节:
\n\n\n\n\n使用基于连接\xe2\x80\x94 的 4 元组(即对等 IP 地址和端口加上本地 IP 地址和端口)的哈希将传入连接和数据报分发到服务器套接字。这意味着,例如,如果客户端使用相同的套接字向服务器端口发送一系列数据报,那么这些数据报将全部定向到相同的接收服务器(只要它继续存在)。这简化了客户端和服务器之间进行有状态对话的任务。
\n
因此,如果我只有一个 UDP 流,则上述散列实现将产生所有数据包被定向到同一接收器线程,从而阻碍我并行化工作的尝试。因此,问题是:有没有办法使用SO_REUSEPORT或其他机制从多个线程接收单个 UDP 数据包流?
请注意,我的应用程序可以处理数据包的重新排序;格式化数据报的协议包含排序信息,我可以使用这些信息在之后正确地重新排序。
\n