예제 #1
0
void Grid::step(float dt)
{
	glFinish();
	
	try
	{
		queue.enqueueWriteBuffer(clSolid[demo], CL_TRUE, 0, num*sizeof(char), &(solid[demo])[0], NULL, &event);
		queue.finish();
	}
	catch(cl::Error e)
	{
		cluErr("Grid: step: GLO", e);
	}
	
	//Set varyable arguments, primarily lattice
	clStream.setArg(0, clLattice[!odd]);
	clStream.setArg(1, clLattice[odd]);
	clStream.setArg(4, dt);
	
	clCollide.setArg(0, clLattice[odd]);
	
	clHWrap.setArg(0, clLattice[odd]);
	clVWrap.setArg(0, clLattice[odd]);
	
	clSolidBB.setArg(0, clLattice[odd]);
	clSolidBB.setArg(1, clSolid[demo]);
	
	clInflow.setArg(0, clLattice[odd]);
	
	
	try
	{
		//Kernels enqueued
		queue.enqueueNDRangeKernel(clStream, cl::NullRange,
		 cl::NDRange(width, height), cl::NullRange, NULL, &event);
		if(hWrap)
		 queue.enqueueNDRangeKernel(clHWrap, cl::NullRange,
		  cl::NDRange(height), cl::NullRange, NULL, &event);
		if(vWrap)
		 queue.enqueueNDRangeKernel(clVWrap, cl::NullRange,
		  cl::NDRange(width), cl::NullRange, NULL, &event);
		queue.enqueueNDRangeKernel(clSolidBB, cl::NullRange,
		 cl::NDRange(width, height), cl::NullRange, NULL, &event);
		
		// non functional inflow kernel disabled
		//queue.enqueueNDRangeKernel(clInflow, cl::NullRange,
		// cl::NDRange(height), cl::NullRange, NULL, &event);
		queue.enqueueNDRangeKernel(clCollide, cl::NullRange,
		 cl::NDRange(width, height), cl::NullRange, NULL, &event);
		queue.finish();
	}
	catch(cl::Error e)
	{
		cluErr("Grid: step: NDR", e);
	}
	
	//Lattice address swapped
	odd = !odd;
}
예제 #2
0
Lbm::Lbm(cl::Platform platform, cl::Device device, std::vector<std::string> kernels)
{
  cl_context_properties cProps[] = {
    CL_CONTEXT_PLATFORM, (cl_context_properties)(platform)(),
    0};

  try
  {
    context = cl::Context(CL_DEVICE_TYPE_ALL, cProps, errorCallbackCL);
    queue = cl::CommandQueue(context, device);
  }
  catch(cl::Error e)
  {
    cluErr("Sim", e);
  }

  std::vector<std::string> sourceStr;
  for(auto it = kernels.begin(); it != kernels.end(); ++it)
  {
    std::ifstream file(it->c_str());
    if(!file.good())
     std::cerr<<"Sim: Kernel: file not good"<<std::endl;
    sourceStr.push_back(std::string((std::istreambuf_iterator<char>(file)),
     std::istreambuf_iterator<char>()));
  }

  try
  {
    cl::Program::Sources source = cl::Program::Sources();

    for(auto it = sourceStr.begin(); it != sourceStr.end(); ++it)
      source.push_back(std::make_pair(it->c_str(), it->size()));

    program = cl::Program(context, source);
  }
  catch(cl::Error e)
  {
    cluErr("Sim: program", e);
  }

  createKernels(device, kernels);
  initData();
}
예제 #3
0
void Lbm::createKernels(cl::Device device, std::vector<std::string> kernels)
{

  std::vector<std::string> sourceStr;
  for(auto it = kernels.begin(); it != kernels.end(); ++it)
  {
    std::ifstream file(it->c_str());
    if(!file.good())
     std::cerr<<"Sim: Kernel: file not good"<<std::endl;
    sourceStr.push_back(std::string((std::istreambuf_iterator<char>(file)),
     std::istreambuf_iterator<char>()));
  }

  try
  {
    cl::Program::Sources source = cl::Program::Sources();

    for(auto it = sourceStr.begin(); it != sourceStr.end(); ++it)
      source.push_back(std::make_pair(it->c_str(), it->size()));

    program = cl::Program(context, source);
  }
  catch(cl::Error e)
  {
    cluErr("Sim: program", e);
  }

  try
  {
    program.build(std::vector<cl::Device>{device});
  }
  catch(cl::Error e)
  {
    std::cout<<"Log: "<<program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(device, NULL)<<std::endl;
    cluErr("Sim: Program", e);
  }
}
예제 #4
0
void Grid::render()
{
	
	clRender.setArg(1, clSolid[demo]);
	try
	{
		queue.enqueueWriteBuffer(clSolid[demo], CL_TRUE, 0, num*sizeof(char), &(solid[demo])[0], NULL, &event);
		queue.enqueueAcquireGLObjects(&clVBOs, NULL, &event);
		queue.enqueueNDRangeKernel(clRender, cl::NullRange,
		 cl::NDRange(width, height), cl::NullRange, NULL, &event);
		queue.enqueueReleaseGLObjects(&clVBOs, NULL, &event);
		queue.finish();
	}
	catch(cl::Error e)
	{
		cluErr("Grid: step: RGLO", e);
	}
	
	//Renderbuffer blitted to main display
	glBlitFramebuffer(
	 width, height, 0, 0,
	 winWidth, winHeight, 0, 0,
	 GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
예제 #5
0
void Grid::initData()
{
	D = 2, Q = 9;
	demo = 0;
	//Input horizontal velocity
	vx = Settings::root["vx"].asFloat();
	//Input vertical velocity
	vy = Settings::root["vy"].asFloat();
	//Input density ρ = rho
	rho = Settings::root["rho"].asFloat();
	//Relaxation time τ = tau
	tau = Settings::root["tau"].asFloat();
	
	//Wrapping
	hWrap = Settings::root["wrap"]["horizontal"].asBool();
	vWrap = Settings::root["wrap"]["vertical"].asBool();
	
	lattice.resize(Q*num);
	solid.resize(2);
	for(int i=0; i<solid.size(); ++i)
	 solid[i].resize(num);
	
	float w0 = 4.f/9.f;
	float w1 = 1.f/9.f;
	float w2 = 1.f/36.f;
	
	float vSq = 1.5f*(vx*vx+vy*vy);
	
	//Fill lattice with equilibrium velocities
	for(int i=0; i<num; ++i)
	{
		int j=i*Q;
		lattice[j]	 = w0*rho*(1.f																			-vSq);
		lattice[j+1] = w1*rho*(1.f+3.f*vx				+4.5f*vx*vx							-vSq);
		lattice[j+2] = w1*rho*(1.f+3.f*vy				+4.5f*vy*vy							-vSq);
		lattice[j+3] = w1*rho*(1.f-3.f*vx				+4.5f*vx*vx							-vSq);
		lattice[j+4] = w1*rho*(1.f-3.f*vy				+4.5f*vy*vy							-vSq);
		lattice[j+5] = w2*rho*(1.f+3.f*( vx+vy)	+4.5f*( vx+vy)*( vx+vy)	-vSq);
		lattice[j+6] = w2*rho*(1.f+3.f*(-vx+vy)	+4.5f*(-vx+vy)*(-vx+vy)	-vSq);
		lattice[j+7] = w2*rho*(1.f+3.f*(-vx-vy)	+4.5f*(-vx-vy)*(-vx-vy)	-vSq);
		lattice[j+8] = w2*rho*(1.f+3.f*( vx-vy)	+4.5f*( vx-vy)*( vx-vy)	-vSq);
		solid[0][i] = false;
		solid[1][i] = true;
	}
	
	
	
	lSize = Q*num*sizeof(float);
	size_t size = num*sizeof(float);
	
	//create renderbuffer
	glGenRenderbuffers(1, &rendBuff);
	glBindRenderbuffer(GL_RENDERBUFFER, rendBuff);
	glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, width, height);
	
	glGenFramebuffers(1, &frameBuff);
	glBindFramebuffer(GL_FRAMEBUFFER, frameBuff);
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rendBuff);
	
	//Check renderbuffer completeness
	GLenum hey = glCheckFramebufferStatus(GL_FRAMEBUFFER);
	std::cout<<"Framebuffer:";
	switch(hey)
	{
		case GL_FRAMEBUFFER_COMPLETE:												std::cout<<"complete"; break;
		case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:					std::cout<<"incomplete attachment"; break;
		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:	std::cout<<"incomplete missing attachment"; break;
		case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:					std::cout<<"incomplete draw buffer"; break;
		default:																						std::cout<<"unknown"; break;
	}
	std::cout<<std::endl;
	glFinish();
	
	//Create OpenCL memory pointer for renderbuffer
	clVBOs.push_back(cl::BufferRenderGL(context, CL_MEM_READ_WRITE, rendBuff));
	
	clLattice.push_back(cl::Buffer(context, CL_MEM_WRITE_ONLY, lSize));
	clLattice.push_back(cl::Buffer(context, CL_MEM_WRITE_ONLY, lSize));
	clVelMag = cl::Buffer(context, CL_MEM_WRITE_ONLY, size);
	for(int i=0; i<solid.size(); ++i)
	 clSolid.push_back(cl::Buffer(context, CL_MEM_WRITE_ONLY, num*sizeof(char)));
	
	try
	{
		//Lattice can be copied to both memory locations for debugging
		//queue.enqueueWriteBuffer(clLattice[0], CL_TRUE, 0, lSize, &lattice[0], NULL, &event);
		queue.enqueueWriteBuffer(clLattice[1], CL_TRUE, 0, lSize, &lattice[0], NULL, &event);
		for(int i=0; i<solid.size(); i++)
		 queue.enqueueWriteBuffer(clSolid[i], CL_TRUE, 0, num*sizeof(char), &(solid[i])[0], NULL, &event);
		queue.finish();
	}
	catch(cl::Error e)
	{
		cluErr("Grid: initData", e);
	}
	
	//init kernels
	try
	{
		
		clStream = cl::Kernel(program, "stream");
		clHWrap = cl::Kernel(program, "hWrap");
		clVWrap = cl::Kernel(program, "vWrap");
		clSolidBB = cl::Kernel(program, "solidBB");
		clInflow = cl::Kernel(program, "inflow");
		clCollide = cl::Kernel(program, "collide");
		clRender = cl::Kernel(program, "render");
		
	}
	catch(cl::Error e)
	{
		cluErr("Grid: initData", e);
	}
	
	try
	{
		//Set constant arguments for each kernel
		clStream.setArg(2, width);
		clStream.setArg(3, height);
		
		clHWrap.setArg(1, width);
		clHWrap.setArg(2, height);
		clVWrap.setArg(1, width);
		clVWrap.setArg(2, height);
		
		clSolidBB.setArg(2, width);
		
		clInflow.setArg(1, vx);
		clInflow.setArg(2, vy);
		clInflow.setArg(3, rho);
		clInflow.setArg(4, width);
		
		clCollide.setArg(1, clVelMag);
		clCollide.setArg(2, width);
		clCollide.setArg(3, tau);
		
		clRender.setArg(0, clVelMag);
		clRender.setArg(2, width);
		clRender.setArg(3, height);
		clRender.setArg(4, vx);
		clRender.setArg(5, vy);
		clRender.setArg(6, clVBOs[0]);
		
		queue.finish();
	}
	catch(cl::Error e)
	{
		cluErr("Grid: initData", e);
	}
	
	//Set framebuffer addressing for blitting at the end of rendering
	glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBuff);
	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}