1 // This is brl/bseg/bstm/ocl/algo/bstm_ocl_update.cxx
2 #include <fstream>
3 #include <iostream>
4 #include <algorithm>
5 #include "bstm_ocl_update.h"
6 //:
7 // \file
8 // \brief A process for updating a model
9 //
10 // \author Ali Osman Ulusoy
11 // \date May 10, 2013
12
13 #ifdef _MSC_VER
14 # include "vcl_msvc_warnings.h"
15 #endif
16 #include <bstm/ocl/bstm_opencl_cache.h>
17 #include <bstm/bstm_scene.h>
18 #include <bstm/bstm_block.h>
19 #include <bstm/bstm_data_base.h>
20 #include <bstm/ocl/bstm_ocl_util.h>
21 #include <bstm/bstm_util.h>
22 #include <boxm2/ocl/algo/boxm2_ocl_camera_converter.h>
23 #include "vil/vil_image_view.h"
24
25 //directory utility
26 #include "vul/vul_timer.h"
27 #include <vcl_where_root_dir.h>
28 #include <bocl/bocl_device.h>
29 #include <bocl/bocl_kernel.h>
30 //
31 #include "vil/vil_save.h"
32 //: Map of kernels should persist between process executions
33 std::map<std::string,std::vector<bocl_kernel*> > bstm_ocl_update::kernels_;
34
35 //Main public method, updates color model
update(const bstm_scene_sptr & scene,bocl_device_sptr device,const bstm_opencl_cache_sptr & opencl_cache,vpgl_camera_double_sptr cam,const vil_image_view_base_sptr & img,float time,float mog_var,bool update_alpha,bool update_changes_only,const vil_image_view_base_sptr & mask_sptr)36 bool bstm_ocl_update::update(const bstm_scene_sptr& scene,
37 bocl_device_sptr device,
38 const bstm_opencl_cache_sptr& opencl_cache,
39 vpgl_camera_double_sptr cam,
40 const vil_image_view_base_sptr& img,
41 float time,
42 float mog_var,
43 bool update_alpha,
44 bool update_changes_only,
45 const vil_image_view_base_sptr& mask_sptr)
46 {
47
48 enum {
49 UPDATE_SEGLEN = 0,
50 UPDATE_PREINF = 1,
51 UPDATE_PROC = 2,
52 UPDATE_BAYES = 3,
53 UPDATE_CELL = 4
54 };
55 float transfer_time=0.0f;
56 float gpu_time=0.0f;
57 std::size_t local_threads[2]={8,8};
58 std::size_t global_threads[2]={8,8};
59
60 //catch a "null" mask (not really null because that throws an error)
61 bool use_mask = false;
62 if ( mask_sptr->ni() == img->ni() && mask_sptr->nj() == img->nj() ) {
63 use_mask = true;
64 }
65
66 vil_image_view<unsigned char >* mask_map = nullptr;
67 if (use_mask) {
68 mask_map = dynamic_cast<vil_image_view<unsigned char> *>(mask_sptr.ptr());
69 if (!mask_map) {
70 std::cout<<"bstm_update_process:: mask map is not an unsigned char map"<<std::endl;
71 return false;
72 }
73 std::cout << "Update using mask..." << std::endl;
74 }
75
76 //cache size sanity check
77 std::size_t binCache = opencl_cache.ptr()->bytes_in_cache();
78 std::cout<<"Update MBs in cache: "<<binCache/(1024.0*1024.0)<<std::endl;
79
80 //make correct data types are here
81 std::string data_type, num_obs_type,options = "";
82 int appTypeSize;
83 if (!validate_appearances(scene, data_type, appTypeSize, num_obs_type, options))
84 return false;
85
86 // create a command queue.
87 int status=0;
88 cl_command_queue queue = clCreateCommandQueue( device->context(), *(device->device_id()), CL_QUEUE_PROFILING_ENABLE, &status);
89 if (status!=0)
90 return false;
91
92 // compile the kernel if not already compiled
93 std::vector<bocl_kernel*>& kernels = get_kernels(device, options);
94
95 //grab input image, establish cl_ni, cl_nj (so global size is divisible by local size)
96 vil_image_view_base_sptr float_img = bstm_util::prepare_input_image(img, true);
97 auto* img_view = static_cast<vil_image_view<float>* >(float_img.ptr());
98 auto cl_ni=(unsigned)RoundUp(img_view->ni(),(int)local_threads[0]);
99 auto cl_nj=(unsigned)RoundUp(img_view->nj(),(int)local_threads[1]);
100 global_threads[0]=cl_ni;
101 global_threads[1]=cl_nj;
102
103 //set generic cam
104 auto* ray_origins = new cl_float[4*cl_ni*cl_nj];
105 auto* ray_directions = new cl_float[4*cl_ni*cl_nj];
106 bocl_mem_sptr ray_o_buff = opencl_cache->alloc_mem(cl_ni*cl_nj*sizeof(cl_float4), ray_origins, "ray_origins buffer");
107 bocl_mem_sptr ray_d_buff = opencl_cache->alloc_mem(cl_ni*cl_nj*sizeof(cl_float4), ray_directions, "ray_directions buffer");
108 boxm2_ocl_camera_converter::compute_ray_image( device, queue, cam, cl_ni, cl_nj, ray_o_buff, ray_d_buff);
109
110 //Visibility, Preinf, Norm, and input image buffers
111 auto* vis_buff = new float[cl_ni*cl_nj];
112 auto* pre_buff = new float[cl_ni*cl_nj];
113 auto* norm_buff = new float[cl_ni*cl_nj];
114 auto* input_buff=new float[cl_ni*cl_nj];
115 for (unsigned i=0;i<cl_ni*cl_nj;i++)
116 {
117 vis_buff[i]=1.0f;
118 pre_buff[i]=0.0f;
119 norm_buff[i]=0.0f;
120 }
121
122 //copy input vals into image
123 int count=0;
124 for (unsigned int j=0;j<cl_nj;++j) {
125 for (unsigned int i=0;i<cl_ni;++i) {
126 input_buff[count] = 0.0f;
127 if ( i<img_view->ni() && j< img_view->nj() )
128 input_buff[count] = (*img_view)(i,j);
129 ++count;
130 }
131 }
132 if (use_mask)
133 {
134 int count = 0;
135 for (unsigned int j=0;j<cl_nj;++j) {
136 for (unsigned int i=0;i<cl_ni;++i) {
137 if ( i<mask_map->ni() && j<mask_map->nj() )
138 if ( (*mask_map)(i,j)==0 ) {
139 input_buff[count] = -1.0f;
140 vis_buff [count] = -1.0f;
141 }
142 ++count;
143 }
144 }
145 }
146
147 bocl_mem_sptr in_image = opencl_cache->alloc_mem(cl_ni*cl_nj*sizeof(float), input_buff, "input image buffer");
148 in_image->create_buffer(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR);
149
150 bocl_mem_sptr vis_image = opencl_cache->alloc_mem(cl_ni*cl_nj*sizeof(float), vis_buff, "vis image buffer");
151 vis_image->create_buffer(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR);
152
153 bocl_mem_sptr pre_image = opencl_cache->alloc_mem(cl_ni*cl_nj*sizeof(float), pre_buff, "pre image buffer");
154 pre_image->create_buffer(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR);
155
156 bocl_mem_sptr norm_image = opencl_cache->alloc_mem(cl_ni*cl_nj*sizeof(float), norm_buff, "norm image buffer");
157 norm_image->create_buffer(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR);
158
159
160 // Image Dimensions
161 int img_dim_buff[4];
162 img_dim_buff[0] = 0;
163 img_dim_buff[1] = 0;
164 img_dim_buff[2] = img_view->ni();
165 img_dim_buff[3] = img_view->nj();
166
167 bocl_mem_sptr img_dim=new bocl_mem(device->context(), img_dim_buff, sizeof(int)*4, "image dims");
168 img_dim->create_buffer(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR);
169
170 // Output Array
171 float output_arr[100];
172 for (float & i : output_arr) i = -1.0f;
173 bocl_mem_sptr cl_output=new bocl_mem(device->context(), output_arr, sizeof(float)*100, "output buffer");
174 cl_output->create_buffer(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR);
175
176 // bit lookup buffer
177 cl_uchar lookup_arr[256];
178 bstm_ocl_util::set_bit_lookup(lookup_arr);
179 bocl_mem_sptr lookup=new bocl_mem(device->context(), lookup_arr, sizeof(cl_uchar)*256, "bit lookup buffer");
180 lookup->create_buffer(CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR);
181
182 // update_alpha boolean buffer
183 cl_int up_alpha[1];
184 up_alpha[0] = update_alpha ? 1 : 0;
185 bocl_mem_sptr up_alpha_mem = new bocl_mem(device->context(), up_alpha, sizeof(up_alpha), "update alpha bool buffer");
186 up_alpha_mem->create_buffer(CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR);
187
188 // update_alpha boolean buffer
189 cl_int up_changes_only[1];
190 up_changes_only[0] = update_changes_only ? 1 : 0;
191 bocl_mem_sptr up_changes_mem = new bocl_mem(device->context(), up_changes_only, sizeof(up_changes_only), "update changes bool buffer");
192 up_changes_mem->create_buffer(CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR);
193
194 // app density used for proc_norm_image
195 //Set app_buffer.x = 1.0, if you want uniform background model
196 //Set app_buffer.x = 0, app_buffer.y and app_buffer.z to the mean and sigma of the gaussian for the background model
197 float app_buffer[4]={1.0,0.0,0.00,0.0};
198 bocl_mem_sptr app_density = new bocl_mem(device->context(), app_buffer, sizeof(cl_float4), "app density buffer");
199 app_density->create_buffer(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR);
200
201 //mog variance, if 0.0f or less, then var of app models will be estimated, otherwise, it will be fixed
202 bocl_mem_sptr mog_var_mem = new bocl_mem(device->context(), &mog_var, sizeof(mog_var), "update gauss variance");
203 mog_var_mem->create_buffer(CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR);
204
205 cl_int use_mask_buf[1];
206 use_mask_buf[0] = use_mask ? 1 : 0;
207 bocl_mem_sptr use_mask_mem = new bocl_mem(device->context(), use_mask_buf, sizeof(use_mask_buf), "update with mask");
208 use_mask_mem->create_buffer(CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR);
209
210 cl_float cl_time = 0;
211 bocl_mem_sptr time_mem =new bocl_mem(device->context(), &cl_time, sizeof(cl_float), "time instance buffer");
212 time_mem->create_buffer(CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR);
213
214
215 // set arguments
216 std::vector<bstm_block_id> vis_order = scene->get_vis_blocks(cam);
217 std::vector<bstm_block_id>::iterator id;
218 for (unsigned int i=0; i<kernels.size(); ++i)
219 {
220 if ( i == UPDATE_PROC ) {
221 bocl_kernel * proc_kern=kernels[i];
222
223 proc_kern->set_arg( norm_image.ptr() );
224 proc_kern->set_arg( vis_image.ptr() );
225 proc_kern->set_arg( pre_image.ptr());
226 proc_kern->set_arg( img_dim.ptr() );
227 proc_kern->set_arg( in_image.ptr() );
228 proc_kern->set_arg( app_density.ptr() );
229
230 //execute kernel
231 proc_kern->execute( queue, 2, local_threads, global_threads);
232 int status = clFinish(queue);
233 if (!check_val(status, MEM_FAILURE, "UPDATE EXECUTE FAILED: " + error_to_string(status)))
234 return false;
235 proc_kern->clear_args();
236 proc_kern->release_current_event();
237 continue;
238 }
239
240 for (id = vis_order.begin(); id != vis_order.end(); ++id)
241 {
242 //choose correct render kernel
243 bocl_kernel* kern = kernels[i];
244
245 //if the current blk does not contain the queried time, no need to ray cast
246 bstm_block_metadata mdata = scene->get_block_metadata(*id);
247 double local_time;
248 if(!mdata.contains_t(time,local_time))
249 continue;
250 //write cl_time
251 cl_time = (cl_float)local_time;
252 time_mem->write_to_buffer(queue);
253
254
255 //grab data from cache
256 vul_timer transfer;
257 bocl_mem* blk = opencl_cache->get_block(*id);
258 bocl_mem* blk_t = opencl_cache->get_time_block(*id);
259 bocl_mem* alpha = opencl_cache->get_data<BSTM_ALPHA>(*id,0,false);
260 bocl_mem* blk_info = opencl_cache->loaded_block_info();
261 bocl_mem* blk_t_info= opencl_cache->loaded_time_block_info();
262 auto* info_buffer_t = (bstm_scene_info*) blk_t_info->cpu_buffer();
263
264 //figure out sizes
265 int alphaTypeSize = (int)bstm_data_info::datasize(bstm_data_traits<BSTM_ALPHA>::prefix());
266 int data_buffer_length = alpha->num_bytes() / alphaTypeSize;
267 int num_time_trees = info_buffer_t->tree_buffer_length;
268 info_buffer_t->data_buffer_length = data_buffer_length;
269 blk_t_info->write_to_buffer((queue));
270
271 //grab MOG
272 int nobsTypeSize = (int)bstm_data_info::datasize(num_obs_type);
273 bocl_mem* mog = opencl_cache->get_data(*id,data_type,data_buffer_length*appTypeSize,false);
274
275 //grab AUX
276 int auxTypeSize = (int)bstm_data_info::datasize(bstm_data_traits<BSTM_AUX0>::prefix());
277 bocl_mem *aux0 = opencl_cache->get_data<BSTM_AUX0>(*id, num_time_trees*auxTypeSize,false);
278 bocl_mem *aux1 = opencl_cache->get_data<BSTM_AUX1>(*id, num_time_trees*auxTypeSize,false);
279 bocl_mem *aux2 = opencl_cache->get_data<BSTM_AUX2>(*id, num_time_trees*auxTypeSize,false);
280 bocl_mem *aux3 = opencl_cache->get_data<BSTM_AUX3>(*id, num_time_trees*auxTypeSize,false);
281
282
283 transfer_time += (float) transfer.all();
284 if (i==UPDATE_SEGLEN)
285 {
286 aux0->zero_gpu_buffer(queue);
287 aux1->zero_gpu_buffer(queue);
288
289 kern->set_arg( blk_info );
290 kern->set_arg( blk );
291 kern->set_arg( blk_t );
292 kern->set_arg( alpha );
293 kern->set_arg( aux0 );
294 kern->set_arg( aux1 );
295 kern->set_arg( lookup.ptr() );
296 kern->set_arg( ray_o_buff.ptr() );
297 kern->set_arg( ray_d_buff.ptr() );
298 kern->set_arg( img_dim.ptr() );
299 kern->set_arg( in_image.ptr() );
300 kern->set_arg( time_mem.ptr() );
301 kern->set_local_arg( local_threads[0]*local_threads[1]*sizeof(cl_uchar16) );//local tree,
302 kern->set_local_arg( local_threads[0]*local_threads[1]*sizeof(cl_uchar8) ); //local time tree
303 kern->set_local_arg( local_threads[0]*local_threads[1]*10*sizeof(cl_uchar) ); //cumsum buffer, imindex buffer
304
305 //execute kernel
306 kern->execute(queue, 2, local_threads, global_threads);
307 int status = clFinish(queue);
308 if (!check_val(status, MEM_FAILURE, "UPDATE EXECUTE FAILED: " + error_to_string(status)))
309 return false;
310 gpu_time += kern->exec_time();
311
312 //clear render kernel args so it can reset em on next execution
313 kern->clear_args();
314 kern->release_current_event();
315 }
316 else if (i==UPDATE_PREINF)
317 {
318
319
320 kern->set_arg( blk_info );
321 kern->set_arg( blk );
322 kern->set_arg( blk_t );
323 kern->set_arg( alpha );
324 kern->set_arg( mog );
325 kern->set_arg( aux0 );
326 kern->set_arg( aux1 );
327 kern->set_arg( lookup.ptr() );
328 kern->set_arg( ray_o_buff.ptr() );
329 kern->set_arg( ray_d_buff.ptr() );
330 kern->set_arg( img_dim.ptr() );
331 kern->set_arg( vis_image.ptr() );
332 kern->set_arg( pre_image.ptr() );
333 kern->set_arg( time_mem.ptr() );
334 kern->set_arg( cl_output.ptr() );
335 kern->set_local_arg( local_threads[0]*local_threads[1]*sizeof(cl_uchar16) );//local tree,
336 kern->set_local_arg( local_threads[0]*local_threads[1]*sizeof(cl_uchar8) ); //local time tree
337 kern->set_local_arg( local_threads[0]*local_threads[1]*10*sizeof(cl_uchar) ); //cumsum buffer, imindex buffer
338 //execute kernel
339 kern->execute(queue, 2, local_threads, global_threads);
340 int status = clFinish(queue);
341 if (!check_val(status, MEM_FAILURE, "UPDATE EXECUTE FAILED: " + error_to_string(status)))
342 return false;
343 gpu_time += kern->exec_time();
344
345 //clear render kernel args so it can reset em on next execution
346 kern->clear_args();
347 kern->release_current_event();
348 }
349 else if (i==UPDATE_BAYES)
350 {
351 aux2->zero_gpu_buffer(queue);
352 aux3->zero_gpu_buffer(queue);
353
354 kern->set_arg( blk_info );
355 kern->set_arg( blk );
356 kern->set_arg( blk_t );
357 kern->set_arg( alpha );
358 kern->set_arg( mog );
359 kern->set_arg( aux0 );
360 kern->set_arg( aux1 );
361 kern->set_arg( aux2 );
362 kern->set_arg( aux3 );
363 kern->set_arg( lookup.ptr() );
364 kern->set_arg( ray_o_buff.ptr() );
365 kern->set_arg( ray_d_buff.ptr() );
366 kern->set_arg( img_dim.ptr() );
367 kern->set_arg( vis_image.ptr() );
368 kern->set_arg( pre_image.ptr() );
369 kern->set_arg( norm_image.ptr() );
370 kern->set_arg( time_mem.ptr() );
371 kern->set_arg( cl_output.ptr() );
372 kern->set_local_arg( local_threads[0]*local_threads[1]*sizeof(cl_uchar16) );//local tree,
373 kern->set_local_arg( local_threads[0]*local_threads[1]*sizeof(cl_uchar8) ); //local time tree
374 kern->set_local_arg( local_threads[0]*local_threads[1]*10*sizeof(cl_uchar) ); //cumsum buffer, imindex buffer
375 kern->execute(queue, 2, local_threads, global_threads);
376 int status = clFinish(queue);
377 if (!check_val(status, MEM_FAILURE, "UPDATE EXECUTE FAILED: " + error_to_string(status)))
378 return false;
379 gpu_time += kern->exec_time();
380
381 //clear render kernel args so it can reset em on next execution
382 kern->clear_args();
383 kern->release_current_event();
384 }
385 else if (i==UPDATE_CELL)
386 {
387 bocl_mem* num_obs = opencl_cache->get_data(*id,num_obs_type,data_buffer_length*nobsTypeSize,false);
388
389 bocl_mem *change = opencl_cache->get_data<BSTM_CHANGE>(*id, num_time_trees*auxTypeSize,false);
390
391
392 local_threads[0] = 64;
393 local_threads[1] = 1 ;
394 global_threads[0]= RoundUp(info_buffer_t->tree_buffer_length ,local_threads[0]);
395 global_threads[1]=1;
396
397 kern->set_arg( blk_t_info );
398 kern->set_arg( blk_t );
399 kern->set_arg( alpha );
400 kern->set_arg( mog );
401 kern->set_arg( num_obs );
402 kern->set_arg( aux0 );
403 kern->set_arg( aux1 );
404 kern->set_arg( aux2 );
405 kern->set_arg( aux3 );
406 kern->set_arg( change );
407
408 kern->set_arg( use_mask_mem.ptr() );
409 kern->set_arg( mog_var_mem.ptr() );
410 kern->set_arg( time_mem.ptr() );
411 kern->set_arg( up_alpha_mem.ptr() );
412 kern->set_arg( up_changes_mem .ptr() );
413
414 kern->set_local_arg( local_threads[0]*local_threads[1]*sizeof(cl_uchar8) ); //local time tree
415
416 //execute kernel
417 kern->execute(queue, 2, local_threads, global_threads);
418 int status = clFinish(queue);
419 if (!check_val(status, MEM_FAILURE, "UPDATE EXECUTE FAILED: " + error_to_string(status)))
420 return false;
421 gpu_time += kern->exec_time();
422
423 //clear render kernel args so it can reset em on next execution
424 kern->clear_args();
425 kern->release_current_event();
426
427 //write info to disk
428 alpha->read_to_buffer(queue);
429 mog->read_to_buffer(queue);
430 num_obs->read_to_buffer(queue);
431 }
432
433 }
434 }
435
436
437
438 delete [] vis_buff;
439 delete [] pre_buff;
440 delete [] norm_buff;
441 delete [] input_buff;
442 delete [] ray_origins;
443 delete [] ray_directions;
444 opencl_cache->unref_mem(in_image.ptr());
445 opencl_cache->unref_mem(vis_image.ptr());
446 opencl_cache->unref_mem(pre_image.ptr());
447 opencl_cache->unref_mem(norm_image.ptr());
448 opencl_cache->unref_mem(ray_o_buff.ptr());
449 opencl_cache->unref_mem(ray_d_buff.ptr());
450
451 std::cout<<"Gpu time "<<gpu_time<<" transfer time "<<transfer_time<<std::endl;
452 clReleaseCommandQueue(queue);
453 return true;
454
455 }
456
457
458 //Returns vector of color update kernels (and caches them per device
get_kernels(const bocl_device_sptr & device,const std::string & opts,bool)459 std::vector<bocl_kernel*>& bstm_ocl_update::get_kernels(const bocl_device_sptr& device, const std::string& opts, bool /*isRGB*/)
460 {
461 // compile kernels if not already compiled
462 std::string identifier = device->device_identifier() + opts;
463 if (kernels_.find(identifier) != kernels_.end())
464 return kernels_[identifier];
465
466 //otherwise compile the kernels
467 std::cout<<"=== bstm_ocl_update::compiling kernels on device "<<identifier<<"==="<<std::endl;
468
469 std::vector<std::string> src_paths;
470 std::string source_dir = std::string(VCL_SOURCE_ROOT_DIR) + "/contrib/brl/bseg/bstm/ocl/cl/";
471 src_paths.push_back(source_dir + "scene_info.cl");
472 src_paths.push_back(source_dir + "pixel_conversion.cl");
473 src_paths.push_back(source_dir + "bit/bit_tree_library_functions.cl");
474 src_paths.push_back(source_dir + "bit/time_tree_library_functions.cl");
475 src_paths.push_back(source_dir + "backproject.cl");
476 src_paths.push_back(source_dir + "statistics_library_functions.cl");
477 src_paths.push_back(source_dir + "bit/update_kernels.cl");
478 std::vector<std::string> non_ray_src = std::vector<std::string>(src_paths);
479
480 //push ray trace files
481 src_paths.push_back(source_dir + "atomics_util.cl");
482 src_paths.push_back(source_dir + "update_functors.cl");
483 src_paths.push_back(source_dir + "bit/cast_ray_bit.cl");
484
485 //compilation options
486 std::string options = opts + " -D ATOMIC_FLOAT ";
487
488 //populate vector of kernels
489 std::vector<bocl_kernel*> vec_kernels;
490
491 //seg len pass
492 auto* seg_len = new bocl_kernel();
493 std::string seg_opts = options + " -D SEGLEN -D STEP_CELL=step_cell_seglen(aux_args,data_ptr,data_ptr_tt,d)";
494 seg_len->create_kernel(&device->context(), device->device_id(), src_paths, "seg_len_main", seg_opts, "update::seg_len");
495 vec_kernels.push_back(seg_len);
496
497
498 auto* pre_inf = new bocl_kernel();
499 std::string pre_opts = options + " -D PREINF -D STEP_CELL=step_cell_preinf(aux_args,data_ptr,data_ptr_tt,d)";
500 pre_inf->create_kernel(&device->context(), device->device_id(), src_paths, "pre_inf_main", pre_opts, "update::pre_inf");
501 vec_kernels.push_back(pre_inf);
502
503 //may need DIFF LIST OF SOURCES FOR THIS GUY
504 auto* proc_img = new bocl_kernel();
505 std::string proc_opts = options + " -D PROC_NORM ";
506 proc_img->create_kernel(&device->context(), device->device_id(), non_ray_src, "proc_norm_image", proc_opts, "update::proc_norm_image");
507 vec_kernels.push_back(proc_img);
508
509 //push back cast_ray_bit
510 auto* bayes_main = new bocl_kernel();
511 std::string bayes_opt = options + " -D BAYES -D STEP_CELL=step_cell_bayes(aux_args,data_ptr,data_ptr_tt,d)";
512 bayes_main->create_kernel(&device->context(), device->device_id(), src_paths, "bayes_main", bayes_opt, "update::bayes_main");
513 vec_kernels.push_back(bayes_main);
514
515 auto* update = new bocl_kernel();
516 std::string update_opts = options + " -D UPDATE_BIT_SCENE_MAIN ";
517 update->create_kernel(&device->context(), device->device_id(), non_ray_src, "update_bit_scene_main", update_opts, "update::update_main");
518 vec_kernels.push_back(update);
519
520 //store and return
521 kernels_[identifier] = vec_kernels;
522 return kernels_[identifier];
523 }
524
525
526 //makes sure appearance types correspond correctly
validate_appearances(const bstm_scene_sptr & scene,std::string & data_type,int & appTypeSize,std::string & num_obs_type,std::string & options)527 bool bstm_ocl_update::validate_appearances(const bstm_scene_sptr& scene,
528 std::string& data_type,
529 int& appTypeSize,
530 std::string& num_obs_type,
531 std::string& options)
532 {
533 std::vector<std::string> apps = scene->appearances();
534 bool foundDataType = false, foundNumObsType = false;
535 for (const auto & app : apps) {
536 if ( app == bstm_data_traits<BSTM_MOG3_GREY >::prefix() )
537 {
538 data_type = app;
539 foundDataType = true;
540 options+= " -D MOG_TYPE_8 ";
541 appTypeSize = (int)bstm_data_info::datasize(bstm_data_traits<BSTM_MOG3_GREY>::prefix());
542 }
543
544 else if( app == bstm_data_traits<BSTM_NUM_OBS>::prefix())
545 {
546 num_obs_type = app;
547 foundNumObsType = true;
548 }
549 }
550 if (!foundDataType) {
551 std::cout<<"BSTM_OPENCL_VIEW_BASED_UPDATE_PROCESS ERROR: scene doesn't have BSTM_MOG3_GREY data type"<<std::endl;
552 return false;
553 }
554 if (!foundNumObsType) {
555 std::cout<<"BSTM_OPENCL_VIEW_BASED_UPDATE_PROCESS ERROR: scene doesn't have BSTM_NUM_OBS data type"<<std::endl;
556 return false;
557 }
558 return true;
559 }
560