|
2 | 2 | # See https://llvm.org/LICENSE.txt for license information.
|
3 | 3 | # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
4 | 4 |
|
| 5 | +import gdb |
5 | 6 | import gdb.xmethod
|
| 7 | +import gdb.printing |
| 8 | +import itertools |
6 | 9 | import re
|
7 | 10 |
|
| 11 | +### XMethod implementations ### |
| 12 | + |
8 | 13 | """
|
9 | 14 | Generalized base class for buffer index calculation
|
10 | 15 | """
|
@@ -134,3 +139,86 @@ def match(self, class_type, method_name):
|
134 | 139 |
|
135 | 140 |
|
136 | 141 | gdb.xmethod.register_xmethod_matcher(None, AccessorOpIndexMatcher(), replace=True)
|
| 142 | + |
| 143 | +### Pretty-printer implementations ### |
| 144 | + |
| 145 | +""" |
| 146 | +Print an object deriving from cl::sycl::detail::array |
| 147 | +""" |
| 148 | +class SyclArrayPrinter: |
| 149 | + class ElementIterator: |
| 150 | + def __init__(self, data, size): |
| 151 | + self.data = data |
| 152 | + self.size = size |
| 153 | + self.count = 0 |
| 154 | + |
| 155 | + def __iter__(self): |
| 156 | + return self |
| 157 | + |
| 158 | + def __next__(self): |
| 159 | + if self.count == self.size: |
| 160 | + raise StopIteration |
| 161 | + count = self.count |
| 162 | + self.count = self.count + 1 |
| 163 | + try: |
| 164 | + elt = self.data[count] |
| 165 | + except: |
| 166 | + elt = "<error reading variable>" |
| 167 | + return ('[%d]' % count, elt) |
| 168 | + |
| 169 | + def __init__(self, value): |
| 170 | + if value.type.code == gdb.TYPE_CODE_REF: |
| 171 | + if hasattr(gdb.Value,"referenced_value"): |
| 172 | + value = value.referenced_value() |
| 173 | + |
| 174 | + self.value = value |
| 175 | + self.type = value.type.unqualified().strip_typedefs() |
| 176 | + self.dimensions = self.type.template_argument(0) |
| 177 | + |
| 178 | + def children(self): |
| 179 | + try: |
| 180 | + return self.ElementIterator(self.value['common_array'], self.dimensions) |
| 181 | + except: |
| 182 | + # There is no way to return an error from this method. Return an |
| 183 | + # empty iterable to make GDB happy and rely on to_string method |
| 184 | + # to take care of formatting. |
| 185 | + return [ ] |
| 186 | + |
| 187 | + def to_string(self): |
| 188 | + try: |
| 189 | + # Check if accessing array value will succeed and resort to |
| 190 | + # error message otherwise. Individual array element access failures |
| 191 | + # will be caught by iterator itself. |
| 192 | + _ = self.value['common_array'] |
| 193 | + return self.type.tag |
| 194 | + except: |
| 195 | + return "<error reading variable>" |
| 196 | + |
| 197 | + def display_hint(self): |
| 198 | + return 'array' |
| 199 | + |
| 200 | +""" |
| 201 | +Print a cl::sycl::buffer |
| 202 | +""" |
| 203 | +class SyclBufferPrinter: |
| 204 | + def __init__(self, value): |
| 205 | + self.value = value |
| 206 | + self.type = value.type.unqualified().strip_typedefs() |
| 207 | + self.elt_type = value.type.template_argument(0) |
| 208 | + self.dimensions = value.type.template_argument(1) |
| 209 | + self.typeregex = re.compile('^([a-zA-Z0-9_:]+)(<.*>)?$') |
| 210 | + |
| 211 | + def to_string(self): |
| 212 | + match = self.typeregex.match(self.type.tag) |
| 213 | + if not match: |
| 214 | + return "<error parsing type>" |
| 215 | + return ('%s<%s, %s> = {impl=%s}' |
| 216 | + % (match.group(1), self.elt_type, self.dimensions, |
| 217 | + self.value['impl'].address)) |
| 218 | + |
| 219 | +sycl_printer = gdb.printing.RegexpCollectionPrettyPrinter("SYCL") |
| 220 | +sycl_printer.add_printer("cl::sycl::id", '^cl::sycl::id<.*$', SyclArrayPrinter) |
| 221 | +sycl_printer.add_printer("cl::sycl::range", '^cl::sycl::range<.*$', SyclArrayPrinter) |
| 222 | +sycl_printer.add_printer("cl::sycl::buffer", '^cl::sycl::buffer<.*$', SyclBufferPrinter) |
| 223 | +gdb.printing.register_pretty_printer(None, sycl_printer, True) |
| 224 | + |
0 commit comments