Equalizer  1.2.1
eqNBody/frameData.cpp
00001 
00002 /*
00003  * Copyright (c) 2009, Philippe Robert <philippe.robert@gmail.com>
00004  *               2010-2011, Stefan Eilemann <eile@eyescale.ch>
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright notice, this
00010  *   list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright notice,
00012  *   this list of conditions and the following disclaimer in the documentation
00013  *   and/or other materials provided with the distribution.
00014  * - Neither the name of Eyescale Software GmbH nor the names of its
00015  *   contributors may be used to endorse or promote products derived from this
00016  *   software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00019  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00022  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028  * POSSIBILITY OF SUCH DAMAGE.
00029  */
00030 
00031 #include "frameData.h"
00032 #include "nbody.h"
00033 
00034 #include <cuda.h>
00035 
00036 #if CUDART_VERSION >= 2020
00037 # define ENABLE_HOSTALLOC
00038 #endif
00039 
00040 namespace eqNbody
00041 {
00042 FrameData::FrameData() : _statistics( true ) , _numDataProxies(0), _hPos(0)
00043                        , _hVel(0), _hCol(0)
00044 {       
00045     _numBodies      = 0;
00046     _deltaTime      = 0.0f;
00047     _clusterScale   = 0.0f;
00048     _velocityScale  = 0.0f;
00049     _newParameters  = false;
00050 }
00051     
00052 FrameData::~FrameData()
00053 {
00054     _numDataProxies = 0;
00055 }
00056     
00057 void FrameData::serialize( co::DataOStream& os, const uint64_t dirtyBits )
00058 {       
00059     co::Serializable::serialize( os, dirtyBits );
00060         
00061     if( dirtyBits & DIRTY_DATA ) {
00062         if(_hPos && _hVel && _hCol) {
00063             os.write(_hPos, sizeof(float)*_numBodies*4);
00064             os.write(_hVel, sizeof(float)*_numBodies*4);
00065             os.write(_hCol, sizeof(float)*_numBodies*4);
00066         }
00067     }
00068         
00069     if( dirtyBits & DIRTY_FLAGS )
00070         os << _statistics << _numBodies << _clusterScale << _velocityScale
00071            << _deltaTime << _newParameters;
00072         
00073     if( dirtyBits & DIRTY_PROXYDATA )
00074     {
00075         os << _numDataProxies;
00076         os.write( _dataProxyID, sizeof(co::ObjectVersion) * MAX_NGPUS ); 
00077         os.write(&_dataRanges[0], sizeof(float) * MAX_NGPUS);           
00078     }
00079 }
00080     
00081 void FrameData::deserialize( co::DataIStream& is,
00082                              const uint64_t dirtyBits )
00083 {
00084     co::Serializable::deserialize( is, dirtyBits );
00085         
00086     if( dirtyBits & DIRTY_DATA ) {
00087         if(_hPos && _hVel && _hCol) {
00088             is.read(_hPos, sizeof(float)*_numBodies*4);
00089             is.read(_hVel, sizeof(float)*_numBodies*4);
00090             is.read(_hCol, sizeof(float)*_numBodies*4);
00091         }
00092     }
00093         
00094     if( dirtyBits & DIRTY_FLAGS )
00095         is >> _statistics >> _numBodies >> _clusterScale >> _velocityScale
00096            >> _deltaTime >> _newParameters;
00097         
00098     if( dirtyBits & DIRTY_PROXYDATA )
00099     {
00100         is >> _numDataProxies;
00101         is.read( _dataProxyID, sizeof( co::ObjectVersion ) * MAX_NGPUS );
00102         is.read(&_dataRanges[0], sizeof(float) * MAX_NGPUS);
00103     }
00104 }
00105     
00106 void FrameData::addProxyID( const eq::uint128_t& pid, const float *range )
00107 {
00108     EQASSERT(_numDataProxies < MAX_NGPUS);
00109         
00110     _dataProxyID[_numDataProxies].identifier = pid;  
00111     _dataProxyID[_numDataProxies].version = co::VERSION_NONE;
00112 
00113     _dataRanges[_numDataProxies++] = (range[1] - range[0]);
00114     setDirty( DIRTY_PROXYDATA );
00115 }
00116     
00117 void FrameData::updateProxyID( const eq::uint128_t& pid,
00118                                const eq::uint128_t& version,
00119                                const float *range )
00120 {
00121     // TODO: Better use a hash here!
00122     for(unsigned int i=0; i< _numDataProxies; i++)
00123     {
00124         if( pid == _dataProxyID[i].identifier )
00125         {
00126             _dataProxyID[i].version = version;
00127             _dataRanges[i] = (range[1] - range[0]);
00128             break;
00129         }
00130     }
00131     setDirty( DIRTY_PROXYDATA );
00132 }
00133     
00134 eq::uint128_t FrameData::commit()
00135 {
00136     const eq::uint128_t v = co::Serializable::commit();
00137     for( unsigned int i = 0; i< _numDataProxies; ++i )
00138         _dataRanges[i] = 0.0f;
00139         
00140     return v;
00141 }
00142     
00143 bool FrameData::isReady()
00144 {
00145     float length = 0.0f;
00146         
00147     for(unsigned int i=0; i<_numDataProxies; i++) {
00148         length += _dataRanges[i];
00149     }
00150         
00151     // Return true if range [0 1] is covered, otherwise false
00152     return (length == 1.0f) ? true : false;
00153 }
00154     
00155 eq::uint128_t FrameData::getVersionForProxyID( const eq::uint128_t& pid ) const
00156 {       
00157     // TODO: Better use a hash here!
00158     for( unsigned int i=0; i< _numDataProxies; ++i )
00159     {
00160         if( pid == getProxyID( i ))
00161             return getProxyVersion( i );
00162     }
00163         
00164     return 0;
00165 }
00166     
00167 void FrameData::toggleStatistics()
00168 {
00169     _statistics = !_statistics;
00170     setDirty( DIRTY_FLAGS );
00171 }
00172     
00173 void FrameData::init(const unsigned int numBodies)
00174 {
00175     _numBodies  = numBodies;
00176                 
00177     setDirty( DIRTY_FLAGS );
00178 }
00179     
00180 void FrameData::initHostData()
00181 {       
00182 #ifdef ENABLE_HOSTALLOC
00183     allocateHostArrays(&_hPos, &_hVel, &_hCol, _numBodies*4*sizeof(float));
00184 #else
00185     _hPos       = new float[_numBodies*4];
00186     _hVel       = new float[_numBodies*4];
00187     _hCol       = new float[_numBodies*4];
00188 #endif
00189         
00190     memset(_hPos, 0, _numBodies*4*sizeof(float));
00191     memset(_hVel, 0, _numBodies*4*sizeof(float));
00192     memset(_hCol, 0, _numBodies*4*sizeof(float));
00193         
00194     setDirty( DIRTY_DATA );
00195 }
00196     
00197 void FrameData::exit()
00198 {
00199     _numDataProxies = 0;
00200     _numBodies      = 0;
00201 
00202 #ifdef ENABLE_HOSTALLOC
00203     deleteHostArrays(_hPos, _hVel, _hCol);
00204 #else
00205     delete [] _hPos;
00206     delete [] _hVel;    
00207     delete [] _hCol;    
00208 #endif
00209 }
00210     
00211 void FrameData::updateParameters(NBodyConfig config, float clusterScale, float velocityScale, float ts)
00212 {       
00213     _clusterScale   = clusterScale;
00214     _velocityScale  = velocityScale;
00215     _deltaTime      = ts;
00216     _newParameters  = true;
00217         
00218     _randomizeData(config);
00219         
00220     setDirty( DIRTY_DATA );
00221     setDirty( DIRTY_FLAGS );
00222 }
00223     
00224 void FrameData::_randomizeData(NBodyConfig config)
00225 {
00226     switch(config)
00227     {
00228       default:
00229       case NBODY_CONFIG_RANDOM:
00230       {
00231           float scale  = _clusterScale * std::max(1.0f, _numBodies / (1024.f));
00232           float vscale = _velocityScale * scale;
00233                 
00234           int p = 0, v = 0;
00235           unsigned int i = 0;
00236           while (i < _numBodies) 
00237           {
00238               eq::Vector3f point;
00239               //const int scale = 16;
00240               point.x() = rand() / (float) RAND_MAX * 2 - 1;
00241               point.y() = rand() / (float) RAND_MAX * 2 - 1;
00242               point.z() = rand() / (float) RAND_MAX * 2 - 1;
00243               float lenSqr = point.squared_length();
00244               if (lenSqr > 1)
00245                   continue;
00246               eq::Vector3f velocity;
00247               velocity.x() = rand() / (float) RAND_MAX * 2 - 1;
00248               velocity.y() = rand() / (float) RAND_MAX * 2 - 1;
00249               velocity.z() = rand() / (float) RAND_MAX * 2 - 1;
00250               lenSqr = velocity.squared_length();
00251               if (lenSqr > 1)
00252                   continue;
00253                     
00254               _hPos[p++] = point.x() * scale; // pos.x
00255               _hPos[p++] = point.y() * scale; // pos.y
00256               _hPos[p++] = point.z() * scale; // pos.z
00257               _hPos[p++] = 1.0f; // mass
00258                     
00259               _hVel[v++] = velocity.x() * vscale; // pos.x
00260               _hVel[v++] = velocity.y() * vscale; // pos.x
00261               _hVel[v++] = velocity.z() * vscale; // pos.x
00262               _hVel[v++] = 1.0f; // inverse mass
00263                     
00264               i++;
00265           }
00266       }
00267       break;
00268       case NBODY_CONFIG_SHELL:
00269       {
00270           float scale = _clusterScale;
00271           float vscale = scale * _velocityScale;
00272           float inner = 2.5f * scale;
00273           float outer = 4.0f * scale;
00274                 
00275           int p = 0, v=0;
00276           unsigned int i = 0;
00277           while (i < _numBodies)//for(int i=0; i < numBodies; i++) 
00278           {
00279               float x, y, z;
00280               x = rand() / (float) RAND_MAX * 2 - 1;
00281               y = rand() / (float) RAND_MAX * 2 - 1;
00282               z = rand() / (float) RAND_MAX * 2 - 1;
00283                     
00284               eq::Vector3f point( x, y, z );
00285               float len = point.normalize();
00286               if (len > 1)
00287                   continue;
00288                     
00289               _hPos[p++] =  point.x() * (inner + (outer - inner) * rand() / (float) RAND_MAX);
00290               _hPos[p++] =  point.y() * (inner + (outer - inner) * rand() / (float) RAND_MAX);
00291               _hPos[p++] =  point.z() * (inner + (outer - inner) * rand() / (float) RAND_MAX);
00292               _hPos[p++] = 1.0f;
00293                     
00294               x = 0.0f; // * (rand() / (float) RAND_MAX * 2 - 1);
00295               y = 0.0f; // * (rand() / (float) RAND_MAX * 2 - 1);
00296               z = 1.0f; // * (rand() / (float) RAND_MAX * 2 - 1);
00297               eq::Vector3f axis( x, y, z );
00298               axis.normalize();
00299                     
00300               if (1 - point.dot(axis) < 1e-6)
00301               {
00302                   axis.x() = point.y();
00303                   axis.y() = point.x();
00304                   axis.normalize();
00305               }
00306               //if (point.y < 0) axis = scalevec(axis, -1);
00307               eq::Vector3f vv( _hPos[4*i], _hPos[4*i+1], _hPos[4*i+2] );
00308               vv = vv.cross( axis );
00309               _hVel[v++] = vv.x() * vscale;
00310               _hVel[v++] = vv.y() * vscale;
00311               _hVel[v++] = vv.z() * vscale;
00312               _hVel[v++] = 1.0f;
00313                     
00314               i++;
00315           }
00316       }
00317       break;
00318       case NBODY_CONFIG_EXPAND:
00319       {
00320           float scale = _clusterScale * std::max(1.0f, _numBodies / (1024.f));
00321           float vscale = scale * _velocityScale;
00322                 
00323           int p = 0, v = 0;
00324           for(unsigned int i=0; i < _numBodies;) 
00325           {
00326               eq::Vector3f point;
00327                     
00328               point.x() = rand() / (float) RAND_MAX * 2 - 1;
00329               point.y() = rand() / (float) RAND_MAX * 2 - 1;
00330               point.z() = rand() / (float) RAND_MAX * 2 - 1;
00331                     
00332               float lenSqr = point.squared_length();
00333               if (lenSqr > 1)
00334                   continue;
00335                     
00336               _hPos[p++] = point.x() * scale; // pos.x
00337               _hPos[p++] = point.y() * scale; // pos.y
00338               _hPos[p++] = point.z() * scale; // pos.z
00339               _hPos[p++] = 1.0f; // mass
00340                     
00341               _hVel[v++] = point.x() * vscale; // pos.x
00342               _hVel[v++] = point.y() * vscale; // pos.x
00343               _hVel[v++] = point.z() * vscale; // pos.x
00344               _hVel[v++] = 1.0f; // inverse mass
00345                     
00346               i++;
00347           }
00348       }
00349       break;
00350     }
00351         
00352     if (_hCol)
00353     {
00354         int v = 0;
00355         for(unsigned int i=0; i < _numBodies; i++) 
00356         {
00357             _hCol[v++] = rand() / (float) RAND_MAX;
00358             _hCol[v++] = rand() / (float) RAND_MAX;
00359             _hCol[v++] = rand() / (float) RAND_MAX;
00360             _hCol[v++] = 1.0f;
00361         }
00362     }       
00363 }
00364 }
00365 
Generated on Fri Jun 8 2012 15:44:30 for Equalizer 1.2.1 by  doxygen 1.8.0