# Buggy code
def __call__(
    self,
    ts_iterator: Iterable[Union[pd.DataFrame, pd.Series]],
    fcst_iterator: Iterable[Forecast],
    num_series: Optional[int] = None,
) -> Tuple[Dict[str, float], pd.DataFrame]:
    """
    Compute accuracy metrics by comparing actual data to the forecasts.

    Parameters
    ----------
    ts_iterator
        iterator containing true target on the predicted range
    fcst_iterator
        iterator of forecasts on the predicted range
    num_series
        number of series of the iterator
        (optional, only used for displaying progress)

    Returns
    -------
    dict
        Dictionary of aggregated metrics
    pd.DataFrame
        DataFrame containing per-time-series metrics
    """
    ts_iterator = iter(ts_iterator)
    fcst_iterator = iter(fcst_iterator)

    rows = []

    with (
        tqdm(
            zip(ts_iterator, fcst_iterator),
            total=num_series,
            desc="Running evaluation",
        ) as it,
        np.errstate(invalid="ignore"),
    ):
        if self.num_workers and not sys.platform == "win32":
            mp_pool = multiprocessing.Pool(
                initializer=_worker_init(self), processes=self.num_workers
            )
            rows = mp_pool.map(
                func=_worker_fun,
                iterable=iter(it),
                chunksize=self.chunk_size,
            )
            mp_pool.close()
            mp_pool.join()
        else:
            for ts, forecast in it:
                rows.append(self.get_metrics_per_ts(ts, forecast))

    assert not any(True for _ in ts_iterator), (
        "ts_iterator has more elements than fcst_iterator"
    )

    assert not any(True for _ in fcst_iterator), (
        "fcst_iterator has more elements than ts_iterator"
    )

    if num_series is not None:
        assert len(rows) == num_series, (
            f"num_series={num_series} did not match number of elements={len(rows)}"
        )

    # If all entries of a target array are NaNs, the resulting metric will have value "masked". Pandas does not
    # handle masked values correctly. Thus we set dtype=np.float64 to convert masked values back to NaNs which
    # are handled correctly by pandas Dataframes during aggregation.
    metrics_per_ts = pd.DataFrame(rows, dtype=np.float64)
    return self.get_aggregate_metrics(metrics_per_ts)


# Traceback (AssertionError)
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/multiprocessing/pool.py", line 125, in worker
result = (True, func(*args, **kwds))
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/multiprocessing/pool.py", line 48, in mapstar
return list(map(*args))
File "/Users/caixiyan/Library/Python/3.8/lib/python/site-packages/gluonts/evaluation/_base.py", line 808, in _worker_fun
assert isinstance(
AssertionError: Something went wrong with the worker initialization.

AssertionError                            Traceback (most recent call last)
<ipython-input-29-b25f87fe7d03> in <module>
1 evaluator = Evaluator(quantiles=[0.1, 0.5, 0.9])
----> 2 agg_metrics, item_metrics = evaluator(iter(tss), iter(forecasts), num_series=len(dataset.test))

~/Library/Python/3.8/lib/python/site-packages/gluonts/evaluation/_base.py in __call__(self, ts_iterator, fcst_iterator, num_series)
168                     initializer=_worker_init(self), processes=self.num_workers
169                 )
--> 170                 rows = mp_pool.map(
171                     func=_worker_fun,
172                     iterable=iter(it),

/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/multiprocessing/pool.py in map(self, func, iterable, chunksize)
362         in a list that is returned.
363         '''
--> 364         return self._map_async(func, iterable, mapstar, chunksize).get()
365
366     def starmap(self, func, iterable, chunksize=None):

/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/multiprocessing/pool.py in get(self, timeout)
766             return self._value
767         else:
--> 768             raise self._value
769
770     def _set(self, i, obj):

AssertionError: Something went wrong with the worker initialization.

# Fixed code
def __call__(
    self,
    ts_iterator: Iterable[Union[pd.DataFrame, pd.Series]],
    fcst_iterator: Iterable[Forecast],
    num_series: Optional[int] = None,
) -> Tuple[Dict[str, float], pd.DataFrame]:
    """
    Compute accuracy metrics by comparing actual data to the forecasts.

    Parameters
    ----------
    ts_iterator
        iterator containing true target on the predicted range
    fcst_iterator
        iterator of forecasts on the predicted range
    num_series
        number of series of the iterator
        (optional, only used for displaying progress)

    Returns
    -------
    dict
        Dictionary of aggregated metrics
    pd.DataFrame
        DataFrame containing per-time-series metrics
    """
    ts_iterator = iter(ts_iterator)
    fcst_iterator = iter(fcst_iterator)

    rows = []

    with (
        tqdm(
            zip(ts_iterator, fcst_iterator),
            total=num_series,
            desc="Running evaluation",
        ) as it,
        np.errstate(invalid="ignore"),
    ):
        if self.num_workers and not sys.platform == "win32":
            mp_pool = multiprocessing.Pool(initializer=None, processes=self.num_workers)
            rows = mp_pool.map(
                func=partial(worker_function, self),
                iterable=iter(it),
                chunksize=self.chunk_size,
            )
            mp_pool.close()
            mp_pool.join()
        else:
            for ts, forecast in it:
                rows.append(self.get_metrics_per_ts(ts, forecast))

    assert not any(True for _ in ts_iterator), (
        "ts_iterator has more elements than fcst_iterator"
    )

    assert not any(True for _ in fcst_iterator), (
        "fcst_iterator has more elements than ts_iterator"
    )

    if num_series is not None:
        assert len(rows) == num_series, (
            f"num_series={num_series} did not match number of elements={len(rows)}"
        )

    # If all entries of a target array are NaNs, the resulting metric will have value "masked". Pandas does not
    # handle masked values correctly. Thus we set dtype=np.float64 to convert masked values back to NaNs which
    # are handled correctly by pandas Dataframes during aggregation.
    metrics_per_ts = pd.DataFrame(rows, dtype=np.float64)
    return self.get_aggregate_metrics(metrics_per_ts)