Runtime Resource Allocation and Deallocation

The app you develop must contain the code logic for runtime resource allocation. See pyACL API Call Sequence to learn about the overall API call sequence before viewing the resource allocation and deallocation workflows in this section.

Principles

Allocate runtime resources including the device and stream in sequence to support the execution of computing and management tasks. After all data is processed, destroy runtime allocations including the streams and devices in sequence.

Streams can be created implicitly or explicitly based on the application scenarios.

  • Implicit stream creation: applies to simple apps with low complicity of interaction logic. However, in multithreaded programming, each thread uses the default stream. The execution sequence of tasks in the default stream depends on the thread scheduling sequence of the operating system.
  • Explicit stream creation: applies to large apps with complex interaction logic, offering better app readability and maintainability.
Single-process, single-thread, and single-stream scenarios are as follows:
  • Single-process: Each app maps to one process.
  • Single-thread: Only one thread is available by default unless you create more.
  • Single-stream: A single stream is used in the entire development process.

    pyACL executes the asynchronous tasks in the same stream in its original order.

Runtime Resource Allocation

Figure 1 Runtime resource allocation flowchart

The key APIs are described as follows:

Allocate the devices and streams in sequence.

  1. Call acl.rt.set_device to specify the device used for compute. This API also implicitly creates the default context and stream. However, the following constraints must be observed:
    • One device corresponds to one default context. The default context is released when the acl.rt.destroy_context API is called to release resources.
    • One device corresponds to one default stream. The default stream is released when the acl.rt.destroy_stream API is called to release resources.
    • The default context and stream are automatically destroyed with the reset of device using acl.rt.reset_device.
  2. To use the default stream as the input parameter, pass 0. Alternatively, you can call acl.rt.create_stream to explicitly create a stream instead of using the default stream.
  3. (Optional) Call acl.rt.get_run_mode to obtain the run mode of the software stack and determine the logic of the memory allocation API call based on the run mode.

    If the query result is ACL_HOST, host memory needs to be allocated for data transfer.

    If the query result is ACL_DEVICE, only device memory needs to be allocated for data transfer.

    For details, see Data Copy.

Runtime Resource Deallocation

Figure 2 Runtime resource deallocation workflow

The key APIs are described as follows:

Destroy the runtime allocations, including the streams and devices in sequence.
  1. If the acl.rt.create_stream API is called to explicitly create a stream, the acl.rt.destroy_stream API needs to be called to release the stream. Otherwise, the acl.rt.destroy_stream API does not need to be called.
  2. If you call acl.rt.reset_device to destroy resources on the device. This API also implicitly destroy the default context and stream. You do not need to destroy the default context and stream separately.

Sample Code

You can view the complete code in Sample Overview.

After APIs are called, add an exception handling branch, and record error logs and warning logs. The following is a code snippet of key steps only, which is not ready to use.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import acl
#......

# ====== Allocate runtime resources. ======
# 1. Specify a compute device.
ret = acl.rt.set_device(device_id)



# 2. Explicitly create a stream.
# Reserve the execution order of asynchronous tasks.
stream, ret = acl.rt.create_stream()
# ====== Allocate runtime resources. ======

#......

# ====== Destroy runtime allocations. ======
ret = acl.rt.destroy_stream(stream)
ret = acl.rt.reset_device(device_id)
# ====== Destroy runtime allocations. ======

#......