FFTW和智慧的签名问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FFTW和智慧的签名问题相关的知识,希望对你有一定的参考价值。
我在Centos 7 Linux目标上使用FFTW 3.3.8。
[第一次测试,我使用FFTW执行一些计算,结果很好,并且我使用fftw_export_wisdom_to_filename
保存计划。
在第二个测试中,与第一个测试相同,我刚刚在计划的计算中添加了对fftw_import_wisdom_from_filename
和属性FFTW_WISDOM
的调用,它也可以正常工作。
[当我在智慧文件上使用fftw-wisdom-to-conf
,编译生成的输出,并将其添加到测试二进制文件中时,就会出现问题(在这种情况下,二进制文件的大小会减小,这对我来说很有趣)。
在这种情况下,导入智慧功能由于签名错误而返回“ 0”。智慧文件中的前四个md5值不正确(与预期值不同)。
如果我在智慧文件中修补这些值,则一切工作正常,可以正常导入,并且还产生FFTW。没有激活gcc优化选项,
我不使用多线程,我的配置看起来很简单,您有什么想法可以解释这种行为吗?
用于生成FFTW库的命令如下:./configure CC=gcc CFLAGS="-g" --with-slow-timer --disable-threads --disable-fortran --host=x86_64-pc-linux-gnu --prefix=/lvcugen/workspace/workspace_ext6/GR712/TMP_FFTW/INSTALL_LINUX
用于执行此测试并从test_fftw_wisdom.c
安装目录编译的fftw
文件的内容如下:
/*
* P.SERAUD : FFTW Wisdom test (define MODE_USE to generate wisdom load binary, default binary generate wisdom
*
* Gen wisdom build command : gcc -u main -o0 -g test_fftw_wisdom.c -I ./include -L ./lib -lfftw3 -lm -lc -o test_fftw_gen_wisdom
* Use wisdom build command : gcc -u main -o0 -g -DMODE_USE test_fftw_wisdom.c conf_wisdom.o -I ./include -L ./lib -lfftw3 -lm -lc -o test_fftw_use_wisdom
*
* conf_wisdom file generated by : ./bin/fftw-wisdom-to-conf < wisdom.txt
*
*/
#include <stdio.h>
#include <string.h>
#include "fftw3.h"
/* in : input image
* reOut : real part (output)
* imOut : imaginary part (output)
* largeur : largeur des images d'entrée et de sortie
* hauteur : idem
*/
void fourierForward(const double* in,
double* reOut,
double* imOut,
unsigned int largeur,
unsigned int hauteur)
{
/* The data is an array of type 'fftw_complex', which is by default a
'double[2]' composed of the real ('in[i][0]') and imaginary ('in[i][1]')
parts of a complex number.
*/
fftw_complex* spatial_repr;
fftw_complex* frequency_repr;
unsigned int i;
fftw_plan plan;
fftw_plan plan2;
int resWisdom=0;
spatial_repr= fftw_malloc(sizeof(fftw_complex)*largeur*hauteur);
frequency_repr= fftw_malloc(sizeof(fftw_complex)*largeur*hauteur);
fftw_set_timelimit(FFTW_NO_TIMELIMIT);
/* Use Wisdom mode called when MODE_USE is set */
#ifdef MODE_USE
printf ("Importing Wisdom %d
",0);
resWisdom = fftw_import_wisdom_from_filename("wisdom.txt");
printf ("Import result %d
",resWisdom);
if(resWisdom == 0)
return;
#endif
printf("Launching fftw_plan_dft_2d FORWARD with %d / %d
",largeur, hauteur);
/*on calcule le plan d'exécution*/
#ifdef MODE_USE
plan=fftw_plan_dft_2d(hauteur, largeur, spatial_repr, frequency_repr, FFTW_FORWARD, FFTW_WISDOM_ONLY | FFTW_ESTIMATE);
#else
plan=fftw_plan_dft_2d(hauteur, largeur, spatial_repr, frequency_repr, FFTW_FORWARD, FFTW_ESTIMATE);
#endif
if (plan == NULL)
{
printf("NULL plan generated by fftw_plan_dft_2d with %d / %d !!!
",largeur, hauteur);
return;
}
/*On remplit la structure qui sera utilisée par fftw*/
for(i=0;i<largeur*hauteur;i++)
{
spatial_repr[i][0] = in[i]; /* real part */
spatial_repr[i][1] = 0.0; /* imaginary part */
frequency_repr[i][0] = 0.0; /* real part */
frequency_repr[i][1] = 0.0; /* imaginary part */
}
printf("Executing fftw_execute with %d / %d
",largeur, hauteur);
/*on effectue la transformée de Fourier*/
fftw_execute(plan);
/*on retranscrit le résultat en 2 images, l'une représentant la partie réelle, l'autre
la partie imaginaire*/
for(i=0;i<largeur*hauteur;i++)
{
reOut[i]=frequency_repr[i][0];
imOut[i]=frequency_repr[i][1];
printf("%d : in (%lf) / reOut (%lf) / imOut (%lf)
",i, in[i],reOut[i],imOut[i]);
}
printf("Launching fftw_plan_dft_2d BACKWARD with %d / %d
",largeur, hauteur);
#ifdef MODE_USE
plan2=fftw_plan_dft_2d(hauteur, largeur, spatial_repr, frequency_repr, FFTW_BACKWARD, FFTW_WISDOM_ONLY | FFTW_ESTIMATE);
#else
plan2=fftw_plan_dft_2d(hauteur, largeur, spatial_repr, frequency_repr, FFTW_BACKWARD, FFTW_ESTIMATE);
#endif
if (plan2 == NULL)
{
printf("NULL plan generated by fftw_plan_dft_2d with %d / %d !!!
",largeur, hauteur);
return;
}
/*On remplit la structure qui sera utilisée par fftw*/
for(i=0;i<largeur*hauteur;i++)
{
spatial_repr[i][0] = reOut[i]; /* real part */
spatial_repr[i][1] = imOut[i]; /* imaginary part */
frequency_repr[i][0] = 0.0; /* real part */
frequency_repr[i][1] = 0.0; /* imaginary part */
}
printf("Executing fftw_execute with %d / %d
",largeur, hauteur);
/*on effectue la transformée de Fourier*/
fftw_execute(plan2);
/*on retrouve la matrice d'origine dans la partie réelle en la divisant par "largeur * hauteur" */
for(i=0;i<largeur*hauteur;i++)
{
reOut[i]=frequency_repr[i][0] /(largeur*hauteur);
imOut[i]=frequency_repr[i][1];
printf("%d : in (%lf) / reOut (%lf) / imOut (%lf)
",i, in[i],reOut[i],imOut[i]);
}
#ifndef MODE_USE
resWisdom = fftw_export_wisdom_to_filename("wisdom.txt");
printf ("Wisdom export res = %d
", resWisdom);
#endif
/*on détruit les objets*/
fftw_destroy_plan(plan);
fftw_destroy_plan(plan2);
fftw_free(spatial_repr);
fftw_free(frequency_repr);
}
int main(void)
{
printf("Starting !!!!
");
double in [8][8] = {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 70.0, 80.0, 90.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 90.0, 100.0, 110.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 110.0, 120.0, 130.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 130.0, 140.0, 150.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
double reOut [8][8] = {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
double imOut [8][8] = {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
fourierForward(&in[0][0], &reOut[0][0], &imOut[0][0], 8, 8);
return 0;
}
conf_wisdom.o
可执行文件中包含的test_fftw_use_wisdom
目标文件是通过conf_wisdom.c
编译gcc -c conf_wisdom.c
源文件的结果。该源文件的内容如下:
/* Automatically generated by fftw-wisdom-to-conf from fftw 3.3.8.
DO NOT EDIT! (Unless you really, really want to. Then it's okay.) */
void fftw_configure_planner(void *plnr)
{
struct solvtab_s { void (*reg)(void *); const char *reg_nam; };
extern void fftw_solvtab_exec(const struct solvtab_s s[], void *);
#define DECLARE(name) extern void name(void *);
#define STRINGIZEx(x) #x
#define STRINGIZE(x) STRINGIZEx(x)
#define SOLVTAB(s) { s, STRINGIZE(s) },
#define DO(X)
X(fftw_codelet_n1_8)
X(fftw_dft_rank_geq2_register)
/* end DO(X) */
DO(DECLARE)
const struct solvtab_s s[] = {
DO(SOLVTAB)
{ 0, 0 }
};
fftw_solvtab_exec(s, plnr);
}
通过调用函数fftw_export_wisdom_to_filename
生成的witness.txt文件的内容如下:
(fftw-3.3.8 fftw_wisdom #x4be12fff #x7b2df9b2 #xa5975329 #x385b0041
(fftw_codelet_n1_8 0 #x31bff #x31bff #x0 #x2874cdd9 #x63ab3b26 #xcb8c1374 #xedc69a82)
(fftw_codelet_n1_8 0 #x31bff #x31bff #x0 #x4e583e34 #x14aedc27 #x54a2fad7 #xd124b261)
(fftw_dft_rank_geq2_register 0 #x31bff #x31bff #x0 #xcd87e2bd #x8b6dd8ee #x2d70ed77 #xd20ea4af)
(fftw_codelet_n1_8 0 #x31bff #x31bff #x0 #xece23a64 #x64207145 #x3f794c2c #x32ef2fbf)
(fftw_dft_rank_geq2_register 0 #x31bff #x31bff #x0 #xd416e586 #xdc5a4e14 #x2b04907f #x69b22bd8)
(fftw_codelet_n1_8 0 #x31bff #x31bff #x0 #x155aa639 #x5f99241d #x6351b1a0 #xc7ccb78d)
)
未成功检查的错误md5值是#x4be12fff#x7b2df9b2#xa5975329#x385b0041。如果将这些值替换为期望的值,则一切正常。
此外,当库的全部内容包含在test_fftw_use_wisdom
二进制文件中(不使用conf_wisdom.o文件)时,它也可以正常工作。
实际上,问题出在导入和导出功能都使用的功能signature_of_configuration
中。当包含conf_wisdom.o
时,就完整列表而言,planner
内容(与nslvdesc
和slvdescsiz
关联的解析器列表)的内容将减少,并且关联的md5值必须有所不同。
测试表明,当从智慧数据生成的wisdom.c
既包含在导入程序中,又包含在导出程序中时,导入就起作用了。当两个程序中均不包含wisdom.c
时,它也适用。如果将它包含在导入程序中但不包含在导出程序中,则它将失败。
因此,解决方法是在不使用wisdom.c
的情况下构建导出程序,导出智慧,生成wisdom.c
,使用wisdom.c
重建导出程序,重新导出智慧,然后使用wisdom.c
生成导入程序。
这似乎是FFTW的缺陷,可能在校验和检查的设计中。
以上是关于FFTW和智慧的签名问题的主要内容,如果未能解决你的问题,请参考以下文章