Accepts unsorted list of chains and returns sorted list with the order of GPU task execution.
| 195 | // Accepts unsorted list of chains and returns sorted list with the order of GPU |
| 196 | // task execution. |
| 197 | std::list<FusionSequence> SortChains( |
| 198 | const std::vector<ValueId>& graph_input_ids, |
| 199 | std::list<FusionSequence>* chains) { |
| 200 | std::list<FusionSequence> sorted_chains; |
| 201 | while (!chains->empty()) { |
| 202 | // Collect ready buffers. |
| 203 | std::vector<ValueId> ready_buffer_ids; |
| 204 | ready_buffer_ids.reserve(graph_input_ids.size() + sorted_chains.size()); |
| 205 | ready_buffer_ids.insert(ready_buffer_ids.begin(), graph_input_ids.begin(), |
| 206 | graph_input_ids.end()); |
| 207 | for (auto& chain : sorted_chains) { |
| 208 | ready_buffer_ids.push_back(chain.back()->output_buffer.id); |
| 209 | } |
| 210 | |
| 211 | for (auto it = chains->begin(); it != chains->end();) { |
| 212 | const FusionSequence& chain = *it; |
| 213 | |
| 214 | // If the input is also is the output in the same chain - eliminate |
| 215 | // because it used internally inside this chain only. |
| 216 | std::vector<ValueId> elements_output_buffer_ids; |
| 217 | elements_output_buffer_ids.reserve(chain.size()); |
| 218 | for (const ComputeTaskDescriptorPtr& element : chain) { |
| 219 | elements_output_buffer_ids.push_back(element->output_buffer.id); |
| 220 | } |
| 221 | |
| 222 | // Collect all inputs also for linked operations. |
| 223 | std::vector<ValueId> elements_input_buffer_ids; |
| 224 | for (auto element : chain) { |
| 225 | for (const auto& buffer : element->input_buffers) { |
| 226 | if (!Contains(elements_output_buffer_ids, buffer.id)) { |
| 227 | elements_input_buffer_ids.push_back(buffer.id); |
| 228 | } |
| 229 | } |
| 230 | } |
| 231 | |
| 232 | if (Contains(ready_buffer_ids, elements_input_buffer_ids)) { |
| 233 | // All input buffers for all elements of this chain are ready. |
| 234 | sorted_chains.push_back(chain); |
| 235 | it = chains->erase(it); |
| 236 | } else { |
| 237 | ++it; |
| 238 | } |
| 239 | } |
| 240 | } |
| 241 | return sorted_chains; |
| 242 | } |
| 243 | |
| 244 | // If a graph structure contains unused outputs then it can lead to unused |
| 245 | // operations and unused input buffers. It's not an error but some sort of |