2011-07-06 6 views
2

일부 계산을 위해 openCL을 사용하려고했지만 결과가 잘못되었습니다.잘못된 계산을 생성하는 OpenCL

I 입력 세 float3 같이의 :이 커널에

[300000,0,0] 
[300000,300000,0] 
[300000,300000,300000] 

:

__kernel void gravitate(__global const float3 *position,__global const float3 *momentum,__global const float3 *mass,__global float3 *newPosition,__global float3 *newMomentum,unsigned int numBodies,unsigned int seconds) 
{ 
    int gid=get_global_id(0); 

    newPosition[gid]=position[gid]*2; 
    newMomentum[gid]=momentum[gid]*2; 
} 

내가 원래 커널이 왜 몸 그룹의 중력 상호 작용을 시뮬레이션하려고했다 그런 것 같습니다. OUPUT를 들어

내가 얻을 : x는 0 ~ 10^-44에 NaN의 범위와 커널이 실행될 때마다 다른 값입니다

[600000.0,0.0,0.0] 
[x,600000.0,0.0] 
[600000.0,x,600000.0] 

. newPosition과 newMomentum은 모두 잘못된 출력 패턴을가집니다. 나는이 같은 모습을 사용하고

파이썬 코드 :

def __init__(self): 
     self.context=cl.create_some_context() 
     self.queue=cl.CommandQueue(self.context) 

     f=open("gravitate.cl") 
     self.program=cl.Program(self.context,f.read()).build() 

def simulate(self,seconds): 
     bodyPosition=[] 
     bodyMomentum=[] 
     bodyMass=[] 

     for body in self.objects: 
      bodyPosition+=[body.position.x,body.position.y,body.position.z] 
      bodyMomentum+=[body.momentum.x,body.momentum.y,body.momentum.z] 
      bodyMass+=[body.mass] 

     bodyPosition=numpy.array(bodyPosition).astype(numpy.float32) 
     bodyMomentum=numpy.array(bodyMomentum).astype(numpy.float32) 
     bodyMass=numpy.array(bodyMass).astype(numpy.float32) 

     bodyPositionCl=cl.Buffer(self.context,cl.mem_flags.READ_ONLY|cl.mem_flags.COPY_HOST_PTR,hostbuf=bodyPosition) 
     bodyMomentumCl=cl.Buffer(self.context,cl.mem_flags.READ_ONLY|cl.mem_flags.COPY_HOST_PTR,hostbuf=bodyMomentum) 
     bodyMassCl=cl.Buffer(self.context,cl.mem_flags.READ_ONLY|cl.mem_flags.COPY_HOST_PTR,hostbuf=bodyMass) 

     newBodyPosition=numpy.zeros(len(self.objects)*3).astype(numpy.float32) 
     newBodyMomentum=numpy.zeros(len(self.objects)*3).astype(numpy.float32) 

     newBodyPositionCl=cl.Buffer(self.context,cl.mem_flags.WRITE_ONLY,newBodyPosition.nbytes) 
     newBodyMomentumCl=cl.Buffer(self.context,cl.mem_flags.WRITE_ONLY,newBodyMomentum.nbytes) 

     self.program.gravitate(self.queue,(3,),None,bodyPositionCl,bodyMomentumCl,bodyMassCl,newBodyPositionCl,newBodyMomentumCl,numpy.uint32(len(self.objects)),numpy.uint32(seconds)) 
     cl.enqueue_read_buffer(self.queue,newBodyPositionCl,newBodyPosition).wait() 
     cl.enqueue_read_buffer(self.queue,newBodyMomentumCl,newBodyMomentum).wait() 

답변

6

float3는 16 바이트로 정렬됩니다. OpenCL 1.1 사양, 6.1.5를 참조하십시오.