Text archives Help
- 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.