[PATCH i-g-t v2] tests/amdgpu: Add multi-GPU test cases for AMDGPU basic functionality

vitaly prosyak vprosyak at amd.com
Wed Jul 30 22:20:22 UTC 2025


Reviewed-by: Vitaly Prosyak  <vitaly.prosyak at amd.com>

On 2025-07-29 03:22, Jesse.Zhang wrote:
> From: "Jesse.zhang" <Jesse.zhang at amd.com>
>
> This commit introduces a new test file `amd_basic_multi_gpu.c` that
> verifies basic AMDGPU functionality across multiple GPUs. The test
> includes:
>
> 1. Memory allocation tests for different memory domains (VRAM visible/invisible,
>    GART cacheable/USWC)
> 2. Command submission tests for GFX, COMPUTE and SDMA IP blocks
> 3. Multi-fence synchronization tests
> 4. User-mode queue (UMQ) tests when enabled via environment variable
> 5. Combined queue testing across all IP blocks
>
> The tests leverage the existing helper functions from the AMDGPU library
> while adding multi-GPU support through forked processes for each GPU.
>
> v2: move the multi-GPU subtests into a separate file (Vitaly)
>
> Signed-off-by: Jesse Zhang <Jesse.Zhang at amd.com>
> ---
>  tests/amdgpu/amd_basic_multi_gpu.c | 425 +++++++++++++++++++++++++++++
>  tests/amdgpu/meson.build           |   1 +
>  2 files changed, 426 insertions(+)
>  create mode 100644 tests/amdgpu/amd_basic_multi_gpu.c
>
> diff --git a/tests/amdgpu/amd_basic_multi_gpu.c b/tests/amdgpu/amd_basic_multi_gpu.c
> new file mode 100644
> index 000000000..22a93ca08
> --- /dev/null
> +++ b/tests/amdgpu/amd_basic_multi_gpu.c
> @@ -0,0 +1,425 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright 2014 Advanced Micro Devices, Inc.
> + * Copyright 2022 Advanced Micro Devices, Inc.
> + * Copyright 2023 Advanced Micro Devices, Inc.
> + */
> +
> +#include "lib/amdgpu/amd_memory.h"
> +#include "lib/amdgpu/amd_sdma.h"
> +#include "lib/amdgpu/amd_PM4.h"
> +#include "lib/amdgpu/amd_command_submission.h"
> +#include "lib/amdgpu/amd_compute.h"
> +#include "lib/amdgpu/amd_gfx.h"
> +#include "lib/amdgpu/amd_shaders.h"
> +#include "lib/amdgpu/amd_dispatch.h"
> +#include "igt.h"
> +#include "igt_multigpu.h"
> +
> +#define BUFFER_SIZE (8 * 1024)
> +
> +/**
> + * MEM ALLOC TEST
> + * @param device
> + */
> +static void amdgpu_memory_alloc(amdgpu_device_handle device)
> +{
> +	amdgpu_bo_handle bo;
> +	amdgpu_va_handle va_handle;
> +	uint64_t bo_mc;
> +
> +	/* Test visible VRAM */
> +	bo = gpu_mem_alloc(device,
> +			   4096, 4096,
> +			   AMDGPU_GEM_DOMAIN_VRAM,
> +			   AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
> +			   &bo_mc, &va_handle);
> +
> +	gpu_mem_free(bo, va_handle, bo_mc, 4096);
> +
> +	/* Test invisible VRAM */
> +	bo = gpu_mem_alloc(device,
> +			   4096, 4096,
> +			   AMDGPU_GEM_DOMAIN_VRAM,
> +			   AMDGPU_GEM_CREATE_NO_CPU_ACCESS,
> +			   &bo_mc, &va_handle);
> +
> +	gpu_mem_free(bo, va_handle, bo_mc, 4096);
> +
> +	/* Test GART Cacheable */
> +	bo = gpu_mem_alloc(device,
> +			   4096, 4096,
> +			   AMDGPU_GEM_DOMAIN_GTT,
> +			   0, &bo_mc, &va_handle);
> +
> +	gpu_mem_free(bo, va_handle, bo_mc, 4096);
> +
> +	/* Test GART USWC */
> +	bo = gpu_mem_alloc(device,
> +			   4096, 4096,
> +			   AMDGPU_GEM_DOMAIN_GTT,
> +			   AMDGPU_GEM_CREATE_CPU_GTT_USWC,
> +			   &bo_mc, &va_handle);
> +
> +	gpu_mem_free(bo, va_handle, bo_mc, 4096);
> +}
> +
> +
> +/**
> + * AMDGPU_HW_IP_GFX
> + * @param device
> + */
> +static void amdgpu_command_submission_gfx(amdgpu_device_handle device,
> +					  bool ce_avails,
> +					  bool user_queue)
> +{
> +
> +	/* write data using the CP */
> +	amdgpu_command_submission_write_linear_helper(device,
> +						      get_ip_block(device, AMDGPU_HW_IP_GFX),
> +						      false, user_queue);
> +
> +	/* const fill using the CP */
> +	amdgpu_command_submission_const_fill_helper(device,
> +						    get_ip_block(device, AMDGPU_HW_IP_GFX),
> +						    user_queue);
> +
> +	/* copy data using the CP */
> +	amdgpu_command_submission_copy_linear_helper(device,
> +						     get_ip_block(device, AMDGPU_HW_IP_GFX),
> +						     user_queue);
> +	if (ce_avails) {
> +		/* separate IB buffers for multi-IB submission */
> +		amdgpu_command_submission_gfx_separate_ibs(device);
> +		/* shared IB buffer for multi-IB submission */
> +		amdgpu_command_submission_gfx_shared_ib(device);
> +	} else {
> +		igt_info("separate and shared IB buffers for multi IB submisison testes are skipped due to GFX11\n");
> +	}
> +}
> +
> +/**
> + * AMDGPU_HW_IP_COMPUTE
> + * @param device
> + */
> +static void amdgpu_command_submission_compute(amdgpu_device_handle device, bool user_queue)
> +{
> +	/* write data using the CP */
> +	amdgpu_command_submission_write_linear_helper(device,
> +						      get_ip_block(device, AMDGPU_HW_IP_COMPUTE),
> +						      false, user_queue);
> +	/* const fill using the CP */
> +	amdgpu_command_submission_const_fill_helper(device,
> +						    get_ip_block(device, AMDGPU_HW_IP_COMPUTE),
> +						    user_queue);
> +	/* copy data using the CP */
> +	amdgpu_command_submission_copy_linear_helper(device,
> +						     get_ip_block(device, AMDGPU_HW_IP_COMPUTE),
> +						     user_queue);
> +	/* nop test */
> +	amdgpu_command_submission_nop(device, AMDGPU_HW_IP_COMPUTE, user_queue);
> +}
> +
> +/**
> + * AMDGPU_HW_IP_DMA
> + * @param device
> + */
> +static void amdgpu_command_submission_sdma(amdgpu_device_handle device, bool user_queue)
> +{
> +	amdgpu_command_submission_write_linear_helper(device,
> +						      get_ip_block(device, AMDGPU_HW_IP_DMA),
> +						      false, user_queue);
> +
> +	amdgpu_command_submission_const_fill_helper(device,
> +						    get_ip_block(device, AMDGPU_HW_IP_DMA),
> +						    user_queue);
> +
> +	amdgpu_command_submission_copy_linear_helper(device,
> +						     get_ip_block(device, AMDGPU_HW_IP_DMA),
> +						     user_queue);
> +	/* nop test */
> +	amdgpu_command_submission_nop(device, AMDGPU_HW_IP_DMA, user_queue);
> +}
> +
> +static void amdgpu_test_all_queues(amdgpu_device_handle device, bool user_queue)
> +{
> +	amdgpu_command_submission_write_linear_helper2(device, AMDGPU_HW_IP_GFX, false, user_queue);
> +	amdgpu_command_submission_write_linear_helper2(device, AMDGPU_HW_IP_COMPUTE, false, user_queue);
> +	amdgpu_command_submission_write_linear_helper2(device, AMDGPU_HW_IP_DMA, false, user_queue);
> +	amdgpu_command_submission_write_linear_helper2(device, AMDGPU_HW_IP_GFX | AMDGPU_HW_IP_COMPUTE |
> +							AMDGPU_HW_IP_DMA, false, user_queue);
> +}
> +/**
> + * MULTI FENCE
> + * @param device
> + */
> +static void amdgpu_command_submission_multi_fence(amdgpu_device_handle device)
> +{
> +	amdgpu_command_submission_multi_fence_wait_all(device, true);
> +	amdgpu_command_submission_multi_fence_wait_all(device, false);
> +}
> +
> +igt_main
> +{
> +	amdgpu_device_handle device;
> +	int fd = -1;
> +	bool enable_test = false;
> +#ifdef AMDGPU_USERQ_ENABLED
> +	const char *env = getenv("AMDGPU_ENABLE_USERQTEST");
> +
> +	enable_test = env && atoi(env);
> +#endif
> +
> +	igt_fixture {
> +		uint32_t major, minor;
> +		int err;
> +
> +		fd = drm_open_driver(DRIVER_AMDGPU);
> +
> +		err = amdgpu_device_initialize(fd, &major, &minor, &device);
> +		igt_require(err == 0);
> +
> +		igt_info("Initialized amdgpu, driver version %d.%d\n",
> +			 major, minor);
> +	}
> +
> +	igt_subtest("multi-gpu-memeory-alloc") {
> +		igt_multi_fork_foreach_gpu(gpu_fd, gpu_idx, DRIVER_AMDGPU) {
> +			amdgpu_device_handle dev;
> +			uint32_t major, minor;
> +			int res;
> +
> +			/* Initialize device */
> +			res = amdgpu_device_initialize(gpu_fd, &major, &minor, &dev);
> +			igt_assert_eq(res, 0);
> +
> +			/* Run test */
> +			amdgpu_memory_alloc(dev);
> +
> +			amdgpu_device_deinitialize(dev);
> +		}
> +		igt_waitchildren();
> +	}
> +
> +	igt_subtest("cs-gfx-with-IP-GFX") {
> +		igt_multi_fork_foreach_gpu(gpu_fd, gpu_idx, DRIVER_AMDGPU) {
> +			amdgpu_device_handle dev;
> +			uint32_t major, minor;
> +			struct amdgpu_gpu_info gpus_info = {0};
> +			bool arr_caps[AMD_IP_MAX] = {0};
> +			struct drm_amdgpu_info_hw_ip info = {0};
> +			int res;
> +
> +			/* Initialize device */
> +			res = amdgpu_device_initialize(gpu_fd, &major, &minor, &dev);
> +			igt_assert_eq(res, 0);
> +
> +			res = amdgpu_query_gpu_info(dev, &gpus_info);
> +			igt_assert_eq(res, 0);
> +			res = amdgpu_query_hw_ip_info(device, AMDGPU_HW_IP_GFX, 0, &info);
> +			igt_assert_eq(res, 0);
> +			res = setup_amdgpu_ip_blocks(major, minor, &gpus_info, dev);
> +			igt_assert_eq(res, 0);
> +			asic_rings_readness(dev, 1, arr_caps);
> +			/* Run test */
> +			if (arr_caps[AMD_IP_GFX])
> +				amdgpu_command_submission_gfx(dev, info.hw_ip_version_major < 11, false);
> +			amdgpu_device_deinitialize(dev);
> +		}
> +		igt_waitchildren();
> +	}
> +
> +	igt_subtest("cs-compute-with-IP-COMPUTE") {
> +		igt_multi_fork_foreach_gpu(gpu_fd, gpu_idx, DRIVER_AMDGPU) {
> +			amdgpu_device_handle dev;
> +			uint32_t major, minor;
> +			struct amdgpu_gpu_info gpus_info = {0};
> +			bool arr_caps[AMD_IP_MAX] = {0};
> +			int res;
> +
> +			/* Initialize device */
> +			res = amdgpu_device_initialize(gpu_fd, &major, &minor, &dev);
> +			igt_assert_eq(res, 0);
> +
> +			res = amdgpu_query_gpu_info(dev, &gpus_info);
> +			igt_assert_eq(res, 0);
> +
> +			res = setup_amdgpu_ip_blocks(major, minor, &gpus_info, dev);
> +			igt_assert_eq(res, 0);
> +			asic_rings_readness(dev, 1, arr_caps);
> +			/* Run test */
> +			if (arr_caps[AMD_IP_COMPUTE])
> +				amdgpu_command_submission_compute(dev, false);
> +			amdgpu_device_deinitialize(dev);
> +		}
> +		igt_waitchildren();
> +	}
> +
> +	igt_subtest("cs-multi-fence-with-IP-GFX") {
> +		igt_multi_fork_foreach_gpu(gpu_fd, gpu_idx, DRIVER_AMDGPU) {
> +			amdgpu_device_handle dev;
> +			uint32_t major, minor;
> +			struct amdgpu_gpu_info gpus_info = {0};
> +			struct drm_amdgpu_info_hw_ip info = {0};
> +			bool arr_caps[AMD_IP_MAX] = {0};
> +			int res;
> +
> +			/* Initialize device */
> +			res = amdgpu_device_initialize(gpu_fd, &major, &minor, &dev);
> +			igt_assert_eq(res, 0);
> +
> +			res = amdgpu_query_gpu_info(dev, &gpus_info);
> +			igt_assert_eq(res, 0);
> +			res = amdgpu_query_hw_ip_info(device, AMDGPU_HW_IP_GFX, 0, &info);
> +			igt_assert_eq(res, 0);
> +			res = setup_amdgpu_ip_blocks(major, minor, &gpus_info, dev);
> +			igt_assert_eq(res, 0);
> +			asic_rings_readness(dev, 1, arr_caps);
> +			/* Run test */
> +			if (arr_caps[AMD_IP_GFX] && info.hw_ip_version_major < 11) {
> +				amdgpu_command_submission_multi_fence(dev);
> +			} else {
> +				igt_info("cs-multi-fence-with-IP-GFX testes are skipped due to GFX11 or no GFX_IP\n");
> +			}
> +			amdgpu_device_deinitialize(dev);
> +		}
> +		igt_waitchildren();
> +	}
> +
> +	igt_subtest("cs-sdma-with-IP-DMA") {
> +		igt_multi_fork_foreach_gpu(gpu_fd, gpu_idx, DRIVER_AMDGPU) {
> +			amdgpu_device_handle dev;
> +			uint32_t major, minor;
> +			struct amdgpu_gpu_info gpus_info = {0};
> +			bool arr_caps[AMD_IP_MAX] = {0};
> +			int res;
> +
> +			/* Initialize device */
> +			res = amdgpu_device_initialize(gpu_fd, &major, &minor, &dev);
> +			igt_assert_eq(res, 0);
> +
> +			res = amdgpu_query_gpu_info(dev, &gpus_info);
> +			igt_assert_eq(res, 0);
> +
> +			res = setup_amdgpu_ip_blocks(major, minor, &gpus_info, dev);
> +			igt_assert_eq(res, 0);
> +			asic_rings_readness(dev, 1, arr_caps);
> +			/* Run test */
> +			if (arr_caps[AMD_IP_DMA])
> +				amdgpu_command_submission_sdma(dev, false);
> +			amdgpu_device_deinitialize(dev);
> +		}
> +		igt_waitchildren();
> +	}
> +
> +	igt_subtest("multi-gpu-cs-gfx-with-IP-GFX-UMQ") {
> +		igt_multi_fork_foreach_gpu(gpu_fd, gpu_idx, DRIVER_AMDGPU) {
> +			amdgpu_device_handle dev;
> +			uint32_t major, minor;
> +			struct amdgpu_gpu_info gpus_info = {0};
> +			bool userq_arr_caps[AMD_IP_MAX] = {0};
> +			int res;
> +
> +			/* Initialize device */
> +			res = amdgpu_device_initialize(gpu_fd, &major, &minor, &dev);
> +			igt_assert_eq(res, 0);
> +
> +			res = amdgpu_query_gpu_info(dev, &gpus_info);
> +			igt_assert_eq(res, 0);
> +
> +			res = setup_amdgpu_ip_blocks(major, minor, &gpus_info, dev);
> +			igt_assert_eq(res, 0);
> +			asic_userq_readiness(device, userq_arr_caps);
> +			/* Run test */
> +			if (enable_test && userq_arr_caps[AMD_IP_GFX])
> +				amdgpu_command_submission_gfx(dev, false, true);
> +			amdgpu_device_deinitialize(dev);
> +		}
> +		igt_waitchildren();
> +	}
> +
> +	igt_subtest("multi-gpu-cs-compute-with-IP-COMPUTE-UMQ") {
> +		igt_multi_fork_foreach_gpu(gpu_fd, gpu_idx, DRIVER_AMDGPU) {
> +			amdgpu_device_handle dev;
> +			uint32_t major, minor;
> +			struct amdgpu_gpu_info gpus_info = {0};
> +			bool userq_arr_caps[AMD_IP_MAX] = {0};
> +			int res;
> +
> +			res = amdgpu_device_initialize(gpu_fd, &major, &minor, &dev);
> +			igt_assert_eq(res, 0);
> +
> +			res = amdgpu_query_gpu_info(dev, &gpus_info);
> +			igt_assert_eq(res, 0);
> +
> +			res = setup_amdgpu_ip_blocks(major, minor, &gpus_info, dev);
> +			igt_assert_eq(res, 0);
> +			asic_userq_readiness(device, userq_arr_caps);
> +			/* Run test */
> +			if (enable_test && userq_arr_caps[AMD_IP_COMPUTE])
> +				amdgpu_command_submission_compute(dev, true);
> +			amdgpu_device_deinitialize(dev);
> +		}
> +		igt_waitchildren();
> +	}
> +
> +	igt_subtest("multi-gpu-cs-sdma-with-IP-DMA-UMQ") {
> +		igt_multi_fork_foreach_gpu(gpu_fd, gpu_idx, DRIVER_AMDGPU) {
> +			amdgpu_device_handle dev;
> +			uint32_t major, minor;
> +			struct amdgpu_gpu_info gpus_info = {0};
> +			bool userq_arr_caps[AMD_IP_MAX] = {0};
> +			int res;
> +
> +			/* Initialize device */
> +			res = amdgpu_device_initialize(gpu_fd, &major, &minor, &dev);
> +			igt_assert_eq(res, 0);
> +
> +			res = amdgpu_query_gpu_info(dev, &gpus_info);
> +			igt_assert_eq(res, 0);
> +
> +			res = setup_amdgpu_ip_blocks(major, minor, &gpus_info, dev);
> +			igt_assert_eq(res, 0);
> +			asic_userq_readiness(dev, userq_arr_caps);
> +			/* Run test */
> +			if (enable_test && userq_arr_caps[AMD_IP_DMA])
> +				amdgpu_command_submission_sdma(dev, true);
> +			amdgpu_device_deinitialize(dev);
> +		}
> +		igt_waitchildren();
> +	}
> +
> +	igt_subtest("multi-gpu-all-queues-test-with-UMQ") {
> +		igt_multi_fork_foreach_gpu(gpu_fd, gpu_idx, DRIVER_AMDGPU) {
> +			amdgpu_device_handle dev;
> +			uint32_t major, minor;
> +			struct amdgpu_gpu_info gpus_info = {0};
> +			bool userq_arr_caps[AMD_IP_MAX] = {0};
> +			int res;
> +
> +			/* Initialize device */
> +			res = amdgpu_device_initialize(gpu_fd, &major, &minor, &dev);
> +			igt_assert_eq(res, 0);
> +
> +			res = amdgpu_query_gpu_info(dev, &gpus_info);
> +			igt_assert_eq(res, 0);
> +
> +			res = setup_amdgpu_ip_blocks(major, minor, &gpus_info, dev);
> +			igt_assert_eq(res, 0);
> +			asic_userq_readiness(dev, userq_arr_caps);
> +			/* Run test */
> +			if (enable_test && userq_arr_caps[AMD_IP_GFX] &&
> +				userq_arr_caps[AMD_IP_COMPUTE] &&
> +				userq_arr_caps[AMD_IP_DMA])
> +			amdgpu_test_all_queues(dev, true);
> +
> +			amdgpu_device_deinitialize(dev);
> +		}
> +		igt_waitchildren();
> +	}
> +
> +	igt_fixture {
> +		amdgpu_device_deinitialize(device);
> +		drm_close_driver(fd);
> +	}
> +}
> diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
> index a8f85bbd8..7cb1c0f57 100644
> --- a/tests/amdgpu/meson.build
> +++ b/tests/amdgpu/meson.build
> @@ -5,6 +5,7 @@ if libdrm_amdgpu.found()
>  	amdgpu_progs += [ 'amd_abm',
>  			  'amd_assr',
>  			  'amd_basic',
> +			  'amd_basic_multi_gpu',
>  			  'amd_bo',
>  			  'amd_bypass',
>  			  'amd_color',


More information about the igt-dev mailing list