Caffe代码分析--crop_layer.cu
因为要修改Caffe crop layer GPU部分的代码,现将自己对这部分GPU代码的理解总结一下,请大家多多指教!
crop layer完成的功能(以matlab的方式表示):A(N,C,H,W),Reference(n,c,h,w),Offsets(o1, o2, o3,o4), croped_A=A[o1:o1+n, o2:o2+c, o3:o3+h, o4:o4+w]
先代码,后解释
#include <vector>
#include "caffe/layers/crop_layer.hpp"
namespace caffe {
__device__ int compute_uncropped_index(
int index,
const int ndims,
const int* src_strides,
const int* dest_strides,
const int* offsets) {
int dest_index = index;
int src_index = ;
for (int i = ; i < ndims; ++i) {
int coord = dest_index / dest_strides[i];
dest_index -= coord * dest_strides[i];
src_index += src_strides[i] * (coord + offsets[i]);
}
return src_index;
}
template <typename Dtype>
__global__ void crop_kernel_forward(const int nthreads,
const int ndims,
const int* src_strides,
const int* dest_strides,
const int* offsets,
const Dtype* src, Dtype* dest) {
CUDA_KERNEL_LOOP(index, nthreads) {
int src_index = compute_uncropped_index(
index, ndims, src_strides, dest_strides, offsets);
dest[index] = src[src_index];
}
}
template <typename Dtype>
__global__ void crop_kernel_backward(const int nthreads,
const int ndims,
const int* src_strides,
const int* dest_strides,
const int* offsets,
Dtype* src, const Dtype* dest) {
CUDA_KERNEL_LOOP(index, nthreads) {
int src_index = compute_uncropped_index(
index, ndims, src_strides, dest_strides, offsets);
src[src_index] = dest[index];
}
}
template <typename Dtype>
void CropLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top) {
const Dtype* bottom_data = bottom[]->gpu_data();
Dtype* top_data = top[]->mutable_gpu_data();
int n = top[]->count();
// NOLINT_NEXT_LINE(whitespace/operators)
crop_kernel_forward<<<CAFFE_GET_BLOCKS(n), CAFFE_CUDA_NUM_THREADS>>>(n,
bottom[]->num_axes(),
src_strides_.gpu_data(),
dest_strides_.gpu_data(),
offsets.gpu_data(),
bottom_data, top_data);
}
template <typename Dtype>
void CropLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {
const Dtype* top_diff = top[]->gpu_diff();
Dtype* bottom_diff = bottom[]->mutable_gpu_diff();
int n = top[]->count();
if (propagate_down[]) {
caffe_gpu_set(bottom[]->count(), static_cast<Dtype>(), bottom_diff);
// NOLINT_NEXT_LINE(whitespace/operators)
crop_kernel_backward<<<CAFFE_GET_BLOCKS(n), CAFFE_CUDA_NUM_THREADS>>>(n,
bottom[]->num_axes(),
src_strides_.gpu_data(),
dest_strides_.gpu_data(),
offsets.gpu_data(),
bottom_diff, top_diff);
}
}
INSTANTIATE_LAYER_GPU_FUNCS(CropLayer);
} // namespace caffe
我将分析的重点放在Forward_gpu函数上,该函数在获取bottom、top data的指针之后,调用GPU端程序crop_kernel_forward。
其参数含义如下:
- nthreads: nxcxhxw
- ndims:4
- src_strides: (CxHxW,HxW,W,1)
- dest_strides:(cxhxw,hxw,w,1)
- offsets:(o1, o2, o3, o4)
- src:源指针
- dest:目的指针
可以理解为src是A矩阵,dest就是我们需要的croped_A矩阵
crop_kernel_forward函数将每一个数据影射到一个线程,先计算通过compute_uncropped_index函数计算src_index,然后进行赋值。这里的重点是compute_uncropped_index,下面我通过函数注释的方式解析一下该函数的具体含义。
__device__ int compute_uncropped_index(
int index,
const int ndims,
const int* src_strides,
const int* dest_strides,
const int* offsets) {
int dest_index = index; //将线程号赋给dest_index
int src_index = ; //初始化src_index
for (int i = ; i < ndims; ++i) { //每个维度分别处理
int coord = dest_index / dest_strides[i];//coord表示dest第i个维度的坐标
dest_index -= coord * dest_strides[i];//消除第i维坐标的影响
src_index += src_strides[i] * (coord + offsets[i]);//coord和offsets[i]在src_index引入的偏移
}
return src_index;
}
注释可能解释的比较含糊,可以简单理解为“给定一个index,获取dest对应的坐标(n’,c’,h’,w’),然后加上offsets偏移量,分别乘以不同坐标对应步长获取dest在src中的对应位置索引”。
Caffe代码分析--crop_layer.cu的更多相关文章
- caffe源代码分析--math_functions.cu代码研究
当中用到一个宏定义CUDA_KERNEL_LOOP 在common.hpp中有. #defineCUDA_KERNEL_LOOP(i,n) \ for(inti = blockIdx.x * bloc ...
- angular代码分析之异常日志设计
angular代码分析之异常日志设计 错误异常是面向对象开发中的记录提示程序执行问题的一种重要机制,在程序执行发生问题的条件下,异常会在中断程序执行,同时会沿着代码的执行路径一步一步的向上抛出异常,最 ...
- Caffe CommonLayer分析
Caffe CommonLayer分析 \(Caffe\)中包含了很多通用的功能层,包含了\(concat\),\(slice\),\(split\),\(crop\),\(flip\),\(scal ...
- Android代码分析工具lint学习
1 lint简介 1.1 概述 lint是随Android SDK自带的一个静态代码分析工具.它用来对Android工程的源文件进行检查,找出在正确性.安全.性能.可使用性.可访问性及国际化等方面可能 ...
- pmd静态代码分析
在正式进入测试之前,进行一定的静态代码分析及code review对代码质量及系统提高是有帮助的,以上为数据证明 Pmd 它是一个基于静态规则集的Java源码分析器,它可以识别出潜在的如下问题:– 可 ...
- [Asp.net 5] DependencyInjection项目代码分析-目录
微软DI文章系列如下所示: [Asp.net 5] DependencyInjection项目代码分析 [Asp.net 5] DependencyInjection项目代码分析2-Autofac [ ...
- [Asp.net 5] DependencyInjection项目代码分析4-微软的实现(5)(IEnumerable<>补充)
Asp.net 5的依赖注入注入系列可以参考链接: [Asp.net 5] DependencyInjection项目代码分析-目录 我们在之前讲微软的实现时,对于OpenIEnumerableSer ...
- 完整全面的Java资源库(包括构建、操作、代码分析、编译器、数据库、社区等等)
构建 这里搜集了用来构建应用程序的工具. Apache Maven:Maven使用声明进行构建并进行依赖管理,偏向于使用约定而不是配置进行构建.Maven优于Apache Ant.后者采用了一种过程化 ...
- STM32启动代码分析 IAR 比较好
stm32启动代码分析 (2012-06-12 09:43:31) 转载▼ 最近开始使用ST的stm32w108芯片(也是一款zigbee芯片).开始看他的启动代码看的晕晕呼呼呼的. 还好在c ...
随机推荐
- ultraedit中文乱码解决方案
高级--->配置--->文件处理--->Unicode/UTF-8检测 打钩自动检测UTF-8 文件,去掉其他钩. 来自为知笔记(Wiz)
- C字符串输入输出函数
下面就几个常用的字符串输入输出函数做个小小的总结TAT 使用时添加头文件:#include<stdio.h>. scanf("格式控制字符串",变量地址列表):(pri ...
- 交作业啊,python爬取58的页面
第一次写博文,好紧张啊,写这么烂怎么给别人看啊先做下总结: 刚开始学习python,自我感觉python写起来确实很方便,各种库,各种语法糖,不过刚接触,一下子记不下来这么多东西,总感觉乱乱的,用的多 ...
- Java--定时器问题
定时器问题 定时器属于基本的基础组件,不管是用户空间的程序开发,还是内核空间的程序开发,很多时候都需要有定时器作为基础组件的支持.一个定时器的实现需要具备以下四种基本行为:添加定时器.取消定时器.定时 ...
- 某公司HP-EVA4400数据丢失的恢复方法和恢复全过程
一.故障描述1.设备清单一台HP-EVA4400控制器(型号:AG638-53011)三台HP-EVA4400扩展柜(型号为AG638-63001),和28块HP-FC磁盘(型号为300G FC硬盘) ...
- 篇2 安卓app自动化测试-初识python调用appium
篇2 安卓app自动化测试-初识python调用appium --lamecho辣么丑 1.1概要 大家好!我是lamecho(辣么丑),上一篇也是<安卓app自动化测 ...
- VMware Ubuntu 安装
最近对Linux系统有兴趣,本想装个双系统,考虑自己是以Windows为主,所以装了个虚拟机 VMware Workstation 12 Pro 版Ubuntu镜源文件下载地址:https://www ...
- 蓝桥杯-写日志-java
/* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...
- 新鲜出炉的less与sass较量
最近接触了Bootstrap,涉及到了LESS,CSS的预处理器使用最广泛的就是LESS和Sass,都是努力把CSS武装成为开发语言,让它从简单的描述性语言过渡到具有程序式特性的语言,主要的特性就是: ...
- Java学习笔记——设计模式之一.简单工厂
蜀道之难.难于上青天,侧身西望长咨嗟 --蜀道难 设计模式第一篇,简单工厂. 定义Operation类 package cn.no1.simplefactory; public abstract cl ...