2013-04-18 8 views
2

장치에 할당 할 클래스를 만들려고합니다. 생성자를 장치에서 실행하여 필드를 포함하여 전체 개체가 호스트 개체를 만들지 않고 장치에 자동으로 할당되도록 한 다음 장치에 수동으로 복사해야합니다.장치에 필드가있는 개체를 직접 만듭니다.

내가 추력을 사용하고있어 device_new 여기

내 코드입니다 : 내가 __device__와 생성자를 주석과 device_new (추력)을 사용하지만,이 누군가에게 설명 할 수있는 작동하지 않습니다
using namespace thrust; 

class Particle 
{ 
    public: 
    int* data; 

    __device__ Particle() 
    { 
     data = new int[10]; 
     for (int i=0; i<10; i++) 
     { 
      data[i] = i*2; 
     } 
    } 
}; 


__global__ void test(Particle* p) 
{ 
    for (int i=0; i<10; i++) 
     printf("%d\n", p->data[i]); 
} 

int main() { 

    device_ptr<Particle> p = device_new<Particle>(); 

    test<<<1,1>>>(thrust::raw_pointer_cast(p)); 


    cudaDeviceSynchronize(); 

    printf("Done!\n"); 

} 

나 왜? 도움

+0

"작동하지 않음"은 문제에 대한 올바른 설명이 아닙니다. 문제가 무엇인지 정확하게 설명하십시오. – talonmies

+0

커널이 아무 것도 인쇄하지 않습니다. –

+0

이 코드에는 * no * 오류 검사가 없습니다. 몇 가지 방법을 추가하여 시작하십시오 (방법은 [이 질문] (http://stackoverflow.com/q/14038589/681865) 참조). 그러면 무엇이 실패했는지 자세히 알 수 있습니다. – talonmies

답변

4

에 대한

건배 나는 대답은 here 주어진 설명에있다 생각합니다. 후드 아래에서 추진력을 아는 사람은 아마도 이것이 사실인지 그렇지 않은지를 나타낼 것입니다.

2009 년 이후 추력이 많이 바뀌었지만, device_new은 개체가 실제로 호스트에서 일시적으로 인스턴스화 된 다음 장치에 복사되는 동작 형식을 계속 사용할 수 있다고 생각합니다. 그러나 위 참조에 설명 된 크기 제한이 더 이상 적용되지 않습니다.

나는 일이를 얻을 수있었습니다 : 내가 생성자에 __host__ 장식을 생략하면

#include <stdio.h> 
#include <thrust/device_ptr.h> 
#include <thrust/device_new.h> 

#define N 512 

using namespace thrust; 

class Particle 
{ 
    public: 
    int data[N]; 

    __device__ __host__ Particle() 
    { 
//  data = new int[10]; 
     for (int i=0; i<N; i++) 
     { 
      data[i] = i*2; 
     } 
    } 
}; 


__global__ void test(Particle* p) 
{ 
    for (int i=0; i<N; i++) 
     printf("%d\n", p->data[i]); 
} 

int main() { 

    device_ptr<Particle> p = device_new<Particle>(); 

    test<<<1,1>>>(thrust::raw_pointer_cast(p)); 


    cudaDeviceSynchronize(); 

    printf("Done!\n"); 

} 

흥미롭게도, 그것은 임시 객체 복사 메커니즘이 자리에 여전히 나에게 제안, 가짜 결과를 제공합니다. 정적 인 대신 data에 대한 동적 할당을 사용하면 device_new이 호스트에서 임시 객체 생성을 사용하고 있음을 나에게 제안하면서 가짜 결과 (및 cuda-memcheck가 범위 밖의 액세스 오류를보고 함)를 제공합니다. 장치에 사본. 자신의 입력 (이전 답변) 그래서 분명히 내가 device_new이 할 수있는 일 "과대 평가"

에 대한 Rovert Crovella에 대한 모든 감사의

+0

예, 당신이 옳다고 생각합니다. 호스트의 객체를 수동으로 초기화 한 다음 (이전 질문에 대한 대답 에서처럼) 장치에 복사하는 것과 같은 방법으로 생각합니다. 그래서 분명히 동적으로 할당 된 필드를 수동으로 복사해야합니다 (다시 이전 질문에 대한 답을 보여주었습니다). 추력은 더 "지능적"이고 장치에 직접 객체를 초기화 할 수 있으므로 내부에 동적으로 할당 된 모든 요소가 장치에있게됩니다. –

+0

나는 당신의 방법이 작동하는 이유는 그것이 정적으로 할당되었을 때, 객체와 함께 장치에 복사되기 때문에 수동으로 그것을 테스트해야하기 때문이다. 나는 다시보고 할 것이다. –

+0

예, 정적 할당에서는 전체'data' 배열이 객체의 일부입니다. 동적 할당을 사용하면 'data'포인터 만 객체의 일부로 취급됩니다. –

0

첫째, 나는 그렇게 어떤 동적 장치에 직접 객체를 초기화 할 수 있다고 생각 할당 된 메모리 내부도 장치에서 수행됩니다.

는하지만 device_new은 기본적으로 그냥 수동 방법으로 같은 일처럼 보인다

Particle temp; 
Particle *d_p; 
cudaMalloc(&d_p, sizeof(Particle)); 
cudaMemcpy(d_p, &temp, sizeof(Particle), cudaMemcpyHostToDevice); 

그래서 그냥 수동으로 수행 할 수 얼마나 같은 임시 호스트 객체 복사를한다. 즉, 객체 내부에 할당 된 메모리가 호스트에 할당되고 포인터 만 객체의 일부로 복사되므로 커널에서 해당 메모리를 사용할 수 없으므로 수동으로 해당 메모리를 디바이스에 복사하고 밀어 넣지 않아야합니다 그 일을하는 것처럼 보입니다.

임시 호스트 개체를 만들고 복사하는 것보다 깔끔한 방법입니다. 단, 임시 변수에 액세스 할 수 없기 때문에 내부에 할당 된 동적 메모리를 복사 할 수있는 능력을 잃을 수 있습니다.

장래에 장치에서 개체를 직접 초기화 할 수있는 CUDA의 메서드 또는 기능이 있으므로 생성자 (또는 다른 곳)에 동적으로 할당 된 데이터가 장치에 할당됩니다. 모든 메모리 조각을 수동으로 복사하는 지루한 방법 중 하나입니다.

관련 문제