SIMD BuiltIn关键字

预定义宏

如其他语言一样,会提供一些内置的宏方便用户编写程序。预定义宏一节着重介绍一些用户在做异构编程时会经常用到的宏,以及宏的解释。

函数执行空间限定符

函数执行空间限定符(Function Execution Space Qualifier)指示函数是在Host侧执行还是在Device侧执行,以及它是否可从Host侧或Device侧调用。

函数标记宏

地址空间限定符

AI Core具备多级独立片上存储,各个地址空间独立编址,具备各自的访存指令,根据架构差异,有些存储空间具备统一地址空间(Generic Address Space),有些则没有。设备侧编程基于语法扩展允许地址空间作为合法的类型限定符,以提供针对不同地址空间的访问能力和地址空间合法性检查。

表2 地址空间映射关系

地址空间限定符

AI Core物理存储空间

__gm__

设备侧内存GM

__ubuf__

Vector Unified Buffer

__ca__

Cube L0A Buffer

__cb__

Cube L0B Buffer

__cc__

Cube L0C Buffer

__cbuf__

Cube L1 Buffer

__fbuf__

Fixpipe Buffer

__ssbuf__

SSBuffer

地址空间限定符可以在变量声明中使用,用于指定对象分配的区域。如果对象的类型被地址空间名称限定,那么该对象将被分配在指定的地址空间中。同样地,对于指针,指向的类型可以通过地址空间进行限定,以指示所指向的对象所在的地址空间。

// declares a pointer p in the __gm__ address space that
// points to an object(has int type) in the __gm__ address space
__gm__ int *p;

__global__ __aicore__ void foo(...)
{
  // declares an array of 4 floats in the private address space.
  float x[4];
}

地址空间限定符不能用于非指针返回类型,非指针函数参数,函数类型,同一个类型上不允许使用多个地址空间限定符。

// OK.
__aicore__ int f() {...}

// Error. Address space qualifier cannot be used with a non-pointer return type.
__ubuf__ int f() { ... }

// OK. Address space qualifier can be used with a pointer return type.
__ubuf__ int *f() { ... }

// Error. Multiple address spaces specified for a type.
__ubuf__ __gm__ int i;

// OK. The first address space qualifies the object pointed to and the second
// qualifies the pointer.
__ubuf__ int * __gm__ ptr;

重要:不同地址空间指针的大小可能不同。例如,不能认为 sizeof(__gm__ int *)总是等于sizeof(__ubuf__ int *),譬如编译器或许可能在某些系统上以32bit存储__ubuf__指针。

内置常量

常量名

取值

功能

constexpr int32_t g_coreType

  • AscendC::AIC
  • AscendC::AIV

常量值由框架自动设置,AIC核下,配置为AscendC::AIC,AIV核下,配置为AscendC::AIV。

可以通过对该常量值的判断,来实现了AIV与AIC核代码的区分和隔离。功能等同于直接使用ASCEND_IS_AIV、ASCEND_IS_AIC。

内置变量

变量名

对应API

功能

block_num

GetBlockNum

当前任务配置的核数,用于代码内部的多核逻辑控制等。

block_idx

GetBlockIdx

当前核的索引,用于代码内部的多核逻辑控制及多核偏移量计算等。

通常,建议用户使用内置变量对应的API获取所需值,不建议用户直接使用内置变量。因为内置变量反映的是单个硬件资源的配置信息,对于软件栈整合硬件资源、扩展硬件的功能,内置变量的值与实际语义可能不符。

例如,在 Atlas 推理系列产品 中,当启用KERNEL_TYPE_MIX_VECTOR_CORE时,算子会同时运行在AI Core和Vector Core上。此时,block_idx在这两种核心上都是从0开始计数,用户无法直接通过block_idx来切分数据和控制多核逻辑。而GetBlockIdx在Vector Core上对block_idx增加偏移量(AI Core的block_num),从而保证返回的值能够正确反映多核环境下的实际逻辑。

SIMD与SIMT混合编程场景

SIMD与SIMT混合编程场景中,SIMT VF的入口函数使用__simt_vf__进行标识,通过在SIMD的__aicore__函数中使用asc_vf_call调用SIMT入口函数。被SIMT VF入口函数调用的函数使用__simt_callee__进行标识。

Ascend C为SIMT编程、SIMD与SIMT混合编程提供了布尔、整形、浮点型的标量数据类型和短向量数据类型,提供了用于表达线程块、线程网格三维信息的内置变量。 关于内置数据格式的详细说明请参见内置数据类型,内置变量请参见内置变量