2014-04-12 2 views
0

나는 도움이 필요한 Cuda의 Monte Carlo 단계가있다. 나는 이미 시리얼 코드를 썼고, 예상대로 작동한다. 256 개의 입자가 저장되어 있다고 가정 해 봅시다.Cuda의 몬테 카를로 스윕

vector< vector<double> > *r; 

각 i의 r은 (x, y) 성분이 모두 double입니다. 여기서 r은 입자의 위치입니다.

이제 CUDA에서이 벡터를 Host에 할당하고 Device로 보냅니다. 일단 장치 안에 있으면,이 입자들은 서로 상호 작용할 필요가 있습니다. 각 스레드는 Monte Carlo Sweep을 실행해야합니다. cudaMalloc을 사용하여 메모리, 참조/참조 해제 포인터를 할당하려면 어떻게해야합니까? global/shared, ...--- 나는 그것으로 머리를 감쌀 수 없습니다.

여기에 내 메모리 할당이 순간에 모습이다 ::

cudaMalloc((void**)&r, (blocks*threads)*sizeof(double));  
CUDAErrorCheck(); 
kernel <<<blocks, threads>>> (&r, randomnums); 
cudaDeviceSynchronize(); 
CUDAErrorCheck(); 
cudaMemcpy(r, blocks*threads*sizeof(double), cudaMemcpyDeviceToHost); 

위의 코드는 감자 수준이다. 나는 무엇을해야할지 잘 모르겠다. 심지어 개념적으로. 내 주요 문제는 메모리를 할당하고 장치 & 호스트에서 정보를 전달하는 것입니다. 벡터 r을 할당하고, 호스트에서 장치로 복사하고, 장치에서이를 수행하고, 호스트로 다시 복사해야합니다. 어떤 도움이나 "포인터"라도 크게 감사 할 것입니다.

+0

당신이하고자하는 것을 우리에게 말하지 않을 때 무엇을해야 할지를 말하는 것은 매우 어렵습니다. 명시된 바와 같이, 나는 귀하의 게시물이 답할 수 있다고 생각하지 않습니다. 순차적 코드를 CUDA로 번역하고 시험판에 질문을 올리려고 노력하십시오. – JackOLantern

+0

내 주요 문제는 메모리를 할당하고 장치 및 호스트간에 정보를 전달하는 데 있습니다. 벡터 r을 할당하고, 호스트에서 장치로 복사하고, 장치에서이를 수행하고, 호스트로 다시 복사해야합니다. 나는 그것이 단지 몇 줄에 불과하다는 것을 알고 있지만, 그것을 시도하는 데 수십 번 실패했고 나는 단지 길을 잃었습니다. – Krishna

답변

2

귀하의 "감자 수준"코드는 r 데이터의 관리를 포함하되 이에 국한되지 않는 CUDA에 대한 전반적인 이해가 부족함을 보여줍니다. 사용 가능한 교육 자료를 활용하여 CUDA에 대한 지식을 늘리고 적어도 vector add sample과 같은 하나 이상의 기본 CUDA 코드에 대한 이해를 발전 시키길 제안합니다. 그러면 질문을 구성하고받는 응답을 이해하는 것이 훨씬 더 쉬워 질 것입니다. 예 :

이하지 않습니다 거의 결코 의미 :

cudaMalloc((void**)&r, (blocks*threads)*sizeof(double));  
    CUDAErrorCheck(); 
    kernel <<<blocks, threads>>> (&r, randomnums); 

그것이 사용할 수 있습니다 전에 하나가 데이터 (cudaMemcpy를 통해) 장치로 전송되어야한다는 아주 기본적인 개념을 모르는 GPU 커널을 사용하거나 전혀 이해할 수없는 "감자 수준"코드를 작성하는 데 신경 쓰지 않아도됩니다. 이는 합리적인 질문을 작성할 때 노력이 부족하다는 것을 의미합니다. 또한 r이 무엇이든 상관없이 &r을 cuda 커널에 전달하는 것이 결코 의미가 없을 것이라고 생각하지 않습니다. 앞뒤로 r을 이동하는 방법에 대한 질문에 대해서는

:

  1. GPU를 커널에서 쉽게 사용할 수있는 무언가로 r 위치 데이터를 개주하는 것입니다 문제를 해결하는 첫 번째 단계. 일반적으로 vector은 일반적인 CUDA 코드에는 유용하지 않고 vector< vector< > >은 그다지 유용하지 않습니다. 그리고 포인터가 주위에 떠있는 경우 (*r) 훨씬 적습니다.

    #define N 1000 
    ... 
    vector< vector<double> > r(N); 
    ... 
    double *pos_x_h, *pos_y_h, *pos_x_d, *pos_y_d; 
    pos_x_h=(double *)malloc(N*sizeof(double)); 
    pos_y_h=(double *)malloc(N*sizeof(double)); 
    for (int i = 0; i<N; i++){ 
        vector<double> temp = r[i]; 
        pos_x_h[i] = temp[0]; 
        pos_y_h[i] = temp[1];} 
    
  2. 지금 당신이 장치의 데이터 공간을 할당하고 장치에 데이터를 복사 할 수 있습니다 :

    따라서, double 중 하나 또는 두 개의 동적으로 할당 된 1 차원 배열로 (사본) 당신의 위치 데이터를 평평 이제
    cudaMalloc(&pos_x_d, N*sizeof(double)); 
    cudaMalloc(&pos_y_d, N*sizeof(double)); 
    cudaMemcpy(pos_x_d, pos_x_h, N*sizeof(double), cudaMemcpyHostToDevice); 
    cudaMemcpy(pos_y_d, pos_y_h, N*sizeof(double), cudaMemcpyHostToDevice); 
    
  3. 제대로 커널에 위치 데이터를 전달할 수 있습니다

    kernel<<<blocks, threads>>>(pos_x_d, pos_y_d, ...); 
    
  4. 데이터를 다시 복사 커널이 위 단계의 역순으로 약 이 될 것입니다. 이것은 당신이 시작하는 것입니다 :

    cudaMemcpy(pos_x_h, pos_x_d, N*sizeof(double), cudaMemcpyDeviceToHost); 
    cudaMemcpy(pos_y_h, pos_y_d, N*sizeof(double), cudaMemcpyDeviceToHost); 
    

물론, 고양이를 피부하는 방법에는 여러 가지가있다, 위에서 단지 예입니다. 그러나 위의 데이터 구성은 하나의 스레드가 하나의 프로세스를 처리하도록 할당하는 커널/스레드 전략에 적합합니다. (x,y) 위치 쌍.

+0

자세한 답변을 보내 주셔서 감사합니다. 언급했듯이 저는 CUDA에서 n00b입니다. 배열을 평평하게하고 거기에서 나가야 할 것처럼 보입니다. 배열을 평평하게하는 위의 코드는 에러를 발생시킵니다. 위치 벡터의 유형이 벡터 <벡터 >이기 때문일 수 있습니다. – Krishna

+0

필자는 대답을 게시하기 전에'vector > '을 올바르게 풀 었는지 확인하기 위해 간단한 테스트 케이스를 만들었습니다. 그것은 [여기] (http://pastebin.com/8mYgUHmR), 나는 그것으로 어떤 문제를 보지 못했어요. –

+0

오류의 원인을 찾지 못하는 것 같습니다. [여기] (http://pastebin.com/M2Sugxst)를 확인하고 잘못된 것이 있는지 확인하면 좋을 것입니다. – Krishna

관련 문제