# Buggy code
def execute(cls, ctx, op):
    def _base_concat(chunk, inputs):
        # auto generated concat when executing a DataFrame, Series or Index
        if chunk.op.object_type == ObjectType.dataframe:
            return _auto_concat_dataframe_chunks(chunk, inputs)
        elif chunk.op.object_type == ObjectType.series:
            return _auto_concat_series_chunks(chunk, inputs)
        else:
            raise TypeError(
                "Only DataFrameChunk, SeriesChunk and IndexChunk "
                "can be automatically concatenated"
            )

    def _auto_concat_dataframe_chunks(chunk, inputs):
        if chunk.op.axis is not None:
            return pd.concat(inputs, axis=op.axis)
        # auto generated concat when executing a DataFrame
        n_rows = max(inp.index[0] for inp in chunk.inputs) + 1
        n_cols = int(len(inputs) // n_rows)
        assert n_rows * n_cols == len(inputs)

        xdf = pd if isinstance(inputs[0], pd.DataFrame) else cudf

        concats = []
        for i in range(n_rows):
            concat = xdf.concat([inputs[i * n_cols + j] for j in range(n_cols)], axis=1)
            concats.append(concat)

        if xdf is pd:
            # The `sort=False` is to suppress a `FutureWarning` of pandas, when the index or column of chunks to
            # concatenate is not aligned, which may happens for certain ops.
            #
            # See also Note [Columns of Left Join] in test_merge_execution.py.
            ret = xdf.concat(concats, sort=False)
        else:
            ret = xdf.concat(concats)
        if getattr(chunk.index_value, "should_be_monotonic", False):
            ret.sort_index(inplace=True)
        if getattr(chunk.columns_value, "should_be_monotonic", False):
            ret.sort_index(axis=1, inplace=True)
        return ret

    def _auto_concat_series_chunks(chunk, inputs):
        # auto generated concat when executing a Series
        if all(np.isscalar(inp) for inp in inputs):
            return pd.Series(inputs)
        else:
            xdf = pd if isinstance(inputs[0], pd.Series) else cudf
            if chunk.op.axis is not None:
                concat = xdf.concat(inputs, axis=chunk.op.axis)
            else:
                concat = xdf.concat(inputs)
            if getattr(chunk.index_value, "should_be_monotonic", False):
                concat.sort_index(inplace=True)
            return concat

    chunk = op.outputs[0]
    inputs = [ctx[input.key] for input in op.inputs]

    if isinstance(inputs[0], tuple):
        ctx[chunk.key] = tuple(
            _base_concat(chunk, [input[i] for input in inputs])
            for i in range(len(inputs[0]))
        )
    else:
        ctx[chunk.key] = _base_concat(chunk, inputs)


# Traceback (RuntimeError)
In [5]: df = md.read_csv('/home/xuye.qin/kaisheng.hks/G1_1e8_1e2_0_0.csv', gpu=True)

In [6]: _ = df.execute()
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-6-bdc0e119412a> in <module>
----> 1 _ = df.execute()

~/kaisheng.hks/mars/mars/core.py in execute(self, session, **kw)
443         if session is None:
444             session = Session.default_or_local()
--> 445         return session.run(self, **kw)
446
447     def fetch(self, session=None, **kw):

~/kaisheng.hks/mars/mars/session.py in run(self, *tileables, **kw)
179         tileables = tuple(mt.tensor(t) if not isinstance(t, (Entity, Base)) else t
180                           for t in tileables)
--> 181         result = self._sess.run(*tileables, **kw)
182
183         for t in tileables:

~/kaisheng.hks/mars/mars/session.py in run(self, *tileables, **kw)
88             # set number of running cores
89             self.context.set_ncores(kw['n_parallel'])
---> 90             res = self._executor.execute_tileables(tileables, **kw)
91             return res
92

~/kaisheng.hks/mars/mars/utils.py in _wrapped(*args, **kwargs)
384                 _kernel_mode.eager = False
385             _kernel_mode.eager_count = enter_eager_count + 1
--> 386             return func(*args, **kwargs)
387         finally:
388             _kernel_mode.eager_count -= 1

~/kaisheng.hks/mars/mars/utils.py in inner(*args, **kwargs)
471     def inner(*args, **kwargs):
472         with build_mode():
--> 473             return func(*args, **kwargs)
474     return inner
475

~/kaisheng.hks/mars/mars/executor.py in execute_tileables(self, tileables, fetch, n_parallel, n_thread, print_progress, mock, compose)
734             self.execute_graph(chunk_graph, list(temp_result_keys), n_parallel=n_parallel or n_thread,
735                                print_progress=print_progress, mock=mock,
--> 736                                chunk_result=chunk_result)
737             if chunk_graph_builder.done:
738                 if len(intermediate_result_keys) > 0:

~/kaisheng.hks/mars/mars/executor.py in execute_graph(self, graph, keys, n_parallel, print_progress, mock, no_intermediate, compose, retval, chunk_result)
610                                          mock=mock, mock_max_memory=self._mock_max_memory,
611                                          fetch_keys=fetch_keys, no_intermediate=no_intermediate)
--> 612         res = graph_execution.execute(retval)
613         self._mock_max_memory = max(self._mock_max_memory, graph_execution._mock_max_memory)
614         if mock:

~/kaisheng.hks/mars/mars/executor.py in execute(self, retval)
495         # wait until all the futures completed
496         for future in executed_futures:
--> 497             future.result()
498
499         if retval:

~/miniconda3/lib/python3.7/concurrent/futures/_base.py in result(self, timeout)
423                 raise CancelledError()
424             elif self._state == FINISHED:
--> 425                 return self.__get_result()
426
427             self._condition.wait(timeout)

~/miniconda3/lib/python3.7/concurrent/futures/_base.py in __get_result(self)
382     def __get_result(self):
383         if self._exception:
--> 384             raise self._exception
385         else:
386             return self._result

~/miniconda3/lib/python3.7/concurrent/futures/thread.py in run(self)
55
56         try:
---> 57             result = self.fn(*self.args, **self.kwargs)
58         except BaseException as exc:
59             self.future.set_exception(exc)

~/kaisheng.hks/mars/mars/executor.py in _execute_operand(self, op)
372             # so we pass the first operand's first output to Executor.handle
373             first_op = ops[0]
--> 374             Executor.handle(first_op, results, self._mock)
375
376             # update maximal memory usage during execution

~/kaisheng.hks/mars/mars/executor.py in handle(cls, op, results, mock)
559         try:
560             if UFuncTypeError is None:
--> 561                 return runner(results, op)
562             else:
563                 # Cast `UFuncTypeError` to `TypeError` since subclasses of the former is unpickleable.

~/kaisheng.hks/mars/mars/dataframe/datasource/read_csv.py in execute(cls, ctx, op)
209                         csv_kwargs['skiprows'] = 1 if op.header == 'infer' else op.header
210                     df = xdf.read_csv(b, sep=op.sep, names=op.names, index_col=op.index_col,
--> 211                                       dtype=out_df.dtypes.to_dict(), **csv_kwargs)
212         ctx[out_df.key] = df
213

~/miniconda3/lib/python3.7/site-packages/cudf/io/csv.py in read_csv(filepath_or_buffer, lineterminator, quotechar, quoting, doublequote, header, mangle_dupe_cols, usecols, sep, delimiter, delim_whitespace, skipinitialspace, names, dtype, skipfooter, skiprows, dayfirst, compression, thousands, decimal, true_values, false_values, nrows, byte_range, skip_blank_lines, parse_dates, comment, na_values, keep_default_na, na_filter, prefix, index_col)
79         na_filter=na_filter,
80         prefix=prefix,
---> 81         index_col=index_col,
82     )
83

cudf/bindings/csv.pyx in cudf.bindings.csv.cpp_read_csv()

cudf/bindings/csv.pyx in cudf.bindings.csv.cpp_read_csv()

RuntimeError: cuDF failure at: /conda/conda-bld/libcudf_1566414954289/work/cpp/src/io/csv/csv_reader_impl.cu:624: Unsupported data type

# Fixed code
def execute(cls, ctx, op):
    def _base_concat(chunk, inputs):
        # auto generated concat when executing a DataFrame, Series or Index
        if chunk.op.object_type == ObjectType.dataframe:
            return _auto_concat_dataframe_chunks(chunk, inputs)
        elif chunk.op.object_type == ObjectType.series:
            return _auto_concat_series_chunks(chunk, inputs)
        else:
            raise TypeError(
                "Only DataFrameChunk, SeriesChunk and IndexChunk "
                "can be automatically concatenated"
            )

    def _auto_concat_dataframe_chunks(chunk, inputs):
        if chunk.op.axis is not None:
            return pd.concat(inputs, axis=op.axis)
        # auto generated concat when executing a DataFrame
        n_rows = max(inp.index[0] for inp in chunk.inputs) + 1
        n_cols = int(len(inputs) // n_rows)
        assert n_rows * n_cols == len(inputs)

        xdf = pd if isinstance(inputs[0], pd.DataFrame) else cudf

        concats = []
        for i in range(n_rows):
            concat = xdf.concat([inputs[i * n_cols + j] for j in range(n_cols)], axis=1)
            concats.append(concat)

        if xdf is pd:
            # The `sort=False` is to suppress a `FutureWarning` of pandas, when the index or column of chunks to
            # concatenate is not aligned, which may happens for certain ops.
            #
            # See also Note [Columns of Left Join] in test_merge_execution.py.
            ret = xdf.concat(concats, sort=False)
        else:
            ret = xdf.concat(concats)
            # cuDF will lost index name when concat two seriess.
            ret.index.name = concats[0].index.name
        if getattr(chunk.index_value, "should_be_monotonic", False):
            ret.sort_index(inplace=True)
        if getattr(chunk.columns_value, "should_be_monotonic", False):
            ret.sort_index(axis=1, inplace=True)
        return ret

    def _auto_concat_series_chunks(chunk, inputs):
        # auto generated concat when executing a Series
        if all(np.isscalar(inp) for inp in inputs):
            return pd.Series(inputs)
        else:
            xdf = pd if isinstance(inputs[0], pd.Series) else cudf
            if chunk.op.axis is not None:
                concat = xdf.concat(inputs, axis=chunk.op.axis)
            else:
                concat = xdf.concat(inputs)
            if getattr(chunk.index_value, "should_be_monotonic", False):
                concat.sort_index(inplace=True)
            return concat

    chunk = op.outputs[0]
    inputs = [ctx[input.key] for input in op.inputs]

    if isinstance(inputs[0], tuple):
        ctx[chunk.key] = tuple(
            _base_concat(chunk, [input[i] for input in inputs])
            for i in range(len(inputs[0]))
        )
    else:
        ctx[chunk.key] = _base_concat(chunk, inputs)