| 141 | dag_builder::dag_builder(runtime *rt) : _rt{rt} {} |
| 142 | |
| 143 | dag_node_ptr dag_builder::build_node(std::unique_ptr<operation> op, |
| 144 | const requirements_list& requirements, |
| 145 | const execution_hints& hints) |
| 146 | { |
| 147 | assert(op); |
| 148 | |
| 149 | // Calculate additional requirements: |
| 150 | // Iterate over all requirements and look for conflicting accesses |
| 151 | |
| 152 | // For a given requirement, checks for conflicts and adds any |
| 153 | // conflicting operations as dependencies |
| 154 | auto add_conflicts_as_requirements = [&](dag_node_ptr req_node){ |
| 155 | if(req_node->get_operation()->is_requirement()){ |
| 156 | auto* req = cast<requirement>(req_node->get_operation()); |
| 157 | |
| 158 | if(req->is_memory_requirement()){ |
| 159 | auto* mem_req = cast<memory_requirement>(req); |
| 160 | |
| 161 | if(mem_req->is_image_requirement()) |
| 162 | assert(false && "dag_builder: Image requirements are unimplemented"); |
| 163 | else { |
| 164 | auto* buff_req = cast<buffer_memory_requirement>(req); |
| 165 | |
| 166 | data_user_tracker &user_tracker = |
| 167 | buff_req->get_data_region()->get_users(); |
| 168 | |
| 169 | user_tracker.for_each_user([&](data_user &user) { |
| 170 | auto user_ptr = user.user.lock(); |
| 171 | if(user_ptr && is_conflicting_access(mem_req, user)) |
| 172 | { |
| 173 | // No reason to take a dependency into account that is alreay completed |
| 174 | if(!user_ptr->is_known_complete()) |
| 175 | req_node->add_requirement(user_ptr); |
| 176 | } |
| 177 | }); |
| 178 | } |
| 179 | } |
| 180 | } |
| 181 | }; |
| 182 | |
| 183 | auto operation_node = std::make_shared<dag_node>( |
| 184 | hints, requirements.get(), std::move(op), _rt); |
| 185 | |
| 186 | bool is_req = operation_node->get_operation()->is_requirement(); |
| 187 | |
| 188 | // Do not change order between add_conflicts_as_requirements() |
| 189 | // and add_to_data_users() to prevent this node ending up as a |
| 190 | // requirement to itself or other cyclic requirements! |
| 191 | if(is_req) |
| 192 | // If we are an explicit requirement, consider conflicts not only |
| 193 | // with our requirements, but with the node itself |
| 194 | add_conflicts_as_requirements(operation_node); |
| 195 | |
| 196 | for (auto weak_node : operation_node->get_requirements()) { |
| 197 | if(auto node = weak_node.lock()) |
| 198 | add_conflicts_as_requirements(node); |
| 199 | } |
| 200 |
no test coverage detected