#ifndef CAFFE_PYTHON_LAYER_HPP_ #define CAFFE_PYTHON_LAYER_HPP_ #include #include #include "caffe/layer.hpp" namespace bp = boost::python; namespace caffe { template class PythonLayer : public Layer { public: PythonLayer(PyObject* self, const LayerParameter& param) : Layer(param), self_(bp::handle<>(bp::borrowed(self))) { } virtual void LayerSetUp(const vector*>& bottom, const vector*>& top) { // Disallow PythonLayer in MultiGPU training stage, due to GIL issues // Details: https://github.com/BVLC/caffe/issues/2936 if (this->phase_ == TRAIN && Caffe::solver_count() > 1 && !ShareInParallel()) { LOG(FATAL) << "PythonLayer is not implemented in Multi-GPU training"; } self_.attr("param_str") = bp::str( this->layer_param_.python_param().param_str()); self_.attr("setup")(bottom, top); } virtual void Reshape(const vector*>& bottom, const vector*>& top) { self_.attr("reshape")(bottom, top); } virtual inline bool ShareInParallel() const { return this->layer_param_.python_param().share_in_parallel(); } virtual inline const char* type() const { return "Python"; } protected: virtual void Forward_cpu(const vector*>& bottom, const vector*>& top) { self_.attr("forward")(bottom, top); } virtual void Backward_cpu(const vector*>& top, const vector& propagate_down, const vector*>& bottom) { self_.attr("backward")(top, propagate_down, bottom); } private: bp::object self_; }; } // namespace caffe #endif