范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

CANN算子利用迭代器高效实现Tensor数据切割分块处理

  摘要:本文以Diagonal算子为例,介绍并详细讲解如何利用迭代器对n维Tensor进行基于位置坐标的大批量数据读取工作。
  本文分享自华为云社区《CANN算子:利用迭代器高效实现Tensor数据切割分块处理-云社区-华为云》,作者: CatherineWang 。 任务场景及目标
  在CANN aicpu算子开发实现中,经常需要对n维Tensor进行切片(slice)、切块(dice)、转置(transpose)、交换指定维度数据(shuffle)等操作。上述操作实质上是按照指定规律依次进行数据读取,并将读取到的数据写入新的数据地址中。
  本文以Diagonal算子为例,介绍并详细讲解如何利用迭代器对n维Tensor进行基于位置坐标的大批量数据读取工作。
  Diagonal算子希望对指定两个维度的数据进行对角元素的提取,最终返回张量的对角线元素。本质上该算子通过属性dim1和dim2确定一个矩阵,返回该矩阵的对角元素(存在偏移量offset),并将其放置在最后一维。非dim1和dim2的维度,将会被当成batch维度处理。 常规方案:
  方案一: 将shape为s,元素个数为numel的 输入Tensor:x转化为Eigen::Tensor:eigen_x;对eigen_x进行shuffle操作,将dim1和dim2换至倒数第二和倒数第一维;通过reshape操作将eigen_x变化为一个三维Eigen::Tensor:reshape_x,shape=(numel/ s[dim1]/s[dim2],s[dim1],s[dim2]);对后两维数据取对角元素,并将最终数据赋值给输出数据地址。 注意: 由于Eigen::Tensor不能够动态设置维度,即NumIndices_项必须是一个具体的值,因此需要提前定义对应维度的Eigen::Tensor备用。
  方案二: 对于一个n维的Tensor,利用n层for循环进行数据的定位读取,并取对角值。
  可以看出上述两个方案对动态大小的输入计算实现处理都较为繁琐,需要提前分情况设置对应维度的Eigen::Tensor或是for循环逻辑结构,即存在维数限制。 准备知识及分析
  我们知道再AICPU中,对于一个Tensor,我们能够通过GetTensorShape、GetData等函数获得Tensor形状大小、具体数据地址等信息。但我们不能通过位置坐标的形式直接获得指定位置的数据值。 1.步长
  首先介绍步长(stride)这一概念(对这部分知识已掌握的可以直接跳转下一部分内容)。stride是在指定维度dim中从一个元素跳到下一个元素所必需的步长。例如,对于一个shape=(2, 3, 4, 5)的Tensor,其stride=(60, 20, 5, 1)。因此如果想要获取到上述Tensor中位置坐标为[1, 2, 1, 3]的数据,只需要找到数据地址中第108(=60*1+20*2+5*1+3)位对应值。 2.迭代器
  定义迭代器PositionIterator,包含私有成员pos_和shape_,其中pos_为初始位置,shape_为标准形状。通过重载++符号,对pos_进行修改,实现迭代器的自增操作。基于上述迭代器,可以实现对给定的shape依次取位操作。如给定对于给定的shape=(d_1,d_2,…,d_n),从初始位置(0,0,…,0)开始,依次取(0,0,…,0,0), (0,0,…,0,1),…,(0,0,…,0,d_n-1), (0,0,…,1,0), (0,0,…,1,1),…, (d_1 - 1,d_2 - 1,…,d_{n-1}-1,d_{n}-1).
  事实上,可以将上述迭代器理解为一种进制,对于给定的标准形状shape_=(d_1,d_2,…,d_n),第i位运算时便是逢d_i进1。同时通过 PositionIterator  .End()控制迭代器的结束。具体实现如下:  template   class PositionIterator {  public:  PositionIterator(){};  ~PositionIterator(){};  PositionIterator(std::vector stt, std::vector sh) {  if (stt.size() != sh.size()) {  PositionIterator();  } else {  for (unsigned int i = 0; i < sh.size(); i++) {  if (stt[i] >= sh[i]) {  PositionIterator();  }  }  pos_ = stt;  shape_ = sh;  }  }  PositionIterator operator++() {  pos_[shape_.size() - 1] += 1;  for (unsigned int i = shape_.size() - 1; i > 0; i--) {  if (pos_[i] / shape_[i] != 0) {  pos_[i - 1] += pos_[i] / shape_[i];  pos_[i] = pos_[i] % shape_[i];  }  }  return *this;  }  bool End() {  if (pos_[0] != shape_[0]) {  return false;  }  return true;  }  std::vector GetPos() { return pos_; }  std::vector GetShape() { return shape_; }  private:  std::vector pos_;  std::vector shape_;  };Diagonal算子的实现
  利用迭代器,在一般情况下,我们只需要两层for循环,便可以实现Diagonal算子的计算过程。第一层for循环用于确定除dim1和dim2维度的位置坐标,第二层for循环用于对dim1和dim2对应维度确定对角元素位置,通过这样的两层for循环,便可将对角元素位置确定。通过这样的取值处理,相较于Eigen实现思路,计算速度有着明显的提升,且无维度限制,st测试结果对比如下:
  具体实现可参见如下代码:  template   uint32_t DiagonalCpuKernel::DoComputeType(CpuKernelContext &ctx,  const int64_t &offset,  const int64_t &dim1,  const int64_t &dim2) {  // Get the inuput and output  Tensor *input_x = ctx.Input(0);  Tensor *y = ctx.Output(0);  // Get some information of input  auto x_shape = input_x->GetTensorShape();  std::vector x_shape_ = x_shape->GetDimSizes();  const int64_t x_dim = x_shape->GetDims();  auto dataptr = reinterpret_cast(ctx.Input(0)->GetData());  auto y_dataptr = reinterpret_cast(y->GetData());  // Compute  // 首先计算出对角线元素个数  int64_t dsize = OffsetSize(offset, dim1, dim2, x_shape_);  // 生成输入Tensor的步长向量x_stride  std::vector x_stride = ConstructStride(x_shape_);  // 分情况讨论,2维和大于2维的情况  if (x_dim != N2) {  //set the vx_shape and vx_stride  // 生成x_shape和x_stride中除去dim1和dim2对应值的vx_shape与vx_stride  std::vector vx_shape, vx_stride;  for (unsigned int tmp_dim = 0; tmp_dim < x_shape_.size(); tmp_dim++) {  if (tmp_dim != dim1 && tmp_dim != dim2) {  vx_shape.push_back(x_shape_[tmp_dim]);  vx_stride.push_back(x_stride[tmp_dim]);  }  }  // set the y_shape, y_stride, vy_stride  // 生成输出Tensor的形状及步长向量:y_shape和y_stride  std::vector y_shape = vx_shape;  y_shape.push_back(dsize);  std::vector y_stride =  ConstructStride(y_shape);  // 生成输出Tensor的出去最后一维的步长向量:vy_stride  std::vector vy_stride = y_stride;  vy_stride.pop_back();  // 读取对角数据  std::vector v_start(vx_shape.size(), 0);  for (PositionIterator myiter(v_start, vx_shape); !myiter.End();  ++myiter) {  // 利用迭代器确定除dim1和dim2维度的位置坐标  auto p = myiter.GetPos();  // 通过步长向量和位置坐标计算出输入和输出的基础位置值base_pos1和outbase_pos  int64_t base_pos1 = MulSum(p, vx_stride);  int64_t outbase_pos = MulSum(p, vy_stride);  for (int i = 0; i < dsize; i++) {  // 结合前面计算出的基础位置值,对dim1和dim2对应维度确定对角元素位置,并赋值给输出数据地址(get_data涉及对上对角还是下对角取元素,不影响对迭代器作用的理解)  int64_t base_pos2 = i * (x_stride[dim1] + x_stride[dim2]);  int64_t arr[N2] = {x_stride[dim1], x_stride[dim2]};  y_dataptr[outbase_pos + i] =  get_data(base_pos1 + base_pos2, offset, arr, dataptr);  }  }  } else {  for (int i = 0; i < dsize; i++) {  int64_t base_pos = i * (x_stride[dim1] + x_stride[dim2]);  int64_t arr[N2] = {x_stride[dim1], x_stride[dim2]};  y_dataptr[i] = get_data(base_pos, offset, arr, dataptr);  }  }  return KERNEL_STATUS_OK;  }迭代器的其他用法
  1、数据切条:如Sort算子中,用迭代器对Tensor数据关于tmp_axis维度进行取条,以进行后续的排序操作。  for (position_iterator mit(v_start, v_shape); !mit.end(); ++mit) {  auto p = mit.get_pos();  int axis_len = input_shape_[tmp_axis];  std::vector> data_(axis_len);  int base_pos = mul_sum(p, v_stride);  for (int32_t i = 0; i < axis_len; i++) {  data_[i].value = x_dataptr[base_pos + i * input_stride[tmp_axis]];  data_[i].index = i;  }
  2、数据切块:切块处理可以利用两个迭代器循环叠加,也可以利用一个迭代器和两个坐标位置for循环
  3、关于指定维度dim,对Tensor降维拆分为N子Tensor:如UniqueConsecutive算子中,首先需要关于属性axis维,将原本的Tensor数据拆分为input_shape[axis]个子Tensor(此处用vector存储Tensor中的数据)。  std::vector> data_;  for (int64_t i = 0; i < dim0; i++) {  std::vector tmp_v1;  for (PositionIterator mit(v_start, v_shape); !mit.End(); ++mit) {  auto pos = mit.GetPos();  tmp_v1.push_back(  x_dataptr[MulSum(pos, v_stride) + i * input_stride[axis]]);  }  data_.push_back(tmp_v1);  }
  点击下方,第一时间了解华为云新鲜技术~
  华为云博客_大数据博客_AI博客_云计算博客_开发者中心-华为云

马化腾不想一条道跑到黑了图片来源视觉中国腾讯曾寄予厚望的XR项目,突然但不令人意外地退场了。2月16日下午,有消息称,腾讯宣布部分解散XR(扩展现实)团队。该团队300余名员工将获得两个月缓冲期,寻找内部Nodejs使用ZooKeeper做服务发现将单体服务拆分为微服务后,为了服务高可用,一般会做集群多实例。但在分布式下,怎么进行高效便捷的进行服务访问问题,出现了各类服务注册和服务发现框架。这里使用的是Zookeeper。Z女子同房后,发现胎死腹中住院治疗女子,34岁,因停经2月,检查发现胚胎停止发育声像半天。女子自诉怀孕2个月,一个星期前因老公想要有同房过,今来医院孕前检查彩超提示宫内胚胎停止发育声像,约6周左右。女子特别伤心难过吴士林这个寒冬里的我(纪实散文)散文家乡人生微语我要上头条这个寒冬里的我(散文)作者吴士林呼啸的北风,把天刮得忽阴忽晴。没精打采的太阳,悬挂在散乱飘飞的云中。公路两旁光秃秃的树枝,在风中不停地晃动。乐陵城的大小街有哪些真正写到你心里去了的句子?1。人生的旅程就是这样,用大把时间迷茫,在几个瞬间成。2。世人慌慌张张,不过图碎银几两,而这碎银几两,可解这世间万种慌张,保老人万年安康,儿女入得学堂,柴米油盐五谷粮。3。要把所有人生的低谷是自由,又是一位中年人的碎碎念作为生活中的中年人,其实已经沦为职场上的老年人。之所以有冲动来奋笔疾书,也是为正在到来的低谷时刻倾吐衷肠,也在奢望由此求得些自我宽慰。大概不超过12周的时间,我将失去一个不太值得珍想,全是问题做,才有答案勇敢的迈出第一步,是治愈焦虑的良药每个人都喜欢站在人群中脱颖而出的感觉,但上帝的的确确没有赋予我们特异功能,所以我们必须努力。千里之行始于足下,蹉跎只会感动自己,而行动才能打动别人在社会中人总是清醒的活着可以留下一句让人清醒的文案吗总会有人觉得清醒是一种痛苦。不,对我来说我知道我不在金字塔的顶端或底部。对于一些高层来说,一顿饭就是我的月薪。对于一些底层人来说,每天的生活费都不够给我三个人的早餐,她,他,他晨曦撩开纱织窗帘,唤醒我和他的睡眼。昨夜的吻痕烙在他胸前,昨夜的齿印留在我的肩。而留下它们后,安然睡熟在中间的你却已不见。他起身勾住我的脖颈,语调清新我们的爱人哪里去了?我亦扬起唇千万不要小看茄子,大厨教你独特做法,比大鱼大肉还过瘾,太香了千万不要小看茄子,大厨教你独特做法,比大鱼大肉还过瘾,太香了。茄子是一年四季都可以买得到的蔬菜,价钱也不贵,对身体也极有好处,常常走上我家的餐桌。关于茄子的烹饪方法有很多,不仅可以10道春季下饭蔬菜,做法简单快手,春季让蔬菜美食为你添饭头条创作挑战赛大家好,欢迎大家来到我的美食自媒体,我是美食领域创作者锦绣V山东专注美食,让生活更有味。今天为大家带来了几道家常美食的做法,这几道美食也是深受大家的喜欢,而且是很常见
运动达人们,造吗?你们的血液比熊猫血还要珍贵体育锻炼通常对人类和动物健康的各个方面都有好处,可以减缓认知衰老和神经退化。体育锻炼对认知的好处与增强可塑性和减少海马体炎症有关,但我们对介导这些影响的因素和机制知之甚少。2019间接承认win11很渣?微软开启长期白嫖策略距离Windows11系统推出也已经一年多的时间了,而与Windows10刚推出时候不同的是,在这一年多的时间里,用户们对Windows11系统的态度并没有以往那么的热情,反而是质李卫东万物互联网中个人数据云传播的隐私安全随着万物互联网与人工智能技术的融合发展,个性化算法和机器学习的应用已取得巨大进步,能为用户提供丰富多彩的智能新媒体服务,但也引起了人们对隐私技术透明性和人为控制的强烈关注。数据过度CQt开发音视频播放播放内存中的音乐QFileread(。musicNevada。mp3)if(!read。open(QIODeviceReadOnly))qDebug()文件打开失败,请重试下面用的70新增小程序使用云开发,腾讯云上开发工具再升级11月13日,腾讯云联合微信云开发举办2022云开发技术峰会,云开发产品公布了最新数据服务超过300万开发者日均调用超30亿次,近七成的新增小程序选择使用云开发。在本次峰会上,腾讯特斯拉再次博眼球在热点新闻上看到了一条触目惊心的消息,广州一辆特斯拉车主驾驶特斯拉行驶到自家店铺门前准备停车时,车辆突然不能正常停止,反而不断加速,直至加速到约200公里小时的速度疯狂行驶,距离长iOS16耗电太高怎么办?试试关掉这几个开关很多朋友在升级iOS16之后都遇到了耗电快发热增加等情况。尤其是在一些老机型上,续航简直可以用尿崩来形容。造成这种现象的原因主要有三点一是系统优化不到位二是新功能的加入三是老机型性外卖商家面对恶意差评神回复,2022各行业都难如今各大外卖平台已经潜移默化影响到我们的日常生活中。平台对于商家的评分也是根据顾客对商家的评价来确定,所以顾客在下单之前很都会去看下这个店铺的评价是怎么样的,一个店铺差评太多的话也又降了1410元!荣耀得意机皇100倍变焦,12G512G大存储国产旗舰中真正能做到高科技外观设计和最顶尖内核配置的机型并不多,比较公认的是华为Mate系列保时捷版本,用了超跑设计基因全陶瓷的机身材质,又有顶级的处理器影像鸿蒙系统等加持,简直是潮州特斯拉失控,数据问题成焦点!业内人士智能驾驶系统检测难度大特斯拉再次卷入刹车失灵风波。日前,广东潮州一辆特斯拉准备停车时突然加速,造成2死3伤,警方正在进行调查。对于该事故,特斯拉与事故车主各执一词,车辆EDR数据以及智能驾驶系统检测成为Web3。0是新风口还是旧炒作?Web3。0风靡全球,一面是红杉A16zCoinbaseVentures腾讯字节等在内的众多机构竞相抢食,一面是在国内A股市场,蹭上Web3。0概念的上市公司股价扶摇直上。不过值得