Normal Accuracy

A correct computation result for operator running is the basis of performance optimization. To evaluate the correctness of the computation result, you need to compare the known correct output with the actual result. After each optimization iteration, check whether the new performance optimization result meets the accuracy evaluation standard.

The following describes the factors that affect accuracy:

To prevent unnecessary inaccuracy, you must also know the rule to be strictly followed during encoding, that is, do not modify kernel parameters.

Correctly Inserting Synchronization

Correctly Calculating the Offset Address

When multi-core computing is enabled for an operator, the computation amount of a single core needs to be determined during tiling, based on which the address offset on the kernel is performed.

The following introduces the allocation scheme: The total data length TOTAL_LENGTH is 8 x 2048 elements. The data is evenly allocated to eight cores, and the size (BLOCK_LENGTH) of data processed by each core is 2048. x + BLOCK_LENGTH * GetBlockIdx() is the memory offset address of input x in the global memory of the single-core processing program. After the offset address is obtained, call SetGlobalBuffer of the GlobalTensor class to set the start address and length of the global memory of the core. For details, see Figure 1.

1
xGm.SetGlobalBuffer((__gm__ half*)x + BLOCK_LENGTH * GetBlockIdx(), BLOCK_LENGTH);
Figure 1 Multi-core parallel processing

Using Float Computation

Forbidding Modifying Kernel Parameters

This means it is not allowed to assign values to or modify function parameters. In the following example of FlashAttentionKernel function, its parameters such as query, key, and tilingData are pointers and cannot be modified. The pointer content cannot be modified for operator input parameters (however, it can be modified for operator output parameters). To implement static compilation, do not modify the tilingData pointer itself or the content it points to.

1
2
3
__aicore__ __global__ void FlashAttentionKernel(__gm__ uint8_t* query, __gm__ uint8_t* key, ..., __gm__ uint8_t* attention,..., __gm__ uint8_t* tilingData) {
    ......
}

[Negative Example]

1
2
3
4
5
// Re-assigning a value to the kernel function parameter and modifying TilingData are not allowed. The following is a negative example:
query = tmpQueryPtr;
key = tmpKeyPtr;
tilingData = tmpTilingDataPtr; 
tilingData[0] = 2;

[Positive Example]

1
2
3
4
5
6
7
// Perform only the read operation on the input parameter.
inputQueryGMTensor.SetGlobalBuffer(query);

//The attention pointer of the output parameter is read-only, but the memory to which it points can be read and written.
outputAttentionGMTensor.SetGlobalBuffer(attention);
...
DataCopy(outputAttentionGMTensor, outputAttentionLocalTensor, count);