I'm trying to load in TEST phase a network configuration which has a memory data layer first and then a convolution layer. The MemoryData layer creation succeeds, But the convolution layer's creation fails at the following location:
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() << ")";
Printed error is:
F0519 14:54:12.494139 14504 layer_factory.hpp:77] Check failed: registry.count(t ype) == 1 (0 vs. 1) Unknown layer type: Convolution (known types: MemoryData)
registry has one entry only, indeed with MemoryData. When stepping into the registry creation functions, it looks like it first (and last, since this is a singletone) called from
REGISTER_LAYER_CLASS(MemoryData);
in memory_data_later.cpp.
I see similar REGISTER_LAYER_CLASS
calls for the other supported layers, but it looks like they are never called.
How could I solve it?
Thanks!
This error occurs when trying to link caffe statically to an executable. You need to pass extra linker flags to make sure that layer registration code gets included.
If you are using cmake take a look at 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()
And then where you create your target:
# target
add_executable(${name} ${source})
target_link_libraries(${name} ${Caffe_LINK})
A quick solution would be to build and link caffe as a shared lib instead of static.
Also see this post.
Just to complete this for MSVC compilation on Windows: Use /OPT:NOREF or /INCLUDE linker options on the target executable or dll.