2017-04-21 1 views
3

두 개의 배열이 같은 메모리 블록을 가리키는 지 어떻게 테스트합니까? 예를 들어,이 같이 작동 할 함수 foo 싶습니다 내가 reinterpret(Float64,ar) === a을 테스트 한두 배열이 같은 메모리 블록을 공유하는지 테스트하는 방법은 무엇입니까?

a = rand(10) # Float64 array with 10 elements 
b = copy(a) # b == a is true, but b === a is false 
ar = reinterpret(Float32,a) 
foo(ar,a) # I'd like this to return true 
foo(reinterpret(Float64,ar),b) # I'd like this to return false, even if reinterpret(Float64,ar) == b 

을하지만 false를 반환합니다.

서브 어레이의 경우 parent(subofA) === A을 통해 이루어지며 true을 반환합니다. 그러나 재 해석 된 배열에 대해서도 같은 결과가 나올 수 있습니다.

답변

7

reinterpret은 동일한 메모리 블록의 타입 해석 만 변경하므로 해결 방법은 포인터를 비교하는 것입니다 : foo(x,y) = pointer(x) == pointer(y).

4

약간 더 강력한 솔루션입니다 :

data_id(A::StridedArray) = A === parent(A) ? UInt(pointer(A)) : data_id(parent(A)) 
data_id(A::AbstractArray) = A === parent(A) ? object_id(A) : data_id(parent(A)) 
might_share_data(A, B) = data_id(A) == data_id(B) 

이 여전히 Array을 비교하기 위해 포인터를 사용하지만, 그것은 또한 첫 번째 요소는 오프셋 하위 어레이를 처리합니다. 그냥 거짓 네거티브가 될 pointer의 비교 반면

julia> A = rand(3,4) 
     B = view(A, 2:3, 2:3); 

julia> pointer(A) == pointer(B) 
false 

julia> might_share_data(A, B) 
true 

,이 방법은 몇 가지 가양있을 것이다. 이 접근법은 어레이 유형에도 적용됩니다. 일부 배열은 포인터를 구현하지 않으므로 사용하려고하면 오류가 발생합니다.

julia> C = view(A, [2,3], [2,3]); 

julia> pointer(C) 
ERROR: conversion to pointer not defined for SubArray{Float64,2,Array{Float64,2},Tuple{Array{Int64,1},Array{Int64,1}},false} 
in pointer(::SubArray{Float64,2,Array{Float64,2},Tuple{Array{Int64,1},Array{Int64,1}},false}) at ./abstractarray.jl:736 

julia> might_share_data(A, C) 
true 
+2

이렇게 복잡하기 때문에 실제로이 작업을 수행해야합니다. – StefanKarpinski