【AI系统】Ascend C 语法扩展
Ascend C 语法扩展
Ascend C 的本质构成其实是标准 C++加上一组扩展的语法和 API。本文首先对 Ascend C 的基础语法扩展进行简要介绍,随后讨论 Ascend C 的两种 API——基础 API 和高阶 API。
接下来针对 Ascend C 的几种关键编程对象——数据存储、任务间通信与同步,资源管理以及临时变量进行详细解读,为后续讲解 Ascend C 的编程范式打下理论基础。
语法扩展概述
Ascend C 采用华为自研的毕昇编译器,设备侧编程采用 C/C++语法扩展允许函数执行空间和地址空间作为合法的类型限定符,提供在主机(Host)侧和设备(Device)侧独立执行的能力,同时提供针对不同地址空间的访问能力。
函数执行限定符
函数执行空间限定符指示函数是在主机上执行还是在设备上执行,以及它是否可从主机或设备调用。主要有以下三种声明方式:
-
首先是
__global__
执行空间限定符。它声明一个 kernel 函数(Ascend C 算子的入口函数,后文会详细介绍),具有如下性质:- 在设备上执行;
- 只能被主机侧函数调用;
__global__
只是表示这是设备侧函数的入口,并不表示具体的设备类型;- 一个
__global__
函数必须返回 void 类型,并且不能是 class 的成员函数; - 主机侧调用
__global__
函数必须使用<<<>>>(内核调用符)异构调用语法; __global__
的调用是异步的,意味着函数返回,并不表示 kernel 函数在设备侧已经执行完成,如果需要同步,须使用运行时提供的同步接口显式同步,如aclrtSynchronizeStream(…)
。
-
第二类是
__aicore__
执行空间限定符。它声明的函数,具有如下属性。- 在 AI Core 设备上执行;
- 只能被
__global__
函数,或者其他 AI Core 函数调用。
-
第三类是
__host__
执行空间限定符。它声明的函数(通常不显示声明)具有如下属性。- 只能在主机侧执行;
- 只能被主机侧函数调用;
__global__
和__host__
不能一起使用。
典型使用函数执行空间限定符的示例:
//定义 aicore 函数
__aicore__ void bar() {}// 定义核函数
__global__ __aicore__ void foo() { bar();}//定义 Host 函数
int () {}
地址空间限定符
地址空间限定符可以在变量声明中使用,用于指定对象分配的区域。AI Core 具备多级独立片上存储,各个地址空间独立编址,具备各自的访存指令。如果对象的类型被地址空间名称限定,那么该对象将被分配在指定的地址空间中。同样地,对于指针,指向的类型可以通过地址空间进行限定,以指示所指向的对象所在的地址空间。
private 地址空间:private 地址空间是大多数变量的默认地址空间,特别是局部变量,代码中不显示标识所在局部地址空间类型。
__g'm__
地址空间:__gm__
地址空间限定符用来表示分配于设备侧全局内存的对象,全局内存对象可以声明为标量、用户自定义结构体的指针。
Ascend C API 概述
Ascend C 算子采用标准 C++ 语法和一组编程类库 API 进行编程,可以根据自己的需求选择合适的 API。Ascend C 编程类库 API 示意图如下图所示,Ascend C API 的操作数都是 Tensor 类型:GlobalTensor
(外部数据存储空间)和 LocalTensor
(核上内存空间);类库 API 分为高阶 API 和基础 API。
基础 API
实现基础功能的 API,包括计算类、数据搬运、内存管理和任务同步等。使用基础 API 自由度更高,可以通过 API 组合实现自己的算子逻辑。基础 API 是对计算能力的表达。
- 基础 API 分类
-
计算类 API:包括标量计算 API、向量计算 API、矩阵计算 API,分别实现调用标量计算单元、向量计算单元、矩阵计算单元执行计算的功能。
-
数据搬运 API:计算 API 基于本地内存(Local Memory)数据进行计算,所以数据需要先从全局内存(Global Memory)搬运至本地内存,再使用计算接口完成计算,最后从本地内存搬出至全局内存。执行搬运过程的接口称之为数据搬运接口,比如 DataCopy 接口。
-
内存管理 API:用于分配板上管理内存,比如 AllocTensor、FreeTensor 接口。这个 API 的出现是由于板上内存较小,通常无法存储完整数据,因此采用动态内存的方式进行内存管理,实现板上内存的复用。
-
任务同步 API:完成任务间的通信和同步,比如 EnQue、DeQue 接口。不同的 API 指令间有可能存在依赖关系,不同的指令异步并行执行,为了保证不同指令队列间的指令按照正确的逻辑关系执行,需要向不同的组件发送同步指令。任务同步类 API 内部即完成这个发送同步指令的过程,开发者无需关注内部实现逻辑,使用简单的 API 接口即可完成。
- 基础 API 计算方式
对于基础 API 中的计算 API,根据对数据操作方法的不同,分为下表所示的几种计算方式:
命名 | 说明 |
---|---|
整个 Tensor 参与计算 | 整个 Tensor 参与计算:通过运算符重载的方式实现,支持+, -, *, /, |, &, <, >, <=, >=, ==, !=,实现计算的简化表达。例如:dst=src1+src2 |
Tensor 前 n 个数据计算 | Tensor 前 n 个数据计算:针对源操作数的连续 n 个数据进行计算并连续写入目的操作数,解决一维 Tensor 的连续计算问题。例如:Add(dst, src1, src2, n); |
Tensor 高维切分计算 | 功能灵活的计算 API,充分发挥硬件优势,支持对每个操作数的 Repeat times(迭代的次数)、 Block stride(单次迭代内不同 block 间地址步长)、Repeat stride(相邻迭代间相同 block 的地址步长)、Mask(用于控制参与运算的计算单元)的操作。 |
下图以向量加法计算为例,展示了不同级别向量计算类 API 的特点。从图中我们可以初步看出,Tensor 高维切分计算操作单元最小,可以针对不同步长实现最为细致的操作,针对 Tensor 高维切分计算更加细致的介绍会在附录 Ascend C API 中呈现。
Tensor 前 n 个数据计算可以实现一维的连续计算,可以指定 Tensor 的特定长度参与计算,Tensor 前 n 个数据计算也是一般开发过程中使用最为频繁的接口,兼具较强的功能性和易用性;整个 Tensor 参与计算是易用性最强的,使用难度最低的,针对整个 Tensor 进行计算,但是功能性较低。开发者可以根据自身水平和不同的需要去灵活地选择各种层级的接口。
高阶 API
封装常用算法逻辑的 API,比如 Matmul、Softmax 等,可减少重复开发,提高开发者开发效率。使用高阶 API 可以快速的实现相对复杂的算法逻辑,高阶 API 是对于某种特定算法的表达。
例如使用高阶 API 完成 Matmul 算子时,需要创建一个矩阵乘法类进行运算,其中入参包含两个相乘的矩阵(一般称为 A 矩阵与 B 矩阵)信息、输出结果矩阵(一般称为 C 矩阵)信息、矩阵乘偏置(一般称为 Bias)信息,上述信息中包括了对应矩阵数据的内存逻辑位置、数据存储格式、数据类型、转置使能参数。
创建完这样的一个矩阵乘法类后,使用 Ascend C 高阶 API 可以直接完成对左右矩阵 A、B 和 Bias 的设置和矩阵乘法操作以及结果的输出,开发者不用再自主实现复杂的数据通路和运算操作。
数据存储
根据 Ascend C 对于 AI Core 的硬件抽象设计,AI Core 内部的存储统一用 Local Memory 来表示,AI Core 外部的存储统一用 Global Memory 来表示。
Ascend C 使用 GlobalTensor
作为 Global Memory 的数据基本操作单元,与之对应的,用 LocalTensor
作为 Local Lemory 的数据基本操作单元。数据的基本操作单元(Tensor,张量)是各种指令 API 直接处理的对象,也是数据的载体。本节具体介绍这两个关键的数据结构的原型定义和用法。
外部存储数据空间
外部存储数据空间(GlobalTensor)用来存放 AI Core 外部存储(Global Memory)的全局数据。
其原型定义如下:
template <typename T> class GlobalTensor {void SetGlobalBuffer(__gm__ T* buffer, uint32_t bufferSize); const __gm__ T* GetPhyAddr(); uint64_t GetSize(); GlobalTensor operator[](const uint64_t offset);
}
在上边的程序中,第 2 行代码的作用是传入全局数据的指针,并手动设置一个 buffer size,初始化 GlobalTensor
;第 3 行代码的作用是返回全局数据的地址类型 T 支持所有数据类型,但需要遵循使用此 GlobalTensor
的指令的数据类型支持情况;第 4 行代码的作用是返回 Tensor 中的 element 个数;第 5 行代码的作用是指定偏移返回一个 GlobalTensor
,offset 单位为 element。
核内数据存储空间
核内数据存储空间(LocalTensor)用于存放 AI Core 中内部存储(Local Memory)的数据。其原型定义如下:
template <typename T> class LocalTensor {T GetValue(const uint32_t offset) const;template <typename T1> void SetValue(const uint32_t offset, const T1 value) const;LocalTensor operator[](const uint32_t offset) const;uint32_t GetSize() const;void SetUserTag(const TTagType tag);TTagType GetUserTag() const;
}
在上边的程序片段中,第 2 行代码的作用是获取 LocalTensor
中的某个值,返回 T 类型的立即数;第 3 行代码的作用是设置LocalTensor
中的某个值,offset 单位为 element;第 4 行代码的作用是获取距原LocalTensor
起始地址偏移量为 offset 的新LocalTensor
,注意 offset 不能超过原有LocalTensor
的 size 大小,offset 单位为 element;第 5 行代码的作用是获取当前LocalTensor
尺寸大小。第 6 行代码的作用是让开发者自定义设置 Tag 信息;第 7 行代码的作用是获取 Tag 信息。
任务通信与同步
Ascend C 使用 TQue
队列完成任务之间的数据通信和同步,在 TQue
队列管理不同层级的物理内存时,用一种抽象的逻辑位置(TPosition)来表达各级别的存储,代替了片上物理存储的概念,开发者无需感知硬件架构。
TPosition 类型包括:VECIN、VECCALC、VECOUT、A1、A2、B1、B2、CO1、CO2。其中 VECIN、VECCALC、VECOUT 主要用于向量编程;A1、A2、B1、B2、CO1、CO2 用于矩阵编程。TPosition 的枚举值定义见下表。
TPosition | 具体含义 |
---|---|
GM | 全局内存(Global Memory),对应 AI Core 的外部存储。 |
VECIN | 用于向量计算,搬入数据的存放位置,在数据搬入矩阵计算单元时使用此位置 |
VECOUT | 用于向量计算,搬出数据的存放位置,在将矩阵计算单元结果搬出时使用此位置 |
VECCALC | 用于向量计算/矩阵计算,在计算需要临时变量时使用此位置 |
A1 | 用于矩阵计算,存放整块 A 矩阵,可类比 CPU 多级缓存中的二级缓存 |
B1 | 用于矩阵计算,存放整块 B 矩阵,可类比 CPU 多级缓存中的二级缓存 |
A2 | 用于矩阵计算,存放切分后的小块 A 矩阵,可类比 CPU 多级缓存中的一级缓存 |
B2 | 用于矩阵计算,存放切分后的小块 B 矩阵,可类比 CPU 多级缓存中的一级缓存 |
CO1 | 用于矩阵计算,存放小块结果 C 矩阵,可理解为 Cube Out |
CO2 | 用于矩阵计算,存放整块结果 C 矩阵,可理解为 Cube Out |
一个使用 TQue
数据结构的样例程序如下所示:
TQue<TPosition::VECIN, BUFFER_NUM> que;
LocalTensor<half> tensor1 = que.AllocTensor();
que.FreeTensor<half>(tensor1);
que.EnQue(tensor1);
LocalTensor<half> tensor1 = que.DeQue<half>();
在上边程序片段中呈现的内容只是 TQue
数据结构使用的一个样例,读者需要根据自己的需求在程序中合理的位置进行使用。其中第 1 行代码的作用是创建队列,VECIN 是 TPosition 枚举中的一员;BUFFER_NUM 参数是队列的深度,que 参数是自定义队列名称;第 2 行代码的作用是使用 TQue
的一个功能:
AllocTensor()
,在片上分配空间给一个 LocalTensor
,分配的默认大小为 que 在初始化时设置的一块的大小,也可以手动设置大小的值但是不能超过分配的大小;第 3 行代码的作用是释放 Tensor,使用 FreeTensor()
方法,需要与 AllocTensor()
成对使用;第 4 行代码的作用是将 LocalTensor
加入到指定队列中,从而利用队列来进行不同任务之间的数据同步与通信;第 5 行代码的作用是将 LocalTensor
从队列中取出,以能够进行后续的计算等操作。
资源管理
在 Ascend C 中,流水任务间数据传递使用到的内存统一由资源管理模块 TPipe
进行管理。TPipe
作为片上内存管理者,通过 InitBuffer 接口对外提供 TQue
内存初始化功能,开发者可以通过该接口为指定的 TQue
分配内存。
TQue
队列内存初始化完成后,需要使用内存时,通过调用 AllocTensor 来为 LocalTensor
分配内存,当创建的 LocalTensor
完成相关计算无需再使用时,再调用 FreeTensor 来回收 LocalTensor
的内存。内存管理示意图如下图所示:
一个使用 TPipe
数据结构的样例展示如下所示:
TPipe pipe;
pipe.InitBuffer(que, num, len);
在上述程序中呈现的内容只是 Tbuf 数据结构使用的一个样例,读者需要根据自己的需求在程序中合理的位置进行使用。其中第 1 行代码的作用是实例化 TPipe
数据结构,名称为 pipe;第 2 行代码的作用是使用 TPipe
的一个功能:初始化片上内存(队列),其中参数 que 为指定的已经创建的队列名称;参数 num 为分配的内存块数,num=2 时开启 double buffer 优化;参数 len 为分配的一块内存大小(单位 Bytes)。
在这里简单介绍一下 double buffer 优化机制。执行于 AI Core 上的指令队列主要包括如下几类,即 Vector 指令队列(V)、Matrix 指令队列(M)和存储移动指令队列(MTE2、MTE3)。不同指令队列间的相互独立性和可并行执行特性,是 double buffer 优化机制的基石。double buffer 基于 MTE 指令队列与 Vector 指令队列的独立性和可并行性,通过将数据搬运与 Vector 计算并行执行以隐藏数据搬运时间并降低 Vector 指令的等待时间,最终提高 Vector 单元的利用效率。
临时变量
使用 Ascend C 编程的过程中,可能会用到一些临时变量,例如在 Compute 阶段开发者会使用到一些复杂的数据结构。这些临时变量占用的内存可以使用 TBuf
来管理,存储位置通过模板参数来设置,可以设置为不同的 TPosition 逻辑位置。
在使用 TBuf 时,建议将临时变量初始化成为算子类成员中的一个,不需要重复地申请与释放,能达到提升算子性能的效果。
TBuf
占用的存储空间通过 TPipe
进行管理,您可以通过 InitBuffer 接口为 TBuf
进行内存初始化操作,之后即可通过 Get 获取指定长度的 Tensor 参与计算。
使用 InitBuffer 为 TBuf
分配内存和为 TQue
分配内存有以下差异:
-
为
TBuf
分配的内存空间只能参与计算,无法执行TQue
队列的入队出队操作。 -
调用一次内存初始化接口,
TPipe
只会为TBuf
分配一块内存,TQue
队列可以通过参数设置申请多块内存。如果要使用多个临时变量,需要定义多个TBuf
数据结构,对每个 Tbuf 数据结构分别调用 InitBuffer 接口进行内存初始化。 -
使用
TBuf
时可以不需要重复进行申请释放内存操作。
一个使用 TBuf
数据结构的样例展示如下所示:
TBuf<TPosition::pos> calcBuf;
pipe.InitBuffer(calcBuf, len);
LocalTensor<half> temtensor1 = calcBuf.Get<half>();
LocalTensor<half> temtensor1 = calcBuf.Get<half>(128);
在上一段程序中呈现的内容只是 TBuf
数据结构使用的一个样例,读者需要根据自己的需求在程序中合理的位置进行使用。其中第 1 行代码的作用是进行临时变量声明,其中 pos 参数为队列逻辑位置 TPosition,可以为 VECIN、VECCALC、VECOUT、A1、A2、B1、B2、CO1、CO2。第 2 行代码的作用是进行临时变量初始化,pipe 为实例化的一个 TPipe
数据结构,同样使用 TPipe
数据结构中的 InitBuffer 操作对临时变量进行初始化,但只需要声明名称和长度 len 即可,长度的单位仍然是 Bytes。第 3、4 行代码的作用是分配临时的 LocalTensor
,使用 TBuf
数据结构中的 Get()
方法进行临时 Tensor 的分配,若不引入入参则分配的空间大小为初始化时 len 的大小,单位为 Bytes,若引入入参,可以指定长度地分配临时 Tensor 的大小,但是长度不能超过 len。
如果您想了解更多AI知识,与AI专业人士交流,请立即访问昇腾社区官方网站https://www.hiascend.com/或者深入研读《AI系统:原理与架构》一书,这里汇聚了海量的AI学习资源和实践课程,为您的AI技术成长提供强劲动力。不仅如此,您还有机会投身于全国昇腾AI创新大赛和昇腾AI开发者创享日等盛事,发现AI世界的无限奥秘~
相关文章:
【AI系统】Ascend C 语法扩展
Ascend C 语法扩展 Ascend C 的本质构成其实是标准 C加上一组扩展的语法和 API。本文首先对 Ascend C 的基础语法扩展进行简要介绍,随后讨论 Ascend C 的两种 API——基础 API 和高阶 API。 接下来针对 Ascend C 的几种关键编程对象——数据存储、任务间通信与同步…...
驱动篇的开端
准备 在做之后的动作前,因为win7及其以上的版本默认是不支持DbgPrint(大家暂时理解为内核版的printf)的打印,所以,为了方便我们的调试,我们先要修改一下注册表 创建一个reg文件然后运行 Windows Registr…...
树莓派4B使用opencv读取摄像头配置指南
本文自己记录,给我们lab自己使用,其他朋友们不一定完全适配,请酌情参考。 一. 安装opecnv 我们的树莓派4B默认是armv7l架构,安装的miniconda最新的版本 Miniconda3-latest-Linux-armv7l.sh 仍然是python3.4几乎无法使用ÿ…...
【AI日记】24.12.03 kaggle 比赛 Titanic-6
【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 工作 内容:学习 kaggle 入门比赛 Titanic - Machine Learning from Disaster时间:7 小时评估:继续 读书 书名:美丽新世界时间:1 小时阅读原因&…...
Linux中的常用基本指令(下)
Linux常用基本指令 Linux中的基本指令12.head指令13.tail指令简单解释重定向与管道(重要) 14.date指令(时间相关的指令)15.cal指令(不重要)16.find指令(灰常重要)17.grep指令(重要)18.which指令和alias指令19.zip/unzip指令:20.tar指令(重要&…...
python笔记3
复习及总结 python的软件安装及简单使用——python3.31 pycharm python的输出:print() 简单(直接)输出 print()输出到指定文件 fpopen(rC:\Users\M15R3\Desktop\1.txt,a) print("334…...
电商营销活动-抽奖业务
目录 一、抽奖系统的核心功能 二、抽奖系统的业务逻辑 三、抽奖系统的业务优势 四、抽奖系统的业务注意事项 电商营销活动中的抽奖系统业务,是一种通过设立抽奖活动来吸引用户参与、提升用户活跃度和转化率的营销手段。以下是对电商营销活动抽奖系统业务的详细解…...
利用 Redis 与 Lua 脚本解决秒杀系统中的高并发与库存超卖问题
1. 前言 1.1 秒杀系统中的库存超卖问题 在电商平台上,秒杀活动是吸引用户参与并提升销量的一种常见方式。秒杀通常会以极低的价格限量出售某些商品,目的是制造紧迫感,吸引大量用户参与。然而,这种活动的特殊性也带来了许多技术挑…...
《山海经》:北山
《山海经》:北山 北山一经单狐山求如山(水马:形状与马相似,滑鱼:背部红色)带山(䑏疏:似马,一只角,鵸鵌:状乌鸦五彩斑斓,儵鱼ÿ…...
React基础教程(12):useRef的使用
12、useRef useRef 是 React 中的一个 Hook,主要用于访问和操作 DOM 元素以及保存组件的可变引用值。它是一个工具,用来避免重新渲染组件的情况下保持某些状态或引用的值。 使用场景: 使用场景 访问 DOM 元素 当需要直接操作某个 DOM 元素(如聚焦、滚动等)时,可以使用…...
释放超凡性能,打造鸿蒙原生游戏卓越体验
11月26日在华为Mate品牌盛典上,全新Mate70系列及多款全场景新品正式亮相。在游戏领域,HarmonyOS NEXT加持下游戏的性能得到充分释放。HarmonyOS SDK为开发者提供了软硬协同的系统级图形加速解决方案——Graphics Accelerate Kit(图形加速服务…...
Linux--Debian或Ubuntu上扩容、挂载磁盘并配置lvm
一、三块12TB组RAID 5 可用容量约24TB 二、安装LVM工具(已安装请忽略) sudo apt-get install lvm2二、查看可用磁盘 sudo lsblk 或者 sudo fdisk -l三、创建物理卷(PV) 选中刚做的磁盘组 sudo pvcreat /dev/sdb1四、创建卷组…...
我谈冈萨雷斯对频域滤波的误解——快速卷积与频域滤波之间的关系
在Rafael Gonzalez和Richard Woods所著的《数字图像处理》中,Gonzalez对频域滤波是有误解的,在频域设计滤波器不是非得图像和滤波器的尺寸相同,不是非得在频域通过乘积实现。相反,FIR滤波器设计都是构造空域脉冲响应。一般的原则是…...
Leetcoed:3274
1,题目 2,思路 把俩个字符串坐标拆开比较二进制, 如a1与b2 ,a与b比较为false ,1与2比较为false,最后俩个结果比较返回true 3,代码 class Solution3274 {public boolean checkTwoChessboards(String str1, String str2) {return (str1.char…...
LabVIEW实现串口调试助手
目录 1、串口通信原理 2、硬件环境部署 3、串口通信函数 4、程序架构 5、前面板设计 6、程序框图设计 本专栏以LabVIEW为开发平台,讲解物联网通信组网原理与开发方法,覆盖RS232、TCP、MQTT、蓝牙、Wi-Fi、NB-IoT等协议。 结合实际案例,展示如何利用LabVIEW和常用模块实现物联…...
ASP.NET Core项目中使用SqlSugar连接多个数据库的方式
之前学习ASP.NETCore及SqlSugar时都是只连接单个数据库处理数据,仅需在Program文件中添加ISqlSugarClient的单例即可(如下代码所示)。 builder.Services.AddSingleton<ISqlSugarClient>(s > {SqlSugarScope sqlSugar new SqlSugar…...
leetcode hot100【Leetcode 72.编辑距离】java实现
Leetcode 72.编辑距离 题目描述 给定两个单词 word1 和 word2,返回将 word1 转换为 word2 所使用的最少操作数。 你可以对一个单词执行以下三种操作之一: 插入一个字符删除一个字符替换一个字符 示例 1: 输入: word1 "horse", word2 &…...
【开源免费】基于Vue和SpringBoot的服装生产管理系统(附论文)
博主说明:本文项目编号 T 066 ,文末自助获取源码 \color{red}{T066,文末自助获取源码} T066,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…...
Android13 允许桌面自动旋转
一)需求-场景 Android13 实现允许桌面自动旋转 Android13 版本开始后,支持屏幕自动旋转,优化体验和兼容性,适配不同屏幕 主界面可自动旋转 二)参考资料 android framework13-launcher3【06手机旋转问题】 Launcher默…...
异常知识及其使用
异常的简单概念 在C中,异常处理是一种机制,用于处理程序运行时发生的意外情况。它允许程序在发生错误时,将控制权转移到一个专门的代码块,而不是让程序直接崩溃。C的异常处理机制包括以下几个关键概念: throw 用途&…...
Spark常问面试题---项目总结
一、数据清洗,你都清洗什么?或者说 ETL 你是怎么做的? 我在这个项目主要清洗的式日志数据,日志数据传过来的json格式 去除掉无用的字段,过滤掉json格式不正确的脏数据 过滤清洗掉日志中缺少关键字段的数据ÿ…...
哈希及其模拟实现
1.哈希的概念 顺序结构以及平衡树中,元素的关键码与其存储位置之间没有对应的关系。因此,在查找一个元素时,必须要经过关键码的多次比较。顺序查找的时间复杂度为O(N),平衡树中为树的高度,即O(log_2 N),搜…...
Day 32 动态规划part01
今天正式开始动态规划! 理论基础 无论大家之前对动态规划学到什么程度,一定要先看 我讲的 动态规划理论基础。 如果没做过动态规划的题目,看我讲的理论基础,会有感觉 是不是简单题想复杂了? 其实并没有,我讲的理论基础内容,在动规章节所有题目都有运用,所以很重要!…...
【娱乐项目】竖式算术器
Demo介绍 一个加减法随机数生成器,它能够生成随机的加减法题目,并且支持用户输入答案。系统会根据用户输入的答案判断是否正确,统计正确和错误的次数,并显示历史记录和错题记录。该工具适合用于数学练习,尤其适合练习基…...
XRP 深度解析:从技术到 Meme 币交易指南
撰文:Ignas | DeFi Research 编译:Yuliya,PANews 本文来源Techub News:XRP 深度解析:从技术到 Meme 币交易指南 在当前加密货币市场,一个令人瞩目的现象正在上演:XRP 在短短一个月内暴涨 3.5 倍…...
机器学习周志华学习笔记-第13章<半监督学习>
机器学习周志华学习笔记-第13章<半监督学习> 卷王,请看目录 13半监督学习13.1 生成式方法13.2 半监督SVM13.3 基于分歧的方法13.4 半监督聚类 13半监督学习 前面我们一直围绕的都是监督学习与无监督学习,监督学习指的是训练样本包…...
【MySql】navicat连接报2013错误
navicat连接mysql报2013错误 报错信息1、检验Mysql数据库是否安装成功2、对Mysql的配置文件进行修改配置2.1、找到配置文件2.2、Linux下修改配置文本 3、连接进入mysql服务4、在mysql下执行授权命令 报错信息 Navicat连接mysql报2013错误 2013-Lost connection to MYSQL serve…...
【微服务】Docker
一、Docker基础 1、依赖的兼容问题:Docker允许开发中将应用、依赖、函数库、配置一起打包,形成可移植镜像Docker应用运行在容器中,使用沙箱机制,相互隔离。 2、如何解决开发、测试、生产环境有差异的问题:Docker镜像…...
renderExtraFooter 添加本周,本月,本年
在 Ant Design Vue 中,a-date-picker 组件提供了一个 renderExtraFooter 属性,可以用来渲染额外的页脚内容。你可以利用这个属性来添加“本周”、“本月”和“本年”的按钮。下面是如何在 Vue 2 项目中实现这一功能的具体步骤: 1.确保安装了…...
警惕开源信息成为泄密源头
文章目录 前言一、信息公开需谨慎1、警惕采购招标泄密。2、警惕信息公开泄密。3、警惕社交媒体泄密。 二、泄密风险需严防1、健全制度,明确责任。2、加强管控,严格审查。3、提高意识,谨言慎行。 前言 大数据时代,信息在网络空间发…...
密码学和CA证书
参考视频 一. 公钥私钥的理解 我们提到的使用公钥私钥进行加密解密只是一种口头表达方式,准确来说应该是公钥和私钥通过加密 算法生成,也需要通过配合加密算法进行解密。而不是直接用公钥和私钥进行加密解密。 二. 对称加密和非对称加密算法 1. 非对…...
Python 入门教程(2)搭建环境 | 2.4、VSCode配置Node.js运行环境
文章目录 一、VSCode配置Node.js运行环境1、软件安装2、安装Node.js插件3、配置VSCode4、创建并运行Node.js文件5、调试Node.js代码 一、VSCode配置Node.js运行环境 1、软件安装 安装下面的软件: 安装Node.js:Node.js官网 下载Node.js安装包。建议选择L…...
Nginx Web服务器管理、均衡负载、访问控制与跨域问题
Nginx Web 服务器的均衡负载、访问控制与跨域问题 Nginx 的配置 1. 安装Nginx 首先安装Nginx apt install nginx -ycaccpurgatory-v:~$ sudo apt install nginx [sudo] password for cacc: Reading package lists... Done Building dependency tree... Done Reading state i…...
排序学习整理(2)
上集回顾 排序学习整理(1)-CSDN博客 2.3 交换排序 交换排序的基本思想是:根据序列中两个记录键值的比较结果,交换这两个记录在序列中的位置。 特点: 通过比较和交换操作,将键值较大的记录逐步移动到序列…...
【前端】将vue的方法挂载到window上供全局使用,也方便跟原生js做交互
【前端】将vue的方法挂载到window上供全局使用,也方便跟原生js做交互 <template><div><el-button click"start">调用方法</el-button></div> </template> <script> // import { JScallbackProc } from ./JScal…...
单片机的中断系统
作者简介 彭煜轩,男,银川科技学院计算机与人工智能学院,2022级计算机与科学技术8班本科生,单片机原理及应用课程第3组。 指导老师:王兴泽 电子邮件:1696409709qq.com 前言 本篇文章是参考《单片机原理…...
Java基础面向对象(接口高级)
高版本的接口 JDK8.0 普通的公开非抽象方法(默认方法) [public] default 返回值类型 方法名(形参列表){//操作语句 } default: 在此位置身份为非抽象标识 接口中的非抽象方法实现类不需要进行重写且通常不会进行重写 当父类与接口的方法体出现冲突时, 优先执行父类内容 (类优…...
OpenCV圆形标定板检测算法findCirclesGrid原理详解
OpenCV的findCirclesGrid函数检测圆形标定板的流程如下: findCirclesGrid函数源码: //_image,输入图像 //patternSize,pattern的宽高 //_centers,blobs中心点的位置 //flags,pattern是否对称 //blobDetector,这里使用的是SimpleBlobDetector bool cv::findCirclesGrid(…...
Linux 网卡收包流程如下
Linux 网卡收包流程如下 网卡收到数据包将数据包从网卡硬件缓存移动到服务器内存中(DMA方式,不经过CPU)通过硬中断通知CPU处理CPU通过软中断通知内核处理经过TCP/IP协议栈处理应用程序通过read()从socket buffer读取数据 网卡丢包 我们先看下ifconfig的输出&#…...
普中51单片机——LED流水灯模块
1、GPIO概念 GPIO(general purpose intput output)是通用输入输出端口的简称,可以通过软件来控制其输入和输出。51 单片机芯片的 GPIO 引脚与外部设备连接起来,从而实现与外部通讯、 控制以及数据采集的功能。 1.1、GPIO分类 &a…...
Linux 各个目录作用
刚毕业的时候学习Linux基础知识,发现了一份特别好的文档快乐的 Linux 命令行,翻译者是happypeter,作者当年也在慕课录制了react等前端相关的视频,通俗易懂,十分推荐 关于Linux的目录,多数博客已有详细介绍…...
【包教包会】CocosCreator3.x——重写Sprite,圆角、3D翻转、纹理循环、可合批调色板、不影响子节点的位移旋转缩放透明度
一、效果演示 重写Sprite组件,做了以下优化: 1、新增自变换,在不影响子节点的前提下位移、旋转、缩放、改变透明度 新增可合批调色板,支持色相、明暗调节 新增圆角矩形、3D透视旋转、纹理循环 所有功能均支持合批、原生平台&…...
腾讯阅文集团Java后端开发面试题及参考答案
Java 的基本数据类型有哪些?Byte 的数值范围是多少? Java 的基本数据类型共有 8 种,可分为 4 类: 整数类型:包括 byte、short、int 和 long。byte 占 1 个字节,其数值范围是 - 128 到 127,用于表示较小范围的整数,节省内存空间,在处理一些底层的字节流数据或对内存要求…...
Kafka如何保证消息可靠?
大家好,我是锋哥。今天分享关于【Kafka如何保证消息可靠?】面试题。希望对大家有帮助; Kafka如何保证消息可靠? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Kafka通过多种机制来确保消息的可靠性,主要包…...
【layui】tabs 控件内通过 iframe 加载url 方式渲染tab页面
<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>tabs 内部使用 iframe 嵌套 url 页面</title><link rel"stylesheet" href"../../../libs/layui/layui-2.4.5/dist/css/layui.css"><scr…...
EtherCAT转DeviceNe台达MH2与欧姆龙CJ1W-DRM21通讯案例
一.案例背景 台达MH2设备通常采用EtherCAT通信协议,这种协议在高速实时通信方面表现出色,适合设备之间的快速数据交换和精准控制。而欧姆龙CJ1W-DRM21 模块基于DeviceNet通信协议,DeviceNet在工业现场总线领域应用广泛,侧重于设备…...
清华、智谱团队:「6000亿合成交错语音文本」预训练,问答性能提升近3倍
与基于文本的大语言模型(LLM)相比,语音语言模型(SpeechLM)接受语音输入并生成语音输出,能够实现更自然的人机交互。然而,传统的 SpeechLM 因缺乏无监督语音数据和并行语音-文本数据,…...
Python办公——openpyxl处理Excel每个sheet每行 修改为软雅黑9号剧中+边框线
目录 专栏导读背景1、库的介绍①:openpyxl 2、库的安装3、核心代码4、完整代码5、最快的方法(50万行44秒)——表头其余单元格都修改样式总结 专栏导读 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 🏳️…...
遇到问题:hive中的数据库和sparksql 操作的数据库不是同一个。
遇到的问题: 1、hive中的数据库和sparksql 操作的数据库不同步。 观察上面的数据库看是否同步 !!! 2、查询服务器中MySQL中hive的数据库,发现创建的位置没有在hdfs上,而是在本地。 这个错误产生的原因是&…...
《网络攻防实践》实践五报告
1.实践内容 防火墙 (1)基本概念 所谓“防火墙”是指一种将内部网和公众访问网(如Internet)分开的方法,它实际上是一种建立在现代通信网络技术和信息安全技术基础上的应用性安全技术,隔离技术。越来…...