# Buggy code
def csrmm2(a, b, c=None, alpha=1.0, beta=0.0, transa=False, transb=False):
    """Matrix-matrix product for a CSR-matrix and a dense matrix.

    .. math::

       C = \\alpha o_a(A) o_b(B) + \\beta C,

    where :math:`o_a` and :math:`o_b` are transpose functions when ``transa``
    and ``tranb`` are ``True`` respectively. And they are identity functions
    otherwise.

    Args:
        a (cupy.sparse.csr): Sparse matrix A.
        b (cupy.ndarray): Dense matrix B. It must be F-contiguous.
        c (cupy.ndarray or None): Dense matrix C. It must be F-contiguous.
        alpha (float): Coefficient for AB.
        beta (float): Coefficient for C.
        transa (bool): If ``True``, transpose of A is used.
        transb (bool): If ``True``, transpose of B is used.

    Returns:
        cupy.ndarray: Calculated C.

    """
    assert a.ndim == b.ndim == 2
    assert b.flags.f_contiguous
    assert c is None or c.flags.f_contiguous

    a_shape = a.shape if not transa else a.shape[::-1]
    b_shape = b.shape if not transb else b.shape[::-1]
    if a_shape[1] != b.shape[0]:
        raise ValueError("dimension mismatch")

    handle = device.get_cusparse_handle()
    m, k = a_shape
    n = b_shape[1]

    a, b, c = _cast_common_type(a, b, c)
    if c is None:
        c = cupy.zeros((m, n), a.dtype, "F")

    ldb = b.shape[0]
    ldc = c.shape[0]
    op_a = _transpose_flag(transa)
    op_b = _transpose_flag(transb)
    alpha = numpy.array(alpha, a.dtype).ctypes
    beta = numpy.array(beta, a.dtype).ctypes
    _call_cusparse(
        "csrmm2",
        a.dtype,
        handle,
        op_a,
        op_b,
        m,
        n,
        k,
        a.nnz,
        alpha.data,
        a._descr.descriptor,
        a.data.data.ptr,
        a.indptr.data.ptr,
        a.indices.data.ptr,
        b.data.ptr,
        ldb,
        beta.data,
        c.data.ptr,
        ldc,
    )
    return c


# Traceback (cupy.cuda.cusparse.CuSparseError)
Traceback (most recent call last):
File "main.py", line 23, in <module>
main()
File "main.py", line 20, in main
gx = cupy.cusparse.csrmm2(W, y.T, transa=True).T
File "/home/tommi/.pyenv/versions/cupy-dev/lib/python3.4/site-packages/cupy-2.0.0rc1-py3.4-linux-x86_64.egg/cupy/cusparse.py", line 205, in csrmm2
b.data.ptr, ldb, beta.data, c.data.ptr, ldc)
File "/home/tommi/.pyenv/versions/cupy-dev/lib/python3.4/site-packages/cupy-2.0.0rc1-py3.4-linux-x86_64.egg/cupy/cusparse.py", line 52, in _call_cusparse
return f(*args)
File "cupy/cuda/cusparse.pyx", line 347, in cupy.cuda.cusparse.scsrmm2
File "cupy/cuda/cusparse.pyx", line 357, in cupy.cuda.cusparse.scsrmm2
File "cupy/cuda/cusparse.pyx", line 229, in cupy.cuda.cusparse.check_status
cupy.cuda.cusparse.CuSparseError: CUSPARSE_STATUS_INVALID_VALUE

# Fixed code
def csrmm2(a, b, c=None, alpha=1.0, beta=0.0, transa=False, transb=False):
    """Matrix-matrix product for a CSR-matrix and a dense matrix.

    .. math::

       C = \\alpha o_a(A) o_b(B) + \\beta C,

    where :math:`o_a` and :math:`o_b` are transpose functions when ``transa``
    and ``tranb`` are ``True`` respectively. And they are identity functions
    otherwise.
    It is forbidden that both ``transa`` and ``transb`` are ``True`` in
    cuSPARSE specification.

    Args:
        a (cupy.sparse.csr): Sparse matrix A.
        b (cupy.ndarray): Dense matrix B. It must be F-contiguous.
        c (cupy.ndarray or None): Dense matrix C. It must be F-contiguous.
        alpha (float): Coefficient for AB.
        beta (float): Coefficient for C.
        transa (bool): If ``True``, transpose of A is used.
        transb (bool): If ``True``, transpose of B is used.

    Returns:
        cupy.ndarray: Calculated C.

    """
    assert a.ndim == b.ndim == 2
    assert b.flags.f_contiguous
    assert c is None or c.flags.f_contiguous
    assert not (transa and transb)

    a_shape = a.shape if not transa else a.shape[::-1]
    b_shape = b.shape if not transb else b.shape[::-1]
    if a_shape[1] != b_shape[0]:
        raise ValueError("dimension mismatch")

    handle = device.get_cusparse_handle()
    m, k = a_shape
    n = b_shape[1]

    a, b, c = _cast_common_type(a, b, c)
    if c is None:
        c = cupy.zeros((m, n), a.dtype, "F")

    ldb = b.shape[0]
    ldc = c.shape[0]
    op_a = _transpose_flag(transa)
    op_b = _transpose_flag(transb)
    alpha = numpy.array(alpha, a.dtype).ctypes
    beta = numpy.array(beta, a.dtype).ctypes
    _call_cusparse(
        "csrmm2",
        a.dtype,
        handle,
        op_a,
        op_b,
        a.shape[0],
        n,
        a.shape[1],
        a.nnz,
        alpha.data,
        a._descr.descriptor,
        a.data.data.ptr,
        a.indptr.data.ptr,
        a.indices.data.ptr,
        b.data.ptr,
        ldb,
        beta.data,
        c.data.ptr,
        ldc,
    )
    return c