迭代器 - 2023.2 简体中文

AI 引擎内核与计算图编程指南 (UG1079)

Document ID
UG1079
Release Date
2023-12-04
Version
2023.2 简体中文

AI 引擎 API 提供了迭代器,以访问 AI 引擎存储器。AI 引擎 API 提供了迭代器,用于基于标量和矢量数据类型进行迭代。此外,它还提供了循环迭代器。下表列出了 AI 引擎 API 所提供的不同类型的迭代器。

表 1. 迭代器
迭代器 描述
aie::begin 返回标量迭代器。
aie::cbegin 返回含只读访问权的标量迭代器。
aie::begin_circular 返回标量循环迭代器。您可指定循环缓冲器大小。
aie::cbegin_circular 返回含只读访问权的标量迭代器。
aie::begin_random_circular 返回含随机访问权的标量循环器迭代器。
aie::cbegin_random_circular 返回含随机只读访问权的标量循环器迭代器。
aie::begin_vector 返回矢量迭代器。您可以指定矢量的大小。
aie::begin_restrict_vector aie::begin_vector 相同,但返回迭代器被视为限制指针。
aie::cbegin_vector 返回含只读访问权的矢量迭代器。
aie::cbegin_restrict_vector aie::cbegin_vector 相同,但返回迭代器被视为限制指针。
aie::begin_restrict_vector 返回 restrict 类型的矢量迭代器。
aie::cbegin_restrict_vector 返回含只读访问权的 restrict 类型矢量迭代器。
aie::begin_vector_circular 返回循环矢量迭代器。您可指定初级矢量大小和循环缓冲器总大小。
aie::cbegin_vector_circular 返回含只读访问权的循环矢量迭代器。
aie::begin_vector_random_circular

返回给定地址和大小所描述的阵列的循环迭代器。

aie::cbegin_vector_random_circular 返回给定地址和大小所描述的阵列的循环迭代器(含只读访问权)。

这两个迭代器可拆分为两个类别:前传迭代器和随机访问迭代器。这些迭代器都支持以下运算:

  • 反引用 *
  • 运算符 ++
  • 运算符 ==
  • 运算符 !=

随机访问迭代器支持更多运算符。例如,aie::begin_vectoraie::begin_vector_random_circular 也支持:

  • 运算符 --
  • 运算符 +
  • 运算符 -
  • 运算符 +=
  • 运算符 -=

如需了解有关每个迭代器类型的更多信息,请参阅 AI 引擎 API 用户指南(UG1529) 中的存储器

循环缓冲器的优势之一是它能避免界外存储器访问。以下提供了使用迭代器访问存储器的一些示例。
alignas(aie::vector_decl_align) int32 init_value[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
auto iIter = aie::begin(init_value);
for(int i=0;i<16;i++, iIter++){
  *iIter=*iIter+1;
}
alignas(aie::vector_decl_align) int32 init_value[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};

// create vector iterator
// first value is [1,2,3,4]
auto pv=aie::begin_vector<4>(init_value); 

// create const circular vector iterator
// first value is [1,2,3,4]
// total 16 elements
auto pv_c=aie::cbegin_vector_circular<4,16>(init_value);  
for(;pv!=init_value+16;pv++){
  aie::vector<int32,4> buff=*pv;
  aie::print(*pv,true,"pv:");
}
for(int i=0;i<5;i++){

  // go back to start 
  // if reach the end of the circular buffer
  aie::vector<int32,4> buff=*pv_c++;
}

// point to circular buffer size 16.
auto p=aie::begin_circular<16>(init_value); 

for(int i=0;i<N;i++){ 

  // return back to init_value+0
  // if reaches init_value+16
  *p++=i;
}
__attribute__ ((noinline)) void pass_through(input_buffer<int> & __restrict in,
    output_buffer<int> & __restrict out
    ){
  auto inIter1=aie::cbegin_restrict_vector<8>(in);
  auto outIter=aie::begin_restrict_vector<8>(out);
  for(int i=0;i<32;i++) {
    *outIter++=*inIter++;
  }
}