Thanks, I will try and figure out if I can work this out from your suggestions.
On Tuesday, October 27, 2015 at 8:29:07 AM UTC-6, Yichao Yu wrote: > > On Tue, Oct 27, 2015 at 10:08 AM, Taylor Maxwell > <taylor....@gmail.com <javascript:>> 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! >