Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[Manta] r2151 - in trunk: Core/Util Engine/Control Model/Groups


Chronological Thread 
  • From: "Solomon Boulos" <boulos@cs.utah.edu>
  • To: manta@sci.utah.edu
  • Subject: [Manta] r2151 - in trunk: Core/Util Engine/Control Model/Groups
  • Date: Wed, 26 Mar 2008 16:41:53 -0600 (MDT)

Author: boulos
Date: Wed Mar 26 16:41:51 2008
New Revision: 2151

Modified:
   trunk/Core/Util/Callback.h
   trunk/Core/Util/CallbackHelpers.h
   trunk/Core/Util/genCallbacks.py
   trunk/Engine/Control/RTRT.cc
   trunk/Model/Groups/DynBVH.cc
   trunk/Model/Groups/DynBVH.h
Log:
Core/Util/Callback.h
Core/Util/CallbackHelpers.h
Core/Util/genCallbacks.py

 Adding Class based 1Data_3Arg callback.

Engine/Control/RTRT.cc

 Add an update transaction before frame 0 as well.

Model/Groups/DynBVH.cc
Model/Groups/DynBVH.h

 Add code to do the preprocess in parallel (building all the bounds,
 object id list, etc) and do this before the build. Previously, I was
 relying on already having the tree built once.


Modified: trunk/Core/Util/Callback.h
==============================================================================
--- trunk/Core/Util/Callback.h  (original)
+++ trunk/Core/Util/Callback.h  Wed Mar 26 16:41:51 2008
@@ -178,6 +178,13 @@
       return new Callback_1Data_2Arg<T, Data1, Arg1, Arg2>(ptr, pmf, arg1, 
arg2);
     }
 
+    // 1 call time args --- 3 creating time args
+    template<class T, typename Data1, typename Arg1, typename Arg2, typename 
Arg3> static
+    CallbackBase_1Data<Data1>*
+    create(T* ptr, void (T::*pmf)(Data1, Arg1, Arg2, Arg3), Arg1 arg1, Arg2 
arg2, Arg3 arg3) {
+      return new Callback_1Data_3Arg<T, Data1, Arg1, Arg2, Arg3>(ptr, pmf, 
arg1, arg2, arg3);
+    }
+
     // 1 call time args --- 4 creating time args
     template<class T, typename Data1, typename Arg1, typename Arg2, typename 
Arg3, typename Arg4> static
     CallbackBase_1Data<Data1>*

Modified: trunk/Core/Util/CallbackHelpers.h
==============================================================================
--- trunk/Core/Util/CallbackHelpers.h   (original)
+++ trunk/Core/Util/CallbackHelpers.h   Wed Mar 26 16:41:51 2008
@@ -570,6 +570,29 @@
     Arg2 arg2;
   };
 
+  // 1 call time args --- 3 creating time args
+  template<class T, typename Data1, typename Arg1, typename Arg2, typename 
Arg3>
+  class Callback_1Data_3Arg : public CallbackBase_1Data<Data1> {
+  public:
+    Callback_1Data_3Arg(T* ptr, void (T::*pmf)(Data1, Arg1, Arg2, Arg3), 
Arg1 arg1, Arg2 arg2, Arg3 arg3)
+      : ptr(ptr), pmf(pmf), arg1(arg1), arg2(arg2), arg3(arg3)
+    {
+    }
+    virtual ~Callback_1Data_3Arg()
+    {
+    }
+    virtual void call(Data1 data1)
+    {
+      (ptr->*pmf)(data1, arg1, arg2, arg3);
+    }
+  private:
+    T* ptr;
+    void (T::*pmf)(Data1, Arg1, Arg2, Arg3);
+    Arg1 arg1;
+    Arg2 arg2;
+    Arg3 arg3;
+  };
+
   // 1 call time args --- 4 creating time args
   template<class T, typename Data1, typename Arg1, typename Arg2, typename 
Arg3, typename Arg4>
   class Callback_1Data_4Arg : public CallbackBase_1Data<Data1> {

Modified: trunk/Core/Util/genCallbacks.py
==============================================================================
--- trunk/Core/Util/genCallbacks.py     (original)
+++ trunk/Core/Util/genCallbacks.py     Wed Mar 26 16:41:51 2008
@@ -394,7 +394,7 @@
     addFunctions(member_functions, 0, (0,1,2,3,4))
     addFunctions(const_member_functions, 0, (0,1,2))
 
-    addFunctions(member_functions, 1, (0,1,2,4,5))
+    addFunctions(member_functions, 1, (0,1,2,3,4,5))
     addFunctions(member_functions, 2, (0,1,2,3))
     addFunctions(member_functions, 3, (0,1))
     addFunctions(member_functions, 4, (0,1,2))

Modified: trunk/Engine/Control/RTRT.cc
==============================================================================
--- trunk/Engine/Control/RTRT.cc        (original)
+++ trunk/Engine/Control/RTRT.cc        Wed Mar 26 16:41:51 2008
@@ -687,6 +687,14 @@
 #if USE_UPDATE_GRAPH
     #warning "Adding objects to the update graph"
     scene->getObject()->addToUpdateGraph(update_graph, NULL);
+#if 1
+#warning "Sending update transaction for first Object in group for frame 0"
+      // Temporary
+      Group* top_level_group = dynamic_cast<Group*>(getScene()->getObject());
+      addUpdateTransaction("Test Update Graph",
+                           Callback::create(PrintHello),
+                           top_level_group->get(0));
+#endif
 #endif
     //update_graph->print(scene->getObject());
   }

Modified: trunk/Model/Groups/DynBVH.cc
==============================================================================
--- trunk/Model/Groups/DynBVH.cc        (original)
+++ trunk/Model/Groups/DynBVH.cc        Wed Mar 26 16:41:51 2008
@@ -30,6 +30,7 @@
 const int BVH_num_samples = 8;
 
 #define LONGEST_AXIS 0
+#define USE_PARALLEL_BUILD 1
 
 #include <Model/Groups/Mesh.h>
 void WriteMeshSorted(Group* group, std::vector<int> ids, const char* 
filename) {
@@ -719,11 +720,83 @@
 typedef Callback_1Data_2Arg<DynBVH, Task*, int, UpdateContext> BVHUpdateTask;
 typedef Callback_1Data_2Arg<DynBVH, TaskList*, int, Task*> 
BVHUpdateReduction;
 
+typedef Callback_1Data_3Arg<DynBVH, Task*, int, int, UpdateContext> 
BVHPreprocessTask;
+
 typedef Callback_1Data_4Arg<DynBVH, Task*, int, int, int, UpdateContext> 
BVHBuildTask;
 typedef Callback_1Data_2Arg<DynBVH, TaskList*, int, Task*> BVHBuildReduction;
 typedef Callback_1Data_5Arg<DynBVH, TaskList*, Task*, int, int, int, 
UpdateContext> BVHSAHReduction;
 
-#define USE_PARALLEL_BUILD 0
+
+void DynBVH::beginParallelPreprocess(UpdateContext context) {
+  cerr << "Computing bounds for all primitives" << endl;
+  // Allocate all the necessary spots first
+  allocate();
+  const unsigned int kNumPrimsPerTask = 1024;
+  unsigned int num_tasks = currGroup->size() / kNumPrimsPerTask;
+  if (TaskListMemory) delete[] TaskListMemory;
+  TaskListMemory = new char[1 * sizeof(TaskList)];
+  CurTaskList = 0;
+  if (TaskMemory) delete[] TaskMemory;
+  TaskMemory = new char[num_tasks * sizeof(Task)];
+  CurTask = 0;
+  TaskList* new_list = new (TaskListMemory) TaskList();
+
+  if (FourArgCallbackMemory) delete[] FourArgCallbackMemory;
+  FourArgCallbackMemory = new char[num_tasks * sizeof(BVHPreprocessTask)];
+  CurFourArgCallback = 0;
+
+  for (unsigned int i = 0; i < num_tasks; i++) {
+    int begin = i * kNumPrimsPerTask;
+    int end   = begin + kNumPrimsPerTask;
+    if (i == num_tasks - 1) {
+      end = currGroup->size();
+    }
+    Task* child = new (TaskMemory + sizeof(Task) * i) Task
+      (new (FourArgCallbackMemory + 
i*sizeof(BVHPreprocessTask))BVHPreprocessTask
+       (this,
+        &DynBVH::parallelPreprocess,
+        begin,
+        end,
+        context));
+    new_list->push_back(child);
+  }
+  new_list->setReduction(
+    Callback::create(this,
+                     &DynBVH::finishParallelPreprocess,
+                     context));
+
+  // Ask the work queue to update my BVH
+  context.insertWork(new_list);
+}
+
+void DynBVH::parallelPreprocess(Task* task, int objectBegin, int objectEnd, 
UpdateContext context) {
+  PreprocessContext preprocess_context(context.manta_interface,
+                                       context.proc,
+                                       context.num_procs,
+                                       NULL);
+  BBox overall_bounds;
+  for ( int i = objectBegin; i < objectEnd; i++ ) {
+    object_ids[i] = i;
+    currGroup->get(i)->computeBounds(preprocess_context, obj_bounds[i]);
+    obj_centroids[i] = obj_bounds[i].center();
+    overall_bounds.extendByBox(obj_bounds[i]);
+  }
+  BBox* output = (BBox*)task->scratchpad_data;
+  *output = overall_bounds;
+  task->finished();
+}
+
+void DynBVH::finishParallelPreprocess(TaskList* tasklist, UpdateContext 
context) {
+  // reduce the individual bounds into one bound and set node 0
+  TaskList& list = *tasklist;
+  BBox overall_bounds;
+  for (size_t i = 0; i < list.tasks.size(); i++) {
+    BBox* task_bounds = (BBox*)list.tasks[i]->scratchpad_data;
+    overall_bounds.extendByBox(*task_bounds);
+  }
+  nodes[0].bounds = overall_bounds;
+  beginParallelBuild(context);
+}
 
 void DynBVH::beginParallelBuild(UpdateContext context) {
   cerr << "Doing parallel BVH build" << endl;
@@ -731,14 +804,18 @@
   nextFree.set(1);
 
   int num_possible_nodes = (2*currGroup->size()) + 1;
+  if (TaskListMemory) delete[] TaskListMemory;
   TaskListMemory = new char[(num_possible_nodes) * sizeof(TaskList)];
   CurTaskList = 0;
+  if (TaskMemory) delete[] TaskMemory;
   TaskMemory = new char[2 * (num_possible_nodes) * sizeof(Task)];
   CurTask = 0;
 
+  if (FourArgCallbackMemory) delete[] FourArgCallbackMemory;
   FourArgCallbackMemory = new char[3 * (num_possible_nodes) * 
sizeof(BVHBuildTask)];
   CurFourArgCallback = 0;
 
+  if (FiveArgCallbackMemory) delete[] FiveArgCallbackMemory;
   FiveArgCallbackMemory = new char[3 * (num_possible_nodes) * 
sizeof(BVHSAHReduction)];
 
   TaskList* new_list = new (TaskListMemory + sizeof(TaskList)*CurTaskList) 
TaskList();
@@ -819,7 +896,8 @@
 
 void DynBVH::performUpdate(const UpdateContext& context) {
 #if USE_PARALLEL_BUILD
-  beginParallelBuild(context);
+  beginParallelPreprocess(context);
+  //beginParallelBuild(context);
 #else
   beginParallelUpdate(0, context);
 #endif
@@ -1040,52 +1118,6 @@
 // We know that there is "lots of work" (objectEnd - objectBegin is
 // sort of big), so no need to check for small cases here
 void DynBVH::parallelApproximateSAH(Task* task, int nodeID, int objectBegin, 
int objectEnd, UpdateContext context) {
-#if 0
-  // First compute overall bounds in parallel
-  int num_objects = objectEnd - objectBegin;
-  const int kNumObjectsPerBound = 1024;
-  int num_tasks = num_objects / kNumObjectsPerBound;
-
-  taskpool_mutex.lock();
-  size_t tasklist_id = CurTaskList;
-  size_t first_task = CurTask;
-  size_t callback_id = CurFourArgCallback;
-  size_t reduction_id = CurFiveArgCallback;
-
-  CurTaskList++;
-  CurTask += num_tasks;
-  CurFourArgCallback += num_tasks;
-  CurFiveArgCallback++;
-  taskpool_mutex.unlock();
-
-  TaskList* children = new (TaskListMemory + sizeof(TaskList) * tasklist_id) 
TaskList();
-  for (int i = 0; i < num_tasks; i++) {
-    int begin = objectBegin + i * kNumObjectsPerBound;
-    int end   = begin + kNumObjectsPerBound;
-    if (i == num_tasks - 1) {
-      end = objectEnd;
-    }
-    Task* child = new (TaskMemory + sizeof(Task) * (first_task + i)) Task
-      (new (FourArgCallbackMemory + 
(callback_id+i)*sizeof(BVHBuildTask))BVHBuildTask
-       (this,
-        &DynBVH::parallelComputeBounds,
-        nodeID,
-        begin,
-        end,
-        context));
-    children->push_back(child);
-  }
-
-  children->setReduction(new (FiveArgCallbackMemory + reduction_id * 
sizeof(BVHSAHReduction))BVHSAHReduction
-                         (this,
-                          &DynBVH::parallelComputeBoundsReduction,
-                          task,
-                          nodeID,
-                          objectBegin,
-                          objectEnd,
-                          context));
-  context.insertWork(children);
-#else
   // Now kick off a parallel bin computation
   BBox& overall_bounds = nodes[nodeID].bounds;
   const int kBinningObjects = 1024;
@@ -1134,7 +1166,6 @@
                           context));
 
   context.insertWork(children);
-#endif
   // Then compute bin entries in parallel (sweep during reduction?)
 
   // If a split has been deemed necessary (very likely), segment the object 
ids in parallel
@@ -1503,6 +1534,19 @@
     group_changed = false;
 }
 
+void DynBVH::allocate() {
+ if(currGroup->size() > object_ids.size()) {
+    nodes.resize(2*currGroup->size());
+    num_prims_beneath.resize(2*currGroup->size());
+    object_ids.resize(currGroup->size());
+
+    // TODO(boulos): Free these after construction? or keep around
+    // for rebuild?
+    obj_bounds.resize(currGroup->size());
+    obj_centroids.resize(currGroup->size());
+  }
+}
+
 void DynBVH::rebuild(int proc, int numProcs)
 {
   if (!group_changed) {
@@ -1511,23 +1555,13 @@
   }
   PreprocessContext context;
 
-  // TODO(boulos/bigler/thiago/wald/sparker): Parallel rebuild ;)
   if (proc > 0) return;
 
   if (print_info)
     cerr << "\nDynBVH::preprocess START (" << currGroup->size() << " 
objects)\n";
   double start = Time::currentSeconds();
 
-  if(currGroup->size() > object_ids.size()) {
-    nodes.resize(2*currGroup->size());
-    num_prims_beneath.resize(2*currGroup->size());
-    object_ids.resize(currGroup->size());
-
-    // TODO(boulos): Free these after construction? or keep around
-    // for rebuild?
-    obj_bounds.resize(currGroup->size());
-    obj_centroids.resize(currGroup->size());
-  }
+  allocate();
 
   BBox overall_bounds;
   for ( size_t i = 0; i < currGroup->size(); i++ ) {
@@ -1539,8 +1573,10 @@
 
   num_nodes.set(1);
   nextFree.set(1);
-  double build_start = Time::currentSeconds();
   nodes[0].bounds = overall_bounds;
+
+  double build_start = Time::currentSeconds();
+
 
   build(context, 0, 0, currGroup->size());
   double updateBound_start = Time::currentSeconds();

Modified: trunk/Model/Groups/DynBVH.h
==============================================================================
--- trunk/Model/Groups/DynBVH.h (original)
+++ trunk/Model/Groups/DynBVH.h Wed Mar 26 16:41:51 2008
@@ -107,8 +107,14 @@
     virtual void addToUpdateGraph(ObjectUpdateGraph* graph,
                                   ObjectUpdateGraphNode* parent);
 
+    void allocate();
+
     void performUpdate(const UpdateContext& context);
     void finishUpdate(TaskList* list, UpdateContext context);
+
+    void beginParallelPreprocess(UpdateContext context);
+    void parallelPreprocess(Task* task, int objectBegin, int objectEnd, 
UpdateContext context);
+    void finishParallelPreprocess(TaskList* tasklist, UpdateContext context);
 
     void beginParallelBuild(UpdateContext context);
     void beginParallelUpdate(TaskList* list, UpdateContext context);




  • [Manta] r2151 - in trunk: Core/Util Engine/Control Model/Groups, Solomon Boulos, 03/26/2008

Archive powered by MHonArc 2.6.16.

Top of page