- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在创建 FFT 信号互相关模块时遇到了一些问题(利用循环卷积定理等)。我只想确认以下方案将确保 FFT 蝶形计算的特定递归级别在下一个级别开始之前完成,并且包含数据的缓冲区已完全写入/完成。因此,循环相关/卷积涉及 FFT、 vector 内积,然后是 IFFT。
由于这个方案,我没有以位反转索引顺序对数据进行排序的内核。正向 FFT 内核产生一个位逆序 FFT,在内积之后,IFFT 仅使用该结果计算自然阶解。
我应该提到我有多个 GPU。
无论如何,这里是每个 FFT/IFFT 的伪代码表示,(访问/操作算法是等效的,除了共轭旋转因子,归一化内核稍后出现:
for numDevices:
data -> buffers
buffers -> kernel arguments
for fftRecursionLevels:
for numDevices:
recursionLevel -> kernel arguments
deviceCommandQueue -> enqueueNDRangeKernel
deviceCommandQueue -> flush()
for numDevices:
deviceCommandQueue -> finish()
(编辑:该方法是 Radix-2 DIT,如果不清楚,抱歉。)
我能逃脱吗?据我所知,finish() 是一个阻塞函数,直到每个内核都完成其全局范围内的计算后,最后一个 for 循环才会完成(这里是 fftSize/2,请参阅有关 Radix-2 蝶形运算的任何文献),并且,对于奖励积分,一些内核已经由于 flush() 而执行,而我正在对剩余的内核进行排队。
总的来说,对于这个特定的软件,我使用 openCL/c++ 得到了一些奇怪/垃圾的结果。 我已经在 python 中实现了完整的数据管道,(算法是“拓扑等效”,显然没有主机<-->设备缓冲区/指令或设备端操作 w/python 方法),并模拟内核应该如何运行并且当我使用 scipy.fftpack 模块时它产生相同的结果并且只对信号数据 vector 进行操作。
我想一些图片会有所帮助。这正是这两个程序中发生的事情。
1) 生成高斯 vector 2) 零填充高斯 vector 到下一个 2 长度的下一个最高幂3) 前向 FFT,产生自然顺序(在 w 中)结果4)剧情
这是我的内核的 python 模拟,与仅使用 scipy.fftpack.fft( vector ) 相比:
http://i.imgur.com/pGcYTrL.png
它们是一样的。现在将其与以下任何一个进行比较:
http://i.imgur.com/pbiYGpR.png
(忽略x轴的索引,都是自然阶的FFT结果)
它们都是相同类型的起始数据(从 0 到 N 的高斯分布,以 N/2 为中心,在本例中用零填充到 2N)。它们看起来都应该像图一中的绿/蓝线,但它们不是。我盯着第二个程序的主机/设备代码看了多长时间,眼睛已经呆滞了,我没有看到任何拼写错误或不正确的算法。我高度怀疑我不知道的设备方面正在发生某些事情,因此我在这里发帖。很明显,该算法看起来运行正常(无论起始数据如何,红色/红色的一般形状都近似于蓝色/绿色。我在不同的起始集上运行了该算法,它始终看起来像蓝色/绿色,但带有那种无意义的噪音/错误),但有些地方不对劲。
所以我转向互联网。提前致谢。
编辑:下面的一位发帖者表示很难在没有看到至少设备端代码的情况下发表评论,因为存在关于内存防护的问题,所以我在下面发布了内核代码。
//fftCorr.cl
//
//OpenCL Kernels/Methods for FFT Cross Correlation of Signals
//
//Copyright (C) 2013 Steve Novakov
//
//This file is part of OCLSIGPACK.
//
//OCLSIGPACK is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//OCLSIGPACK is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with OCLSIGPACK. If not, see <http://www.gnu.org/licenses/>.
//
#define PIE 3.14159265359f
void DFT2(float2 * a,float2 * b, float2 *w){
float2 tmp;
float2 bmul = ( (*w).x*((*b).x) - (*w).y*((*b).y), (*w).x*((*b).y) + (*w).y*((*b).x) );
tmp = (*a) - bmul;
(*a) += bmul;
(*b) = tmp;
}
//
//
// Spin Factor Calc
//
// Computes spin/twiddle factor for particular bit reversed index.
//
//
float2 spinFact(unsigned int N, unsigned int k)
{
float phi = -2.0 * PIE * (float) k / (float) N;
// \bar{w}^offset_(groupDist)
float spinRe, spinIm;
spinIm = sincos( phi, &spinRe);
return (float2) (spinRe, spinIm);
}
float2 spinFactR(unsigned int N, unsigned int k)
{
float phi = 2.0 * PIE * (float) k / (float) N;
// w^offset_(groupDist)
float spinRe, spinIm;
spinIm = sincos( phi, &spinRe);
return (float2) (spinRe, spinIm);
}
//
// Bit-Reversed Index Reversal, (that sounds confusing)
//
unsigned int BRIR( unsigned int index, unsigned int fftDepth)
{
unsigned int rev = index;
rev = (((rev & 0xaaaaaaaa) >> 1 ) | ((rev & 0x55555555) << 1 ));
rev = (((rev & 0xcccccccc) >> 2 ) | ((rev & 0x33333333) << 2 ));
rev = (((rev & 0xf0f0f0f0) >> 4 ) | ((rev & 0x0f0f0f0f) << 4 ));
rev = (((rev & 0xff00ff00) >> 8 ) | ((rev & 0x00ff00ff) << 8 ));
rev = (((rev & 0xffff0000) >> 16) | ((rev & 0x0000ffff) << 16));
rev >>= (32-fftDepth);
return rev;
}
//
//
// Index Bit Reversal Kernel, if Necessary/for Testing.
//
// Maybe I should figure out an in-place swap algorithm later.
//
//
__kernel void bitRevKernel( __global float2 * fftSetX,
__global float2 * fftSetY,
__global float2 * fftRevX,
__global float2 * fftRevY,
unsigned int fftDepth
)
{
unsigned int glID = get_global_id(0);
unsigned int revID = BRIR(glID, fftDepth);
fftRevX[revID] = fftSetX[glID];
fftRevY[revID] = fftSetY[glID];
}
//
//
// FFT Radix-2 Butterfly Operation Kernel
//
// This is an IN-PLACE algorithm. It calculates both bit-reversed indeces and spin factors in the same thread and
// updates the original set of data with the "butterfly" results.
//
// recursionLevel is the level of recursion of the butterfly operation
// # of threads is half the vector size N/2, (glID is between 0 and this value, non inclusive)
//
// Assumes natural order data input. Produces bit-reversed order FFT output.
//
//
__kernel void fftForwKernel( __global float2 * fftSetX,
__global float2 * fftSetY,
unsigned int recursionLevel,
unsigned int totalDepth
)
{
unsigned int glID = get_global_id(0);
unsigned int gapSize = 1 << (recursionLevel - 1);
unsigned int groupSize = 1 << recursionLevel;
unsigned int base = (glID >> (recursionLevel - 1)) * groupSize;
unsigned int offset = glID & (gapSize - 1 );
unsigned int bitRevIdA = (unsigned int) base + offset;
unsigned int bitRevIdB = (unsigned int) bitRevIdA + gapSize;
unsigned int actualIdA = BRIR(bitRevIdA, totalDepth);
unsigned int actualIdB = BRIR(bitRevIdB, totalDepth);
float2 tempXA = fftSetX[actualIdA];
float2 tempXB = fftSetX[actualIdB];
float2 tempYA = fftSetY[actualIdA];
float2 tempYB = fftSetY[actualIdB];
float2 spinF = spinFact(groupSize, offset);
// size 2 DFT
DFT2(&tempXA, &tempXB, &spinF);
DFT2(&tempYA, &tempYB, &spinF);
fftSetX[actualIdA] = tempXA;
fftSetX[actualIdB] = tempXB;
fftSetY[actualIdA] = tempYA;
fftSetY[actualIdB] = tempYB;
}
对于图中提供的数据。我按照文章开头所述运行“fftForwKernel”,然后运行“bitRevKernel”
最佳答案
因此,如果没有代码来告知任何信息,并且在代码确实“相同”的假设下运行,我倾向于说假设所使用的算法在 Python 和OpenCL 可能是同步问题。如果不是全局同步问题(在内核调用之间正确拆分工作),那么就是缺少全局内存栅栏,甚至是每个内核调用每个本地组的本地内存栅栏的问题。
您如何组织通话?关于您拆分递归 FFT 的确切程度,所提供的伪代码似乎含糊不清。我猜您正在为...做“正确的事情”……好吧,我什至不确定您是在做 DIT 还是 DIF 或任何其他可用于 FFT 算法的大量数据流。据我所知,可能是你在做蝴蝶时没有正确地内存它们,或者你可能非常严格地同步你的 FFT 步骤,以至于蝴蝶是与递归 FFT 步骤完全不同的内核调用的一部分,我的建议完全无效并且无效。
(我会把它淡化成评论,但我缺乏这样做的声誉,所以我很抱歉这是作为“答案”发布的)
关于c++ - OpenCL FFT 实现 - 无意义的输出数据 - 可能是正确的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17137765/
Intel、AMD 和 Khronos OpenCL 之间有什么区别。我对 OpenCL 完全陌生,想从它开始。我不知道在我的操作系统上安装哪个更好。 最佳答案 OpenCL 是 C 和 C++ 语言
我在这里的一篇文章中看到,我们可以从 OpenCL 内核调用函数。但是在我的情况下,我还需要并行化该复杂函数(由所有可用线程运行),所以我是否必须将该函数也设为内核并像从主内核中调用函数一样直接调
最近我看到一些开发板支持 OpenCL EP,例如 odroid XU。我知道的一件事是 OpenCL EP 适用于 ARM 处理器,但它与基于主要桌面的 OpenCL 在哪些特性上有所不同。 最佳答
我想知道在 OpenCL 中设置为内核函数的参数数量是否有任何限制。设置参数时出现 INVALID_ARG_INDEX 错误。我在内核函数中设置了 9 个参数。请在这方面帮助我。 最佳答案 您可以尝试
我对零拷贝的工作原理有点困惑。 1-要确认以下内容对应于opencl中的零拷贝。 ....................... . . . .
我是 OpenCL 的初学者,我很难理解某些东西。 我想改进主机和设备之间的图像传输。 我制定了一个计划以更好地了解我。 顶部:我现在拥有的 |底部:我想要的 HtD(主机到设备)和 DtH(设备到主
今天我又加了四个 __local变量到我的内核以转储中间结果。但是只需将另外四个变量添加到内核的签名并添加相应的内核参数就会将内核的所有输出呈现为“0”。没有一个 cl 函数返回错误代码。 我进一步尝
我知道工作项被分组到工作组中,并且您不能在工作组之外进行同步。 这是否意味着工作项是并行执行的? 如果是这样,使用 128 个工作项创建 1 个工作组是否可能/有效? 最佳答案 组内的工作项将一起安排
我相当确定经纱仅在 CUDA 中定义。但也许我错了。就 OpenCL 而言,什么是扭曲? 它与工作组不一样,是吗? 任何相关的反馈都受到高度赞赏。谢谢! 最佳答案 它没有在 OpenCL 标准中定义。
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
在OpenCL中,我的理解是可以使用barrier()函数来同步工作组中的线程。我(通常)确实了解它们的用途以及何时使用它们。我还知道工作组中的所有线程都必须遇到障碍,否则会出现问题。然而,到目前为止
我的主板上有 Nvidia 显卡 (GeForce GT 640)。我已经在我的盒子上安装了 OpenCL。当我使用“clGetPlatformInfo(参数)”查询平台时,我看到以下输出:-#可用平
我目前正在构建一个 ray marcher 来查看像 mandelbox 等东西。它工作得很好。但是,在我当前的程序中,它使用每个 worker 作为从眼睛转换的光线。这意味着每个 worker 有大
我编写了两个不同的 openCl 内核,使用 nvidia profiler 获取了有关它们的一些信息,发现两者每个工作项都使用 63 个寄存器。 我尝试了一切我能想到的方法来降低这个数字(用 ush
我的主板上有 Nvidia 显卡 (GeForce GT 640)。我已经在我的盒子上安装了 OpenCL。当我使用“clGetPlatformInfo(参数)”查询平台时,我看到以下输出:-#可用平
我目前正在构建一个 ray marcher 来查看像 mandelbox 等东西。它工作得很好。但是,在我当前的程序中,它使用每个 worker 作为从眼睛转换的光线。这意味着每个 worker 有大
我正在尝试使用 OpenCL 加速一些计算,算法的一部分包括矩阵求逆。是否有任何开源库或免费可用的代码来计算用 OpenCL 或 CUDA 编写的矩阵的 lu 分解(lapack dgetrf 和 d
我正在尝试在 OpenCL 内核中使用递归。编译成功,但运行时出现编译错误,所以我想知道,由于 CUDA 现在支持动态并行,OpenCL 是否支持动态并行? 最佳答案 OpenCL 不支持递归。请参阅
考虑以下代码,它从大小为 size 的 double 组创建缓冲区内存对象: coef_mem = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM
OpenCL 中目标平台的示例是什么?例如,它是 Windows、Android、Mac 等操作系统,还是设备中的实际芯片? 最佳答案 OpenCL 平台本质上是一个 OpenCL 实现。它与操作系统
我是一名优秀的程序员,十分优秀!