# Path: indigo/util.py
# class profile(object):
#     extra = dict()
# 
#     def __init__(self, event, **kwargs):
#         self._event = event
#         self._kwargs = kwargs
# 
#     def __enter__(self):
#         if log.level > logging.DEBUG:
#             return
# 
#         self._backend.barrier()
#         self._start = time.time()
# 
#         return self
# 
#     def __exit__(self, exc_type, exc_value, traceback):
#         if log.level > logging.DEBUG:
#             return
# 
#         self._backend.barrier()
#         data = dict(
#             duration = time.time() - self._start,
#             event    = self._event,
#         )
#         data.update(self.extra)
#         data.update(self._kwargs)
# 
#         if 'nflops' in data:
#             data['gflop_rate'] = data['nflops'] / data['duration'] * 1e-9
#             del data['nflops']
# 
#         if 'nbytes' in data:
#             data['membw_rate'] = data['nbytes'] / data['duration'] * 1e-9
#             del data['nbytes']
# 
#         kvs = sorted(data.items(), key=lambda kv: kv[0])
# 
#         def fmt(k, v):
#             if isinstance(v, float):
#                 return k, "%2.5g" % v
#             else:
#                 return k, repr(v)
# 
#         msg = "PROFILE(%s)" % ", ".join("%s=%s" % fmt(*kv) for kv in kvs)
#         log.debug(msg)
# 
#         self.duration = data['duration']


import sys
import time
import logging
import io, copy
import itertools
import numpy as np
import scipy.sparse as spp
from ctypes import c_ulong
from indigo.util import profile
        from indigo.transforms import Optimize
        from indigo.analyses import Memusage
        from indigo.analyses import TreeHasOp
        from indigo.transforms import RealizeMatrices
                self._matrix_d = self._backend.dia_matrix(self._backend, M, self._name)
            else:
                log.debug("storing in CSR format: %s", self._name)
                M = self._matrix.tocsr()
                M.sort_indices() # cuda requires sorted indictes
                self._matrix_d = self._backend.csr_matrix(self._backend, M, self._name)
                if not self._allow_exwrite:
                    log.debug("disallowing exwrite for %s" % self._name)
                    self._matrix_d._exwrite = False
                else:
                    log.debug("allowing exwrite for %s" % self._name)
        return self._matrix_d

    def _eval(self, y, x, alpha=1, beta=0, forward=True, left=True):
        if not left:
            raise NotImplementedError("Right-multiplication not implemented for {}.".format(self.__class__.__name__))
        M = self._get_or_create_device_matrix()
        if forward:
            read_frac, write_frac = M._col_frac, M._row_frac
        else:
            read_frac, write_frac = M._row_frac, M._col_frac
        if beta == 0:
            y_part = 1
        elif beta == 1:
            y_part = write_frac * (1 if M._exwrite else 2)
        else:
            y_part = 2
        nbytes = M.nbytes + x.nbytes*read_frac + y.nbytes*y_part
        nflops = 5 * len(self._matrix.data) * x.shape[1]
        event = 'csrmm' if 'csr' in type(M).__name__ else 'diamm'

# Path: indigo/util.py
# class profile(object):
#     extra = dict()
# 
#     def __init__(self, event, **kwargs):
#         self._event = event
#         self._kwargs = kwargs
# 
#     def __enter__(self):
#         if log.level > logging.DEBUG:
#             return
# 
#         self._backend.barrier()
#         self._start = time.time()
# 
#         return self
# 
#     def __exit__(self, exc_type, exc_value, traceback):
#         if log.level > logging.DEBUG:
#             return
# 
#         self._backend.barrier()
#         data = dict(
#             duration = time.time() - self._start,
#             event    = self._event,
#         )
#         data.update(self.extra)
#         data.update(self._kwargs)
# 
#         if 'nflops' in data:
#             data['gflop_rate'] = data['nflops'] / data['duration'] * 1e-9
#             del data['nflops']
# 
#         if 'nbytes' in data:
#             data['membw_rate'] = data['nbytes'] / data['duration'] * 1e-9
#             del data['nbytes']
# 
#         kvs = sorted(data.items(), key=lambda kv: kv[0])
# 
#         def fmt(k, v):
#             if isinstance(v, float):
#                 return k, "%2.5g" % v
#             else:
#                 return k, repr(v)
# 
#         msg = "PROFILE(%s)" % ", ".join("%s=%s" % fmt(*kv) for kv in kvs)
#         log.debug(msg)
# 
#         self.duration = data['duration']


# Path: indigo/operators.py
import sys
import time
import logging
import io, copy
import itertools
import numpy as np
import scipy.sparse as spp
from ctypes import c_ulong
from indigo.util import profile
        from indigo.transforms import Optimize
        from indigo.analyses import Memusage
        from indigo.analyses import TreeHasOp
        from indigo.transforms import RealizeMatrices

                self._matrix_d = self._backend.dia_matrix(self._backend, M, self._name)
            else:
                log.debug("storing in CSR format: %s", self._name)
                M = self._matrix.tocsr()
                M.sort_indices() # cuda requires sorted indictes
                self._matrix_d = self._backend.csr_matrix(self._backend, M, self._name)
                if not self._allow_exwrite:
                    log.debug("disallowing exwrite for %s" % self._name)
                    self._matrix_d._exwrite = False
                else:
                    log.debug("allowing exwrite for %s" % self._name)
        return self._matrix_d

    def _eval(self, y, x, alpha=1, beta=0, forward=True, left=True):
        if not left:
            raise NotImplementedError("Right-multiplication not implemented for {}.".format(self.__class__.__name__))
        M = self._get_or_create_device_matrix()
        if forward:
            read_frac, write_frac = M._col_frac, M._row_frac
        else:
            read_frac, write_frac = M._row_frac, M._col_frac
        if beta == 0:
            y_part = 1
        elif beta == 1:
            y_part = write_frac * (1 if M._exwrite else 2)
        else:
            y_part = 2
        nbytes = M.nbytes + x.nbytes*read_frac + y.nbytes*y_part
        nflops = 5 * len(self._matrix.data) * x.shape[1]
        event = 'csrmm' if 'csr' in type(M).__name__ else 'diamm'

        with profile(event, xval=read_frac, yval=y_part, nbytes=nbytes, shape=x.shape, forward=forward, nflops=nflops) as p: