1 | /* |
2 | * Licensed to the Apache Software Foundation (ASF) under one |
3 | * or more contributor license agreements. See the NOTICE file |
4 | * distributed with this work for additional information |
5 | * regarding copyright ownership. The ASF licenses this file |
6 | * to you under the Apache License, Version 2.0 (the |
7 | * "License"); you may not use this file except in compliance |
8 | * with the License. You may obtain a copy of the License at |
9 | * |
10 | * http://www.apache.org/licenses/LICENSE-2.0 |
11 | * |
12 | * Unless required by applicable law or agreed to in writing, |
13 | * software distributed under the License is distributed on an |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
15 | * KIND, either express or implied. See the License for the |
16 | * specific language governing permissions and limitations |
17 | * under the License. |
18 | */ |
19 | |
20 | /*! |
21 | * \file src/runtime/debug.cc |
22 | * \brief Helpers for debugging at runtime. |
23 | */ |
24 | |
25 | #include <tvm/runtime/debug.h> |
26 | |
27 | namespace tvm { |
28 | namespace runtime { |
29 | |
30 | template <typename T> |
31 | void AppendMembers(std::ostream& os, const NDArray& nd_array, int64_t dim0) { |
32 | os << "=[" ; |
33 | for (int64_t i = 0; i < dim0; ++i) { |
34 | if (i > 0) { |
35 | os << "," ; |
36 | } |
37 | os << reinterpret_cast<T*>(nd_array->data)[i]; |
38 | } |
39 | os << "]" ; |
40 | } |
41 | |
42 | void AppendNDArray(std::ostream& os, const NDArray& nd_array, const DLDevice& host_device, |
43 | bool show_contents) { |
44 | os << "NDArray[" ; |
45 | os << "(" ; |
46 | for (int dim = 0; dim < nd_array->ndim; ++dim) { |
47 | if (dim > 0) { |
48 | os << "," ; |
49 | } |
50 | os << nd_array->shape[dim]; |
51 | } |
52 | std::string basic_type = DLDataType2String(nd_array->dtype); |
53 | os << ")," << basic_type; |
54 | os << ",(" << nd_array->device.device_type; |
55 | os << "," << nd_array->device.device_id; |
56 | os << ")]" ; |
57 | if (show_contents && nd_array->device.device_type == host_device.device_type && |
58 | nd_array->device.device_id == host_device.device_id) { |
59 | int64_t dim0; |
60 | if (nd_array->ndim == 0) { |
61 | dim0 = 1; |
62 | } else if (nd_array->ndim == 1) { |
63 | dim0 = nd_array->shape[0]; |
64 | if (dim0 > 10) { |
65 | // Too large. |
66 | dim0 = 0; |
67 | } |
68 | } else { |
69 | // Not rank-1. |
70 | dim0 = 0; |
71 | } |
72 | if (dim0 > 0) { |
73 | if (basic_type == "bool" ) { |
74 | AppendMembers<bool>(os, nd_array, dim0); |
75 | } else if (basic_type == "int8" ) { |
76 | AppendMembers<int8_t>(os, nd_array, dim0); |
77 | } else if (basic_type == "int16" ) { |
78 | AppendMembers<int16_t>(os, nd_array, dim0); |
79 | } else if (basic_type == "int32" ) { |
80 | AppendMembers<int32_t>(os, nd_array, dim0); |
81 | } else if (basic_type == "int64" ) { |
82 | AppendMembers<int64_t>(os, nd_array, dim0); |
83 | } else if (basic_type == "uint8" ) { |
84 | AppendMembers<uint8_t>(os, nd_array, dim0); |
85 | } else if (basic_type == "uint16" ) { |
86 | AppendMembers<uint16_t>(os, nd_array, dim0); |
87 | } else if (basic_type == "uint32" ) { |
88 | AppendMembers<uint32_t>(os, nd_array, dim0); |
89 | } else if (basic_type == "uint64" ) { |
90 | AppendMembers<uint64_t>(os, nd_array, dim0); |
91 | } else if (basic_type == "float32" ) { |
92 | AppendMembers<float>(os, nd_array, dim0); |
93 | } else if (basic_type == "float64" ) { |
94 | AppendMembers<double>(os, nd_array, dim0); |
95 | } |
96 | } |
97 | } |
98 | } |
99 | |
100 | void AppendADT(std::ostream& os, const ADT& adt, const DLDevice& host_device, bool show_contents) { |
101 | os << "ADT(" << adt->tag; |
102 | for (size_t i = 0; i < adt->size; ++i) { |
103 | os << "," ; |
104 | AppendRuntimeObject(os, adt[i], host_device, show_contents); |
105 | } |
106 | os << ")" ; |
107 | } |
108 | |
109 | void AppendRuntimeObject(std::ostream& os, const ObjectRef& object, const DLDevice& host_device, |
110 | bool show_contents) { |
111 | if (const auto* adt_obj = object.as<ADTObj>()) { |
112 | AppendADT(os, GetRef<ADT>(adt_obj), host_device, show_contents); |
113 | } else if (const auto* nd_array_cont = object.as<NDArray::Container>()) { |
114 | AppendNDArray(os, GetRef<NDArray>(nd_array_cont), host_device, show_contents); |
115 | } else { |
116 | os << "?" ; |
117 | } |
118 | } |
119 | |
120 | std::string RuntimeObject2String(const ObjectRef& object, const DLDevice& host_device, |
121 | bool show_contents) { |
122 | std::ostringstream os; |
123 | AppendRuntimeObject(os, object, host_device, show_contents); |
124 | return os.str(); |
125 | } |
126 | |
127 | } // namespace runtime |
128 | } // namespace tvm |
129 | |