# N-dimensional view into an N+1 dimension array

I have an `Array{T,N+1}` and I want to pass a slice/view of the first `N` dimensions to a function. If I knew, say, `N=2` I would do

``````b = @view a[:,:,1]
f(b,args...)
``````

But the number of colons depends on `N`. Is there a way to do this for general `N`?

2 Likes

Awesome!

Or also `selectdim(array,dim_to_select,indx_on_that_dim)`, e.g. `b = selectdim(a,3,1)`

4 Likes

I really like the solution with selectdim(), but I add this one too

``````vv = @view v[ntuple(_->:,ndims(v)-1)...,1]
``````
1 Like

Does this produce a â€śviewâ€ť or copy to a new array?

A tupple of colons! Didnâ€™t know you could do that!

As far as I understand `(:)` is a function, like `isless()` for example
It should be equivalent (alias?) of Colon().

But letâ€™s wait for someone who knows to explain better how it works

Just try it :

``````julia> x = [1 2; 3 4]
2Ă—2 Matrix{Int64}:
1  2
3  4
julia> xd2_1 = selectdim(x,2,1)
2-element view(::Matrix{Int64}, :, 1) with eltype Int64:
1
3
julia> xd2_1[2] = 30
30
julia> x
2Ă—2 Matrix{Int64}:
1  2
30  4
``````
1 Like

Thatâ€™s right:

So `Colon` is a struct type and the singleton instance `Colon()` is a function and `:` is a synonym for that.

1 Like

I donâ€™t have Julia installed on my phoneâ€¦ yet!

This is the Base solution, so Iâ€™ll switch this to the answer. But `b=@view a(..,i)` from EllipsisNotation.jl is a really nice bit of syntactic sugar.

1 Like

Huh. The ellipsis version works fine on the GPU, but `selectdim` throws an allocation error:

``````ERROR: InvalidIRError: compiling MethodInstance for (::GPUArrays.var"#broadcast_kernel#28")(::CUDA.CuKernelContext, ::CuDeviceVector{SVector{3, Float32}, 1}, ::Base.Broadcast.Broadcasted{CUDA.CuArrayStyle{1}, Tuple{Base.OneTo{Int64}}, typeof(interp!), Tuple{Base.Broadcast.Extruded{CuDeviceVector{SVector{3, Float32}, 1}, Tuple{Bool}, Tuple{Int64}}, Base.Broadcast.Extruded{CuDeviceVector{SVector{3, Float32}, 1}, Tuple{Bool}, Tuple{Int64}}, CUDA.CuRefValue{CuDeviceArray{Float32, 4, 1}}}}, ::Int64) resulted in invalid LLVM IR
Reason: unsupported call through a literal pointer (call to ijl_alloc_array_1d)
``````

@maleadt , Is there a reason why a view created by `selectdim` shouldnâ€™t work within a kernel?

Not that I know; SubArrays of CuDeviceArrays should generally be supported. Please include the full backtrace, and make sure the code is type stable first.

Iâ€™ll work on a MWE.