caffe中多个cpp共享一个变量 c++类中的静态变量

发布时间 2023-03-24 09:54:16作者: 无左无右

caffe中需要整个共享变量,就是从bias过来的tensor转图片,然后后面目标检测第一阶段查看定位效果,把目标框画在图上就需要一开始的图片。

实验1:这个可以在prototxt增加一个top通过网络给到后面的层,但是这样太麻烦。

实验2:
然后想想能不能通过类似与共享变量能完成,
首先实验的是在基类Layer添加一个变量,然后bias_layer压入图片,因为所有的层都是从Layer派生出来。
class BiasLayer : public Layer<Ftype, Btype>
这样添加的:

class Layer : public LayerBase {
 public:
//    std::vector<cv::Mat> v_img;

不好使,各种报错。

又实验了在blob定义变量,在bias用extern std::vectorcv::Mat v_img_0;声明。编译报错其他cpp提示重复定义,然后在blob.hpp这么写
static std::vectorcv::Mat v_img_0;
这样重复定义的错误解决可以正常编译通过,但是在其他cpp用这个变量v_img_0报错,明明已经在bias压入了但是好像在其他cpp里面访问是空的,没法解决。。

实验3:
在blob类中添加静态变量

class Blob {
 public:
    static std::vector<cv::Mat> v_img_0;

在bias_layer.cu里面代码如下:
主要是
Blob::v_img_0.clear();
Blob::v_img_0.push_back(image.clone());

#include <vector>

#include "caffe/filler.hpp"
#include "caffe/layers/bias_layer.hpp"
#include "caffe/util/math_functions.hpp"
#include "opencv2/opencv.hpp"



namespace caffe {
//    extern std::vector<cv::Mat> v_img_0;

template <typename Dtype>
__global__ void BiasForward(const int n, const Dtype* in,
    const Dtype* bias, const int bias_dim, const int inner_dim,
    Dtype* out) {
  CUDA_KERNEL_LOOP(index, n) {
    const int bias_index = (index / inner_dim) % bias_dim;
    out[index] = in[index] + bias[bias_index];
  }
}

template <typename Ftype, typename Btype>
void BiasLayer<Ftype, Btype>::Forward_gpu(const vector<Blob*>& bottom,
      const vector<Blob*>& top) {
  const int count = top[0]->count();
  const Ftype* bottom_data = bottom[0]->gpu_data<Ftype>();
  const Ftype* bias_data =
      ((bottom.size() > 1) ? bottom[1] : this->blobs_[0].get())->template gpu_data<Ftype>();
  Ftype* top_data = top[0]->mutable_gpu_data<Ftype>();
  BiasForward  // NOLINT_NEXT_LINE(whitespace/operators)
      <<<CAFFE_GET_BLOCKS(count), CAFFE_CUDA_NUM_THREADS, 0, Caffe::thread_stream()>>>(
      count, bottom_data, bias_data, bias_dim_, inner_dim_, top_data);
  CUDA_CHECK(cudaStreamSynchronize(Caffe::thread_stream()));


int batchsize = bottom[0]->shape(0);
//  this->v_img.clear();
  Blob::v_img_0.clear();
for(int b =0;b<batchsize;b++)
{
const Ftype* top_cpu_data = top[0]->template cpu_data<Ftype>();
//  Ftype* top_cpu_data = top[0]->mutable_cpu_data()<Ftype>();




  int topheight= 192;
  int topwidth= 768;
  cv::Mat image=cv::Mat::zeros(topheight, topwidth, CV_8UC3);
  for (int i=0; i<topheight; i++)
    for(int j=0; j<topwidth; j++) {
      const Ftype* top_cpu_data1 = top_cpu_data + b * 3 * topheight * topwidth;
      int row = i;
      int col = j;
      uchar* ptr = image.data+(i*topwidth +j)*3;
      ptr[0] = (uchar)((top_cpu_data1[(topheight*0+i)*topwidth+j])*1 + 128);
      ptr[1] = (uchar)((top_cpu_data1[(topheight*1+i)*topwidth+j])*1 + 128);
      ptr[2] = (uchar)((top_cpu_data1[(topheight*2+i)*topwidth+j])*1 + 128);
    }
//  this->v_img.push_back(image.clone());
    Blob::v_img_0.push_back(image.clone());

//  cvtColor(image, image, CV_BGR2RGB);
  cv::imshow("imageslds", image);
  cv::waitKey(0);

}


}

template <typename Ftype, typename Btype>
void BiasLayer<Ftype, Btype>::Backward_gpu(const vector<Blob*>& top,
      const vector<bool>& propagate_down, const vector<Blob*>& bottom) {
  if (propagate_down[0] && bottom[0] != top[0]) {
    const Btype* top_diff = top[0]->gpu_diff<Btype>();
    Btype* bottom_diff = bottom[0]->mutable_gpu_diff<Btype>();
    caffe_copy(bottom[0]->count(), top_diff, bottom_diff);
  }
  // in-place, we don't need to do anything with the data diff
  const bool bias_param = (bottom.size() == 1);
  if ((!bias_param && propagate_down[1]) ||
      (bias_param && this->param_propagate_down_[0])) {
    const Btype* top_diff = top[0]->gpu_diff<Btype>();
    Btype* bias_diff = (bias_param ? this->blobs_[0].get() : bottom[1])
        ->template mutable_gpu_diff<Btype>();
    bool accum = bias_param;
    for (int n = 0; n < outer_dim_; ++n) {
      caffe_gpu_gemv(CblasNoTrans, bias_dim_, inner_dim_, Btype(1),
          top_diff, bias_multiplier_.template gpu_data<Btype>(), Btype(accum), bias_diff);
      top_diff += dim_;
      accum = true;
    }
  }
}

INSTANTIATE_LAYER_GPU_FUNCS_FB(BiasLayer);

}  // namespace caffe

这么整编译报错。

[  2%] Linking CXX shared library ../../lib/libcaffe-nv-d.so
[100%] Built target caffe
[100%] Linking CXX executable caffe-d
../lib/libcaffe-nv-d.so.0.16.0:对‘caffe::Blob::v_img_0’未定义的引用

在blob.cpp添加初始化代码,就解决

 std::vector<cv::Mat> Blob::v_img_0 = {};

在其他cpp就可以访问这变量

cv::Mat img = Blob::v_img_0[i];

解决!

c++类中的静态变量属于类,任何对象都可以访问且是共享的。
1、属于类,不属于对象,是类域中的全局变量

2、程序运行期间只有一个副本

3、不能在对象创建时初始化,即不能在类的构造函数初始化

4、被类、类对象、类的派生类对象共享

5、可以作为成员函数的可选参数,普通数据成员则不可以

6、数据成员类型可以声明为所属类的类型,普通数据成员只能声明为所属类类型的指针或引用