Run tapes in parallel. See :py:func:`new_tape` for an example. :param args: list of tape handles or tuples of tape handle and extra argument (for :py:func:`~Compiler.library.get_arg`) :returns: list of thread numbers
(self, args)
| 401 | return self.run_tapes([[tape_index, arg]])[0] |
| 402 | |
| 403 | def run_tapes(self, args): |
| 404 | """Run tapes in parallel. See :py:func:`new_tape` for an example. |
| 405 | |
| 406 | :param args: list of tape handles or tuples of tape handle and extra |
| 407 | argument (for :py:func:`~Compiler.library.get_arg`) |
| 408 | :returns: list of thread numbers |
| 409 | """ |
| 410 | if not self.curr_tape.singular: |
| 411 | raise CompilerError( |
| 412 | "Compiler does not support " "recursive spawning of threads" |
| 413 | ) |
| 414 | args = [list(util.tuplify(arg)) for arg in args] |
| 415 | singular_tapes = set() |
| 416 | for arg in args: |
| 417 | if self.tapes[arg[0]].singular: |
| 418 | if arg[0] in singular_tapes: |
| 419 | raise CompilerError("cannot run singular tape in parallel") |
| 420 | singular_tapes.add(arg[0]) |
| 421 | assert len(arg) |
| 422 | assert len(arg) <= 2 |
| 423 | if len(arg) == 1: |
| 424 | arg += [0] |
| 425 | thread_numbers = [] |
| 426 | while len(thread_numbers) < len(args): |
| 427 | free_threads = self.curr_tape.free_threads |
| 428 | self.curr_tape.ran_threads = True |
| 429 | if free_threads: |
| 430 | thread_numbers.append(min(free_threads)) |
| 431 | free_threads.remove(thread_numbers[-1]) |
| 432 | else: |
| 433 | thread_numbers.append(self.n_threads) |
| 434 | self.n_threads += 1 |
| 435 | self.curr_tape.start_new_basicblock(name="pre-run_tape") |
| 436 | Compiler.instructions.run_tape( |
| 437 | *sum(([x] + list(y) for x, y in zip(thread_numbers, args)), []) |
| 438 | ) |
| 439 | self.curr_tape.start_new_basicblock(name="post-run_tape") |
| 440 | for arg in args: |
| 441 | self.curr_block.req_node.children.append( |
| 442 | self.tapes[arg[0]].req_tree) |
| 443 | return thread_numbers |
| 444 | |
| 445 | def join_tape(self, thread_number): |
| 446 | self.join_tapes([thread_number]) |