Device Memory Usage

In Ascend heterogeneous compute programming, the typical application scenario is as follows: The aclrtMallocHost API is used to allocate the host memory, the aclrtMalloc API is used to allocate the device memory, and the aclrtMemcpy (synchronous)/aclrtMemcpyAsync (asynchronous) API is used to copy data from the host to the device. During operator execution, the device memory is used for computation and result storage.

The following is a simple sample code snippet. In the sample code, two tensors are copied from the host memory to the device memory, computation is performed on the device, and then the result is copied from the device memory to the host memory.
int main(void)
{
    int32_t deviceId = 0;
    int64_t N = 16; 
    const size_t bytes = static_cast<size_t>(N) * sizeof(float);
    aclrtStream stream = nullptr;

    // Step 1: Perform initialization and create a stream.
    aclInit(nullptr);
    aclrtSetDevice(deviceId);
    aclrtCreateStream(&stream);

    // Step 2: Allocate the host memory.
    void* hostA = nullptr;
    void* hostB = nullptr;
    void* hostOut = nullptr;

    aclrtMallocHost(&hostA, bytes);
    aclrtMallocHost(&hostB, bytes);
    aclrtMallocHost(&hostOut, bytes);

    // Initialize the input data.
    ...

    // Step 3: Allocate the device memory.
    void* deviceA = nullptr;
    void* deviceB = nullptr;
    void* deviceOut = nullptr;

    // The third parameter aclrtMemMallocPolicy indicates the memory page allocation policy when memory is allocated.
    // ACL_MEM_MALLOC_HUGE_FIRST indicates that huge page memory is preferred. For details about other definitions, see the API reference.
    aclrtMalloc(&deviceA, bytes, ACL_MEM_MALLOC_HUGE_FIRST);
    aclrtMalloc(&deviceB, bytes, ACL_MEM_MALLOC_HUGE_FIRST);
    aclrtMalloc(&deviceOut, bytes, ACL_MEM_MALLOC_HUGE_FIRST);

    // Step 4: Transfer the input data from the host memory to the device memory.
    aclrtMemcpy(deviceA, bytes, hostA, bytes, ACL_MEMCPY_HOST_TO_DEVICE);
    aclrtMemcpy(deviceB, bytes, hostB, bytes, ACL_MEMCPY_HOST_TO_DEVICE);

    // Step 5: Perform the computation operation, such as aclnnAdd, and save the computation result in the device memory.
    // ...

    // Step 6: Transfer the computation result from the device memory to the host memory.
    aclrtMemcpy(hostOut, bytes, deviceOut, bytes, ACL_MEMCPY_DEVICE_TO_HOST);

    // Step 7: Handle the computation result on the host.
    // ...

    // Step 8: Clean up resources.
    // Step 8.1: Free the host and device memory.
    if (deviceA) (void)aclrtFree(deviceA);
    if (deviceB) (void)aclrtFree(deviceB);
    if (deviceOut) (void)aclrtFree(deviceOut);
    if (hostA) (void)aclrtFreeHost(hostA);
    if (hostB) (void)aclrtFreeHost(hostB);
    if (hostOut) (void)aclrtFreeHost(hostOut);

    // Step 8.2: Clean up device and process resources.
    if (stream) (void)aclrtDestroyStream(stream);
    (void)aclrtResetDevice(deviceId);
    (void)aclFinalize();

    return 0;
}