首页 > 编程语言 >caffe中多个cpp共享一个变量 c++类中的静态变量

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

时间:2023-03-24 09:55:20浏览次数:39  
标签:const 变量 img bottom top c++ bias caffe diff

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、数据成员类型可以声明为所属类的类型,普通数据成员只能声明为所属类类型的指针或引用

标签:const,变量,img,bottom,top,c++,bias,caffe,diff
From: https://www.cnblogs.com/yanghailin/p/17250391.html

相关文章

  • C++ this 指针
    在C++中,每一个对象都能通过 this 指针来访问自己的地址。this 指针是所有成员函数的隐含参数。因此,在成员函数内部,它可以用来指向调用对象。友元函数没有 this 指......
  • C++ 标准库 sort() / stable_sort() / partial_sort() 对比
    C++STL标准库中提供了多个用于排序的Sort函数,常用的包括有sort()/stable_sort()/partial_sort(),具体的函数用法如下表所示:函数用法std::sort(first,last)......
  • what's the difference between const and constexpr in C++?
    BothconstandconstexprareusedtodefineconstantsinC++,buttheyhavedifferentmeaningsandusecases.constisusedtodeclareavariableasconstant,......
  • Loops in C++
    #include<iostream>usingnamespacestd;intmain(){intv[]={0,1,2,3,4};for(autox:v){cout<<x<<endl;}for(autoy:......
  • when should we use struct in C++?
    InC++,structisakeywordusedtodefineadatastructurethatgroupsmultiplevariablesofdifferentdatatypesintoasingleunit.Herearesomesituations......
  • what are the primitive types of C++?
    InC++,thereareseveralprimitivedatatypes,whicharealsoknownasfundamentalorbuilt-indatatypes.Theseinclude:Integertypes:Usedtorepresentw......
  • how to learn C++?
    HerearesomestepstolearnC++:Learnthebasics:StartwiththebasicsofC++,includingvariables,datatypes,controlstructures,loops,andfunctions.......
  • 解决使用同名32位和64位程序的环境变量冲突方案
    说到底环境变量只是一个简便用户书写路径的方式而已,当然可以使用环境变量优化用户体验或者使用指定文件亦可行。如果只是单一的程序,为了简单使用,可以配置环境变量,如iscc(......
  • C++ 内存池技术初探
    目录内存池意义单线程内存池全局函数new(),delete()局限性版本1:专用Rational内存管理器版本2:固定大小对象的内存池版本3:单线程可变大小内存管理器MemoryChunk内存块列表类......
  • 适用list数据分割 数据1000条更新处理一次,循环处理 for 循环 departments.size() 和
    数据1000条更新处理一次,循环处理for循环https://www.cnblogs.com/wanbiao/p/16587707.html为了缓解数据库压力,每次取值List后的更新操作改为1000条更新一次if(depa......