我们有一个快速相机(>= 700 fps),我们需要计算图像的 fft 并做一些动作。但是,FFT 适用于某些帧,然后崩溃。当我使用像 10 fps 这样的慢帧率时,问题不会出现。
为了进一步隔离问题,我写了一个测试程序循环做fft,也崩溃了。请让我知道我做错了什么。
提前谢谢你。
更新:我用 -g 编译并用 lldb 运行它,我仍然没有看到有效的堆栈跟踪。
➜ cmake-build-debug lldb IntelTest
(lldb) target create "IntelTest"
Current executable set to '/Users/harshmathur/CourseworkRepo/IntelTest/cmake-build-debug/IntelTest' (x86_64).
(lldb) run
Process 13947 launched: '/Users/harshmathur/CourseworkRepo/IntelTest/cmake-build-debug/IntelTest' (x86_64)
DftiGetValue DFTI_PACKED_FORMAT : 57
Process 13947 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x111844100)
frame #0: 0x0000000110568a4c libmkl_avx2.2.dylib`mkl_dft_avx2_ipps_cFFTfwd_64_64fc + 2428
libmkl_avx2.2.dylib`mkl_dft_avx2_ipps_cFFTfwd_64_64fc:
-> 0x110568a4c <+2428>: vmovupd %ymm2, (%rsi)
0x110568a50 <+2432>: vmovupd %ymm7, 0x200(%rsi)
0x110568a58 <+2440>: vaddpd %ymm13, %ymm6, %ymm2
0x110568a5d <+2445>: vsubpd %ymm13, %ymm6, %ymm6
问候, 苛刻
更新:此外,如果 NN 设置为 32,下面的代码可以正常工作,没有任何错误或中止,只有当 NN > 32 时,它才会突然停止。
代码如下。
#include <iostream>
#include <mkl.h>
#define NN 128
#define NPIXFFT NN * (1 + NN / 2)
using namespace std;
typedef struct {
double re;
double im;
} mkl_double_complex;
int getFFTWPlans(DFTI_DESCRIPTOR_HANDLE *descHandle);
int main() {
int i;
MKL_LONG status;
DFTI_DESCRIPTOR_HANDLE descHandle;
getFFTWPlans(&descHandle);
double *image = (double*)malloc(sizeof(double) * NN * NN);
double *recoveredImage = (double*)malloc(sizeof(double) * NN * NN);
mkl_double_complex *imageFT = (mkl_double_complex*) mkl_malloc(
NPIXFFT * sizeof(mkl_double_complex),64);
for (i=0; i < NN * NN; i++) {
image[i] = i * 2 + 1;
}
while (1) {
status = DftiComputeForward(descHandle, image, imageFT);
if (status != 0) {
cout <<"DftiComputeForward Failed: " << status << endl;
break;
}
status = DftiComputeBackward(descHandle, imageFT, recoveredImage);
if (status != 0) {
cout <<"DftiComputeBackward Failed: " << status << endl;
break;
}
}
return 0;
}
int getFFTWPlans(DFTI_DESCRIPTOR_HANDLE *descHandle){
MKL_LONG lengths[2];
lengths[0] = NN;
lengths[1] = NN;
MKL_LONG status = DftiCreateDescriptor(descHandle, DFTI_DOUBLE, DFTI_REAL, 2, lengths);
if (status != 0) {
cout << "DftiCreateDescriptor failed : " << status << endl;
return -1;
}
status = DftiSetValue(*descHandle, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
if (status != 0) {
cout << "DftiSetValue DFTI_PLACEMENT failed : " << status << endl;
return -2;
}
status = DftiSetValue(*descHandle, DFTI_THREAD_LIMIT, 1);
if (status != 0) {
cout << "DftiSetValue DFTI_THREAD_LIMIT failed : " << status << endl;
return -2;
}
MKL_LONG format;
status = DftiGetValue(*descHandle, DFTI_PACKED_FORMAT, &format);
if (status != 0) {
cout << "DftiGetValue DFTI_PACKED_FORMAT failed : " << status << endl;
return -3;
}
cout << "DftiGetValue DFTI_PACKED_FORMAT : " << format << endl;
status = DftiCommitDescriptor(*descHandle);
if (status != 0) {
cout << "DftiCommitDescriptor failed : " << status << endl;
return -4;
}
return status;
}
原来问题是图像是二维的,并且按行主要顺序存储在一维数组中。由于我正在创建 2D FFT 描述符,因此必须给出输入和输出步幅。
这是工作代码:
#include <iostream>
#include <fstream>
#include <mkl.h>
#include <complex>
#include <chrono>
#define NN 256
#define NPIXFFT NN * (1 + (NN / 2))
using namespace std;
typedef struct {
double re;
double im;
} mkl_double_complex;
int getFFTWPlans(DFTI_DESCRIPTOR_HANDLE *descHandle);
int printFFT(mkl_double_complex *imageFT);
int main() {
chrono::high_resolution_clock::time_point t0, t1;
chrono::duration<double> dt;
int i, flag=0;
MKL_LONG status, count;
DFTI_DESCRIPTOR_HANDLE descHandle;
getFFTWPlans(&descHandle);
double *image = (double*)malloc(sizeof(double) * NN * NN);
double *recoveredImage = (double*)malloc(sizeof(double) * NN * NN);
mkl_double_complex *imageFT = (mkl_double_complex*) mkl_malloc(
NPIXFFT * sizeof(mkl_double_complex),64);
// ifstream currentImage("F:\\tiptilt\\20230421_121442\\CurrentImage_286.dat", ios::binary);
double TEMP;
for (int i=0; i<NN * NN; i++){
// currentImage.read((char*) &TEMP, sizeof(double));
image[i] = i * i + i * 2 + 1;
}
double x;
count = 0;
while (1) {
if (count == 0) {
t0 = chrono::high_resolution_clock::now();
}
status = DftiComputeForward(descHandle, image, imageFT);
if (status != 0) {
cout <<"DftiComputeForward Failed: " << status << endl;
break;
}
// if (flag == 0) {
// printFFT(imageFT);
// flag = 1;
// }
for (i=0; i<NPIXFFT; i++){
x = imageFT[i].re;
}
status = DftiComputeBackward(descHandle, imageFT, recoveredImage);
if (status != 0) {
cout <<"DftiComputeBackward Failed: " << status << endl;
break;
}
count += 1;
if (count == 3000) {
t1 = chrono::high_resolution_clock::now();
dt = chrono::duration_cast<chrono::duration<double>>(t1 - t0);
cout<< "Time (ms): "<<dt.count() * 1000 / (count - 1) <<"\r";
cout.flush();
}
}
return 0;
}
int getFFTWPlans(DFTI_DESCRIPTOR_HANDLE *descHandle){
MKL_LONG lengths[2];
lengths[0] = NN;
lengths[1] = NN;
MKL_LONG status = DftiCreateDescriptor(descHandle, DFTI_DOUBLE, DFTI_REAL, 2, lengths);
if (status != 0) {
cout << "DftiCreateDescriptor failed : " << status << endl;
return -1;
}
status = DftiSetValue(*descHandle, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
if (status != 0) {
cout << "DftiSetValue DFTI_PLACEMENT failed : " << status << endl;
return -2;
}
status = DftiSetValue(*descHandle, DFTI_THREAD_LIMIT, 1);
if (status != 0) {
cout << "DftiSetValue DFTI_THREAD_LIMIT failed : " << status << endl;
return -3;
}
status = DftiSetValue(*descHandle, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX);
if (status != 0) {
cout << "DftiSetValue DFTI_CONJUGATE_EVEN_STORAGE failed : " << status << endl;
return -4;
}
status = DftiSetValue(*descHandle, DFTI_PACKED_FORMAT, DFTI_CCE_FORMAT);
if (status != 0) {
cout << "DftiSetValue DFTI_PACKED_FORMAT failed : " << status << endl;
return -5;
}
MKL_LONG strides[2];
strides[0] = NN;
strides[1] = 1;
status = DftiSetValue(*descHandle, DFTI_INPUT_STRIDES, strides);
if (status != 0) {
cout << "DftiSetValue DFTI_INPUT_STRIDES failed : " << status << endl;
return -6;
}
status = DftiSetValue(*descHandle, DFTI_OUTPUT_STRIDES, strides);
if (status != 0) {
cout << "DftiSetValue DFTI_OUTPUT_STRIDES failed : " << status << endl;
return -7;
}
MKL_LONG format;
status = DftiGetValue(*descHandle, DFTI_PACKED_FORMAT, &format);
if (status != 0) {
cout << "DftiGetValue DFTI_PACKED_FORMAT failed : " << status << endl;
return -8;
}
cout << "DftiGetValue DFTI_PACKED_FORMAT : " << format << endl;
status = DftiCommitDescriptor(*descHandle);
if (status != 0) {
cout << "DftiCommitDescriptor failed : " << status << endl;
return -9;
}
return status;
}
int printFFT(mkl_double_complex *imageFT) {
int i;
for (i=0;i<NPIXFFT;i++) {
cout <<i << " " << imageFT[i].re << " "<<imageFT[i].im<<endl;
}
return 0;
}