2015-05-19 5 views
7

Я пытаюсь загрузить на этапе TEST сетевую конфигурацию, которая сначала имеет уровень данных памяти, а затем уровень свертки. Создание слой MemoryData успешно, Но создание свертка слоя не удается по следующему адресу:Ошибка создания слоя Caffe

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 (т ип) == 1 (0 против 1) Неизвестного типа слоя: Свертка (известные типов: MemoryData)

реестра имеет один вход, действительно только с М emoryData. При пошаговом в функции создания реестра, это выглядит, как это первый (и последний, так как это singletone) вызывается из

REGISTER_LAYER_CLASS(MemoryData); 

в memory_data_later.cpp.

Я вижу похожие REGISTER_LAYER_CLASS вызывает другие поддерживаемые слои, но похоже, что они никогда не вызываются. Как я могу это решить?

Спасибо!

ответ

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}) 

Быстрое решение было бы построить и ссылку кофейная, как shared lib вместо статического.

См. Также this post.

Просто заполните это для компиляции MSVC в Windows: Используйте /OPT:NOREF или /INCLUDE параметры компоновщика в исполняемом файле или dll.

+0

Это была именно эта проблема. Я сначала преодолел это, принудив компоновщика включать «неиспользуемые» (= почти все слои) файлы obj в хакерском уродливом виде - ваше предложение наверняка будет правильным. Спасибо! – rkellerm

+0

В IOS не поддерживалась динамическая библиотека. Я создал статический lib для Caffe.I получил ту же ошибку выше в 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

Замените -l$(PROJECT) на $(STATIC_LINK_COMMAND) в вашем файле Makefile в соответствующих местах и ​​удалите ненужный путь загрузки во время работы: -Wl,-rpath,$(ORIGIN)/../lib.

Смежные вопросы