关于mindspore 原地更新类算子的一点思考记录如下:

现象记录:

原始测试代码

错误结果复现:

分析:

如果在场景中加入42行的copy()操作此时cpu的结果就会正确,但是gpu的结果则不受copy做操作的影响

修改后测试结果:

Mindspore 控制流场景中,我们的H是由mnp.one 新建出来的,但是其底层是调用的numpy的封装申请出来的是一个const的数据,这样的数据通过赋值给H,如果H在传递到其他地方,其内部被修改,下次在赋值,这块const的地址不会新创建,那么下次循环H的

值就会不对了。

解决办法:

  1. 打開42行copy的注釋
  2. 將k 以及 k_iter的值從tensor改成数值0,这样while控制流会将这些body 展开,相当于 H的值存储了多份也不会有任何更改
  3. 查看tensorscatterNdUpdate 后端实现,确定其实现是否是直接修改输入并且返回输入的操作

结果发现:其实现是在input的基础上inplace操作然后拷贝到输出地址,这样修改了原先的干净的输入地址,倘若存在内存复用其生命周期还未结束,那么其他地方拿到的值就会被污染,因此修改实现为拷贝输入到输出然后在做inplace 操作,修改后代码,这样不论输入的生命周期是否结束,均不会影响到原来的值

总结:

1.为什么静态图下会出错?

动态图中不会有静态的推断,H的值每次都会新赋值不同地址,因此上次的H的地址内容被修改,不会有影响

  1. 为什么cpu会出错 gpu 不出错?

因为cpu不存在host和device的概念,在图运行时cpu inplace类算子做相关操作时直接污染了cpu的输入原始地址,但是gpu操作时会先将host侧内容拷贝到device侧操作那么device侧输入原始地址被污染没关系,下次循环子图时会有新的地址过来,无影响。

  1. 解决办法加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 控制流中存在原地更新操作类副作用算子时循环值不更新问题记录的更多相关文章

  1. JAVA中的集合容器操作类

    目录 JAVA中的集合容器操作类 List集合 ArrayList的操作方法说明 LinkedList Stack Set Map Queue 总结 JAVA中的集合容器操作类 Java容器类库总共分 ...

  2. mybatis高级(2)_数据库中的列和实体类不匹配时的两种解决方法_模糊查询_智能标签

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "- ...

  3. 技术干货丨如何在VIPKID中构建MQ服务

    小结: 1. https://mp.weixin.qq.com/s/FQ-DKvQZSP061kqG_qeRjA 文 |李伟 VIPKID数据中间件架构师 交流微信 | datapipeline201 ...

  4. golang中使用mongodb的操作类以及如何封装

    mgo简介 mongodb官方没有关于go的mongodb的驱动,因此只能使用第三方驱动,mgo就是使用最多的一种. mgo(音mango)是MongoDB的Go语言驱动,它用基于Go语法的简单API ...

  5. 利用FastJson,拼接复杂嵌套json数据&&直接从json字符串中(不依赖实体类)解析出键值对

    1.拼接复杂嵌套json FastJson工具包中有两主要的类: JSONObject和JSONArray ,前者表示json对象,后者表示json数组.他们两者都能添加Object类型的对象,但是J ...

  6. java并发编程基础 --- 7章节 java中的13个原子操作类

    当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量 i=1,A线程更新 i+1,B线程也更新 I+1,经过两个线程的操作之后可能 I不等于3,而是等于2.因为A和B线程更 ...

  7. Java中的13个原子操作类

    java.util.concurrent.atomic包一共提供了13个类.属于4种类型的原子更新方式,分别是原子更新基本类型,原子更新数组,原子更新引用和原子更新属性.Atomic包里的类基本都是使 ...

  8. 关于for与forEach遍历集合中对集合进行操作的问题

    遍历List集合,在循环中再对List集合进行操作,有时候会遇到ConcurrentModificationException(并发修改异常);其实只有在forEach循环集合再对集合操作会发生异常: ...

  9. 技术干货 | 基于MindSpore更好的理解Focal Loss

    [本期推荐专题]物联网从业人员必读:华为云专家为你详细解读LiteOS各模块开发及其实现原理. 摘要:Focal Loss的两个性质算是核心,其实就是用一个合适的函数去度量难分类和易分类样本对总的损失 ...

随机推荐

  1. Qt5的安装和编译

    Ubuntu18.04安装Qt5 1.配置unbuntu 和宿主机共享文件夹安装vmware-tools 2.下载 Qt  http://download.qt.io/archive/qt/ 3.修改 ...

  2. Spark集群环境搭建——部署Spark集群

    在前面我们已经准备了三台服务器,并做好初始化,配置好jdk与免密登录等.并且已经安装好了hadoop集群. 如果还没有配置好的,参考我前面两篇博客: Spark集群环境搭建--服务器环境初始化:htt ...

  3. DP-Burst Balloons

    leetcode312: https://leetcode.com/problems/burst-balloons/#/description Given n balloons, indexed fr ...

  4. Android 高级UI组件(三)

    一.popupWindow 1.AlertDialog和PopupWindow最关键的区别是AlertDialog不能指定显示位置,只能默认显示在屏幕最中间(当然也可以通过设置WindowManage ...

  5. Linux基础命令---slabtop

    slabtop slabtop实时显示详细的内核板条缓存信息.它显示按所列排序条件之一排序的顶级缓存的列表.它还会显示一个统计信息头,其中填充了板坯层信息. 此命令的适用范围:RedHat.RHEL. ...

  6. error信息

    /opt/hadoop/src/contrib/eclipse-plugin/build.xml:61: warning: 'includeantruntime' was not set, defau ...

  7. 【Java 8】Optional 使用

    一.前言 如果要给 Java 所有异常弄个榜单,我会选择将 NullPointerException 放在榜首.这个异常潜伏在代码中,就像个遥控炸弹,不知道什么时候这个按钮会被突然按下(传入 null ...

  8. pipeline parameters指令

    目录 一.简介 二.类型 参数类型 多参数 一.简介 参数化pipeline是指通过传参来决定pipeline的行为.参数化让写pipeline就像写函数,而函数意味着可重用.更抽象.所以,通常使用参 ...

  9. MySQL获取对应时间

    一.查询当前时间包含年月日 SELECT CURDATE(); SELECT CURRENT_DATE(); 二.查询当前时间包含年月日时分秒 SELECT NOW(); SELECT SYSDATE ...

  10. 车载以太网第二弹 | 测试之实锤-IOP测试实践

    前言 上一期"物理层PMA测试实践",咱们从环境设备组成.被测对象组成再到测试过程和测试结果,将完整的PMA测试过程做了一个经验分享. 由下层开始逐层"披沙沥金" ...