aclSetAclOpExecutorRepeatable

Description

Enables aclOpExecutor to be reusable. If you want to reuse existing aclOpExecutor, you must call this API immediately to enable the reuse after the first-phase API aclxxXxxGetworkspaceSize is executed. Later, you can call the second-phase API aclXxx multiple times for operator execution.

aclOpExecutor is a built-in operator executor, a container for executing operator computation. You can use it without knowing how it works inside.

Prototype

aclnnStatus aclSetAclOpExecutorRepeatable(aclOpExecutor *executor)

Parameter Description

Parameter

Input/Output

Description

executor

Input

aclOpExecutor to be reused.

Return Value

0 on success; otherwise, failure. For details about the return codes, see Common API Return Codes.

Possible causes:

  • Error code 561103: The executor is a null pointer.

Constraints

  • Currently, operators that use AI CPU and AI Core compute units support aclOpExecutor reuse.
  • When a single-operator API is called, aclOpExecutor reuse cannot be enabled in the following situations:
    • If L0 APIs related to host-to-device and device-to-device copy are used, such as CopyToNpu, CopyNpuToNpu, and CopyToNpuSync, aclOpExecutor cannot be reused.
    • If the L0 ViewCopy API is used and the source address and destination address of ViewCopy are the same, aclOpExecutor cannot be reused.

    For details about L0 APIs, see Basic Tensor APIs.

  • When this API is called, the tensor resources (such as shape, format, and dtype, except for addr) in the executor are fixed, and their lifecycle is managed by the user. Their lifecycle ends by calling aclDestroyAclOpExecutor. If an aclSetXxxAddr API is used to configure the address of a tensor with an unknown lifecycle, issues such as concurrent access and resource management disorder may occur during the execution of the second-phase aclnn API.
  • aclOpExecutor that is set to the reusable state does not clear the executor resources after the second API is executed. It needs to be used in conjunction with aclDestroyAclOpExecutor to clear the resources.

Example

The following sample code is for reference only. Do not copy and run it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Create aclTensor and aclTensorList for the input and output.
std::vector<int64_t> shape = {1, 2, 3};
aclTensor tensor1 = aclCreateTensor(shape.data(), shape.size(), aclDataType::ACL_FLOAT,
nullptr, 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), nullptr);
aclTensor tensor2 = aclCreateTensor(shape.data(), shape.size(), aclDataType::ACL_FLOAT,
nullptr, 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), nullptr);
aclTensor tensor3 = aclCreateTensor(shape.data(), shape.size(), aclDataType::ACL_FLOAT,
nullptr, 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), nullptr);
aclTensor output = aclCreateTensor(shape.data(), shape.size(), aclDataType::ACL_FLOAT,
nullptr, 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), nullptr);
aclTensor *list[] = {tensor1, tensor2};
auto tensorList = aclCreateTensorList(list, 2);
uint64_t workspaceSize = 0;
aclOpExecutor *executor;
// The AddCustom operator has two inputs (aclTensorList and aclTensor) and one output (aclTensor).
// Call the first-phase API.
aclnnAddCustomGetWorkspaceSize(tensorList, tensor3, output, &workspaceSize, &executor);
// Set the executor to be reusable.
aclSetAclOpExecutorRepeatable(executor);  
void *addr;
aclSetDynamicInputTensorAddr(executor, 0, 0, tensorList, addr);   // Update the device address of the first aclTensor in the input tensorList.
aclSetDynamicInputTensorAddr(executor, 0, 1, tensorList, addr);  // Update the device address of the second aclTensor in the input tensorList.
...
// Call the second-phase API.
aclnnAddCustom(workspace, workspaceSize, executor, stream);
// Destroy the executor.
aclDestroyAclOpExecutor(executor);