Skip to content

Base.any has different semantics from base implementation #154

Open
@ssz66666

Description

@ssz66666

The Base.mapreduce based implementation of Base.any and Base.all

Base.any(A::GPUArray{Bool}) = mapreduce(identity, |, A; init = false)

currently has slightly different semantics from the implementation in Base, in two ways:

  1. The base implementation specifies that any and all are short-circuiting reductions. Their semantics can differ if the predicate applied is side-effecting (note any(p, itr) which is implemented in Support Transpose and Adjoint in broadcast better #148 ). Would retaining the difference and clarifying it in documentation be reasonable?

  2. The base implementation implements three-valued logic if the input iterable contains missing values. We might well implement it with something like:

function any(p, itr::GPUArray)
    v, m = mapreduce(
        x -> begin
            b = p(x)
            ismissing(b) ? (false, true) : (b::Bool, false)
        end,
        ((v1, m1), (v2, m2)) ->
            (v1 || v2, m1 || m2),
        itr,
        init = (false, false)
    )
    v || (m ? missing : false)
end

function all(p, itr::GPUArray)
    v, m = mapreduce(
        x -> begin
            b = p(x)
            ismissing(b) ? (true, true) : (b::Bool, false)
        end,
        ((v1, m1), (v2, m2)) ->
            (v1 && v2, m1 || m2),
        itr,
        init = (true, false)
    )
    v && (m ? missing : true)
end

However, currently CuArrays doesn't handle missing values correctly yet (~~~I'll write an issue there as well~~~ see issue here). I don't know if it makes sense to implement this in GPUArrays and make CuArrays fail the test.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions