Extracts the delegate segments inlined in the program into a list of buffers. The program is modified in-place to remove the delegate data. Args: program: The program to extract segments from. Modified in-place. segments: A list of buffers to append extracted segments to
(
program: Program,
segments: List[AlignedData],
)
| 277 | |
| 278 | |
| 279 | def _extract_delegate_segments( |
| 280 | program: Program, |
| 281 | segments: List[AlignedData], |
| 282 | ) -> None: |
| 283 | """Extracts the delegate segments inlined in the program into a list of buffers. |
| 284 | The program is modified in-place to remove the delegate data. |
| 285 | |
| 286 | Args: |
| 287 | program: The program to extract segments from. Modified in-place. |
| 288 | segments: A list of buffers to append extracted segments to. Modified in-place. |
| 289 | """ |
| 290 | remaining_inline: List[BackendDelegateInlineData] = [] |
| 291 | inline_indices_seen: set[int] = set() |
| 292 | segment_index_map: dict[bytes, int] = {} |
| 293 | for plan in program.execution_plan: |
| 294 | for delegate in plan.delegates: |
| 295 | if delegate.processed.location != DataLocation.INLINE: |
| 296 | raise ValueError( |
| 297 | "Program must only contain inline delegate data, " |
| 298 | + f"saw {repr(delegate)}" |
| 299 | ) |
| 300 | # TODO(T144120904): Don't extract small blobs into segments; |
| 301 | # have a cutoff. Or callers could provide a callback that |
| 302 | # returns true/false for a given BackendDelegate, letting them |
| 303 | # use their own logic. |
| 304 | try: |
| 305 | inline: BackendDelegateInlineData = program.backend_delegate_data[ |
| 306 | delegate.processed.index |
| 307 | ] |
| 308 | except IndexError: |
| 309 | raise ValueError( |
| 310 | f"Delegate processed index {delegate.processed.index} " |
| 311 | + ">= len(Program.backend_delegate_data) " |
| 312 | + f"{len(program.backend_delegate_data)} " |
| 313 | + f"in {repr(delegate)}" |
| 314 | ) |
| 315 | inline_indices_seen.add(delegate.processed.index) |
| 316 | if inline.data: |
| 317 | # Move the delegate data out of the program. |
| 318 | segment_index = segment_index_map.get(inline.data) |
| 319 | if segment_index is None: |
| 320 | segment_index = len(segments) |
| 321 | segments.append(AlignedData(Cord(inline.data))) |
| 322 | segment_index_map[inline.data] = segment_index |
| 323 | delegate.processed = BackendDelegateDataReference( |
| 324 | location=DataLocation.SEGMENT, |
| 325 | index=segment_index, |
| 326 | ) |
| 327 | else: |
| 328 | # Not moving into a segment. Keep it inline, but update the |
| 329 | # index. |
| 330 | new_index = len(remaining_inline) |
| 331 | remaining_inline.append(inline) |
| 332 | delegate.processed.index = new_index |
| 333 | |
| 334 | # Make sure we visited all entries in backend_delegate_data, so that it's |
| 335 | # safe to overwrite it. |
| 336 | remaining_indices: set[int] = set( |
no test coverage detected