111qqz的小窝

老年咸鱼冲锋!

vim 插件 NERDTree 学习笔记

迫于要在服务器上写cpp代码,又由于各种原因,没办法把同步到本地。因此要在服务器上配置一个cpp的环境orz.

我是用vim-plug来管理插件的,只需要添加

Plug ‘scrooloose/nerdtree’, { ‘on’:  ‘NERDTreeToggle’ }  就好了。
下面记录一些会用到的快捷键:

ctrl+w类似tmux里面的功能键。

crtl+w+w: 光标自动在左右侧窗口切换

cril+w+r:调换左右侧窗口的布局位置

t 在新 Tab 中打开选中文件/书签,并跳到新 Tab
T 在新 Tab 中打开选中文件/书签,但不跳到新 Tab
gT 前一个 tab
gt 后一个 tab

gRPC学习笔记

gRPC 是 google 最新发布的开源 RPC 框架, 声称是”一个高性能,开源,将移动和HTTP/2放在首位的通用的RPC框架.”. 技术栈非常的新, 基于HTTP/2, netty4.1, proto3, 拥有非常丰富而实用的特性, 堪称新一代RPC框架的典范.

//上面这段话是我抄的,其实我之前连RPC是什么都不知道,

关于RPC,如果你和我一样根本不知道是什么,请参考这里 

我对RPC的理解就是,一层封装,使得不在同一个机器上的程序A可以一个调用另一个程序B,而不需要考虑这两台机器,以及这两个程序使用的语言的不同。

而gRPC是诸多RPC框架中比较新,也比较好用的一个。

学习gRPC需要会使用protobuf3,关于protobuf,可以参考protobuf学习笔记

官方文档 还是要给出的,虽然我没怎么看就是了orz

gRPC的安装

参考这个,从源码编译安装

如果出现

参考

Compile fails on Ubuntu 14.04 ?  发现是protobuf的锅,需要手动编译一下:

 

gRPC的使用

grpc/examples下有一些例子,自己搞搞就会写基本的了。(已经硬着头皮用gRPC写了一个项目的通信部分了orz…其实还挺容易的。但是项目的代码没办法放上来。。。所以。。直接看examples的代码就好了。

8102年了,来更新一波vim配置

现在用的vim配置还是2015年7月的时候写的。

三年过去了,vim到了8.0,很多功能也有了更多选择。因此打算来更新一波vim配置。目前还在更新过程中。。。等差不多折腾完再来记录一些信息。

 

protobuf学习笔记

Protobuff 是一种轻便高效的结构化数据存储格式,可以用于结构化数据序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

之前由于要用levelDB存feature,而levelDB的key只能是string(?,反正不能是一个数组), 使用了protobuf. protobuf本身还比较easy,不过目前似乎protobuf2仍然是主流,但是由于最近在看gRPC的缘故,要使用protobuf3. 如果protobuf2没有卸载干净,绝对欲仙欲死…记录一些坑.详细一点的笔记之后补.

// protobuf3坑好多啊…语法全靠猜,也是有毒 

行吧,怪我没找到orz,生成的cpp语法部分在 这里

先放参考资料好了。一开始找到一个pdf文档,说是官方文档的翻译版…但实际上感觉,讲得很烂。直接看官方文档比较好。

其中 Language Guide (proto3) 讲了protobuf3的proto文件的语法相关。

Protocol Buffer Basics: C++ 讲了怎么从编写proto文件到在cpp中使用的一般步骤(注意此处貌似是按照protobuf2讲的)

C++ Generated Code 讲了生成的cpp代码的接口,并且强调了protobuf2和protobuf3的区别。

生成相应代码的语法为: protoc  –cpp_out=.    test.proto

编译选项为:g++ mytest.cc test.pb.cc -o test -lprotobuf

可能遇到这个问题

Undefined reference to google protobuf

解决办法是卸载掉系统自带的protobuf相关(ubuntu14.04默认还都是protbuf2,protobuf3我是从源码自己编译的)
apt-get remove libprotobuf-dev

 

如果X是单个的变量,那么语法为set_X(val)

如果X是repeated类型,语法为add_X(val)

protobuf中message的嵌套:

对于如下的.proto


使用cpp代码访问如下:

需要注意,如果我们想要修改某个class中的另一个class的单个值,需要用mutable_name()方法,而不是name()方法.参考如下例子:

Feature里嵌套了一个Single,我现在想修改某个feature中的sin,代码如下:

但是如果要修改的是某个class中另一个class的repeated的值,则要使用add_name.

参考如下例子:

 

需要注意的是生成的代码的大小写敏感问题

对于生成cpp代码来说,无论.proto文件中的变量名是Abc还是aBc还是ABC,在生成的cpp代码中都是abc…

protobuf的大小写敏感有点坑orz..

 

troubleshooting

试图从3.5降级到3.3时编译helloworld无问题,但是运行时报错

折腾了一下午。。发现其实并不是protobuf的问题。。

用gdb调试发现。。。是grpc的一个动态库中check版本挂掉了。。。

观察grpc。。。发现还是4月20号左右的版本。。。于是删掉了所有之前的grpc在/usr/local/lib下的4月的.so文件。。。

再次运行。。成功了orz….

所以这个问题其实是。。。降级grpc遇到的问题。。。

报错太有误导性了。

 

levelDB 学习笔记

大三的时候看过一点levelDB的源码,不过没有怎么用过。

最近有个需求是存人脸的feature到硬盘,似乎使用levelDB比较合适,因此来学习一下使用。

先放参考资料。

关于levelDB的语法,看这里就好了。

以及由于caffe中使用了levelDB,因此也可以参考下caffe源码。不过caffe中对levelDB的使用是又封装了一层。

具体可以参考:

 

 

 

几个文件。。。感觉比看文档更有实际意义orz

levelDB简介

Leveldb是google开源的一个高效率的K/V数据库.有如下特点:

  1. 首先,LevelDb是一个持久化存储的KV系统,和Redis这种内存型的KV系统不同,LevelDb不会像Redis一样狂吃内存,而是将大部分数据存储到磁盘上。
  2. 其次,LevleDb在存储数据时,是根据记录的key值有序存储的,就是说相邻的key值在存储文件中是依次顺序存储的,而应用可以自定义key大小比较函数,LevleDb会按照用户定义的比较函数依序存储这些记录。
  3. 再次,像大多数KV系统一样,LevelDb的操作接口很简单,基本操作包括写记录,读记录以及删除记录。也支持针对多条操作的原子批量操作。
  4. 另外,LevelDb支持数据快照(snapshot)功能,使得读取操作不受写操作影响,可以在读操作过程中始终看到一致的数据。
  5. 除此外,LevelDb还支持数据压缩等操作,这对于减小存储空间以及增快IO效率都有直接的帮助。
  6. LevelDb性能非常突出,官方网站报道其随机写性能达到40万条记录每秒,而随机读性能达到6万条记录每秒。总体来说,LevelDb的写操作要大大快于读操作,而顺序读写操作则大大快于随机读写操作。

LevelDB的安装

以ubuntu14.04为例,但实际上除了路径可能不同,其他部分是系统无关的。

leveldb_github地址

然后记得切换到指定tag

可以使用git tag命令得到,然后用git checkout命令切换,我这里使用的是1.20版本

之后直接执行make

之后将头文件拷贝到系统路径下:

编译之后分别会得到out-shared和out-static两个文件夹,分别是动态库和静态库

我们进入out-shared文件夹,讲libleveldb.so*的三个文件(有两个是链接)拷贝到/usr/lib下

然后用sudo ldconfig 命令将动态库加到缓存中。

我们用如下代码测试一下:

编译选项为:

g++ mytest.cc -o mytest -lpthread -lleveldb

如果运行得到jason,表示安装成功。

 

LevelDB的使用

一些基本操作可以参考github文档

不过发现levelDB的接口似乎只支持key和value都是string类型。。

然而对于人脸提取feature,实际上需要的是string映射到float**

,偶然发现caffe中使用了levelDB,

发现它的做法是使用protobuf将数据序列化,然后再存储。

protobuf学习笔记

 

注意事项

记录一些踩坑的经历..

如果有100条数据,想要每10条存一个数据库,那么每10条执行一次DB::Open就行了…不然会报错在put那里,导致core dumped

 

 

 

caffe2 添加自定义op

记录一些一个没有之前没有接触过caffe/caffe2的人为了添加自定义的op 到caffe2需要做的工作.

首先参考caffe2 tutorial,随便跑个op来试试,不妨以比较简单的  Accumulate_op 为例子.

这个op的作用就是计算Y=X+gamma*Y, 其中X为输入,Y为输出,gamma是参数.

跑起来这个运算所需要的代码如下:

c之后我们仿照caffe2/operators/accumultate_op.h和affe2/operators/accumultate_op.cc,仿写一个我们自己的运算atest_op.h和atest_op.cc

实现的功能为Y=5*X+gamma*Y

之后我们编译整个caffe2,编译方式是运行pytorch/scripts/build_local.sh

编译成功后,需要将pytorch目录添加到PYTHONPATH中

然后运行

看是否成功

编译的时候可能出现mpi_test.cc.o: undefined reference to symbol ‘_ZN3MPI8Datatype4FreeEv  的报错。。解决办法是把CMakeList中的MPI关掉就好了。。。

以及。。。operators中的文件都不要删。。。本想删一些不相关的op来减少编译时间。。。想法是对的。。。但是似乎只删op是行不通的。。。。不如不删。。。不然会编译出现奇怪的错误!

不然会编译出现奇怪的错误!

不然会编译出现奇怪的错误!

以及。。。从github download的速度太慢了。。。干脆开了个40$/m的vps来搞。。。

编译成功后修改测试的python代码,来测试一下我们定义的op

发现确实是得到了Y=5*X+gamma*Y 的结果。。

撒花!(然而这只是最近要做的任务中最容易的一条线orz…

需要注意的是,运行bash build_local.sh脚本之后会在pytorch目录下生成build文件夹,下次编译的时候直接在build目录下执行make -j20,这样才是增量编译

编译的时候直接在build目录下执行make -j20,这样才是增量编译

编译的时候直接在build目录下执行make -j20,这样才是增量编译

不然每次执行build_local.sh…不知caffe2用了什么机制…每次要把所有文件编译一遍…简直没有人性啊…16个cpu一起编也要5分钟Orz

以及...要在自己定义的函数最后返回true…这样在运行的时候才不会报错.否则会报net error 的错误Orz….我好傻啊?

 

 

Eigen: C++开源矩阵学习笔记

接触Eigen的原因是最近在看caffe/caffe2源码,caffe2中使用了Eigen库. Eigen 是一个基于C++模板的线性代数库,直接将库下载后放在项目目录下,然后包含头文件就能使用,非常方便。对于Linux用户,只需要把头文件放到/usr/include 下即可此外,Eigen的接口清晰,稳定高效。

之后会更新一些,Eigen中我使用过的函数.

ubuntu14.04LTS 下使用方式:

然后尝试运行如下代码,直接编译即可.如果可以正常运行,表明安装完毕.

map的使用办法:

double arr[9]={1,2,3,4,5,6,7,8,9};
Map<MatrixXd> A(arr,3,3);
得到
1 4 7
2 5 8
3 6 9

以看出默认是按列优先的…
如果需要按行优先,可以修改矩阵的定义方式:
typedef Matrix<double, Dynamic, Dynamic,RowMajor>rMatrixXd;//定义矩阵行优先
double arr[9]={1,2,3,4,5,6,7,8,9};
Map A(arr,3,3);

map使用的时候,只需要指定map<>中,缺少(dynamic)的维度.
比如

得到结果

1
2
3
4

平均值

对于矩阵:

1 4 7
2 5 8
3 6 9

按行求平均值A.rowwise().mean()

得到:

4
5
6

按列求平均值 A.colwise().mean
得到
2 5 8

unaryExpr()

参数为一元函数算子,表示对每一项应用该一元算子.具体看例子

返回的结果为:
1 16 49
4 25 64
9 36 81

 

replicate

将一个对象重复多干次.

语法为A.replicate(x,y)表示将A横向扩展x次(包含本身),纵向扩展y次(包含本身),共得到x*y个

 

linux/win双系统 更新win后 grub 出现 Error: unknown filesystem 的解决办法

windows自己更新把grub更新挂了….

更新的时候要重启几次,重启一次挂一次…

讲真,windows(或者说win10?) 是我见过的最辣鸡的OS了…  自己把自己弄挂这事不是一两次了.

下面说修复办法:

先ls,得到一堆诸如(hd0,gpt7) 这种

然后选设X=第一个(x,y)形式的输出

之后

[/crayon]

然后记得要进入linux分区…..
执行:
sudo update-grub
sudo grub-install /dev/sda

总结:珍爱生命,远离辣鸡windows!!!!!

珍爱生命,远离辣鸡windows!!!!!

珍爱生命,远离辣鸡windows!!!!!