## @package dataio
# Module caffe2.python.dataio
"""
Defines the base interface for reading and writing operations.

Readers/Writers are objects that produce operations that read/write sequences
of data. Each operation reads or writes a list of BlobReferences.

Readers and Writers must be implemented such that read and write operations
are atomic and thread safe.

Examples of possible Readers and Writers:
    QueueReader, QueueWriter,
    DatasetReader, DatasetWriter,

See `dataset.py` for an example of implementation.
"""





from caffe2.python import core
from caffe2.python.schema import Field, Struct, from_blob_list
import numpy as np
import time


class Reader:
    """
    Reader is an abstract class to be implemented in order to provide
    operations capable of iterating through a dataset or stream of data.

    A Reader must implement at least one operation, `read`, which
    adds operations to a net that read the next batch of data. Readers can
    optionally support the `reset` operation, which is useful when multiple
    passes over the data are required.
    """
    def __init__(self, schema=None):
        if schema is not None:
            assert isinstance(schema, Field)
        self._schema = schema

    def schema(self):
        assert self._schema is not None, 'Schema not provided for this reader.'
        return self._schema

    def _set_schema(self, schema):
        self._schema = schema

    def setup_ex(self, init_net, finish_net):
        """Setup nets to run at task initialization and cleanup time.

        Args:
            init_net: A net invoked at task init time.
            finish_net: A net invoked at task cleanup time.
        """
        pass

    def read_ex(self, local_init_net, local_finish_net):
        read_net = core.Net('reader_body')
        return ([read_net], ) + self.read(read_net)

    def read_record_ex(self, local_init_net, local_finish_net):
        nets, should_stop, fields = self.read_ex(
            local_init_net, local_finish_net)
        if self._schema:
            fields = from_blob_list(self._schema, fields)
        return nets, should_stop, fields

    def read(self, read_net):
        """Append operations to read_net that will read a batch from the
        underlying data soruce.

        Operations added to `read_net` must be thread safe and atomic, that is,
        it should be possible to clone `read_net` and run multiple instances of
        it in parallel.

        Args:
            read_net: the net that will be appended with read operations

        Returns:
            A tuple (should_stop, fields), with:
                should_stop: BlobReference pointing to a boolean scalar
                    blob that indicates whether the read operation
                    was succesfull or whether the end of data has
                    been reached.
                fields: A tuple of BlobReference containing the latest batch
                    of data that was read.
        """
        raise NotImplementedError('Readers must implement `read`.')

    def reset(self, net):
        """Append operations to `net` that will reset the reader.

        This can be used to read the data multiple times.
        Not all readers support this operation.
        """
        raise NotImplementedError('This reader cannot be resetted.')

    def read_record(self, read_net):
        should_stop, fields = self.read(read_net)
        if self._schema:
            fields = from_blob_list(self._schema, fields)
        return should_stop, fields

    def execution_step(self, reader_net_name=None, external_should_stop=None):
        """Create an execution step with a net containing read operators.

        The execution step will contain a `stop_blob` that knows how to stop
        the execution loop when end of data was reached.

        E.g.:

            read_step, fields = reader.execution_step()
            consume_net = core.Net('consume')
            consume_net.Print(fields[0], [])
            p = core.Plan('reader')
            p.AddStep(read_step.AddNet(consume_net))
            core.RunPlan(p)

        Args:
            reader_net_name: (optional) the name of the reader_net to be
                             created. The execution step will
                             be named accordingly.

        Returns:
            A tuple (read_step, fields), with:
                read_step: A newly created execution step containing a net with
                           read operations. The step will have `stop_blob` set,
                           in order to stop the loop on end of data.
                fields: A tuple of BlobReference containing the latest batch
                        of data that was read.
        """
        reader_net = core.Net(reader_net_name or 'reader')
        should_stop, fields = self.read_record(reader_net)
        if external_should_stop is not None:
            should_stop = reader_net.Or([external_should_stop, should_stop])
        read_step = core.execution_step(
            '{}_step'.format(reader_net_name),
            reader_net,
            should_stop_blob=should_stop)
        return (read_step, fields)


class Writer:
    """
    Writer is an abstract class to be implemented in order to provide
    operations capable of feeding a data stream or a dataset.

    A Writer must implement 2 operations:
    `write`, which adds operations to a net that write the write batch of
    data, and `commit`, which adds operations to a net in order to indicate
    that no more data will be written.
    """
    _schema = None

    def schema(self):
        return self._schema

    def write(self, writer_net, fields):
        """Add operations to `writer_net` that write the next batch of data.

        Operations added to the net must be thread-safe and unique, that is:
        multiple writers must be able to write to the dataset in parallel.

        Args:
            fields: a tuple of BlobReference containing the batch of data to
                    write.
        """
        raise NotImplementedError('Writers must implement write.')

    def write_record(self, writer_net, fields):
        if isinstance(fields, Field):
            self._schema = fields
            fields = fields.field_blobs()
        self.write(writer_net, fields)

    def setup_ex(self, init_net, finish_net):
        """Experimental, don't use yet"""
        self.commit(finish_net)

    def write_ex(self, fields, local_init_net, local_finish_net, stop_blob):
        """Experimental extension to the interface. Don't use yet"""
        write_net = core.Net('write_net')
        self.write(write_net, fields)
        return [write_net]

    def write_record_ex(
            self, fields, local_init_net, local_finish_net, stop_blob=None):
        """Experimental extension to the interface. Don't use yet."""
        if isinstance(fields, Field):
            self._schema = fields
            fields = fields.field_blobs()
        if stop_blob is None:
            stop_blob = local_init_net.NextName("dequeue_status")
        write_nets = self.write_ex(
            fields, local_init_net, local_finish_net, stop_blob)
        return (write_nets, stop_blob)

    def commit(self, finish_net):
        """Add operations to `finish_net` that signal end of data.

        This must be implemented by all Writers, but may be no-op for some
        of them.
        """
        pass


class ReaderBuilder:
    """ Allow usage of a reader in distributed fashion. """
    def schema(self):
        raise NotImplementedError()

    def setup(self, **kwargs):
        """
        Optionally, perform one-time setup before calling new_reader().
        Subclass should make sure this function is only called once.
        """
        raise NotImplementedError()

    def new_reader(self, **kwargs):
        raise NotImplementedError()


class PipedReaderBuilder(ReaderBuilder):
    """ReaderBuilder that modifies underlying builder by calling `piper`
    function on each new reader produced, and return the result of
    the function. This way, it is possible to append data processing
    pipelines that will be replicated for each reader that gets created.

    E.g.:

    PipedReaderBuilder(
        ReaderBuilder(...),
        lambda reader: pipe(reader, processor=my_proc))
    """

    def __init__(self, builder, piper):
        self._builder = builder
        self._piper = piper

    def schema(self):
        return self._builder.schema()

    def setup(self, **kwargs):
        return self._builder.setup(**kwargs)

    def new_reader(self, **kwargs):
        # Passing everything down since you could wrap a PipedReaderBuilder in
        # another PipedReaderBuilder
        output = self._piper(
            reader=self._builder.new_reader(**kwargs),
            **kwargs
        )
        return output if isinstance(output, Reader) else output.reader()


class Pipe:
    def __init__(self, schema=None, obj_key=None):
        self._num_writers = 0
        self._num_readers = 0
        self._schema = schema
        self._obj_key = obj_key

    def schema(self):
        return self._schema

    def setup(self, global_init_net):
        pass

    def reader(self):
        raise NotImplementedError()

    def writer(self):
        raise NotImplementedError()

    def num_readers(self):
        return self._num_readers

    def num_writers(self):
        return self._num_writers

    def _new_writer(self, writer_schema, writer_init_net):
        if writer_schema is not None and self._schema is None:
            self._schema = writer_schema
        self._num_writers += 1
        if self._obj_key is not None:
            writer_init_net.add_attribute(self._obj_key, self)

    def _new_reader(self, reader_init_net):
        self._num_readers += 1
        if self._obj_key is not None:
            reader_init_net.add_attribute(self._obj_key, self)


class CounterReader(Reader):
    """ Reader that produces increasing integers. """
    def __init__(self):
        Reader.__init__(self, schema=Struct(('iter', np.int64)))
        self.counter = None
        self.should_stop = None

    def setup_ex(self, global_init_net, global_finish_net):
        if self.counter is None:
            self.counter = global_init_net.CreateCounter([], init_count=0)
            self.should_stop = global_init_net.ConstantFill(
                [], shape=[], dtype=core.DataType.BOOL, value=False)

    def read_ex(self, local_init_net, local_finish_net):
        count_net = core.Net('limited_reader_counter')
        value = count_net.CountUp([self.counter], 1)
        return [count_net], self.should_stop, [value]


class ReaderWithLimitBase(Reader):
    """Abstract Reader constrained by certain conditions.

    Base class for Reader classes which check for certain conditions to stop
    further processing (e.g. max number of iterations or time limit).
    Also produces a boolean blob (data_finished) that can be used to see if
    the reader exausted all input data (true) or stopped for another reason
    (false).
    """

    def __init__(self, reader):
        Reader.__init__(self, schema=reader._schema)
        self.reader = reader
        self.net = core.Net('reader_with_limit')
        self._data_finished = self.net.AddExternalInput(
            self.net.NextName('data_finished'))
        self.should_stop = None

    def setup_ex(self, global_init_net, global_finish_net):
        global_init_net.ConstantFill(
            [], [self._data_finished],
            shape=[], value=False, dtype=core.DataType.BOOL)
        self.reader.setup_ex(global_init_net, global_finish_net)
        self.setup_limiter(global_init_net, global_finish_net)

    def read_ex(self, local_init_net, local_finish_net):
        """Reads from an underlying Reader class, but may stop due to additional
        constraints.

        Build and return network(s) to read data from a Reader with
        additional constraints, depending on which derived class is used.
        Derived classes implement setup_limited and check_limiter_condition
        which determine the nature of the constraint imposed on the reader,
        e.g. iteration limits or time limit.

        Args:
            local_init_net: A net invoked at task instance init time (Once per
                parallel thread).
            local_finish_net: A net invoked at task instance cleanup time (Once
                per parallel thread).
        """

        # Check if limiting constraint is met.
        stop_condition_net = core.Net('limited_reader_condition')
        should_stop = self.check_limiter_condition(stop_condition_net)

        # Call original reader.
        nets, local_data_finished, fields = self.reader.read_ex(
            local_init_net, local_finish_net)
        self._set_schema(self.reader._schema)

        # Check if original reader is done.
        check_done_net = core.Net('limited_reader_post')
        # Copy to the same blob as the counter output to trigger reader
        # stopping - this is ok because execution will check should_stop_blob
        # after every single operation, so it has already been checked on this
        # iteration by this point.
        check_done_net.Copy(local_data_finished, should_stop)
        # Update externally-accessible flag indicating if reader is done
        check_done_net.Or([self._data_finished, local_data_finished],
                          [self._data_finished])

        return [stop_condition_net] + nets + [check_done_net], should_stop, fields

    def setup_limiter(self, global_init_net, global_finish_net):
        """Configure task level init/cleanup nets required to implement limit
        condition. Must be implemented by subclass.

        Args:
            global_init_net: A net invoked at task init time.
            global_finish_net: A net invoked at task cleanup time.
        """
        raise NotImplementedError("Subclass must implement `setup_limiter`")

    def check_limiter_condition(self, stop_condition_net):
        """Configure a net that is invoked between reading batches to see if
        limit condition is met. Must be implemented by subclass.

        Args:
            stop_condition_net: A net invoked to evaluate an early termination
                condition.
        """
        raise NotImplementedError("Subclass must implement `check_limiter_condition")

    def data_finished(self):
        """
        Return a blob that can be checked after the end of the reading task,
        which will contain a scalar float indicating whether the underlying
        reader has been exhausted (True) or whether we stopped because reached
        the limit of iterations (False).
        """
        return self._data_finished


class ReaderWithLimit(ReaderWithLimitBase):
    """Reader that stops after `num_iter` batches.

    If `num_iter` <= 0 or is None, reverts to an unconstrained reader that
    exports a boolean blob indicating that the reader has exhausted
    the data steam.
    """
    def __init__(self, reader, num_iter=1):
        """Class initializer.

        Args:
            reader: The underlying reader object doing the actual read.
            num_iter: Number of batches to read. If `None`,
                the class reverts to a normal reader except that it also
                produces a data_finished blob as a side effect to indicate
                whether the input stream is exhausted.
        """
        super().__init__(reader)
        self.counter = None
        self.num_iter = num_iter
        if self.num_iter is not None:
            self.counter = self.net.AddExternalInput(
                self.net.NextName('counter'))

    def setup_limiter(self, global_init_net, global_finish_net):
        if self.counter:
            global_init_net.CreateCounter(
                [], [self.counter], init_count=int(self.num_iter))

    def check_limiter_condition(self, stop_condition_net):
        if self.counter:
            return stop_condition_net.CountDown([self.counter], 1)
        else:
            return stop_condition_net.ConstantFill(
                [], 1,
                shape=[], value=False, dtype=core.DataType.BOOL)


def CountUntil(num_iter):
    return ReaderWithLimit(CounterReader(), num_iter)


class ReaderWithTimeLimit(ReaderWithLimitBase):
    """Reader that stops after `duration` seconds.

    If `duration` <= 0 or is None, reverts to an unconstrained reader that
    exports a boolean blob indicating that the reader has exhausted
    the data steam.
    """
    def __init__(self, reader, duration=0):
        """Class initializer.

        Args:
            reader: The underlying reader object doing the actual read.
            duration: Number of seconds to read. If un-specified, None, or <= 0,
                the class reverts to a normal reader except that it also
                produces a data_finished blob as a side effect to indicate
                whether the input stream is exhausted.
        """
        super().__init__(reader)

        self.timer = None
        self.duration = duration
        self.duration_ns_blob = None

    def setup_limiter(self, global_init_net, global_finish_net):
        if self.duration is not None and self.duration > 0:
            duration_ns = int(self.duration * (10**9))

            self.timer = global_init_net.TimerBegin(
                [], counter_name='epoch_timer')
            start_time = global_init_net.TimerGet(self.timer)
            self.duration_ns_blob = global_init_net.ConstantFill(
                [start_time], value=duration_ns)

            global_finish_net.TimerEnd([self.timer], [])

    def check_limiter_condition(self, stop_condition_net):
        if self.duration:
            time_elapsed = stop_condition_net.TimerGet(self.timer)
            return stop_condition_net.GE(
                [time_elapsed, self.duration_ns_blob], str(self.should_stop))
        else:
            return stop_condition_net.ConstantFill(
                [], 1, shape=[], value=False, dtype=core.DataType.BOOL
            )


class ReaderWithDelay(Reader):
    """Test reader class that inserts a delay between reading batches."""

    def __init__(self, reader, delay):
        Reader.__init__(self, schema=reader._schema)
        self.reader = reader
        self.delay = delay

    def setup_ex(self, global_init_net, global_finish_net):
        self.reader.setup_ex(global_init_net, global_finish_net)

    def read_ex(self, local_init_net, local_finish_net):
        read_net = core.Net("reader_body")

        def sleep_op(*args, **argd):
            time.sleep(self.delay)

        read_net.Python(sleep_op)([], [])
        return ([read_net],) + self.reader.read(read_net)


class CompositeReader(Reader):
    """
    Base class for a reader that wrap multiple readers, e.g., reading from
    multiple sources simultaneously.
    """
    def __init__(self, names, readers):
        """
        Args:
            names: list[str] names of readers; used as schema keys
            readers: list[Reader] Reader instances, must have schema
        """
        assert len(names) == len(readers)
        super().__init__(schema=Struct(*[
            (name, reader.schema()) for name, reader in zip(names, readers)
        ]))
        self._names = names
        self._readers = readers

    def setup_ex(self, init_net, finish_net):
        for reader in self._readers:
            reader.setup_ex(init_net, finish_net)

    def read_ex(self, local_init_net, local_finish_net):
        """
        Stops when one of the reader finished
        """
        # First, instantiate all the reader nets
        fields = []
        stop_blobs = []
        all_sub_read_nets = []
        for name, reader in zip(self._names, self._readers):
            sub_read_nets, should_stop, record = reader.read_record_ex(
                local_init_net, local_finish_net)
            stop_blobs.append(should_stop)
            all_sub_read_nets.append(sub_read_nets)
            fields.extend(record.field_blobs())

        read_nets = []
        # Use the stop blob of the last reader as stop blob of composite reader.
        local_should_stop = stop_blobs[-1]
        for name, sub_read_nets, stop_blob in zip(self._names, all_sub_read_nets, stop_blobs):
            read_nets.extend(sub_read_nets)
            if stop_blob == local_should_stop:
                # Skip adding stop net because Or([A, A], A) doesn't pass operator
                # schema check
                continue
            stop_net = core.Net("{}_stop".format(name))
            stop_net.Or([local_should_stop, stop_blob], local_should_stop)
            read_nets.append(stop_net)

        return read_nets, local_should_stop, fields

    def reset(self, net):
        for reader in self._readers:
            reader.reset(net)


class CompositeReaderBuilder(ReaderBuilder):
    """
    A reader builder for CompositeReader
    """
    def __init__(self, names, reader_builders):
        """
        Args:
            names: list[str] names of readers; used as schema keys
            reader_builders: list[ReaderBuilder] ReaderBuilder instances;
                must have schema
        """
        super().__init__()
        self._names = names
        self._reader_builders = reader_builders
        self._schema = Struct(*[
            (name, reader_builder.schema())
            for name, reader_builder in zip(names, reader_builders)
        ])

    def schema(self):
        return self._schema

    def setup(self, **kwargs):
        data_finished_blobs = {}
        # limiter is stateful; it can only be used once. Since
        # CompositeReader stops when one of the reader stops,
        # this is fine.
        if "limiter" in kwargs:
            limiter = kwargs.pop("limiter")
        else:
            limiter = None
        for i, reader_builder in enumerate(self._reader_builders):
            if i == len(self._reader_builders) - 1 and limiter is not None:
                # The limiter must be applied to the last reader so that the
                # batch counter is incremented only if every reader has data
                kwargs["limiter"] = limiter
            sub_reader_data_finished_blobs = reader_builder.setup(**kwargs)
            overlapping_keys = set(data_finished_blobs.keys()) & set(sub_reader_data_finished_blobs.keys())
            overlapping_values = set(data_finished_blobs.values()) & set(sub_reader_data_finished_blobs.values())
            assert overlapping_keys == set(), "Overlapping keys: {}".format(overlapping_keys)
            assert overlapping_values == set(), "Overlapping values: {}".format(overlapping_values)
            data_finished_blobs.update(sub_reader_data_finished_blobs)

        return data_finished_blobs

    def new_reader(self, **kwargs):
        readers = []
        for reader_builder in self._reader_builders:
            reader = reader_builder.new_reader(**kwargs)
            if isinstance(reader, Reader):
                pass
            elif hasattr(reader, 'reader'):
                reader = reader.reader()
            else:
                raise ValueError('reader must be an instance of Reader or Pipe')
            readers.append(reader)

        multi_reader = CompositeReader(self._names, readers)
        assert multi_reader.schema() == self._schema
        return multi_reader
