2016-09-20 4 views
0

Когда я бегу Caffe.exe, он делает это:Имеет ли Caffe статическое фиаско инициализации?

cudaDeviceProp deviceProp; 
cudaGetDeviceProperties(&deviceProp, 0); 
Caffe::SetDevice(0); 
Caffe::set_mode(Caffe::GPU); 
Net<float> caffe_net(modelFile, caffe::TEST); 
caffe_net.CopyTrainedLayersFrom(weightsFile); 

и все слои статически добавлены в LayerRegistry и все работает, как ожидалось.

Но если я Net член указатель класса ограждающей и поместить инициализацию в конструкторе, затем слои не статически добавлены в LayerRegistry:.

class Foo 
{ 
    Foo(); 
    std::unique_ptr< Net<float> > net; 
} 

Foo::Foo() 
{ 
    cudaDeviceProp deviceProp; 
    cudaGetDeviceProperties(&deviceProp, 0); 
    Caffe::SetDevice(0); 
    Caffe::set_mode(Caffe::GPU); 
    Net<float> caffe_net(modelFileName, caffe::TEST); 
    net.reset(new Net<float>(modelFileName, caffe::TEST)); 
    net->CopyTrainedLayersFrom(weightsFileName); 
} 

В layer_factory * я вижу что слои имеют REGISTER_LAYER_CREATOR макросъемки, где макрос определяется как:

#define REGISTER_LAYER_CREATOR(type, creator)         \ 
    static LayerRegisterer<float> g_creator_f_##type(#type, creator<float>);  \ 
    static LayerRegisterer<double> g_creator_d_##type(#type, creator<double>) \ 

ли Caffe содержат static initialization fiasco?

+0

Я вообще не знаю 'Caffe', поэтому возьмите это с солью. Какова связь между кодом в 'Foo :: Foo()' и 'REGISTER_LAYER_CREATOR'? –

+0

@RSahu Net содержит статически инициализированный реестр Layer, который статически инициализируется на основе макросов. Кофе ... сложный, поэтому кому-то, кто знает об этом, вероятно, придется ответить. – empty

+0

Вы пытались скомпилировать с '-Wl, - no-as-needed' (или что-то вроде эквивалента MSVC)? –

ответ

0

Ответ «Нет».

Проблема, как отмечает @TravisGockel в комментариях выше, заключается в том, что конструкторы LayerRegisterer необходимо принудительно связывать с DLL или исполняемыми файлами, когда они находятся в статической библиотеке.

Для Visual Studio C++, как указано в Forcing Construction of Global Objects in Static Libraries, решение состоит в том, чтобы принудительно связать эти конструкторы, установив Project|Properties|References|libcaffe|Project Reference Properties|Use Library Dependency Inputs в true.