For res = f(x::AbstractArray), we'd like a method to get "similar but dense" (@maleadt) version of x, so one can implement it as
function f(x::AbstractArray)
res = similar_but_dense(x)
f!(res, x)
end
where f!(res, x) is the inplace version of f.
This is useful if x is a CuArray, SparseArrays or PooledArray (@nalimilan) but such a function lacks now.
Related issue: https://github.com/JuliaStats/Distances.jl/pull/142
Basically, we need a more fine-grained version of similar which allows specifying more precisely what are the expected properties of the returned array, as suggestedl by @mbauman at https://github.com/JuliaLang/julia/issues/13731#issuecomment-336269236.
What properties do you want from a "dense" array? It seems like this is just a case of either wanting Array or CuArray — are there other relevant types could envision returning here?
Yeah, in this particular case we mostly know what we don't want: not a sparse result if the input is sparse, not a PooledArray if the input is pooled, etc. I'm not sure how to generalize that: basically, a dense array that is meant to contain values that are not from the same set as input values; i.e. the most general case of dense array I guess.
Maybe this makes more sense if we contrast this with the situation where you want a dense array supposed to contain values from the same set as the input. We could have a series of properties (dense/sparse, same set/different set...) that you can combine. Most arrays would only define some cases, like they currently do with similar, and there would be a fallback to the most general case.
EDIT: I should have noted that one of the reasons to want this API in addition to having things work in a generic way is that we don't want Distances to depend on CuArray. That situation can probably happen with other packages too.
I'm considering more the fact that you really just want an Array — but want it to live on a GPU if appropriate...
Yes, that's probably another way of saying "give me the most general kind of array", but still allowing it to live on the GPU. It's hard to design something without concrete examples, so maybe let's think about what to do with SharedArray: should it be treated the same as CuArray in that context?
Maybe what's needed is actually:
Then we'll just have to ask for a non-sparse, non-pooled result to get a CuArray from a CuArray input.
I guess potentially this is useful for any dense matrix that does not live on CPU RAM? and a related thing might be zero_like I found it is useful in some cases, like creating a jacobian: https://github.com/FluxML/Zygote.jl/pull/235/files#diff-d6d410078d0f8a1d8001da9adb996b5fR20
There are plenty of other issues about getting more control over similar (e.g., https://github.com/JuliaLang/julia/issues/18161). I think this one is worth keeping open due to its targeted use-case for GPU/accelerator storage types.
Most helpful comment
Basically, we need a more fine-grained version of
similarwhich allows specifying more precisely what are the expected properties of the returned array, as suggestedl by @mbauman at https://github.com/JuliaLang/julia/issues/13731#issuecomment-336269236.