[技术干货-算子使用] Mindspore 控制流中存在原地更新操作类副作用算子时循环值不更新问题记录
关于mindspore 原地更新类算子的一点思考记录如下:
现象记录:
原始测试代码
错误结果复现:
分析:
如果在场景中加入42行的copy()操作此时cpu的结果就会正确,但是gpu的结果则不受copy做操作的影响
修改后测试结果:
Mindspore 控制流场景中,我们的H是由mnp.one 新建出来的,但是其底层是调用的numpy的封装申请出来的是一个const的数据,这样的数据通过赋值给H,如果H在传递到其他地方,其内部被修改,下次在赋值,这块const的地址不会新创建,那么下次循环H的
值就会不对了。
解决办法:
- 打開42行copy的注釋
- 將k 以及 k_iter的值從tensor改成数值0,这样while控制流会将这些body 展开,相当于 H的值存储了多份也不会有任何更改
- 查看tensorscatterNdUpdate 后端实现,确定其实现是否是直接修改输入并且返回输入的操作
结果发现:其实现是在input的基础上inplace操作然后拷贝到输出地址,这样修改了原先的干净的输入地址,倘若存在内存复用其生命周期还未结束,那么其他地方拿到的值就会被污染,因此修改实现为拷贝输入到输出然后在做inplace 操作,修改后代码,这样不论输入的生命周期是否结束,均不会影响到原来的值
总结:
1.为什么静态图下会出错?
动态图中不会有静态的推断,H的值每次都会新赋值不同地址,因此上次的H的地址内容被修改,不会有影响
- 为什么cpu会出错 gpu 不出错?
因为cpu不存在host和device的概念,在图运行时cpu inplace类算子做相关操作时直接污染了cpu的输入原始地址,但是gpu操作时会先将host侧内容拷贝到device侧操作那么device侧输入原始地址被污染没关系,下次循环子图时会有新的地址过来,无影响。
- 解决办法加copy操作好还是直接修改后端算子好?
3.1. 直接加copy会导致某一后端正确(cpu)但某一后端无影响是冗余操作,不妥且只是规避并没有解决这个问题。
3.2. 直接修改后端算子的话除了能解决当前场景的问题,也能避免内存复用引用计数时因为输入的生命周期过长,而输入的原始地址被污染产生更难定位的问题。
3.3. 同时也能知道mindspore的机制在后端是不支持直接的inplace操作的,一切对输入的inplace操作,都存在一定的隐患,因此编写算子过程中不光cpu 其他gpu ascend,均应该先将输入拷贝到输出,再在输出中做inplace 操作,不管要保证输出地址的合法性也要保证输入地址没有被污染。因此编写原地更新操作类算子应该遵循上述准则才可以。
对应pr 修改:
https://gitee.com/mindspore/mindspore/pulls/27203/files
https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=171550&fromuid=642331
[技术干货-算子使用] Mindspore 控制流中存在原地更新操作类副作用算子时循环值不更新问题记录的更多相关文章
- JAVA中的集合容器操作类
目录 JAVA中的集合容器操作类 List集合 ArrayList的操作方法说明 LinkedList Stack Set Map Queue 总结 JAVA中的集合容器操作类 Java容器类库总共分 ...
- mybatis高级(2)_数据库中的列和实体类不匹配时的两种解决方法_模糊查询_智能标签
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "- ...
- 技术干货丨如何在VIPKID中构建MQ服务
小结: 1. https://mp.weixin.qq.com/s/FQ-DKvQZSP061kqG_qeRjA 文 |李伟 VIPKID数据中间件架构师 交流微信 | datapipeline201 ...
- golang中使用mongodb的操作类以及如何封装
mgo简介 mongodb官方没有关于go的mongodb的驱动,因此只能使用第三方驱动,mgo就是使用最多的一种. mgo(音mango)是MongoDB的Go语言驱动,它用基于Go语法的简单API ...
- 利用FastJson,拼接复杂嵌套json数据&&直接从json字符串中(不依赖实体类)解析出键值对
1.拼接复杂嵌套json FastJson工具包中有两主要的类: JSONObject和JSONArray ,前者表示json对象,后者表示json数组.他们两者都能添加Object类型的对象,但是J ...
- java并发编程基础 --- 7章节 java中的13个原子操作类
当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量 i=1,A线程更新 i+1,B线程也更新 I+1,经过两个线程的操作之后可能 I不等于3,而是等于2.因为A和B线程更 ...
- Java中的13个原子操作类
java.util.concurrent.atomic包一共提供了13个类.属于4种类型的原子更新方式,分别是原子更新基本类型,原子更新数组,原子更新引用和原子更新属性.Atomic包里的类基本都是使 ...
- 关于for与forEach遍历集合中对集合进行操作的问题
遍历List集合,在循环中再对List集合进行操作,有时候会遇到ConcurrentModificationException(并发修改异常);其实只有在forEach循环集合再对集合操作会发生异常: ...
- 技术干货 | 基于MindSpore更好的理解Focal Loss
[本期推荐专题]物联网从业人员必读:华为云专家为你详细解读LiteOS各模块开发及其实现原理. 摘要:Focal Loss的两个性质算是核心,其实就是用一个合适的函数去度量难分类和易分类样本对总的损失 ...
随机推荐
- 【php安全】 register_argc_argv 造成的漏洞分析
对register_argc_argv的分析 简介 使用 cli模式下,不论是否开始register_argc_argv,都可以获取命令行或者说外部参数 web模式下,只有开启了register_ar ...
- pyqt5 改写函数
重新改写了keyPressEvent() class TextEdit(QTextEdit): def __init__(self): QtWidgets.QTextEdit.__init__(sel ...
- k8s之ansible安装
项目地址:https://github.com/easzlab/kubeasz #:先配置harbor #:利用脚本安装docker root@k8s-harbor1:~# vim docker_in ...
- 增大Oracle Virtualbox的磁盘空间
https://blog.csdn.net/hiyachen/article/details/102131823 背景 在virtualbox中装好Linux以及Application之后,发现硬盘空 ...
- I/O流之文件流
1.文件操作类 File 1.public File(String pathname)//给定一个要操作文件的完整路径 2.public File(File parent,String child)/ ...
- JavaEE复习三
Http协议是基于请求/响应模式.无状态的协议:所有请求时相互独立的.无连续的:服务器无法记住与识别用户. 对于简单的页面浏览或信息获取,http协议可以完全胜任:对于需要提供客户端和服务器端交互的网 ...
- 【JS】原生实现拖拽
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- python内置模块(一)
re模块 基本操作方法 1.使用findall方法可以根据正则表达式筛选所有符合的字符.基本句式为: re.findall('正则表达式',待匹配的字符) 结果为一个列表,没有结果为空列表. 2.使用 ...
- python解释器安装指导教程
python解释器安装指导教程 1.官网下载 进入官网https://www.python.org/,在download下选择符合操作系统的版本 在找到合适的版本后选择相应的安装文件下载 2.进行安装 ...
- Iphone开源项目汇总
扫描wifi信息: http://code.google.com/p/uwecaugmentedrealityproject/ http://code.google.com/p/iphone-wire ...