技术背景

在前面的一篇博客中我们介绍了MindSpore-2.4-gpu的安装和其中可能出现的一些问题。这里我们在安装完成之后,可以尝试使用一些MindSpore新版本的特性。那么在安装之后,如果是使用VSCode作为IDE,可以使用ctrl+shift+P快捷键,然后搜索python:sele将Python解释器切换到我们所需要的最新MindSpore环境下。

设备管理和资源监测

在mindspore-2.4版本中增加了mindspore.hal接口,可以用于管理设备、监测设备以及执行流的处理等等。例如,常用的获取设备的数量:

import mindspore as ms
ms.set_context(device_target="GPU")
device_target = ms.context.get_context("device_target")
print(ms.hal.device_count(device_target))
# 2

这个输出表明我们的环境下有两个GPU卡。也可以打印这两块显卡的名称:

import mindspore as ms
ms.set_context(device_target="GPU")
device_target = ms.context.get_context("device_target")
print(ms.hal.get_device_name(0, device_target))
print(ms.hal.get_device_name(1, device_target))
# Quadro RTX 4000
# Quadro RTX 4000

以及设备的可用状态:

import mindspore as ms
ms.set_context(device_target="GPU")
device_target = ms.context.get_context("device_target")
print(ms.hal.is_available(device_target))
# True

查询设备是否被初始化:

import mindspore as ms
ms.set_context(device_target="GPU")
device_target = ms.context.get_context("device_target")
print(ms.hal.is_initialized(device_target))
A = ms.Tensor([0.], ms.float32)
A2 = (A+A).asnumpy()
print(ms.hal.is_initialized(device_target))
# False
# True

这也说明,只有在计算的过程中,MindSpore才会将Tensor的数据传输到计算后端。除了设备管理之外,新版本的MindSpore还支持了一些内存监测的功能,对于性能管理非常的实用:

import mindspore as ms
import numpy as np
ms.set_context(device_target="GPU")
A = ms.Tensor(np.random.random(1000), ms.float32)
A2 = (A+A).asnumpy()
print(ms.hal.max_memory_allocated())
# 8192

这里输出的占用最大显存的Tensor的大小。需要说明的是,这里不能直接按照浮点数占用空间来进行计算,应该说MindSpore在构建图的过程中会产生一些额外的数据结构,这些数据结构也会占用一定的显存,但是显存增长的趋势是准确的。除了单个的打印,还可以整个的输出一个summary:

import mindspore as ms
import numpy as np
ms.set_context(device_target="GPU")
A = ms.Tensor(np.random.random(1000), ms.float32)
A2 = (A+A).asnumpy()
print(ms.hal.memory_summary())

输出的结果为:

|=============================================|
| Memory summary |
|=============================================|
| Metric | Data |
|---------------------------------------------|
| Reserved memory | 1024 MB |
|---------------------------------------------|
| Allocated memory | 4096 B |
|---------------------------------------------|
| Idle memory | 1023 MB |
|---------------------------------------------|
| Eager free memory | 0 B |
|---------------------------------------------|
| Max reserved memory | 1024 MB |
|---------------------------------------------|
| Max allocated memory | 8192 B |
|=============================================|

ForiLoop

其实简单来说就是一个内置的for循环的操作,类似于Jax中的fori_loop:

import mindspore as ms
import numpy as np
from mindspore import ops
ms.set_context(device_target="GPU") @ms.jit
def f(_, x):
return x + x A = ms.Tensor(np.ones(10), ms.float32)
N = 3
AN = ops.ForiLoop()(0, N, f, A).asnumpy()
print (AN)
# [8. 8. 8. 8. 8. 8. 8. 8. 8. 8.]

有了这个新的for循环体,我们可以对整个循环体做端到端自动微分:

import mindspore as ms
import numpy as np
from mindspore import ops, grad
ms.set_context(device_target="GPU", mode=ms.GRAPH_MODE) @ms.jit
def f(_, x):
return x + x @ms.jit
def s(x, N):
return ops.ForiLoop()(0, N, f, x) A = ms.Tensor(np.ones(10), ms.float32)
N = 3
AN = grad(s, grad_position=(0, ))(A, N).asnumpy()
print (AN)
# [8. 8. 8. 8. 8. 8. 8. 8. 8. 8.]

流计算

首先我们来看这样一个例子:

import mindspore as ms
import numpy as np
np.random.seed(0)
from mindspore import numpy as msnp
ms.set_context(device_target="GPU", mode=ms.GRAPH_MODE) @ms.jit
def U(x, mu=1.0, k=1.0):
return msnp.sum(0.5 * k * (x-mu) ** 2) x = ms.Tensor(np.ones(1000000000), ms.float32)
energy = U(x)
print (energy)

在本地环境下执行就会报错:

Traceback (most recent call last):
File "/home/dechin/projects/gitee/dechin/tests/test_ms.py", line 13, in <module>
energy = U(x)
File "/home/dechin/anaconda3/envs/mindspore-master/lib/python3.9/site-packages/mindspore/common/api.py", line 960, in staging_specialize
out = _MindsporeFunctionExecutor(func, hash_obj, dyn_args, process_obj, jit_config)(*args, **kwargs)
File "/home/dechin/anaconda3/envs/mindspore-master/lib/python3.9/site-packages/mindspore/common/api.py", line 188, in wrapper
results = fn(*arg, **kwargs)
File "/home/dechin/anaconda3/envs/mindspore-master/lib/python3.9/site-packages/mindspore/common/api.py", line 588, in __call__
output = self._graph_executor(tuple(new_inputs), phase)
RuntimeError:
----------------------------------------------------
- Memory not enough:
----------------------------------------------------
Device(id:0) memory isn't enough and alloc failed, kernel name: 0_Default/Sub-op0, alloc size: 4000000000B. ----------------------------------------------------
- C++ Call Stack: (For framework developers)
----------------------------------------------------
mindspore/ccsrc/runtime/graph_scheduler/graph_scheduler.cc:1066 Run

说明出现了内存不足的情况。通常情况下,可能需要手动做一个拆分,然后使用循环体遍历:

import time
import mindspore as ms
import numpy as np
from mindspore import numpy as msnp
ms.set_context(device_target="GPU", mode=ms.GRAPH_MODE) @ms.jit
def U(x, mu=1.0, k=1.0):
return msnp.sum(0.5 * k * (x-mu) ** 2) def f(x, N=1000, size=1000000):
ene = 0.
start_time = time.time()
for i in range(N):
x_tensor = ms.Tensor(x[i*size:(i+1)*size], ms.float32)
ene += U(x_tensor)
end_time = time.time()
print ("The calculation time cost is: {:.3f} s".format(end_time - start_time))
return ene.asnumpy() x = np.ones(1000000000)
energy = f(x)
print (energy)
# The calculation time cost is: 11.732 s
# 0.0

这里至少没有报内存错误了,因为每次只有在计算的时候我们才把相应的部分拷贝到显存中。接下来使用流计算,也就是边拷贝边计算的功能:

def f_stream(x, N=1000, size=1000000):
ene = 0.
s1 = ms.hal.Stream()
s2 = ms.hal.Stream()
start_time = time.time()
for i in range(N):
if i % 2 == 0:
with ms.hal.StreamCtx(s1):
x_tensor = ms.Tensor(x[i*size:(i+1)*size], ms.float32)
ene += U(x_tensor)
else:
with ms.hal.StreamCtx(s2):
x_tensor = ms.Tensor(x[i*size:(i+1)*size], ms.float32)
ene += U(x_tensor)
ms.hal.synchronize()
end_time = time.time()
print ("The calculation with stream time cost is: {:.3f} s".format(end_time - start_time))
return ene.asnumpy()

因为要考虑到程序编译对性能带来的影响,所以这里使用与不使用Stream的对比需要分开执行。经过多次测试之后,不使用Stream的运行时长大约为:

The calculation time cost is: 10.925 s
41666410.0

而使用Stream的运行时长大约为:

The calculation with stream time cost is: 9.929 s
41666410.0

就直观而言,Stream计算在MindSpore中有可能带来一定的加速效果,但其实这种加速效果相比于直接写CUDA Stream带来的效果增益其实要弱一些,可能跟编译的逻辑有关系。但至少现在有了Stream这样的一个工具可以在MindSpore中直接调用,就可以跟很多同类型的框架同步竞争了。

总结概要

接上一篇对于MindSpore-2.4-gpu版本的安装介绍,本文主要介绍一些MindSpore-2.4版本中的新特性,例如使用hal对设备和流进行管理,进而支持Stream流计算。另外还有类似于Jax中的fori_loop方法,MindSpore最新版本中也支持了ForiLoop循环体,使得循环的执行更加高效,也是端到端自动微分的强大利器之一。

版权声明

本文首发链接为:https://www.cnblogs.com/dechinphy/p/ms24.html

作者ID:DechinPhy

更多原著文章:https://www.cnblogs.com/dechinphy/

请博主喝咖啡:https://www.cnblogs.com/dechinphy/gallery/image/379634.html

MindSpore-2.4版本中的一些新特性的更多相关文章

  1. cocos3.2版本中的一些新特性

    1.设置屏幕分辨率的大小,需要手动添加: 2.去掉了所有CC开头的命名: 3.所有的单例(以前是采用shared开头方法),全部改为getInstance(); 4.cocos3.x以上的版本支持C+ ...

  2. MVC中的其他新特性

    MVC中的其他新特性 (GlobalImport全局导入功能) 默认新建立的MVC程序中,在Views目录下,新增加了一个_GlobalImport.cshtml文件和_ViewStart.cshtm ...

  3. xmake v2.1.5版本正式发布,大量新特性更新

    此版本带来了大量新特性更新,具体详见:xmake v2.1.5版本新特性介绍. 更多使用说明,请阅读:文档手册. 项目源码:Github, Gitee. 新特性 #83: 添加 add_csnippe ...

  4. Xcode中StoryBoard Reference 新特性的使用

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  5. 浅析Oracle 12c中Data Guard新特性

    浅析Oracle 12c中Data Guard新特性   写在前面 无论是做Oracle运维的小伙伴还是老伙伴,想必对Oracle数据库的数据级灾备核心技术—Data Guard是再熟悉不过了!这项从 ...

  6. ES6系列之项目中常用的新特性

    ES6系列之项目中常用的新特性 ES6常用特性 平时项目开发中灵活运用ES6+语法可以让开发者减少很多开发时间,提高工作效率.ES6版本提供了很多新的特性,接下来我列举项目中常用的ES6+的特性: l ...

  7. Jdk5.0中出现的新特性

    掌握jdk5.0中出现的新特性1.泛型(Generics)2.增强的"for"循环(Enhanced For loop)3.自动装箱/自动拆箱(Autoboxing/unboxin ...

  8. C#6.0 中的那些新特性

    C#6.0 中的那些新特性 前言 VS2015在自己机器上确实是装好了,费了老劲了,想来体验一下跨平台的快感,结果被微软狠狠的来了一棒子了,装好了还是没什么用,应该还需要装Xarmain插件,配置一些 ...

  9. iOS中的项目新特性页面的处理

    一般项目中都会出现新特性页面,比如第一次使用应用的时候,或者在应用设置里查看新特性的时候会出现. 这里,选择新建一个专门处理项目新特性的控制器,来完成功能. 首先是 NewFeaturesViewCo ...

  10. [译] OpenStack Kilo 版本中 Neutron 的新变化

    OpenStack Kilo 版本,OpenStack 这个开源项目的第11个版本,已经于2015年4月正式发布了.现在是个合适的时间来看看这个版本中Neutron到底发生了哪些变化了,以及引入了哪些 ...

随机推荐

  1. C++11新特性(二):语言特性

    C++11新特性 nullptr空指针 nullptr空指针的使用可以规避掉以往设置为NULL的风险.NULL在编译器中常常被设置为0或者其它数字,此时判断指针是否为NULL,即判断指针类型是否能够等 ...

  2. 安装nvm,并通过nvm安装nodejs

    转载请注明出处: 1.安装nvm 打开终端,然后运行以下命令来下载并安装nvm: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39 ...

  3. freertos总结

    freertos学习总结:(别人的)https://blog.csdn.net/qq_39397153/article/details/123997346 freertos学习笔记:(别人的)http ...

  4. APT 使用

    使用 Ubuntu 包搜索器 apt 命令 功能 apt install 安装软件包 apt remove 移除软件包 apt purge 移除软件包及配置文件 apt update 刷新存储库索引 ...

  5. Cannot find loader com.jme3.scene.plugins.ogre.MeshLoader

    五月 20, 2022 2:46:07 下午 com.jme3.asset.AssetConfig loadText 警告: Cannot find loader com.jme3.scene.plu ...

  6. Kubernetes 环境中切换代理ipvs模式

    Kubernetes 环境中切换代理ipvs模式 service代理默认使用iptables规则通过内核模块netfilter实现流量转发,内核转发效率高,但是iptables不具备更为灵活的负载均衡 ...

  7. Angular Material 18+ 高级教程 – CDK Scrolling

    Angular CDK 的意义 经过之前两篇文章 CDK Portal 和 CDK Layout の Breakpoints,我相信大家已经悟到了 CDK 的意义. CDK 有 3 个方向: 包装 B ...

  8. Wpf使用NLog将日志输出到LogViewer

    1 LogViewer LogViewer是通过UDP传输的高性能实时log查看器. 具有一下特性: 通过UDP读取日志 通过文件导入日志 导出日志到一个文件中 排序.过滤(日志树,日志等级)和查找 ...

  9. Vue3——axios 安装和封装

    axios 安装和封装 安装 npm install axios 最后通过 axios 测试接口!!! axios 二次封装 在开发项目的时候避免不了与后端进行交互,因此我们需要使用 axios 插件 ...

  10. 4Templates Bootstrap Navbars and Links

    链接 传递参数