aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/lib/rocm.exp
blob: 2276bb3640ecd50a0cbd2766b5e36a5e167708ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# 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 <http://www.gnu.org/licenses/>.
#
# 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 <hip/hip_runtime.h>
	    __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
}