2016-07-19 4 views
2

큰 매트릭스 data을 특정 방식으로 "구성"하고 싶습니다. 행렬에는 5 개의 열과 약 200 만 개의 행이 있습니다. 첫 번째 4 개 열은 각 관측치의 특성이며 (정수입니다) 마지막 열은 관심있는 결과 변수입니다 (여기에는 실수가 포함되어 있습니다). 이 배열을 배열 배열로 구성하려고합니다. 나는 루프가 완료되면병렬 처리 데이터 처리

Error: syntax: invalid assignment location 

: 나는 오류가 발생하지만 내가 for 루프를 실행하려고하면

addprocs(3) 

@everywhere data = readcsv("datalocation", Int) 

@everywhere const Z = 65 
@everywhere const z = 16 
@everywhere const Y = 16 
@everywhere const y = 10 

@everywhere const arr = Array{Vector}(Z-z+1,Y-y+1,Z-z+1,Y-y+1) 

@parallel (vcat) for a1 in z:Z, e1 in y:Y, a2 in z:Z, e2 in y:Y 
    arr[a1-z+1,e1-y+1,a2-z+1,e2-y+1] = data[(data[:,1].==a1) & (data[:,2].==e1) & (data[:,3].==a2) & (data[:,4].==e2), end] 
end 

: data이 매우 크기 때문에, 나는이 작업을 병렬화하기 위해 노력하고있어 모든 프로세서에서 arr을 사용하고 싶습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

편집 : 매트릭스 data이 (특별한 순서없이 행)과 같은 입력 :

16 10 16 10 100 
16 10 16 11 200 
20 12 21 13 500 
16 10 16 10 300 
20 12 21 13 500 

공지 사항 일부 행이 반복 될 수 있음을, 그리고 몇몇 다른 사람은 동일한 "키"하지만 다른이있을 것이다 다섯 번째 열.

내가 원하는 출력이 (처럼 보이는

나는 "사전"은 "키"로 arr의 크기를 사용하고 어떻게주의 사항 :

입니다
arr[16-z+1, 10-y+1, 16-z+1, 10-y+1] = [100, 300] 
arr[16-z+1, 10-y+1, 16-z+1, 11-y+1] = [200] 
arr[20-z+1, 12-y+1, 21-z+1, 13-y+1] = [500, 500] 

는, 인덱스 arr의 요소가 (16-z+1, 10-y+1, 16-z+1, 10-y+1)입니다 . 벡터 [100, 300] 나는 행의 순서 또는 벡터의 마지막 컬럼의 순서에 대해 걱정하지 않는다

+0

왜 (vcat)를 사용하고 있습니까? 그것은'arr [a1-z + 1, e1-y + 1, a2-z + 1, e2-y + 1]의 모든 것을 함께 모으 겠지만'arr'의 해결책은 아닙니다. 반환 값을 사용해야합니까? 이 작업을하기 위해'arr'을 공유 배열이나 분산 배열로 만들거나, 할당을 취소하고 루프에서 ar을 만들 필요가 있다고 생각합니다. –

+0

나는 당신의 질문을 오해한다는 것을 깨달았습니다. 나는 당신이 당신의 데이터를 근로자들 사이에 쪼개려고하고 있다고 생각했지만 실제로는 주 근로자를 사용하여 주 프로세스에서 데이터를 구성하는 것뿐입니다. –

+0

어쨌든 @michael은 큰 노력에 감사드립니다. – amrods

답변

1

이 기능이 유용합니까? 나는 당신이 1000 번 준 스 니펫을 반복하여 데이터를 시뮬레이션하려고 시도했다. 내가 원했던 것처럼 우아하지는 않았고 특히 @async으로 감싸는 경우에도 내가 원하는대로 작동하여 remotecall_fetch()을 얻을 수 없었기 때문에 두 단계로 호출과 페칭을 분할해야했습니다. 이게 어떻게 보이는지 알려주세요.

addprocs(n) 

@everywhere begin 
    if myid() != 1 
     multiplier = 10^3; 
     Data = readdlm("/path/to/Input.txt") 
     global data = kron(Data,ones(multiplier)); 
     println(size(data)) 
    end 
end 

@everywhere begin 
    function Select_Data(a1, e1, a2, e2, data=data) 
     return data[(data[:,1].==a1) & (data[:,2].==e1) & (data[:,3].==a2) & (data[:,4].==e2), end] 
    end 
end 

n_workers = nworkers() 
function next_pid(pid, n_workers) 
    if pid <= n_workers 
     return pid + 1 
    else 
     return 2 
    end 
end 

const arr = Array{Any}(Z-z+1,Y-y+1,Z-z+1,Y-y+1); 
println("Beginning Processing Work") 
@sync begin 
    pid = 2 
    for a1 in z:Z, e1 in y:Y, a2 in z:Z, e2 in y:Y 
     pid = next_pid(pid, n_workers) 
     arr[a1-z+1,e1-y+1,a2-z+1,e2-y+1] = remotecall(pid, Select_Data, a1, e1, a2, e2) 
    end 
end 
println("Retrieving Completed Jobs") 
@sync begin 
    pid = 2 
    for a1 in z:Z, e1 in y:Y, a2 in z:Z, e2 in y:Y 
     arr[a1-z+1,e1-y+1,a2-z+1,e2-y+1] = fetch(arr[a1-z+1,e1-y+1,a2-z+1,e2-y+1]) 
    end 
end 
+0

지금 실제 데이터로 시도 중입니다. 나는'remotecall'이'Vector'를 반환하지 않기 때문에'arr'은'Array {Any} '이되어야한다고 생각합니다. 이과 관련된 처벌이 있습니까? – amrods

+0

@ amrods 예,있을 수 있습니다. 그러나 나는 왜'remotecall_fetch()'를 사용하여 시도했을 때 한 프로세스에서만 작업이 이루어 졌는지 알 수 없었다. 어쩌면 크리스는 그면을 수정하는 방법에 대한 아이디어를 갖고있을 수도 있습니다. –

+1

@amrods 두 개의 배열을 사용할 수도 있습니다. 하나는 any 타입 인'arr1 '을위한 것이고,'arr2'는 여러분이 원하는 타입이고'arr1'을 가져 오는'arr2'입니다. 또한 최종 결과 (예 : 사용하고 있던 'vcat'에서 무슨 일이 일어나고 있는지)에서 정확히 원하는 부분이 확실하지 않았습니다. 그러나, 이것이 원리에서 작동한다면, 그것이 당신이 원하는 것을 정확하게하지 않더라도, 그것은 잘 적응할 수있을 것입니다. –

1

참고 :.. 내가 처음에 질문을 잘못 해석 난 당신이 데이터를 분할하려고했던 것을 생각했다 너의 일 사이에 ers,하지만 지금은 꽤 당신이 무엇을했는지는 알 수 없습니다. 나는 달성 할 수있는 방법의 몇 가지 간단한 예를 썼다. 나중에 누군가가 유용하다고 생각할 경우를 대비하여 응답으로 남겨 둘 것입니다.

은 시작하기 :

writedlm("path/to/data.csv", rand(100,10), ',') 
addprocs(4) 

옵션을 1 :

function sendto(p::Int; args...) 
    for (nm, val) in args 
     @spawnat(p, eval(Main, Expr(:(=), nm, val))) 
    end 
end 

Data = readcsv("/path/to/data.csv") 

for (idx, pid) in enumerate(workers()) 
    Start = (idx-1)*25 + 1 
    End = Start + 24 
    sendto(pid, Data = Data[Start:End,]) 
end 

옵션 2 :

@everywhere begin 
    if myid() != 1 
     Start = (myid()-2)*25 + 1 
     End = Start + 24 
     println(Start) 
     println(End) 
     Data = readcsv("path/to/data.csv")[Start:End,:] 
    end 
end 

# verify everything looks right for what got sent 
@everywhere if myid()!= 1 println(typeof(Data)) end 
@everywhere if myid()!= 1 println(size(Data)) end 

옵션 3 :

for (idx, pid) in enumerate(workers()) 
    Start = (idx-1)*25 + 1 
    End = Start + 24 
    sendto(pid, Start = Start, End = End) 
end 

@everywhere if myid()!= 1 Data = readcsv("path/to/data.csv")[Start:End,:] end 
+1

@ amrods. 조금 까다 롭지 만 그렇게 나쁘지는 않습니다. 나는 당신에게 시동기를주기 위해 몇 가지 예를 들고 업데이트했다. –