Allocate the `Flow` i.e. assign the `workdir` and (optionally)
        the :class:`TaskManager` to the different tasks in the Flow.

        Args:
            workdir: Working directory of the flow. Must be specified here
                if we haven't initialized the workdir in the __init__.

        Return:
            self

def allocate(self, workdir=None, use_smartio=False):
        """
        Allocate the `Flow` i.e. assign the `workdir` and (optionally)
        the :class:`TaskManager` to the different tasks in the Flow.

        Args:
            workdir: Working directory of the flow. Must be specified here
                if we haven't initialized the workdir in the __init__.

        Return:
            self
        """
        if workdir is not None:
            # We set the workdir of the flow here
            self.set_workdir(workdir)
            for i, work in enumerate(self):
                work.set_workdir(os.path.join(self.workdir, "w" + str(i)))

        if not hasattr(self, "workdir"):
            raise RuntimeError("You must call flow.allocate(workdir) if the workdir is not passed to __init__")

        for work in self:
            # Each work has a reference to its flow.
            work.allocate(manager=self.manager)
            work.set_flow(self)
            # Each task has a reference to its work.
            for task in work:
                task.set_work(work)

        self.check_dependencies()

        if not hasattr(self, "_allocated"): self._allocated = 0
        self._allocated += 1

        if use_smartio:
            self.use_smartio()

        return self