def print_progress(self, index):
        """Display the process of the parallel execution only a fraction
           of time, controled by self.verbose.
        """
        if not self.verbose:
            return
        elapsed_time = time.time() - self._start_time

        # This is heuristic code to print only 'verbose' times a messages
        # The challenge is that we may not know the queue length
        if self._iterable:
            if _verbosity_filter(index, self.verbose):
                return
            self._print("Done %3i jobs       | elapsed: %s", (index + 1, short_format_time(elapsed_time)))
        else:
            # We are finished dispatching
            queue_length = self.n_dispatched
            # We always display the first loop
            if not index == 0:
                # Display depending on the number of remaining items
                # A message as soon as we finish dispatching, cursor is 0
                cursor = queue_length - index + 1 - self._pre_dispatch_amount
                frequency = (queue_length // self.verbose) + 1
                is_last_item = index + 1 == queue_length
                if is_last_item or cursor % frequency:
                    return
            remaining_time = elapsed_time / (index + 1) * (self.n_dispatched - index - 1.0)
            self._print(
                "Done %3i out of %3i | elapsed: %s remaining: %s",
                (index + 1, queue_length, short_format_time(elapsed_time), short_format_time(remaining_time)),
            )
Example #2
0
 def dispatch(self, func, args, kwargs):
     """ Queue the function for computing, with or without multiprocessing
     """
     if self._pool is None:
         job = ImmediateApply(func, args, kwargs)
         index = len(self._jobs)
         if not _verbosity_filter(index, self.verbose):
             self._print('Done %3i jobs       | elapsed: %s',
                     (index + 1,
                         short_format_time(time.time() - self._start_time)
                     ))
         self._jobs.append(job)
         self.n_dispatched += 1
     else:
         self._lock.acquire()
         # If job.get() catches an exception, it closes the queue:
         try:
             try:
                 job = self._pool.apply_async(SafeFunction(func), args,
                             kwargs, callback=CallBack(self.n_dispatched, self))
                 self._jobs.append(job)
                 self.n_dispatched += 1
             except AssertionError:
                 print '[Parallel] Pool seems closed'
         finally:
             self._lock.release()
    def __call__(self, iterable):
        if self._jobs:
            raise ValueError("This Parallel instance is already running")
        n_jobs = self.n_jobs
        if n_jobs < 0 and multiprocessing is not None:
            n_jobs = max(multiprocessing.cpu_count() + 1 + n_jobs, 1)

        # The list of exceptions that we will capture
        self.exceptions = [TransportableException]
        if n_jobs is None or multiprocessing is None or n_jobs == 1:
            n_jobs = 1
            self._pool = None
        else:
            if multiprocessing.current_process()._daemonic:
                # Daemonic processes cannot have children
                n_jobs = 1
                self._pool = None
                warnings.warn("Parallel loops cannot be nested, setting n_jobs=1", stacklevel=2)
            else:
                self._pool = multiprocessing.Pool(n_jobs)
                self._lock = threading.Lock()
                # We are using multiprocessing, we also want to capture
                # KeyboardInterrupts
                self.exceptions.extend([KeyboardInterrupt, WorkerInterrupt])

        if self.pre_dispatch == "all" or n_jobs == 1:
            self._iterable = None
            self._pre_dispatch_amount = 0
        else:
            self._iterable = iterable
            self._dispatch_amount = 0
            pre_dispatch = self.pre_dispatch
            if hasattr(pre_dispatch, "endswith"):
                pre_dispatch = eval(pre_dispatch)
            self._pre_dispatch_amount = pre_dispatch = int(pre_dispatch)
            iterable = itertools.islice(iterable, pre_dispatch)

        self._start_time = time.time()
        self.n_dispatched = 0
        try:
            for function, args, kwargs in iterable:
                self.dispatch(function, args, kwargs)

            self.retrieve()
            # Make sure that we get a last message telling us we are done
            elapsed_time = time.time() - self._start_time
            self._print(
                "Done %3i out of %3i | elapsed: %s finished",
                (len(self._output), len(self._output), short_format_time(elapsed_time)),
            )

        finally:
            if n_jobs > 1:
                self._pool.close()
                self._pool.join()
            self._jobs = list()
        output = self._output
        self._output = None
        return output
Example #4
0
    def print_progress(self, index):
        """Display the process of the parallel execution only a fraction
           of time, controled by self.verbose.
        """
        if not self.verbose:
            return
        elapsed_time = time.time() - self._start_time

        # This is heuristic code to print only 'verbose' times a messages
        # The challenge is that we may not know the queue length
        if self._iterable:
            if _verbosity_filter(index, self.verbose):
                return
            self._print('Done %3i jobs       | elapsed: %s',
                        (index + 1,
                         short_format_time(elapsed_time),
                        ))
        else:
            # We are finished dispatching
            queue_length = self.n_dispatched
            # We always display the first loop
            if not index == 0:
                # Display depending on the number of remaining items
                # A message as soon as we finish dispatching, cursor is 0
                cursor = (queue_length - index + 1
                          - self._pre_dispatch_amount)
                frequency = (queue_length // self.verbose) + 1
                is_last_item = (index + 1 == queue_length)
                if (is_last_item or cursor % frequency):
                    return
            remaining_time = (elapsed_time / (index + 1) *
                        (self.n_dispatched - index - 1.))
            self._print('Done %3i out of %3i | elapsed: %s remaining: %s',
                        (index + 1,
                         queue_length,
                         short_format_time(elapsed_time),
                         short_format_time(remaining_time),
                        ))
Example #5
0
    def __call__(self, iterable):
        if self._jobs:
            raise ValueError('This Parallel instance is already running')
        n_jobs = self.n_jobs
        if n_jobs < 0 and multiprocessing is not None:
            n_jobs = max(multiprocessing.cpu_count() + 1 + n_jobs, 1)

        # The list of exceptions that we will capture
        self.exceptions = [TransportableException]
        if n_jobs is None or multiprocessing is None or n_jobs == 1:
            n_jobs = 1
            self._pool = None
        else:
            if multiprocessing.current_process()._daemonic:
                # Daemonic processes cannot have children
                n_jobs = 1
                self._pool = None
                warnings.warn(
                    'Parallel loops cannot be nested, setting n_jobs=1',
                    stacklevel=2)
            else:
                self._pool = multiprocessing.Pool(n_jobs)
                self._lock = threading.Lock()
                # We are using multiprocessing, we also want to capture
                # KeyboardInterrupts
                self.exceptions.extend([KeyboardInterrupt, WorkerInterrupt])

        if self.pre_dispatch == 'all' or n_jobs == 1:
            self._iterable = None
            self._pre_dispatch_amount = 0
        else:
            self._iterable = iterable
            self._dispatch_amount = 0
            pre_dispatch = self.pre_dispatch
            if hasattr(pre_dispatch, 'endswith'):
                pre_dispatch = eval(pre_dispatch)
            self._pre_dispatch_amount = pre_dispatch = int(pre_dispatch)
            iterable = itertools.islice(iterable, pre_dispatch)

        self._start_time = time.time()
        self.n_dispatched = 0
        try:
            for function, args, kwargs in iterable:
                self.dispatch(function, args, kwargs)

            self.retrieve()
            # Make sure that we get a last message telling us we are done
            elapsed_time = time.time() - self._start_time
            self._print('Done %3i out of %3i | elapsed: %s finished',
                        (len(self._output),
                         len(self._output),
                            short_format_time(elapsed_time)
                        ))

        finally:
            if n_jobs > 1:
                self._pool.close()
                self._pool.join()
            self._jobs = list()
        output = self._output
        self._output = None
        return output