2015-05-19 9 views
7

Sto provando a caricare in fase di PROVA una configurazione di rete che ha prima un livello di dati di memoria e poi un livello di convoluzione. La creazione strato di MemoryData riesce, Ma la creazione del livello spira fallisce al seguente indirizzo:Errore di creazione del livello di 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() << ")"; 

errore stampata è:

F0519 14: 54: 12,494,139 mila 14504 layer_factory.hpp: 77] Controllare fallito : registry.count (t ipo) == 1 (0 vs 1) Unknown strato di tipo: convoluzione (di tipo noto: MemoryData)

registro contiene una sola voce, anzi con M emoryData. quando si entra le funzioni di creazione del Registro, sembra che prima (e ultima, poiché questo è un Singletone) chiamato da

REGISTER_LAYER_CLASS(MemoryData); 

in memory_data_later.cpp.

Vedo chiamate simili REGISTER_LAYER_CLASS per gli altri livelli supportati, ma sembra che non vengano mai chiamati. Come posso risolverlo?

Grazie!

risposta

7

Questo errore si verifica quando si tenta di collegare caffe static a un file eseguibile. È necessario passare flag di linker aggiuntivi per assicurarsi che il codice di registrazione del layer venga incluso.

Se si utilizza cmake dare un'occhiata a 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() 

E poi in cui si crea il tuo obiettivo:

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

Una soluzione rapida sarebbe quella di costruire e di collegamento caffe come una lib condivisa anziché statica.

Vedere anche this post.

Solo per completare questo per la compilation MSVC su Windows: Utilizzare le opzioni di collegamento /OPT:NOREF o /INCLUDE sul file eseguibile o dll di destinazione.

+0

Questo era esattamente il problema. L'ho dapprima superato imponendo al linker di includere file obj "non utilizzati" (= quasi tutti i livelli) in un modo brutto e hacky - il tuo suggerimento è sicuramente la cosa giusta da fare qui. Grazie! – rkellerm

+0

In IOS non supporta la libreria dinamica. Ho creato la libreria statica per Caffe.ho ottenuto lo stesso errore precedente in IOS. Come hai risolto questo errore? – balajichinna

+1

@balajichinna: è possibile applicare il collegamento, ad esempio, prototipando una funzione fittizia in un file di intestazione (ad esempio layer_factory.hpp), implementandolo in cpp il cui codice non è collegato (ad esempio, layer_factory.cpp, e chiamandolo staticamente nell'intestazione in cui era stato prototipato. Ad esempio: in layer_factory.hpp: int lf_foo(); static int lf_dummy = lf_foo(); in layer_factory.cpp: int lf_foo() {return 0;}. Ugly, ma funziona – rkellerm

2

Sostituire -l$(PROJECT) con $(STATIC_LINK_COMMAND) nel Makefile nelle posizioni appropriate e rimuovere il percorso di caricamento di runtime non necessario ora: -Wl,-rpath,$(ORIGIN)/../lib.

Problemi correlati