1 /* 2 * Copyright (c) Meta Platforms, Inc. and affiliates. 3 * All rights reserved. 4 * 5 * This source code is licensed under the BSD-style license found in the 6 * LICENSE file in the root directory of this source tree. 7 */ 8 9 #include <executorch/backends/vulkan/runtime/graph/Logging.h> 10 11 #include <executorch/backends/vulkan/runtime/graph/ComputeGraph.h> 12 13 #include <iomanip> 14 #include <iostream> 15 #include <map> 16 #include <set> 17 18 namespace vkcompute { 19 print_readable()20void ComputeGraph::print_readable() { 21 std::set<ValueRef> input_set; 22 for (const IOValueRef& io_val : inputs()) { 23 input_set.insert(io_val.value); 24 } 25 26 std::set<ValueRef> output_set; 27 for (const IOValueRef& io_val : outputs()) { 28 output_set.insert(io_val.value); 29 } 30 31 std::set<ValueRef> prepack_set; 32 for (const std::unique_ptr<PrepackNode>& node : prepack_nodes()) { 33 prepack_set.insert(node->tref_); 34 prepack_set.insert(node->packed_); 35 } 36 37 std::map<ValueRef, size_t> value_ref_to_shared_object_idx; 38 39 std::cout << "====================" << std::left << std::setfill('=') 40 << std::setw(40) << " Shared Object List " << std::right 41 << std::setfill(' ') << std::endl; 42 43 std::cout << std::setw(6) << "idx" << std::setw(20) << "sizes" 44 << std::setw(24) << "users" << std::endl; 45 46 size_t so_idx = 0; 47 for (const SharedObject& shared_object : shared_objects_) { 48 std::cout << std::setw(6) << so_idx; 49 { 50 std::stringstream ss; 51 ss << shared_object.aggregate_memory_requirements.size; 52 std::cout << std::setw(20) << ss.str(); 53 } 54 55 { 56 std::stringstream ss; 57 ss << shared_object.users; 58 std::cout << std::setw(24) << ss.str(); 59 } 60 std::cout << std::endl; 61 62 for (const ValueRef& user : shared_object.users) { 63 value_ref_to_shared_object_idx[user] = so_idx; 64 } 65 66 so_idx++; 67 } 68 69 std::cout << "====================" << std::left << std::setfill('=') 70 << std::setw(40) << " Value List " << std::right 71 << std::setfill(' ') << std::endl; 72 73 std::cout << std::setw(6) << "idx" << std::setw(10) << "type" << std::setw(20) 74 << "sizes" << std::setw(10) << "node_type" << std::setw(15) 75 << "storage_bytes" << std::setw(10) << "so_idx" << std::endl; 76 77 size_t value_idx = 0; 78 for (Value& val : values_) { 79 std::cout << std::setw(6) << value_idx << std::setw(10) << val.type(); 80 81 // sizes 82 std::cout << std::setw(20); 83 if (val.isTensor()) { 84 const api::vTensor& v_tensor = val.toTensor(); 85 std::stringstream ss; 86 ss << v_tensor.sizes(); 87 std::cout << ss.str(); 88 } else if (val.isTensorRef()) { 89 const TensorRef tensor_ref = val.toTensorRef(); 90 std::stringstream ss; 91 ss << tensor_ref.sizes; 92 std::cout << ss.str(); 93 } else { 94 std::cout << ""; 95 } 96 97 // Node type 98 std::cout << std::setw(10); 99 { 100 if (input_set.count(value_idx) > 0) { 101 std::cout << "INPUT"; 102 } else if (output_set.count(value_idx) > 0) { 103 std::cout << "OUTPUT"; 104 } else if (prepack_set.count(value_idx) > 0) { 105 std::cout << "PREPACK"; 106 } else { 107 std::cout << ""; 108 } 109 } 110 111 // Actual storage bytes used 112 std::cout << std::setw(15); 113 if (val.isTensor()) { 114 const api::vTensor& v_tensor = val.toTensor(); 115 auto memory_reqs = v_tensor.get_memory_requirements(); 116 std::cout << memory_reqs.size; 117 } else { 118 std::cout << ""; 119 } 120 121 std::cout << std::setw(10); 122 if (value_ref_to_shared_object_idx.count(value_idx) > 0) { 123 size_t shared_obj_idx = value_ref_to_shared_object_idx.at(value_idx); 124 std::cout << shared_obj_idx; 125 } else { 126 std::cout << ""; 127 } 128 129 std::cout << std::endl; 130 value_idx++; 131 } 132 133 std::cout << "====================" << std::left << std::setfill('=') 134 << std::setw(40) << " Prepack Node List " << std::right 135 << std::setfill(' ') << std::endl; 136 std::cout << std::setw(6) << "idx" << std::setw(32) << "shader_name" 137 << std::setw(8) << "tref" << std::setw(8) << "packed" << std::endl; 138 139 size_t prepack_node_idx = 0; 140 for (const std::unique_ptr<PrepackNode>& node : prepack_nodes()) { 141 std::cout << std::setw(6) << prepack_node_idx << std::setw(32) 142 << node->shader_.kernel_name << std::setw(8) << node->tref_ 143 << std::setw(8) << node->packed_ << std::endl; 144 145 prepack_node_idx++; 146 } 147 148 std::cout << "====================" << std::left << std::setfill('=') 149 << std::setw(40) << " Execute Node List " << std::right 150 << std::setfill(' ') << std::endl; 151 152 std::cout << std::setw(6) << "idx" << std::setw(32) << "shader_name" 153 << std::setw(24) << "READ_arg" << std::setw(24) << "WRITE_arg" 154 << std::endl; 155 156 size_t node_idx = 0; 157 for (const std::unique_ptr<ExecuteNode>& node : execute_nodes()) { 158 std::cout << std::setw(6) << node_idx; 159 std::cout << std::setw(32) << node->name(); 160 161 std::stringstream read_s; 162 for (const ArgGroup& arg_group : node->args_) { 163 if (arg_group.access != vkapi::MemoryAccessType::READ) { 164 continue; 165 } 166 read_s << arg_group.refs; 167 } 168 std::cout << std::setw(24) << read_s.str(); 169 170 std::stringstream write_s; 171 for (const ArgGroup& arg_group : node->args_) { 172 if (arg_group.access != vkapi::MemoryAccessType::WRITE) { 173 continue; 174 } 175 write_s << arg_group.refs; 176 } 177 std::cout << std::setw(24) << write_s.str(); 178 179 std::cout << std::endl; 180 181 node_idx++; 182 } 183 } 184 185 } // namespace vkcompute 186