Skip to content

Commit

Permalink
add arrayslice
Browse files Browse the repository at this point in the history
Native method for Array slices using shared memory
  • Loading branch information
gummif committed Oct 25, 2014
1 parent df1fcba commit 949bd78
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 0 deletions.
13 changes: 13 additions & 0 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,19 @@ linspace(start::Real, stop::Real) = linspace(start, stop, 100)
logspace(start::Real, stop::Real, n::Integer) = 10.^linspace(start, stop, n)
logspace(start::Real, stop::Real) = logspace(start, stop, 50)


arrayslice(A, i::Int, n::Int) = arrayslice(A, i, (n,))
arrayslice(A, dims::Tuple, n::Tuple) = arrayslice(A, sub2ind(size(A),dims...), n)
arrayslice(A, dims::Tuple, n::Int) = arrayslice(A, dims, (n,))
function arrayslice{T, N}(A::Array{T}, i::Int, n::NTuple{N,Int})
len = prod(n)
@assert 0 < i <= length(A)
@assert 0 <= len
@assert i-1+len <= length(A)
ccall(:jl_slice_owned_array, Array{T,N}, (Any, Any, Any, Uint),
Array{T,N}, A, n, uint(i-1))
end

## Conversions ##

convert{T,n}(::Type{Array{T}}, x::Array{T,n}) = x
Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ export
zeta,

# arrays
arrayslice,
bitbroadcast,
broadcast!,
broadcast!_function,
Expand Down
9 changes: 9 additions & 0 deletions doc/helpdb.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5964,6 +5964,15 @@ popdisplay(d::Display)
"),

("Base","arrayslice","arrayslice(A, pos, dims)
Create an array of size \"dims\" with the data shared with the
given array. The returned array uses the contiguous memory of
\"A\" starting at \"pos\" of length \"prod(dims)\". The \"pos\" and
\"dims\" arguments may be tuple or integer arguments.
"),

("Base","broadcast","broadcast(f, As...)
Broadcasts the arrays \"As\" to a common size by expanding
Expand Down
5 changes: 5 additions & 0 deletions doc/stdlib/base.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4104,6 +4104,11 @@ Constructors

Construct a vector of ``n`` logarithmically-spaced numbers from ``10^start`` to ``10^stop``.

.. function:: arrayslice(A, pos, dims)

Create an array of size ``dims`` with the data shared with the given array. The returned array uses the contiguous memory of ``A`` starting at ``pos`` of length ``prod(dims)``. The ``pos`` and ``dims`` arguments may be tuple or integer arguments.


Mathematical operators and functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
58 changes: 58 additions & 0 deletions src/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,64 @@ jl_array_t *jl_ptr_to_array(jl_value_t *atype, void *data, jl_tuple_t *dims,
return a;
}

jl_array_t *jl_slice_owned_array(jl_value_t *atype, jl_array_t *data, jl_tuple_t *dims, size_t offset)
{
size_t i;
jl_array_t *a;
size_t ndims = jl_tuple_len(dims);

int ndimwords = jl_array_ndimwords(ndims);
a = (jl_array_t*)allocobj((sizeof(jl_array_t) + sizeof(void*) + ndimwords*sizeof(size_t) + 15)&-16);
a->type = atype;
a->ndims = ndims;
a->offset = 0;
a->data = NULL;
a->isaligned = data->isaligned;
jl_value_t *el_type = jl_tparam0(atype);
if (store_unboxed(el_type)) {
a->elsize = jl_datatype_size(el_type);
a->ptrarray = 0;
}
else {
a->elsize = sizeof(void*);
a->ptrarray = 1;
}
JL_GC_PUSH1(&a);

jl_array_data_owner(a) = (jl_value_t*)data;
a->how = 3;
a->data = (data->data) + offset*(a->elsize);
a->isshared = 1;
data->isshared = 1;

if (ndims == 1) {
size_t l = jl_unbox_long(jl_tupleref(dims,0));
#ifdef STORE_ARRAY_LEN
a->length = l;
#endif
a->nrows = l;
a->maxsize = l;
}
else {
size_t *adims = &a->nrows;
size_t l=1;
wideint_t prod;
for(i=0; i < ndims; i++) {
adims[i] = jl_unbox_long(jl_tupleref(dims, i));
prod = (wideint_t)l * (wideint_t)adims[i];
if (prod > (wideint_t) MAXINTVAL)
jl_error("invalid Array dimensions");
l = prod;
}
#ifdef STORE_ARRAY_LEN
a->length = l;
#endif
}
JL_GC_POP();

return a;
}

jl_array_t *jl_new_array(jl_value_t *atype, jl_tuple_t *dims)
{
size_t ndims = jl_tuple_len(dims);
Expand Down
2 changes: 2 additions & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,8 @@ DLLEXPORT jl_array_t *jl_ptr_to_array_1d(jl_value_t *atype, void *data,
size_t nel, int own_buffer);
DLLEXPORT jl_array_t *jl_ptr_to_array(jl_value_t *atype, void *data,
jl_tuple_t *dims, int own_buffer);
DLLEXPORT jl_array_t *jl_slice_owned_array(jl_value_t *atype, jl_array_t *data,
jl_tuple_t *dims, size_t offset);
int jl_array_store_unboxed(jl_value_t *el_type);

DLLEXPORT jl_array_t *jl_alloc_array_1d(jl_value_t *atype, size_t nr);
Expand Down
17 changes: 17 additions & 0 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,23 @@ begin
@test size(n1) == (6,1,4) && size(n2) == (6,3,1) && size(n3) == (2,6,1)
end

# arrayslice
x = rand(3,5)
y = arrayslice(x,7,(3,3))
y[:] *= 5
x[7:end] = y[:]*2
@test reshape(x[7:end],(3,3)) == y
y = arrayslice(x,1,4)
@test Array{eltype(x),1} == typeof(y)
@test length(y) == 4
y = arrayslice(x,1,0)
@test y == eltype(y)[]
y = arrayslice(x,(1,3),2)
@test y[1] == x[1,3]
y = arrayslice(x,(3,1),(1,2))
@test y[:] == x[3:4]
y = arrayslice(x,1,(5,3))
@test reshape(x,(5,3)) == y

# single multidimensional index
let
Expand Down

0 comments on commit 949bd78

Please sign in to comment.