Skip to content

reducing while iterating over the index #66

@albertomercurio

Description

@albertomercurio

Hello,

I have a situation where I need to reduce and iterate over the indices of the array, rather than the array itself. A simple example:

x = rand(10);

AcceleratedKernels.mapreduce(+, eachindex(x)) do i
   i > 8 && return 0
   return x[i] + x[i+1]
end
ERROR: ArgumentError: Implement `KernelAbstractions.get_backend(::Base.OneTo{Int64})`
Stacktrace:
 [1] get_backend(A::Base.OneTo{Int64})
   @ KernelAbstractions ~/.julia/packages/KernelAbstractions/lGrz7/src/KernelAbstractions.jl:522
 [2] mapreduce(f::Function, op::Function, src::Base.OneTo{Int64})
   @ AcceleratedKernels ~/.julia/packages/AcceleratedKernels/AdYRJ/src/reduce/reduce.jl:156
 [3] top-level scope
   @ REPL[9]:1

This would be helpful on implementing the trace of a sparse CSC matrix. My current implementation uses the foreachindex function and atomic operations, which I don't think are optimal

function LinearAlgebra.tr(A::DeviceSparseMatrixCSC)
    m, n = size(A)
    m == n || throw(DimensionMismatch("Matrix must be square to compute the trace."))

    res = similar(nonzeros(A), 1)
    fill!(res, zero(eltype(A)))

    AcceleratedKernels.foreachindex(getcolptr(A)) do col
        col == n+1 && return
        for j in getcolptr(A)[col]:(getcolptr(A)[col+1]-1)
            if rowvals(A)[j] == col
                @atomic res[1] += nonzeros(A)[j]
            end
        end
    end

    return res[1]
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions