Multi-Device Selection
In the scenario where one host is used with multiple devices, you can call the aclrtGetDeviceCount API in the application on the host to obtain the number of devices on the host. The devices are numbered in ascending order, starting from 0.
The following is the sample code for obtaining the device information, which is for reference only and cannot be directly copied for compilation and running:
1 2 3 4 5 6 7 8 9 10 |
// Obtain the number of devices and their attributes. uint32_t deviceCount; aclrtGetDeviceCount(&deviceCount); uint32_t deviceId; for (deviceId = 0; deviceId < deviceCount; ++deviceId) { // Query device attributes as required. aclrtDevAttr attr = ACL_DEV_ATTR_VECTOR_CORE_NUM; int64_t value; aclrtGetDeviceInfo(deviceId, attr, &value); } |
In this case, you can call the aclrtSetDevice API to switch the device by thread at any time (without affecting other threads). After a device is specified, subsequent operations such as memory allocation and kernel execution are performed on the device, and the stream and event are also associated with the specified device. You can call the aclrtResetDevice API to free resources. However, it is recommended that you call the aclrtResetDeviceForce API to clear resources on the device at a time, including the default context, default stream, and all streams created in the default context. If a task in the default context or stream is not complete, resources will be freed after the task is complete. If the aclrtResetDevice API is used in your program, ensure that the aclrtSetDevice and aclrtResetDevice APIs are called in pairs.
The following figure shows the API call sequence for multi-device selection.

The following is the sample code for multi-device selection, which is for reference only and cannot be directly copied for compilation and running:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// Specify device 0 as the compute device and use the default context of device 0 as the default context of the current thread. aclrtSetDevice(0); aclrtStream s0; aclrtCreateStream(&s0); // Execute task 1. ...... // Specify device 1 as the compute device and use the default context of device 1 as the default context of the current thread. aclrtSetDevice(1); aclrtStream s1; aclrtCreateStream(&s1); // Execute task 2. ...... // Reset device 1 to free the compute resources. The default context of the thread is freed. // To continue running a task, you need to explicitly specify the device and context. aclrtResetDeviceForce(1); // Reset device 0 to free the compute resources. aclrtResetDeviceForce(0); |