知知爸爸是码农

其他

AI杂谈:手推BP

把w2、w1、b1的梯度计算出来之后,就可以按照公式(13)、(14)、(15)来更新参数值了,下面用oneflow按照图1来搭建一个对应的网络做实验,代码如下:import
2022年3月26日
其他

OneFlow学习笔记:Consistent view的相关概念和实现

view所需抽象的一种Tensor,里面需要有前面讲的placement和SBP相关的属性,下面把OneFlow所有Tensor一并总结列出:图2OneFlow的Tensor设计采用了bridge
2022年2月1日
其他

OneFlow学习笔记:python到C++调用过程分析

m);};这个类提供了一个Register接口,被封装进了下面这个注册宏里,代码位于oneflow/api/python/of_api_registry.h:#define
2021年12月26日
其他

C/C++杂谈:CRTP

Pattern的缩写,中文可以翻成奇异递归模板,它是通过将子类类型作为模板参数传给基类的一种模板的使用技巧,类似下面代码形式:templateclass
2021年9月11日
其他

深入理解TVM:内存分配器

make_inplace_array_object用于构造Object数组,同样是使用了SimpleObjAllocator这个内存分配器,下面是它的定义:template
2021年9月4日
其他

内存管理:具有共享所有权的智能指针(二)

上篇文章《内存管理:具有共享所有权的智能指针(一)》主要讲了下面几个点:shared_ptr的引用计数如何更新自定义析构器原理make_shared分析本文来继续挖掘具有共享所有权语义的智能指针的更多细节,主要针对下面几个点:weak_ptr在解决什么问题多线程使用shared_ptr要不要加锁shared_from_thissize和performance分析一、weak_ptr在解决什么问题weak_ptr算是shared_ptr的一个扩充,它本身不是一种独立的智能指针,它可以用来指向shared_ptr中管理的数据块,但是它不会影响前文提到的强引用计数_M_use_count,它只会影响弱引用计数_M_weak_count。之所以引入weak_ptr,是为了解决shared_ptr的循环引用问题,举个例子说明一下,假如有下面两个示例类:class
2021年8月21日
其他

内存管理:具有共享所有权的智能指针(一)

前文分析了具有专属所有权的智能指针,本文继续看一下具有共享所有权语义的智能指针shared_ptr和weak_ptr一、简介一句话来讲,shared_ptr的共享所有权的语义是通过引用计数机制来实现的,资源只有一份,引用计数记录了用户个数,当引用计数为0时释放资源,为了方便表达,本文把包含引用计数的数据结构叫做控制块,被管理的资源对象叫做数据块,共享所有权的概念源于多个智能指针可以同时hold同一个数据块,并且通过一个控制块来管理数据块的生命周期,下图是一个不是十分准确但能帮助理解的示意图:图1在shared_ptr的实际实现中,比上面图1要复杂的多,下面的图2是标准库实际代码实现的类的关系图,实线表示继承关系,虚线表示包含关系,红色类是智能指针的实现类,绿色类是控制块的实现类:图2控制块有三种,对应上面图中绿色部分的三个子类:标准控制块,里面只有引用计数和数据块的指针,对应上面图2中的_Sp_counted_ptr类,本文起名叫CBV1(control
2021年8月14日
其他

内存管理:具有专属所有权的智能指针

从C++11开始有了真正的智能指针unique_ptr、shared_ptr和weak_ptr,加上在这之前也已经有的一个智能指针auto_ptr,现在一共有四种智能指针,本文主要来看auto_ptr和unique_ptr,它们是具有专属所有权的智能指针,本文和前文new
2021年8月7日
其他

内存管理:new and delete

前几篇文章看了malloc的实现,本文再来看下new和delete,每个C++程序员对它们应该都比较熟悉,在C++11的智能指针出现之前基本都是靠它们来直接管理内存,本文不讲它们最基本的用法,着重看下代码实现和一些平时使用可能注意不到的细节一、new/delete
2021年7月31日
其他

深入理解TVM:RELAY_REGISTER_OP

set_name();};这里使用的时候也是可以像下面这样使用链式调用(src/relay/op/nn/convolution.cc):RELAY_REGISTER_OP("nn.conv1d")
2021年5月2日
其他

注册机调研:TVM之TVM_REGISTER_GLOBAL

这个主题的内容和前面TVM系列的一篇文章重复,这里只是为了把这篇文章收录到这个系列里,所以只是做一个链接链过去:深入理解TVM:Python/C++互调(中)
2021年4月18日
其他

深入理解TVM:Python/C++互调(中)

一、概述前文已经讲过python/c++互调的c++端的底层核心数据结构:PackedFunc,详情请见:深入理解TVM:Python/C++互调(上),本文是python/c++互调这个系列的第二篇,主要来讲c++端的函数注册,python端对c++端的函数调用都来源于c++端的注册函数,最主要的一个函数注册宏是TVM_REGISTER_GLOBAL,code
2021年4月17日
其他

深入理解TVM:Python/C++互调(上)

一、概述TVM已经是一个很庞大的系统,包含了很多的功能模块,其中python和c++的互相调用这个功能模块,没有使用第三方的开源库(boost.python、pybind11等),而是自己实现了一套复杂但精致高效强大的机制,值得好好研究学习。这部分内容很多,一篇文章很难说清楚,我准备把这部分分成上、中、下三篇来说,尽可能的把实现原理讲清楚:上篇:最底层的c++数据结构支撑(围绕c++端PackedFunc)中篇:基于PackedFunc的函数注册(围绕TVM_REGISTER_GLOBAL)下篇:偏上层的python的调用细节(围绕ctypes内置库和python端PackedFunc)本文讲第一部分,也就是围绕PackedFunc这个类来说,它是python和c++互调的桥梁,此类实现代码在include/tvm/runtime/packed_func.h文件中,这里面还有一个TypedPackedFunc类,它只是PackedFunc的一个wrapper,主要增加了类型检查的功能,开发TVM的c++代码要尽可能的使用这个类,但是我们为了把问题尽可能的简化,只关注PackedFunc这个最底层类,其中用到了下面这几个关键的数据结构:TVMValueTVMArgsTVMPODValue_TVMArgValueTVMRetValueTVMArgsSetter下面结合代码,逐个来说(注:本文基于fe25b9e7c这个commit,下面所有列出的代码都做了相当大量的精简和修改,一来只为讲清楚原理,二来限于篇幅,大家如果有兴趣了解更多的细节,需要再去github上看实际的实现)二、TVMValue这是最基本的一个数据结构,是一个union,主要是为了储存c++和其它语言交互时所支持的几种类型的数据,代码很简单(其中DLDataType和DLDevice是两个复合数据类型,限于篇幅,这里不能全部列出来,大家需要自己到github追下细节)://
2021年4月11日
自由知乎 自由微博
其他

注册机调研:从Caffe开始

一、简介现在开源的深度学习框架都会用到注册机,我准备做一个系列,来详细看一下各个开源框架注册机的实现,先从Caffe开始。Caffe代码现在来看虽然比较古老,但是作为训练框架的先驱,依然有值得学习的地方,比如模块化、高性能(单机单卡)、易扩展等,本文着重来看里面的注册机制。caffe里主要有两个注册宏:REGISTER_LAYER_CLASSREGISTER_SOLVER_CLASS下面通过实际代码来详细解读这两个注册宏(注:为方便理解,相关代码都做了简化和修改)二、REGISTER_LAYER_CLASS这个注册宏用于注册一个函数,这个函数用于创建某种layer的对象,这样在创建layer的时候,代码会比较简洁容易维护,不易出错。而如果使用类似下面这种if或者switch的做法来创建layer,当layer种类少的时候还没问题,当layer种类越来越多的时候,不光性能不好,也很容易写错,现在Caffe的官方仓库里有大概五十种layer,试想如果都在下面列出来,很容易在某个if语句上就会写错。if
2021年4月10日
其他

深入理解TVM:Object家族

RuntimeTypeIndex接口在Object类的继承体系中,每个类都会有一个RuntimeTypeIndex的静态接口,返回一个能够标识这个类的全局unique
2021年4月4日