Tracing several rays from a closest hit program

Hello All,

I don’t know if it is possible, but I would like to trace 3 rays from a closest hit program depending on which object the initial ray is hitting. I mean, if the initial ray hits object A I would trace 3 new rays from the hiting point, if the initial ray hits any other object I would trace only one more ray. To avoid inifine tracing, I only allow this to happen two times controlling it with the payload (pay_load).

If I do it directly, the code works… But the payload that is sent in the rtTrace function is shared with the 3 throws, so it is changed after each call to rtTrace. If I try to create a new payload with the information of the original payload before trace each ray I get a crash in the nvidia display driver and when it recovers I caught one exception with this error string:
“Unknown error (Details: Function “_rtContextLaunch2D” caught exception: Encountered a CUDA error: driver().cuEventSynchronize(m_event) returned (702): Launch timeout, [6619195])”

Is it possible to do what I want to do? Maybe I’m doing something wrong…

The current configuration is CUDA 4.1, Optix SDK 2.5.0, Windows 7 64 bits, Visual Studio 2010 with a 32 bits project, and GTX 460 driver version 311.06.

My code looks like this:
rtDeclareVariable(float, t_hit, rtIntersectionDistance, );
rtDeclareVariable(PhotonPRD, hit_record, rtPayload, );

rtDeclareVariable(optix::Ray, ray, rtCurrentRay, );

RT_PROGRAM void ppass_closest_hit()
{
//compute the new ray direction
   float3 new_ray_dir = ...

//Compute the energy of the photon after the hit and store it in a optix::buffer connected to a vbo
   new_energy = ...
   storeInBuffer(new_energy);

//Determine the object hitted
   int object_hitted = ...;

//update the number of times that photon has hitten
   hit_record.num_deposits++;

//throw new rays
   if(object_hitted == A)
   {
      PhotonPRD prd;
      prd.energy = hit_record.energy;
      optix::ray new_ray1(hit_point, ray_dir, ppass_ray_type, scene_epsilon, 60.0)
      rtTrace(top_object, new_ray1, prd);

      PhotonPRD prd2;
      prd.energy = hit_record.energy * -1;
      optix::ray new_ray2(hit_point, ray_dir, ppass_ray_type, scene_epsilon, 60.0)
      rtTrace(top_object, new_ray2, prd2);

      PhotonPRD prd3;
      prd.energy = new_energy;
      optix::ray new_ray3(hit_point, new_ray_dir, ppass_ray_type, scene_epsilon, 60.0)
      rtTrace(top_object, new_ray3, prd3);
   }
   else
   {
       hit_record.energy = new_energy;
       optix::Ray new_ray( hit_point, new_ray_dir, ppass_ray_type, scene_epsilon, 60.0);
       rtTrace(top_object, new_ray, hit_record);
   }

}

Any idea?

Thanks!!!

Can you first verify that this isn’t just a timeout issue? There are a lot of posts about this here, for instance https://devtalk.nvidia.com/default/topic/759073/optix/display-driver-has-stopped-responding-and-has-recovered/.

Hello, thanks to reply so fast.

I have implemented a very simple callback:

static int timeout_callback(void) {
	int earlyexit = 0;
	float deltat, totalt;
	/*if (vmd_timeout_init == 0) 
	    vmd_timeout_reset();
		vmd_timeout_time(deltat, totalt);*/
	std::cout << "OptiX timeout callback" << std::endl; 
	return earlyexit; 
}

And i have set to the context before the launch:

try{
		_context->setTimeoutCallback(timeout_callback, 0.5);
		_context->launch( PROGRAM_PHOTON,
					   static_cast<unsigned int>(_numPhotons),
					   static_cast<unsigned int>(1) );
	} catch (optix::Exception e) {
		std::cout << _context->getErrorString(e.getErrorCode()) << std::endl;
	}

And now the output says this:
OptiX timeout callback
Unknown error (Details: Function “_rtContextLaunch2D” caught exception: Encountered a CUDA error: driver().cuEventSynchronice(m_event) returned (702): Launch timeout, [6619195])
ERROR: Unknown error (Details: Function “_rtBufferMap” caught exception: Encountered a CUDA error: driver().cuMemcpyDtoH(static_cast<char *>(dst) + dstOffset, src + srcOffset, bytes) returned (702): Launch timeout, [6750363])

I don’t know if I’m doing well with the callbacks…

The callback function itself looks fine. Your output seems to indicate that the callback was only called once. Is that correct? Windows TDR could still happen if an individual kernel thread runs for longer than 2 seconds, in which case, the callback function won’t have a chance to be called again before the timeout occurs. Try changing your TDR timeout in the windows registry to check if this is the case. If it is, you may want to break those three bounce rays into separate kernel calls to reduce the work per call.

Is the exception thrown by rtBufferMap happening after the code that you’ve pasted?

I don’t know it the callback is called only once, at least it only appears once in the std::out.

The exception by rtBufferMap doesn’t appear until i add the timeout callbacks.

I will try to change the TDR timeout, I have to look in the net how to do it…

Thaaaaaaaaaaaanks!

Finally I have changed the strategy. Instead generating rays depending the object hitted, now I generate three rays in the ray generator and for those which only affect some objects I ignore the rest.

The computation works now, but i get a windows TDR when I draw the results in a texture… I increased the TDR in the registry and now everyhting works!

Thank you very much!!!

Dear imanolooo!

I have read “but i get a windows TDR when I draw the results in a texture… I increased the TDR in the registry and now everyhting works!”.
Please inform what internet site helps you to increase TDR. I tried a pair of internet advices without success. Although my OS is Win 8.1 and yours - Win 7. Nevertheless, inform please.

Thank you!
sudak

I believe this is the definitive site: http://msdn.microsoft.com/en-us/library/windows/hardware/ff570088(v=vs.85).aspx

See the section on TDR Registry Keys.

I followed the instructions of the post of this forum:

https://forums.geforce.com/default/topic/503962/tdr-fix-here-for-nvidia-driver-crashing-randomly-in-firefox/

I hope it works for you too!

:)