首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ImportError:未定义符号: fftw_execute

ImportError:未定义符号: fftw_execute
EN

Stack Overflow用户
提问于 2022-05-27 04:26:44
回答 1查看 183关注 0票数 0

我试图建立一个使用gr_modtool的快速傅立叶变换和峰度能力的接收器块。

代码本身可以编译而没有错误。

但是,当我在GRC中运行流图时,它会产生以下错误消息。

问:如何解决这个错误?

我正在通过fftw3f路径,但是我得到了一个错误。

预先感谢您所能提供的任何指导。

代码语言:javascript
复制
Generating: '/home/nomo/gr-Kurtosis/kurtosis.py'

Executing: /usr/bin/python3 -u /home/nomo/gr-Kurtosis/kurtosis.py

Traceback (most recent call last):
  File "/home/nomo/gr-Kurtosis/kurtosis.py", line 34, in <module>
    import Kurtosis
  File "/usr/local/lib/python3/dist-packages/Kurtosis/__init__.py", line 30, in <module>
    from .Kurtosis_swig import *
  File "/usr/local/lib/python3/dist-packages/Kurtosis/Kurtosis_swig.py", line 13, in <module>
    from . import _Kurtosis_swig
ImportError: /usr/local/lib/x86_64-linux-gnu/libgnuradio-Kurtosis.so.1.0.0git: undefined symbol: fftw_execute

下面是实现源文件:

代码语言:javascript
复制
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gnuradio/io_signature.h>
#include "Kurtosis_c_impl.h"

namespace gr {
  namespace Kurtosis {

    Kurtosis_c::sptr
    Kurtosis_c::make(int fftsize)
    {
      return gnuradio::get_initial_sptr
        (new Kurtosis_c_impl(fftsize));
    }


    /*
     * The private constructor
     */
    Kurtosis_c_impl::Kurtosis_c_impl(int fftsize)
      : gr::sync_block("Kurtosis_c",
              gr::io_signature::make(1, 1, sizeof(gr_complex)),
              gr::io_signature::make(0, 0, 0)),
              d_N(fftsize)
    {
      d_input = (fftw_complex*)fftw_malloc(sizeof(gr_complex) * d_N);
      K = (fftw_complex*)fftw_malloc(sizeof(gr_complex) * d_N);
      d_plan = fftw_plan_dft_1d(d_N, d_input, d_input, FFTW_BACKWARD, FFTW_ESTIMATE);
    }

    /*
     * Our virtual destructor.
     */
    Kurtosis_c_impl::~Kurtosis_c_impl()
    {
    }

    int
    Kurtosis_c_impl::work(int noutput_items,
        gr_vector_const_void_star &input_items,
        gr_vector_void_star &output_items)
    {
      const gr_complex *in = (const gr_complex*) input_items[0];

      for(int k = 0; k < noutput_items; k++)
      {
        for(int j = 0; j < M; j++)
        {
          for(int i = 0; i < d_N; i++)
          {
            d_input[i][0] = in[i].real();
            d_input[i][1] = in[i].imag();
          }
      
          fftw_execute(d_plan);
      
          M = 29296;
      
        
          for(int i = 0; i < d_N; i++)
          {   
            S1[i][0] = S1[i][0] + d_input[i][0];
            S1[i][1] = S1[i][1] + d_input[i][1];
        
            S2[i][0] = S2[i][0] + d_input[i][0] * d_input[i][0];
            S2[i][1] = S2[i][1] + d_input[i][1] * d_input[i][1];
        
            S3[i][0] = S3[i][0] + d_input[i][0] * d_input[i][0] * d_input[i][0];
            S3[i][1] = S3[i][1] + d_input[i][1] * d_input[i][1] * d_input[i][1];
        
            S4[i][0] = S4[i][0] + d_input[i][0] * d_input[i][0] * d_input[i][0] * d_input[i][0];
            S4[i][1] = S4[i][1] + d_input[i][1] * d_input[i][1] * d_input[i][1] * d_input[i][1];
        
            dc[i][0] = dc[i][0] + 1;
            dc[i][1] = dc[i][1] + 1;
          }
    
          for(int i = 0; i < d_N; i++)
          {
            Myu1[i][0] = S1[i][0] / dc[i][0];
            Myu1[i][1] = S1[i][1] / dc[i][1];
      
            Myu2[i][0] = S2[i][0] / dc[i][0];
            Myu2[i][1] = S2[i][1] / dc[i][1];
       
            Myu3[i][0] = S3[i][0] / dc[i][0];
            Myu3[i][1] = S3[i][1] / dc[i][1];
       
            Myu4[i][0] = S4[i][0] / dc[i][0];
            Myu4[i][1] = S4[i][1] / dc[i][1];
          }

    

          for(int i = 0; i < d_N; i++)
          {
            K[i][0] = (Myu4[i][0] - 4 * Myu3[i][0] * Myu1[i][0] + 6 * Myu2[i][0] * Myu1[i][0] 
                   * Myu1[i][0] - 3 * Myu1[i][0] * Myu1[i][0] * Myu1[i][0] * Myu1[i][0]) / 
                    ((Myu2[i][0] - Myu1[i][0] * Myu1[i][0]) * (Myu2[i][0] - Myu1[i][0] 
                      * Myu1[i][0]));
      
            K[i][1] = (Myu4[i][1] - 4 * Myu3[i][1] * Myu1[i][1] + 6 * Myu2[i][1] * Myu1[i][1] 
                   * Myu1[i][1] - 3 * Myu1[i][1] * Myu1[i][1] * Myu1[i][1] * Myu1[i][1]) / 
                    ((Myu2[i][1] - Myu1[i][1] * Myu1[i][1]) * (Myu2[i][1] - Myu1[i][1] 
                      * Myu1[i][1]));
          }
        }
      }
      // Tell runtime system how many output items we produced.
      return noutput_items;
    }

  } /* namespace Kurtosis1 */
} /* namespace gr */

下面是顶级CMakeLists.txt文件:

代码语言:javascript
复制
########################################################################
# Project setup
########################################################################
cmake_minimum_required(VERSION 3.8)
project(gr-Kurtosis CXX C)
enable_testing()

# Install to PyBOMBS target prefix if defined
if(DEFINED ENV{PYBOMBS_PREFIX})
    set(CMAKE_INSTALL_PREFIX $ENV{PYBOMBS_PREFIX})
    message(STATUS "PyBOMBS installed GNU Radio. Setting CMAKE_INSTALL_PREFIX to $ENV{PYBOMBS_PREFIX}")
endif()

# Select the release build type by default to get optimization flags
if(NOT CMAKE_BUILD_TYPE)
   set(CMAKE_BUILD_TYPE "Release")
   message(STATUS "Build type not specified: defaulting to release.")
endif(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")

# Make sure our local CMake Modules path comes first
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules)

# Set the version information here
set(VERSION_MAJOR 1)
set(VERSION_API   0)
set(VERSION_ABI   0)
set(VERSION_PATCH git)

cmake_policy(SET CMP0011 NEW)

# Enable generation of compile_commands.json for code completion engines
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

########################################################################
# Compiler specific setup
########################################################################
if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
    CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    AND NOT WIN32)
    #http://gcc.gnu.org/wiki/Visibility
    add_definitions(-fvisibility=hidden)
endif()

IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    SET(CMAKE_CXX_STANDARD 11)
ELSEIF(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    SET(CMAKE_CXX_STANDARD 11)
ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
    SET(CMAKE_CXX_STANDARD 11)
ELSE()
    message(WARNING "C++ standard could not be set because compiler is not GNU, Clang or MSVC.")
ENDIF()

IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
    SET(CMAKE_C_STANDARD 11)
ELSEIF(CMAKE_C_COMPILER_ID MATCHES "Clang")
    SET(CMAKE_C_STANDARD 11)
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
    SET(CMAKE_C_STANDARD 11)
ELSE()
    message(WARNING "C standard could not be set because compiler is not GNU, Clang or MSVC.")
ENDIF()

########################################################################
# Install directories
########################################################################
find_package(Gnuradio "3.8" REQUIRED)
include(GrVersion)

include(GrPlatform) #define LIB_SUFFIX

find_package(FFTW3f)

if(NOT CMAKE_MODULES_DIR)
  set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake)
endif(NOT CMAKE_MODULES_DIR)

set(GR_INCLUDE_DIR      include/Kurtosis)
set(GR_CMAKE_DIR        ${CMAKE_MODULES_DIR}/Kurtosis)
set(GR_PKG_DATA_DIR     ${GR_DATA_DIR}/${CMAKE_PROJECT_NAME})
set(GR_PKG_DOC_DIR      ${GR_DOC_DIR}/${CMAKE_PROJECT_NAME})
set(GR_PKG_CONF_DIR     ${GR_CONF_DIR}/${CMAKE_PROJECT_NAME}/conf.d)
set(GR_PKG_LIBEXEC_DIR  ${GR_LIBEXEC_DIR}/${CMAKE_PROJECT_NAME})
set(GR_REQUIRED_COMPONENTS RUNTIME FFTW3f)

########################################################################
# On Apple only, set install name and use rpath correctly, if not already set
########################################################################
if(APPLE)
    if(NOT CMAKE_INSTALL_NAME_DIR)
        set(CMAKE_INSTALL_NAME_DIR
            ${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE
            PATH "Library Install Name Destination Directory" FORCE)
    endif(NOT CMAKE_INSTALL_NAME_DIR)
    if(NOT CMAKE_INSTALL_RPATH)
        set(CMAKE_INSTALL_RPATH
            ${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE
            PATH "Library Install RPath" FORCE)
    endif(NOT CMAKE_INSTALL_RPATH)
    if(NOT CMAKE_BUILD_WITH_INSTALL_RPATH)
        set(CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE
            BOOL "Do Build Using Library Install RPath" FORCE)
    endif(NOT CMAKE_BUILD_WITH_INSTALL_RPATH)
endif(APPLE)

########################################################################
# Find gnuradio build dependencies
########################################################################
find_package(Doxygen)

########################################################################
# Setup doxygen option
########################################################################
if(DOXYGEN_FOUND)
    option(ENABLE_DOXYGEN "Build docs using Doxygen" ON)
else(DOXYGEN_FOUND)
    option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF)
endif(DOXYGEN_FOUND)

########################################################################
# Create uninstall target
########################################################################
configure_file(
    ${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in
    ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
@ONLY)

add_custom_target(uninstall
    ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
    )


########################################################################
# Add subdirectories
########################################################################
add_subdirectory(include/Kurtosis)
add_subdirectory(lib)
add_subdirectory(apps)
add_subdirectory(docs)
add_subdirectory(swig)
add_subdirectory(python)
add_subdirectory(grc)

########################################################################
# Install cmake search helper for this library
########################################################################

install(FILES cmake/Modules/KurtosisConfig.cmake
    DESTINATION ${CMAKE_MODULES_DIR}/Kurtosis
)

下面是lib/CMakeLists.txt文件:

代码语言:javascript
复制
########################################################################
# Setup library
########################################################################
include(GrPlatform) #define LIB_SUFFIX

list(APPEND Kurtosis_sources
    Kurtosis_c_impl.cc
)

set(Kurtosis_sources "${Kurtosis_sources}" PARENT_SCOPE)
if(NOT Kurtosis_sources)
    MESSAGE(STATUS "No C++ sources... skipping lib/")
    return()
endif(NOT Kurtosis_sources)

add_library(gnuradio-Kurtosis SHARED ${Kurtosis_sources})
target_link_libraries(gnuradio-Kurtosis PUBLIC ${FFTW3F_LIBRARIES}
                      gnuradio::gnuradio-runtime fftw3f::fftw3f)
target_include_directories(gnuradio-Kurtosis
    PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
    PUBLIC $<INSTALL_INTERFACE:include>
  )
link_directories(${FFTW3F_LIBRARY_DIRS})
set_target_properties(gnuradio-Kurtosis PROPERTIES DEFINE_SYMBOL "gnuradio_Kurtosis_EXPORTS")

if(APPLE)
    set_target_properties(gnuradio-Kurtosis PROPERTIES
        INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib"
    )
endif(APPLE)

########################################################################
# Install built library files
########################################################################
include(GrMiscUtils)
GR_LIBRARY_FOO(gnuradio-Kurtosis FFTW3f)


########################################################################
# Print summary
########################################################################
message(STATUS "Using install prefix: ${CMAKE_INSTALL_PREFIX}")
message(STATUS "Building for version: ${VERSION} / ${LIBVER}")

########################################################################
# Build and register unit test
########################################################################
include(GrTest)

include_directories(${CPPUNIT_INCLUDE_DIRS})

# If your unit tests require special include paths, add them here
#include_directories()
# List all files that contain Boost.UTF unit tests here
list(APPEND test_Kurtosis_sources
)


# Anything we need to link to for the unit tests go here
list(APPEND GR_TEST_TARGET_DEPS gnuradio-Kurtosis)

if(NOT test_Kurtosis_sources)
    MESSAGE(STATUS "No C++ unit tests... skipping")
    return()
endif(NOT test_Kurtosis_sources)

foreach(qa_file ${test_Kurtosis_sources})
    GR_ADD_CPP_TEST("Kurtosis_${qa_file}"
        ${CMAKE_CURRENT_SOURCE_DIR}/${qa_file}
    )
endforeach(qa_file)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-27 09:26:20

代码语言:javascript
复制
link_directories(${FFTW3F_LIBRARY_DIRS})

这不是一个好主意;您需要链接到库,而不仅仅是告诉链接器包含库的目录可能也很有趣。

相反,您可以使用现代的CMake接口来链接库:这已经告诉CMake链接,以及如何在链接时找到库。太棒了!您只需删除这行link_directories

这里的问题是链接到FFTWf (请注意f:单精度,这对于SDR应用程序来说通常是足够的!),但是要使用一些双精度例程。使用fftwf_executefftwf_complex

这只是一种不必要复杂的内存复制方式:

代码语言:javascript
复制
      for(int i = 0; i < d_N; i++)
      {
        d_input[i][0] = in[i].real();
        d_input[i][1] = in[i].imag();
      }

gr_complex类型是真实的,假想的部分就在彼此后面,与fftwf_complex完全相同。计划您的DFT允许您选择您的输入内存,而不是必须将数据复制到固定位置。

更舒服的是:移除您自己的所有FFTW(f)处理,只需使用gr::fft::fft_complex_rev,它为您完成了所有这些操作:

在Kurtosis_c_impl.h中:

代码语言:javascript
复制
#include <gnuradio/fft/fft.h>
…
class Kurtosis_c {
…
   fft::fft_complex_rev d_fft;
…
};

在Kurtosis_c_impl.cc中:

代码语言:javascript
复制
…
// constructor gets shorter :)
Kurtosis_c_impl::Kurtosis_c_impl(int fftsize) //should be unsigned int, by the way
      : gr::sync_block("Kurtosis_c",
              gr::io_signature::make(1, 1, sizeof(gr_complex)),
              gr::io_signature::make(0, 0, 0)),
              d_N(fftsize),
              d_fft(fftsize) {}
…
// work function:
    int
    Kurtosis_c_impl::work(int noutput_items,
        gr_vector_const_void_star &input_items,
        gr_vector_void_star &output_items)
    {
      const gr_complex *in = (const gr_complex*) input_items[0];
      for(unsigned int idx = 0; idx < d_N; ++idx) {
        d_fft.get_inbuf()[idx] = in[idx];
      }
      d_fft.execute();

关于:

代码语言:javascript
复制
      for(int i = 0; i < d_N; i++)
      {   
        S1[i][0] = S1[i][0] + d_input[i][0];
        S1[i][1] = S1[i][1] + d_input[i][1];

你意识到在C++中有复数,你可以做复数运算吗?如果您的S1gr_complex的数组/向量/其他容器(它只是std::complex<float>的别名,给定包含顺序,与fftwf_complex一样),那么这可以归结为

代码语言:javascript
复制
for(unsigned int i = 0; i < d_N; ++i)
{
  S1[i] += d_input[i];
}

编写可读的代码是很重要的!在这种情况下,它是可以的,特别是因为你后来做了更高的力量的真实和想象部分的d_input,无论如何。

然而,

代码语言:javascript
复制
        dc[i][0] = dc[i][0] + 1;
        dc[i][1] = dc[i][1] + 1;

来一个。那太浪费了。与其把一个数字增加+1,N倍,不如把它增加N,一次。

代码语言:javascript
复制
      for(int i = 0; i < d_N; i++)
      {
        K[i][0] = (Myu4[i][0] - 4 * Myu3[i][0] * Myu1[i][0] + 6 * Myu2[i][0] * Myu1[i][0] 
               * Myu1[i][0] - 3 * Myu1[i][0] * Myu1[i][0] * Myu1[i][0] * Myu1[i][0]) / 
                ((Myu2[i][0] - Myu1[i][0] * Myu1[i][0]) * (Myu2[i][0] - Myu1[i][0] 
                  * Myu1[i][0]));
  
        K[i][1] = (Myu4[i][1] - 4 * Myu3[i][1] * Myu1[i][1] + 6 * Myu2[i][1] * Myu1[i][1] 
               * Myu1[i][1] - 3 * Myu1[i][1] * Myu1[i][1] * Myu1[i][1] * Myu1[i][1]) / 
                ((Myu2[i][1] - Myu1[i][1] * Myu1[i][1]) * (Myu2[i][1] - Myu1[i][1] 
                  * Myu1[i][1]));
      }

老实说,这是不可读的,你和你的主管将诅咒你下周,当你们中的任何一个试图阅读这篇文章。

代码语言:javascript
复制
      for(int i = 0; i < d_N; i++)
      {
        const auto& M1 = Myu1[i];
        const auto& M2 = Myu2[i];
        const auto& M3 = Myu3[i];
        const auto& M4 = Myu4[i];
        K[i].real() = (M4.real() - 4 * M3.real() * M1.real()  //comment on what this is
               + 6 * M2.real() * M1.real() * M1.real()  // comment
               - 3 * M1.real() * M1.real() * M1.real() * M1.real() /  // comment
                ((M2.real() - M1.real() * M1.real()) * (M2.real() - M1.real() * M1.real())); //comment
  
        K[i].imag() = /* This seems to be the exact same thing as above.
                          Clear indication that you should write a small inline
                          function that takes four float arguments and 
                          returns a flow to do this */
      }

请注意,这实际上产生了与您的编写方法相同的机器代码,因为这些.real().imag()函数只是编译到相同的内存访问中。以及像M1…这样的参考资料M4只是逻辑糖,也没有开销。

最重要的是,

代码语言:javascript
复制
  // Tell runtime system how many output items we produced.
  return noutput_items;

你没看过那个评论!您不会返回您生产的项目的数量(这与您生产的相同)。您的行为就好像您使用了所有的输入,即使您只是使用d_N!您甚至没有检查是否至少有d_N输入项。,这是必要的。 GNU电台将给你不同数量的输入项目,而不是总是相同的数字!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72400469

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档