SIMD Built-In Keywords

Predefined Macros

Like other languages, some built-in macros are provided for users to write programs. This part describes some macros that are frequently used during heterogeneous programming.

Function Execution Space Qualifier

The function execution space qualifier indicates whether the function is executed on the host or device, and whether the function can be called from the host or device.

Function Marking Macro

Address Space Qualifiers

The AI Core has multi-level independent on-chip storage. Each address space has independent addressing and its own memory access instructions. Depending on the architecture, some storage spaces have a generic address space, while others do not. On-device programming allows address spaces to be used as valid type qualifiers based on syntax extensions, providing access to different address spaces and check of address space validity.

Table 2 Address space mapping

Address Space Qualifier

AI Core Physical Storage Space

__gm__

Global memory on the device

__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

Address space qualifiers can be used in variable declarations to specify the region in which an object is allocated. If the type of an object is qualified by an address space name, the object will be allocated in the specified address space. Similarly, for pointers, the pointing type can be qualified by an address space to indicate the address space in which the pointed-to object resides.

// 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];
}

Address space qualifiers cannot be used for non-pointer return types, non-pointer function parameters, or function types. Multiple address space qualifiers cannot be used for the same type.

// 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;

Important: The pointer size may vary with the address space. For example, sizeof(__gm__ int *) may not always be equal to sizeof(__ubuf__ int *). The compiler may store __ubuf__ pointers in 32-bit mode on some systems.

Built-in Constants

Constant

Value

Description

constexpr int32_t g_coreType

  • AscendC::AIC
  • AscendC::AIV

The constant value is automatically set by the framework. For the AIC core, set it to AscendC::AIC. For the AIV core, set it to AscendC::AIV.

By checking the constant value, you can distinguish and isolate the AIV and AIC core code. The function is the same as that of directly using ASCEND_IS_AIV and ASCEND_IS_AIC.

Built-in Variables

Variable

API

Description

block_num

GetBlockNum

Number of cores configured for the current task, which is used for multi-core logic control in the code.

block_idx

GetBlockIdx

Index of the current core, which is used for multi-core logic control and multi-core offset computation in the code.

Generally, you are advised to use the APIs corresponding to the built-in variables to obtain the required values. You are advised not to directly use the built-in variables. This is because a built-in variable reflects the configuration information of a single hardware resource. For functions of integrating hardware resources and extending hardware by the software stack, the values of built-in variables may not match the actual semantics.

For example, in Atlas inference product , when KERNEL_TYPE_MIX_VECTOR_CORE is enabled, the operator runs on both the AI Core and Vector Core. In this case, block_idx starts counting from 0 on both cores, and users cannot directly use block_idx to split data and control multi-core logic. GetBlockIdx adds an offset (block_num of the AI Core) to block_idx on the Vector Core to ensure that the returned value correctly reflects the actual logic in a multi-core environment.

SIMD and SIMT Programming Scenario

In the SIMD and SIMT programming scenario, the entry function of the SIMT VF is identified by __simt_vf__, and asc_vf_call is used in the __aicore__ function of the SIMD to call the SIMT entry function. The function called by the SIMT VF entry function is identified by __simt_callee__.

Ascend C provides Boolean, integer, and floating-point scalar data types and short vector data types for SIMT programming and SIMD and SIMT programming, and provides built-in variables for expressing three-dimensional information of thread blocks and thread grids. For details about the built-in data formats, see Built-in Data Types. For details about the built-in variables, see Built-in Variables.