On Tue, Oct 27, 2015 at 10:08 AM, Taylor Maxwell
<[email protected]> wrote:
> Thanks for your response. It looks like pointer(::Array) gives me the same
> pointer as if I defined the base.convert call from 0.3.
>
> I am not passing it to a ccall. Below is an example of what i am doing.
> The bedfreq function gets the genotype and missing counts (4 possibilities
> encoded in every 2 bits) where b is the UInt8 matrix and ns is the number of
> individuals (this helps me figure out how far to go for each locus. The pj
> variable within the function moves the pointer to the beginning of each
> column (each locus). The ival function used to pull out the genotype or
> missing call for each subject which is then added up in the cc matrix.
I didn't look at the code close enough to rewrite the code myself but
it seems like you could just pass the column number to ival instead.
You could also construct a sub array for the column.
This also avod some undefined behavior since the GC/codegen might get
smarter and figure out that you are not actually using the array
anymore after casting it to a pointer and free it while you are still
using the pointer.
>
> I read the garbage collection safety section in documentation and and only
> partially understand it. Once the b Uint8 Matrix is created, it will not be
> changed or deleted while the pointer is in use. From your knowledge of the
> the safe and unsafe uses of pointer to an array, is this ok (it worked
> perfectly fine in 0.3).
The separation of cconvert and unsafe_convert does not really matter
for this case. But in general, there are cases that the conversion
might allocate new buffers for the c function so you want to put that
part in cconvert and only do the unsafe take-pointer part in
unsafe_convert. I think we remove the convert method for converting to
Ptr because you almost never want that convertion to happen
automatically. (It's unsafe and you should be explicit if you want it,
by calling pointer() (which should also be unnecessary in most cases),
for example.
>
> ival(p::Ptr{UInt8},i::Integer) = i>0 ?
> (unsafe_load(p,(i-1)>>2+1)>>(2(i-1)&0x06))&0x03 : throw(DomainError)
>
> function bedfreq(b::Matrix{UInt8},ns::Integer)
> m,n = size(b)
> div(ns+3,4) == m || error("ns = $ns should be in [$(4m-3),$(4m)] for
> size(b) = $(size(b))")
hint, we have \div operator
> cc = zeros(Int, 4, n)
> bpt = convert(Ptr{UInt8},b)
> for j in 0:(n-1)
> pj = bpt + j*m
> ## the ival function is inlined explicitly
> for i in 1:ns cc[1+ival(pj,i),1+j] += 1 end
> end
> cc
> end
>
> Thanks!