7

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!

rkellerm
  • 5,362
  • 8
  • 58
  • 95

2 Answers2

7

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.

rkellerm
  • 5,362
  • 8
  • 58
  • 95
Abai
  • 760
  • 1
  • 8
  • 16
  • This was exactly the issue. I first overcame it by enforcing the linker to include "unused" (=almost all layers) obj files in a hacky ugly way - your suggestion is for sure the right thing to do here. Thank you! – rkellerm May 25 '15 at 10:13
  • In IOS did not support Dynamic Library.I created static lib for Caffe.I got same above error in IOS. How did you solve this error.? – balajichinna Jul 07 '15 at 09:04
  • 1
    @balajichinna: you can enforce the linkage by, for example, prototyping a dummy function in a header file (for example layer_factory.hpp), implementing it in the cpp which its code isn't linked (for example layer_factory.cpp, and calling it statically within the header it was prototyped in. For example: in layer_factory.hpp: int lf_foo(); static int lf_dummy = lf_foo(); in layer_factory.cpp: int lf_foo() { return 0; }. Ugly, but works. – rkellerm Jul 08 '15 at 12:01
  • Thanks for your reply.So i declare the function in layer_factory.hpp: int lf_foo() {static int lf_dummy = lf_foo(); }.Is it right?..Can you tell how will i declare prototype method in "layer_factory.hpp" header file.? – balajichinna Jul 08 '15 at 15:59
  • @balajichinna: Like written above - in the hpp you only declare, not implement, e.g. int lf_foo(); and then use it, for example static int lf_dummy = lf_foo(); . These 2 lines of code only. in the cpp you implement it - int lf_foo() { return 0; }. – rkellerm Jul 13 '15 at 06:36
  • @rursw1 The only solution that I could make work in Visual Studio. – Elena Nov 26 '15 at 02:19
  • 2
    Actually /OPT:NOREF with "Use Library Dependency Inputs" set to true worked for me. I read about it here https://social.msdn.microsoft.com/Forums/vstudio/en-US/2aa2e1b7-6677-4986-99cc-62f463c94ef3/linkexe-bug-optnoref-option-doesnt-work?forum=vclanguage – Elena Nov 26 '15 at 02:44
  • @Elena, add this as an answer so we can vote up :) thank you! – rkellerm Dec 22 '15 at 11:13
  • @Elena, it did not solve the problem (in my case, the unknown layer type is Data). Any other suggestion? – Atena Nguyen Jul 11 '17 at 07:10
  • @AtenaNguyen I can only suggest rursw1's solution in this case. I cannot really check for other solutions in the moment since I no longer use Caffe (not doing CNNs anymore). – Elena Jul 21 '17 at 11:08
  • 1
    For iOS and static frameworks the fix was adding `-all_load` to `OTHER_LDFLAGS` in Xcode's build settings. – jimj Nov 07 '19 at 20:06
2

Replace -l$(PROJECT) with $(STATIC_LINK_COMMAND) in your Makefile in the appropriate places, and remove the now unnecessary runtime load path: -Wl,-rpath,$(ORIGIN)/../lib.

nicodjimenez
  • 1,180
  • 17
  • 15