Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r1344 - in trunk: Interface Model/Groups Model/MiscObjects Model/Primitives


Chronological Thread 
  • From: thiago@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r1344 - in trunk: Interface Model/Groups Model/MiscObjects Model/Primitives
  • Date: Fri, 13 Apr 2007 18:51:27 -0600 (MDT)

Author: thiago
Date: Fri Apr 13 18:51:26 2007
New Revision: 1344

Modified:
   trunk/Interface/Interpolable.h
   trunk/Model/Groups/DynBVH.cc
   trunk/Model/Groups/Group.cc
   trunk/Model/Groups/Group.h
   trunk/Model/MiscObjects/KeyFrameAnimation.cc
   trunk/Model/Primitives/Heightfield.cc
   trunk/Model/Primitives/Heightfield.h
   trunk/Model/Primitives/Sphere.cc
   trunk/Model/Primitives/Sphere.h
   trunk/Model/Primitives/Triangle.cc
   trunk/Model/Primitives/Triangle.h
Log:
Interface/Interpolable.h:
   Instead of interpolate, we now have serial and parallel interpolate
   functions. In order to use the parallel version, the derived class
   should implement isParallel() and have it return true.

Model/Groups/Group.h
Model/Groups/Group.cc:
   Made a parallel interpolate

Model/Groups/DynBVH.cc:
   Some debug output cleanup since I had previously moved output out of
   preprocess and some of the timings no longer applied.

Model/Primitives/Heightfield.h
Model/Primitives/Heightfield.cc :
   Implemented a parallel interpolate. Fixed some bugs.

Model/Primitives/Sphere.h
Model/Primitives/Sphere.cc
Model/Primitives/Triangle.h
Model/Primitives/Triangle.cc : 
   Made these play nice with SWIG (let me know if there are other
   things still not getting along with it) and updated to use new
   Interpolable interface.

Model/MiscObjects/KeyFrameAnimation.cc:
   Updated to take advantage of parallel interpolation. Also fixed some
   bugs.


Modified: trunk/Interface/Interpolable.h
==============================================================================
--- trunk/Interface/Interpolable.h      (original)
+++ trunk/Interface/Interpolable.h      Fri Apr 13 18:51:26 2007
@@ -19,10 +19,22 @@
     //supposed to do something like the following: 
     //       *this = keyframe[0]*t[0] + ... + keyframe[n]*t[n];
     //Make sure to check types of keyframes match
-    virtual InterpErr interpolate(const std::vector<keyframe_t> &keyframes)
+    virtual InterpErr serialInterpolate(const std::vector<keyframe_t> 
&keyframes)
     {
       return notInterpolable;
     }
+
+    virtual InterpErr parallelInterpolate(const std::vector<keyframe_t> 
&keyframes,
+                                          int proc, int numProc)
+    {
+      //don't call serialInterpolate by default, since we don't want
+      //to hide from user that they are doing something stupid.
+      //either throw an error or do nothing.
+      return notInterpolable;
+    }
+
+    virtual bool isParallel() const { return false; }
+
   };
 }
 #endif //Manta_Interface_Interpolable_h

Modified: trunk/Model/Groups/DynBVH.cc
==============================================================================
--- trunk/Model/Groups/DynBVH.cc        (original)
+++ trunk/Model/Groups/DynBVH.cc        Fri Apr 13 18:51:26 2007
@@ -445,7 +445,6 @@
 
     cerr << "\nDynBVH::preprocess START\n";
     double start = SCIRun::Time::currentSeconds();
-    double group_preprocess_end = SCIRun::Time::currentSeconds();
 
     if(group->getSize() > object_ids.size()) {
       nodes.resize(2*group->getSize());
@@ -464,9 +463,8 @@
     double updateBound_start = SCIRun::Time::currentSeconds();
     updateBounds(context, 0);
     double end = SCIRun::Time::currentSeconds();
-    cerr << "\nDynBVH Preprocess time: Total ("<<end-start<<")\n"
-         << "Group::preprocess ("<<group_preprocess_end-start<<")\n"
-         << "object_ids initialization 
("<<build_start-group_preprocess_end<<")\n"
+    cerr << "\nDynBVH build time: Total ("<<end-start<<")\n"
+         << "object_ids initialization ("<<build_start-start<<")\n"
          << "build ("<<updateBound_start-build_start<<")\n"
          << "updateBounds ("<<end-updateBound_start<<")\n\n";
   }

Modified: trunk/Model/Groups/Group.cc
==============================================================================
--- trunk/Model/Groups/Group.cc (original)
+++ trunk/Model/Groups/Group.cc Fri Apr 13 18:51:26 2007
@@ -1,6 +1,7 @@
 
 #include <Model/Groups/Group.h>
 #include <SCIRun/Core/Util/Assert.h>
+#include <algorithm>
 #include <assert.h>
 
 using namespace Manta;
@@ -38,7 +39,15 @@
   return copy;
 }
 
-Interpolable::InterpErr Group::interpolate(const std::vector<keyframe_t> 
&group_keyframes)
+Interpolable::InterpErr 
+Group::serialInterpolate(const std::vector<keyframe_t> &group_keyframes)
+{
+  return parallelInterpolate(group_keyframes, 0, 1);
+}
+
+Interpolable::InterpErr 
+Group::parallelInterpolate(const std::vector<keyframe_t> &group_keyframes,
+                           int proc, int numProc)
 {
   InterpErr worstError = success;
   vector<keyframe_t> keyframes(group_keyframes);
@@ -52,11 +61,25 @@
     assert(group->getSize() == getSize());
   }
 
-  for (int i=0; i < objs.size(); ++i) {
+  //Do the serial objects in parallel
+  int serialSize = (parallelSplit - objs.begin());
+  int start = proc*serialSize/numProc;
+  int end = (proc+1)*serialSize/numProc;
+  for (int i=start; i < end; ++i) {
     for(int frame=0; frame < keyframes.size(); ++frame) {
       keyframes[frame].keyframe = groups[frame]->get(i);
     }
-    InterpErr retcode = objs[i]->interpolate(keyframes);
+    InterpErr retcode = objs[i]->serialInterpolate(keyframes);
+    if (retcode != success)
+      worstError = retcode;
+  }
+
+  //now do the parallel objects
+  for (int i=serialSize; i < objs.size(); ++i) {
+    for(int frame=0; frame < keyframes.size(); ++frame) {
+      keyframes[frame].keyframe = groups[frame]->get(i);
+    }
+    InterpErr retcode = objs[i]->parallelInterpolate(keyframes, proc, 
numProc);
     if (retcode != success)
       worstError = retcode;
   }
@@ -96,8 +119,20 @@
   return static_cast<int>(objs.size());
 }
 
+//used by partition
+bool isSerial(Interpolable *i)
+{
+  return !i->isParallel();
+}
+
 void Group::preprocess(const PreprocessContext& context)
 {
+  //partition so that objs are serial and then parallel
+  parallelSplit = partition(objs.begin(), objs.end(), isSerial);
+
+  for(int i=0; i<objs.size(); ++i)
+    objs[i]->preprocess(context);
+
   for(vector<Object*>::iterator iter = objs.begin();
       iter != objs.end(); ++iter)
     (*iter)->preprocess(context);

Modified: trunk/Model/Groups/Group.h
==============================================================================
--- trunk/Model/Groups/Group.h  (original)
+++ trunk/Model/Groups/Group.h  Fri Apr 13 18:51:26 2007
@@ -48,8 +48,11 @@
 #ifndef SWIG
     virtual Group* clone(CloneDepth depth, Clonable* incoming=NULL);
 
-    virtual InterpErr interpolate(const std::vector<keyframe_t> &keyframes);
+    virtual InterpErr serialInterpolate(const std::vector<keyframe_t> 
&keyframes);
+    virtual InterpErr parallelInterpolate(const std::vector<keyframe_t> 
&keyframes,
+                                          int proc, int numProc);
 #endif
+    virtual bool isParallel() const { return true; }
 
     void add(Object* obj);
     void set( int i, Object *obj );
@@ -68,6 +71,7 @@
 
   protected:
     vector<Object*> objs;
+    vector<Object*>::iterator  parallelSplit; //point to the start of the 
parallel objects
   };
 }
 

Modified: trunk/Model/MiscObjects/KeyFrameAnimation.cc
==============================================================================
--- trunk/Model/MiscObjects/KeyFrameAnimation.cc        (original)
+++ trunk/Model/MiscObjects/KeyFrameAnimation.cc        Fri Apr 13 18:51:26 
2007
@@ -44,7 +44,6 @@
 {
   startTime = SCIRun::Time::currentSeconds();
   paused = false;
-  currGroup = NULL;
 
   if (spareGroup == NULL && interpolation != truncate && !frames.empty()) {
     spareGroup = frames[0]->clone(shallow);
@@ -112,11 +111,10 @@
       keyframes[1].keyframe = frames[end];
       keyframes[1].t = t;
 
-      if (context.proc == 0) {//TODO: Parallellize this!
-        InterpErr errCode = currGroup->interpolate(keyframes);
-        if (errCode != success)
-          printf("KeyFrameAnimation had trouble interpolating!\n");
-      }
+      InterpErr errCode = currGroup->parallelInterpolate(keyframes, 
+                                                         context.proc, 
context.numProcs);
+      if (errCode != success)
+        printf("KeyFrameAnimation had trouble interpolating!\n");
     }
     else if (interpolation == truncate) {
       if (context.proc == 0) //TODO: Parallellize this!
@@ -198,6 +196,8 @@
   for (int i=0; i < frames.size(); ++i) {
     frames[i]->preprocess(context);
   }
+  if (spareGroup)
+    spareGroup->preprocess(context);
 
   if (as)
     as->preprocess(context);

Modified: trunk/Model/Primitives/Heightfield.cc
==============================================================================
--- trunk/Model/Primitives/Heightfield.cc       (original)
+++ trunk/Model/Primitives/Heightfield.cc       Fri Apr 13 18:51:26 2007
@@ -19,7 +19,8 @@
                          const Vector &minBound, const Vector &maxBound// ,
 //                          Real scale
                          )
-  : PrimitiveCommon(material)
+  : PrimitiveCommon(material), barrier("heightfield barrier"),
+    mutex("heightfield mutex")
 {
   cout << "\n\nbounds are: " << minBound << " " <<maxBound<<endl;
   ifstream in(filename.c_str());
@@ -72,7 +73,7 @@
   else
     h = new Heightfield();
 
-  h->PrimitiveCommon::clone(depth, h);
+  PrimitiveCommon::clone(depth, h);
 
   h->m_Box = m_Box;
   h->nx = nx;
@@ -90,16 +91,18 @@
 }
 
 Interpolable::InterpErr 
-Heightfield::interpolate(const std::vector<keyframe_t> &keyframes)
+Heightfield::serialInterpolate(const std::vector<keyframe_t> &keyframes)
+{
+  return parallelInterpolate(keyframes, 0, 1);
+}
+
+Interpolable::InterpErr 
+Heightfield::parallelInterpolate(const std::vector<keyframe_t> &keyframes,
+                                 int proc, int numProc)
 {
   //TODO: Parallelize this
   assert(!keyframes.empty());
 
-//   if (proc == 0) {
-
-
-  PrimitiveCommon::interpolate(keyframes);
-
   Heightfield *heightfields[keyframes.size()];
 
   for (int frame=0; frame < keyframes.size(); ++frame) {
@@ -114,48 +117,65 @@
     }
   }
 
-  if (nx != heightfields[0]->nx || ny != heightfields[0]->ny) {
-    for (int i=0; i<=nx; ++i)
-      delete data[i];
-    delete[] data;
+
+  float minz = std::numeric_limits<float>::max(),
+        maxz = -std::numeric_limits<float>::max();
+
+  if (proc == 0) {
+    PrimitiveCommon::interpolate(keyframes);
+    m_Box = BBox( Vector(m_Box.getMin().x(), m_Box.getMin().y(), minz),
+                  Vector(m_Box.getMax().x(), m_Box.getMax().y(), maxz));
+
+    if (nx != heightfields[0]->nx || ny != heightfields[0]->ny) {
+      for (int i=0; i<=nx; ++i)
+        delete data[i];
+      delete[] data;
     
-    nx = heightfields[0]->nx;
-    ny = heightfields[0]->ny;
+      nx = heightfields[0]->nx;
+      ny = heightfields[0]->ny;
 
-    data = new float*[nx+1];
-    float* p = new float[(nx+1)*(ny+1)];
-    for(int i=0;i<=nx;i++)
-      data[i] = p+i*(ny+1);
+      data = new float*[nx+1];
+      float* p = new float[(nx+1)*(ny+1)];
+      for(int i=0;i<=nx;i++)
+        data[i] = p+i*(ny+1);
+    }
   }
 
-  float minz = std::numeric_limits<float>::max(),
-        maxz = -std::numeric_limits<float>::max();
+  barrier.wait(numProc);  
+
+  //being tricky here and using the fact that data is contiguously allocated
+  int start = proc*(nx*ny+1)/numProc;
+  int end = (proc+1)*(nx*ny+1)/numProc;
+  for (int i = start; i < end; ++i) {
+    float val = 0;
+    //lets hope this loop gets unrolled!
+    for (int frame=0; frame < keyframes.size(); ++frame) {
+      val += keyframes[frame].t * heightfields[frame]->data[0][i]; 
+    }
+    data[0][i] = val;
+    minz = min(data[0][i], minz);
+    maxz = max(data[0][i], maxz);
+  }
 
-    for (int i = 0; i <= nx; ++i)
-      for (int j = 0; j <= ny; ++j) {
-        float val = 0;
-        //lets hope this loop gets unrolled!
-        for (int frame=0; frame < keyframes.size(); ++frame) {
-          val += keyframes[frame].t * heightfields[frame]->data[i][j]; 
-        }
-        data[i][j] = val;
-        minz = min(data[i][j], minz);
-        maxz = max(data[i][j], maxz);
-      }
-
-    float dz = maxz-minz;
-    if(dz < 1.e-3)
-      dz = 1.e-3;
+  float dz = maxz-minz;
+  if(dz < 1.e-3)
+    dz = 1.e-3;
 
-    m_Box = BBox( Vector(m_Box.getMin().x(), m_Box.getMin().y(), 
minz-dz*1.e-4),
-                  Vector(m_Box.getMax().x(), m_Box.getMax().y(), 
maxz+dz*1.e-4));
+  mutex.lock();
+  m_Box.extendByBox(BBox( Vector(m_Box.getMin().x(), m_Box.getMin().y(), 
minz-dz*1.e-4),
+                          Vector(m_Box.getMax().x(), m_Box.getMax().y(), 
maxz+dz*1.e-4)));
+  mutex.unlock();
 
+  barrier.wait(numProc);
+
+  if (proc == 0) {
     // Step 1
     diag = m_Box.diagonal();
     cellsize = diag/Vector(nx, ny, 1);
     inv_cellsize = cellsize.inverse();
+  }
 
-    return success;
+  return success;
 }
 
 

Modified: trunk/Model/Primitives/Heightfield.h
==============================================================================
--- trunk/Model/Primitives/Heightfield.h        (original)
+++ trunk/Model/Primitives/Heightfield.h        Fri Apr 13 18:51:26 2007
@@ -2,11 +2,14 @@
 #ifndef Manta_Model_Heightfield_h
 #define Manta_Model_Heightfield_h
 
-#include <Model/Primitives/PrimitiveCommon.h>
 #include <Core/Geometry/Vector.h>
 #include <Core/Geometry/BBox.h>
-#include <Model/MiscObjects/KeyFrameAnimation.h>
+#include <Core/Thread/Barrier.h>
 #include <Interface/Clonable.h>
+#include <Model/MiscObjects/KeyFrameAnimation.h>
+#include <Model/Primitives/PrimitiveCommon.h>
+#include <SCIRun/Core/Thread/Mutex.h>
+
 namespace Manta {
 
   class Heightfield : public PrimitiveCommon
@@ -27,7 +30,10 @@
 
 //     virtual void rescaleDataHeight(Real scale);
 
-    Interpolable::InterpErr interpolate(const std::vector<keyframe_t> 
&keyframes);
+    virtual bool isParallel() const { return true; }
+    Interpolable::InterpErr serialInterpolate(const std::vector<keyframe_t> 
&keyframes);
+    Interpolable::InterpErr parallelInterpolate(const 
std::vector<keyframe_t> &keyframes,
+                                                int proc, int numproc);
 
   private:
     BBox m_Box;
@@ -37,7 +43,10 @@
     Vector cellsize;
     Vector inv_cellsize;
 
-    Heightfield() { };
+    SCIRun::Barrier barrier;
+    SCIRun::Mutex mutex;
+
+    Heightfield() : barrier("heightfield barrier"), mutex("heightfield 
mutex"){ };
 
   };
 }

Modified: trunk/Model/Primitives/Sphere.cc
==============================================================================
--- trunk/Model/Primitives/Sphere.cc    (original)
+++ trunk/Model/Primitives/Sphere.cc    Fri Apr 13 18:51:26 2007
@@ -30,7 +30,7 @@
   else
     copy = new Sphere();
 
-  copy->PrimitiveCommon::clone(depth, copy);
+  PrimitiveCommon::clone(depth, copy);
   copy->center = center;
   copy->radius = radius;
   copy->inv_radius = inv_radius;
@@ -389,7 +389,7 @@
   rays.setFlag(RayPacket::HaveTexture2|RayPacket::HaveTexture3);
 }
 
-Interpolable::InterpErr Sphere::interpolate(const std::vector<keyframe_t> 
&keyframes)
+Interpolable::InterpErr Sphere::serialInterpolate(const 
std::vector<keyframe_t> &keyframes)
 {
   PrimitiveCommon::interpolate(keyframes);
   center = Vector(0,0,0);

Modified: trunk/Model/Primitives/Sphere.h
==============================================================================
--- trunk/Model/Primitives/Sphere.h     (original)
+++ trunk/Model/Primitives/Sphere.h     Fri Apr 13 18:51:26 2007
@@ -12,7 +12,10 @@
     Sphere(Material* material, const Vector& center, Real radius);
     virtual ~Sphere();
 
+#ifndef SWIG
     virtual Sphere* clone(CloneDepth depth, Clonable* incoming);
+    virtual InterpErr serialInterpolate(const std::vector<keyframe_t> 
&keyframes);
+#endif
 
     virtual void computeBounds(const PreprocessContext& context,
                                BBox& bbox) const;
@@ -22,8 +25,6 @@
                                   RayPacket& rays) const;
     virtual void computeTexCoords3(const RenderContext& context,
                                   RayPacket& rays) const;
-
-    virtual InterpErr interpolate(const std::vector<keyframe_t> &keyframes);
 
     Vector getCenter(void) const
     {

Modified: trunk/Model/Primitives/Triangle.cc
==============================================================================
--- trunk/Model/Primitives/Triangle.cc  (original)
+++ trunk/Model/Primitives/Triangle.cc  Fri Apr 13 18:51:26 2007
@@ -31,7 +31,7 @@
   else
     copy = new Triangle();
 
-  copy->PrimitiveCommon::clone(depth, copy);
+  PrimitiveCommon::clone(depth, copy);
   copy->p1 = p1;
   copy->p2 = p2;
   copy->p3 = p3;
@@ -96,7 +96,7 @@
     rays.setNormal(i, Cross((p2-p1),(p3-p1)));
 }
 
-Interpolable::InterpErr Triangle::interpolate(const std::vector<keyframe_t> 
&keyframes)
+Interpolable::InterpErr Triangle::serialInterpolate(const 
std::vector<keyframe_t> &keyframes)
 {
   PrimitiveCommon::interpolate(keyframes);
   p1 = Vector(0,0,0);

Modified: trunk/Model/Primitives/Triangle.h
==============================================================================
--- trunk/Model/Primitives/Triangle.h   (original)
+++ trunk/Model/Primitives/Triangle.h   Fri Apr 13 18:51:26 2007
@@ -19,14 +19,16 @@
              const Vector& _p1, const Vector& _p2, const Vector& _p3);
     virtual ~Triangle();
     
+#ifndef SWIG
     virtual Triangle* clone(CloneDepth depth, Clonable* incoming);
+    virtual InterpErr serialInterpolate(const std::vector<keyframe_t> 
&keyframes);
+#endif
 
     virtual void computeBounds(const PreprocessContext& context,
                                BBox& bbox) const;
     virtual void intersect(const RenderContext& context, RayPacket& rays) 
const ;
     virtual void computeNormal(const RenderContext& context, RayPacket 
&rays) const;    
     
-    virtual InterpErr interpolate(const std::vector<keyframe_t> &keyframes);
     Vector p1, p2, p3;
   };
 }




  • [MANTA] r1344 - in trunk: Interface Model/Groups Model/MiscObjects Model/Primitives, thiago, 04/13/2007

Archive powered by MHonArc 2.6.16.

Top of page