Initialization#

The initialization involves setting up the environment and resources needed for using GPUs. The following steps are covered with the initialization:

  • Setting up the HIP runtime

    This includes reading the environment variables set during init, setting up the active or visible devices, loading necessary libraries, setting up internal buffers for memory copies or cooperative launches, initialize the compiler as well as HSA runtime and checks any errors due to lack of resources or no active devices.

  • Querying and setting GPUs

    Identifying and querying the available GPU devices on the system.

  • Setting up contexts

    Creating contexts for each GPU device, which are essential for managing resources and executing kernels. For further details, check the context section.

Initialize the HIP runtime#

The HIP runtime is initialized automatically when the first HIP API call is made. However, you can explicitly initialize it using hipInit(), to be able to control the timing of the initialization. The manual initialization can be useful to ensure that the GPU is initialized and ready, or to isolate GPU initialization time from other parts of your program.

Note

You can use hipDeviceReset() to delete all streams created, memory allocated, kernels running and events created by the current process. Any new HIP API call initializes the HIP runtime again.

Querying and setting GPUs#

If multiple GPUs are available in the system, you can query and select the desired GPU(s) to use based on device properties, such as size of global memory, size shared memory per block, support of cooperative launch and support of managed memory.

Querying GPUs#

The properties of a GPU can be queried using hipGetDeviceProperties(), which returns a struct of hipDeviceProp_t. The properties in the struct can be used to identify a device or give an overview of hardware characteristics, that might make one GPU better suited for the task than others.

The hipGetDeviceCount() function returns the number of available GPUs, which can be used to loop over the available GPUs.

Example code of querying GPUs:

#include <hip/hip_runtime.h>
#include <iostream>

int main() {

    int deviceCount;
    if (hipGetDeviceCount(&deviceCount) == hipSuccess){
        for (int i = 0; i < deviceCount; ++i){
            hipDeviceProp_t prop;
            if ( hipGetDeviceProperties(&prop, i) == hipSuccess)
                std::cout << "Device" << i << prop.name << std::endl;
        }
    }

    return 0;
}

Setting the GPU#

hipSetDevice() function select the GPU to be used for subsequent HIP operations. This function performs several key tasks:

  • Context Binding

    Binds the current thread to the context of the specified GPU device. This ensures that all subsequent operations are executed on the selected device.

  • Resource Allocation

    Prepares the device for resource allocation, such as memory allocation and stream creation.

  • Check device availability

    Checks for errors in device selection and returns error if the specified device is not available or not capable of executing HIP operations.