# Copyright (C) 2019-2024 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Support library for testing ROCm (AMD GPU) GDB features. # Get the list of gpu targets to compile for. # # If HCC_AMDGPU_TARGET is set in the environment, use it. Otherwise, # try reading it from the system using the rocm_agent_enumerator # utility. proc hcc_amdgpu_targets {} { # Look for HCC_AMDGPU_TARGET (same env var hipcc uses). If # that fails, try using rocm_agent_enumerator (again, same as # hipcc does). if {[info exists ::env(HCC_AMDGPU_TARGET)]} { return [split $::env(HCC_AMDGPU_TARGET) ","] } set rocm_agent_enumerator "rocm_agent_enumerator" # If available, use ROCM_PATH to locate rocm_agent_enumerator. if { [info exists ::env(ROCM_PATH)] } { set rocm_agent_enumerator \ "$::env(ROCM_PATH)/bin/rocm_agent_enumerator" } # If we fail to locate the rocm_agent_enumerator, just return an empty # list of targets and let the caller decide if this should be an error. if { [which $rocm_agent_enumerator] == 0 } { return [list] } set result [remote_exec host $rocm_agent_enumerator] if { [lindex $result 0] != 0 } { error "rocm_agent_enumerator failed" } set targets [list] foreach target [lindex $result 1] { # Ignore gfx000 which is the host CPU. if { $target ne "gfx000" } { lappend targets $target } } return $targets } gdb_caching_proc allow_hipcc_tests {} { # Only the native target supports ROCm debugging. E.g., when # testing against GDBserver, there's no point in running the ROCm # tests. if {[target_info gdb_protocol] != ""} { return {0 "remote debugging"} } if {![istarget "*-linux*"]} { return {0 "target platform is not Linux"} } # Ensure that GDB is built with amd-dbgapi support. set output [remote_exec host $::GDB "$::INTERNAL_GDBFLAGS --configuration"] if { [string first "--with-amd-dbgapi" $output] == -1 } { return {0 "amd-dbgapi not supported"} } # Check we have a working hipcc compiler available. set targets [hcc_amdgpu_targets] if { [llength $targets] == 0} { return {0 "no suitable amdgpu targets found"} } set flags [list hip additional_flags=--offload-arch=[join $targets ","]] if {![gdb_simple_compile hipprobe { #include __global__ void kern () {} int main () { kern<<<1, 1>>> (); if (hipDeviceSynchronize () != hipSuccess) return -1; return 0; } } executable $flags]} { return {0 "failed to compile hip program"} } return 1 } # The lock file used to ensure that only one GDB has access to the GPU # at a time. set gpu_lock_filename gpu-parallel.lock # Run body under the GPU lock. Also calls gdb_exit before releasing # the GPU lock. proc with_rocm_gpu_lock { body } { with_lock $::gpu_lock_filename $body # In case BODY returned early due to some testcase failing, and # left GDB running, debugging the GPU. gdb_exit } # Return true if all the devices support debugging multiple processes # using the GPU. proc hip_devices_support_debug_multi_process {} { set unsupported_targets \ {gfx900 gfx906 gfx908 gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032} set targets [hcc_amdgpu_targets] if { [llength $targets] == 0 } { return 0 } foreach target $targets { if { [lsearch -exact $unsupported_targets $target] != -1 } { return 0 } } return 1 } # Return true if all the devices on the host support precise memory. proc hip_devices_support_precise_memory {} { set unsupported_targets \ {gfx900 gfx906 gfx908 gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032} set targets [hcc_amdgpu_targets] if { [llength $targets] == 0 } { return 0 } foreach target $targets { if { [lsearch -exact $unsupported_targets $target] != -1 } { return 0 } } return 1 }