Caffe层的创建失败

7

我正在尝试加载一个网络配置,其中首先有一个内存数据层,然后是一个卷积层,在测试阶段进行。MemoryData层的创建成功了,但是卷积层在以下位置的创建失败了:

LOG(INFO) << "Creating layer " << param.name();
const string& type = param.type();
CreatorRegistry& registry = Registry();
CHECK_EQ(registry.count(type), 1) << "Unknown layer type: " << type
<< " (known types: " << LayerTypeList() << ")";

打印出的错误是:

F0519 14:54:12.494139 14504 layer_factory.hpp:77] 检查失败: registry.count(type) == 1 (0 vs. 1) 未知层类型:Convolution (已知类型:MemoryData)

注册表只有一项,确实是MemoryData。 当进入注册表创建函数时,看起来它首先调用了一个(也是最后一个,因为这是单例)由...调用。

REGISTER_LAYER_CLASS(MemoryData);

在memory_data_layer.cpp文件中。

我看到其他支持的层有类似的REGISTER_LAYER_CLASS调用,但似乎它们从未被调用。 我该如何解决这个问题?

谢谢!

2个回答

7
当试图将caffe静态链接到可执行文件时,会出现此错误。您需要传递额外的链接器标志,以确保层注册代码得到包含。
如果您正在使用cmake,请查看Targets.cmake:
###########################################################################################
# Defines global Caffe_LINK flag, This flag is required to prevent linker from excluding
# some objects which are not addressed directly but are registered via static constructors
if(BUILD_SHARED_LIBS)
  set(Caffe_LINK caffe)
else()
  if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
    set(Caffe_LINK -Wl,-force_load caffe)
  elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
    set(Caffe_LINK -Wl,--whole-archive caffe -Wl,--no-whole-archive)
  endif()
endif()

接着,在创建目标时:

# target
add_executable(${name} ${source})
target_link_libraries(${name} ${Caffe_LINK})

一个快速的解决方案是构建并链接caffe作为共享库而不是静态库。

还可以参见此帖子

仅为了在Windows上使用MSVC编译完成: 在目标可执行文件或动态链接库上使用/OPT:NOREF/INCLUDE链接器选项。


这正是问题所在。我最初通过以一种丑陋的方式强制链接器包含“未使用”的(几乎所有层)obj文件来克服它 - 你的建议肯定是正确的。谢谢! - rkellerm
在IOS中不支持动态库。我为Caffe创建了静态库。在IOS中我遇到了同样的错误。你是如何解决这个错误的? - balajichinna
1
@balajichinna: 你可以通过在头文件中原型化一个虚拟函数来强制进行链接(例如layer_factory.hpp),在其代码未链接的cpp文件中实现它(例如layer_factory.cpp),并在原型所在的头文件中静态调用它。例如:在layer_factory.hpp中:int lf_foo(); static int lf_dummy = lf_foo(); 在layer_factory.cpp中:int lf_foo() { return 0; }。丑陋,但有效。 - rkellerm
2
实际上,将“使用库依赖项输入”设置为true的/OPT:NOREF对我有用。我在这里阅读了相关信息:https://social.msdn.microsoft.com/Forums/vstudio/en-US/2aa2e1b7-6677-4986-99cc-62f463c94ef3/linkexe-bug-optnoref-option-doesnt-work?forum=vclanguage - Elena
1
对于iOS和静态框架,解决方法是在Xcode的构建设置中将-all_load添加到OTHER_LDFLAGS - jimj
显示剩余6条评论

2
请在你的Makefile中将-l$(PROJECT)替换为$(STATIC_LINK_COMMAND),并在适当的位置进行修改。同时删除不再需要的运行时加载路径:-Wl,-rpath,$(ORIGIN)/../lib

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接