BrookFloatStreamInternal.cpp 14.9 KB
Newer Older
Mark Friedrichs's avatar
Mark Friedrichs committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/* -------------------------------------------------------------------------- *
 *                                   OpenMM                                   *
 * -------------------------------------------------------------------------- *
 * This is part of the OpenMM molecular simulation toolkit originating from   *
 * Simbios, the NIH National Center for Physics-Based Simulation of           *
 * Biological Structures at Stanford, funded under the NIH Roadmap for        *
 * Medical Research, grant U54 GM072970. See https://simtk.org.               *
 *                                                                            *
 * Portions copyright (c) 2008 Stanford University and the Authors.           *
 * Authors: Peter Eastman, Mark Friedrichs                                    *
 * Contributors:                                                              *
 *                                                                            *
 * Permission is hereby granted, free of charge, to any person obtaining a    *
 * copy of this software and associated documentation files (the "Software"), *
 * to deal in the Software without restriction, including without limitation  *
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
 * and/or sell copies of the Software, and to permit persons to whom the      *
 * Software is furnished to do so, subject to the following conditions:       *
 *                                                                            *
 * The above copyright notice and this permission notice shall be included in *
 * all copies or substantial portions of the Software.                        *
 *                                                                            *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
 * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
 * -------------------------------------------------------------------------- */

32
#include <sstream>
Mark Friedrichs's avatar
Mark Friedrichs committed
33
34
#include "BrookFloatStreamInternal.h"
#include "BrookPlatform.h"
35
#include "OpenMMException.h"
Mark Friedrichs's avatar
Mark Friedrichs committed
36
37
38

using namespace OpenMM;

39
/** 
Mark Friedrichs's avatar
Mark Friedrichs committed
40
 * BrookFloatStreamInternal constructor
41
42
43
44
45
46
47
48
49
50
 * 
 * @param name                      stream name
 * @param size                      stream size
 * @param type                      stream type (float, float2, ...)
 * @param platform                  platform
 * @param inputStreamWidth          stream width
 * @param inputDefaultDangleValue   default dangle value
 *
 */

Mark Friedrichs's avatar
Mark Friedrichs committed
51
52
BrookFloatStreamInternal::BrookFloatStreamInternal( const std::string& name, int size, int streamWidth, BrookStreamInternal::DataType type,
                                                    double inputDefaultDangleValue ) : BrookStreamInternal( name, size, streamWidth, type ){
53
54
55

// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mark Friedrichs committed
56
   static const std::string methodName      = "BrookFloatStreamInternal::BrookFloatStreamInternal";
57
58
59
60
61
62
63
64
   // static const int debug                   = 1;

// ---------------------------------------------------------------------------------------

   // set base type (currently only FLOAT supported)

   switch( type ){

Mark Friedrichs's avatar
Mark Friedrichs committed
65
66
67
68
      case BrookStreamInternal::Float:
      case BrookStreamInternal::Float2:
      case BrookStreamInternal::Float3:
      case BrookStreamInternal::Float4:
69
   
Mark Friedrichs's avatar
Mark Friedrichs committed
70
          _baseType = BrookStreamInternal::Float;
71
72
          break;
   
Mark Friedrichs's avatar
Mark Friedrichs committed
73
74
75
76
      case BrookStreamInternal::Double:
      case BrookStreamInternal::Double2:
      case BrookStreamInternal::Double3:
      case BrookStreamInternal::Double4:
77

Mark Friedrichs's avatar
Mark Friedrichs committed
78
          _baseType = BrookStreamInternal::Double;
79
80
81
82
83
84
85
          break;

      default:
         std::stringstream message;
         message << methodName << " stream=" << name << " input type=" << type << " not recognized.";
         throw OpenMMException( message.str() );
         break;
Mark Friedrichs's avatar
Mark Friedrichs committed
86
87
   }

88
   // set _width (FLOAT, FLOAT2, ... )
Mark Friedrichs's avatar
Mark Friedrichs committed
89

90
   switch( type ){
Mark Friedrichs's avatar
Mark Friedrichs committed
91

Mark Friedrichs's avatar
Mark Friedrichs committed
92
93
      case BrookStreamInternal::Float:
      case BrookStreamInternal::Double:
Mark Friedrichs's avatar
Mark Friedrichs committed
94

95
96
97
          _width = 1;
          break;

Mark Friedrichs's avatar
Mark Friedrichs committed
98
99
      case BrookStreamInternal::Float2:
      case BrookStreamInternal::Double2:
100
101
102
103

          _width = 2;
          break;

Mark Friedrichs's avatar
Mark Friedrichs committed
104
105
      case BrookStreamInternal::Float3:
      case BrookStreamInternal::Double3:
Mark Friedrichs's avatar
Mark Friedrichs committed
106

107
108
          _width = 3;
          break;
Mark Friedrichs's avatar
Mark Friedrichs committed
109

Mark Friedrichs's avatar
Mark Friedrichs committed
110
111
      case BrookStreamInternal::Float4:
      case BrookStreamInternal::Double4:
Mark Friedrichs's avatar
Mark Friedrichs committed
112

113
114
115
116
          _width = 4;
          break;
   }

Mark Friedrichs's avatar
Mark Friedrichs committed
117
   _defaultDangleValue = (float) inputDefaultDangleValue;
118
119
120

   // set stream height based on specified stream _width

Mark Friedrichs's avatar
Mark Friedrichs committed
121
   if( streamWidth < 1 ){
122
      std::stringstream message;
Mark Friedrichs's avatar
Mark Friedrichs committed
123
      message << methodName << " stream=" << name << " input stream width=" << streamWidth << " is less than 1.";
124
125
126
127
      throw OpenMMException( message.str() );
   }

   // create Brook stream handle
Mark Friedrichs's avatar
Mark Friedrichs committed
128

129
   switch( _width ){
Mark Friedrichs's avatar
Mark Friedrichs committed
130

131
      case 1:
Mark Friedrichs's avatar
Mark Friedrichs committed
132

133
134
135
136
         _aStream      = brook::stream::create<float>(  _streamHeight, _streamWidth );
         break;
   
      case 2:
Mark Friedrichs's avatar
Mark Friedrichs committed
137

138
139
140
141
         _aStream      = brook::stream::create<float2>( _streamHeight, _streamWidth );
         break;
   
      case 3:
Mark Friedrichs's avatar
Mark Friedrichs committed
142

143
144
145
146
         _aStream      = brook::stream::create<float3>( _streamHeight, _streamWidth );
         break;
   
      case 4:
Mark Friedrichs's avatar
Mark Friedrichs committed
147

148
149
         _aStream      = brook::stream::create<float4>( _streamHeight, _streamWidth );
         break;
Mark Friedrichs's avatar
Mark Friedrichs committed
150
151
   }

Mark Friedrichs's avatar
Mark Friedrichs committed
152
   int streamSize = getStreamSize();
Mark Friedrichs's avatar
Mark Friedrichs committed
153

Mark Friedrichs's avatar
Mark Friedrichs committed
154
   // allocate memory for data buffer
Mark Friedrichs's avatar
Mark Friedrichs committed
155

Mark Friedrichs's avatar
Mark Friedrichs committed
156
   _data = new float[streamSize*_width];
157
158
159
160

}

/** 
Mark Friedrichs's avatar
Mark Friedrichs committed
161
 * BrookFloatStreamInternal destructor
162
163
164
 * 
 */

Mark Friedrichs's avatar
Mark Friedrichs committed
165
BrookFloatStreamInternal::~BrookFloatStreamInternal( ){
166
167
168

// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mark Friedrichs committed
169
   //static const std::string methodName      = "BrookFloatStreamInternal::~BrookFloatStreamInternal";
170
171
172
173
174
175
176
   // static const int debug                   = 1;

// ---------------------------------------------------------------------------------------

   //delete _aStream;
   delete[] _data;

Mark Friedrichs's avatar
Mark Friedrichs committed
177
178
179
180
181
182
183
}

/** 
 * Get dangle value
 * 
 * @return  dangle value
 */
184

Mark Friedrichs's avatar
Mark Friedrichs committed
185
186
double BrookFloatStreamInternal::getDangleValue( void ) const {
   return _defaultDangleValue;
187
188
189
}

/** 
Mark Friedrichs's avatar
Mark Friedrichs committed
190
 * Load data from input array
191
192
193
194
195
196
 * 
 * @param  array a pointer to the start of the array.  The array is assumed to have the same length as this stream,
 * and to contain elements of the correct _data type for this stream.  If the stream has a compound _data type, all
 * the values should be packed into a single array: all the values for the first element, followed by all the values
 * for the next element, etc.
 *
Mark Friedrichs's avatar
Mark Friedrichs committed
197
198
 * @throw exception if baseType not recognized
 *
199
200
 */

Mark Friedrichs's avatar
Mark Friedrichs committed
201
void BrookFloatStreamInternal::loadFromArray( const void* array ){
202
203
204

// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mark Friedrichs committed
205
   //static const std::string methodName      = "BrookFloatStreamInternal::loadFromArray";
206
207
208

// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mark Friedrichs committed
209
   return loadFromArray( array, getBaseDataType() );
210

Mark Friedrichs's avatar
Mark Friedrichs committed
211
212
}

213
/** 
Mark Friedrichs's avatar
Mark Friedrichs committed
214
 * Load data from input array
215
216
217
218
219
220
 * 
 * @param  array a pointer to the start of the array.  The array is assumed to have the same length as this stream,
 * and to contain elements of the correct _data type for this stream.  If the stream has a compound _data type, all
 * the values should be packed into a single array: all the values for the first element, followed by all the values
 * for the next element, etc.
 *
Mark Friedrichs's avatar
Mark Friedrichs committed
221
 * @throw exception if baseType not float or double
222
223
 *
 */
Mark Friedrichs's avatar
Mark Friedrichs committed
224

Mark Friedrichs's avatar
Mark Friedrichs committed
225
void BrookFloatStreamInternal::loadFromArray( const void* array, BrookStreamInternal::DataType baseType ){
226
227
228

// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mark Friedrichs committed
229
   static const std::string methodName      = "BrookFloatStreamInternal::loadFromArray";
230
231
232
233
   // static const int debug                   = 1;

// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mark Friedrichs committed
234
   int totalSize                           = getSize()*getWidth();
235

Mark Friedrichs's avatar
Mark Friedrichs committed
236
237
238
239
240
241
242
   if( baseType == BrookStreamInternal::Float ){

      memcpy( _data, array, sizeof( float )*totalSize );
/*
      float* arrayData = (float*) array;
      for( int ii = 0; ii < totalSize; ii++ ){
         _data[ii] = (BrookOpenMMFloat) arrayData[ii];
Mark Friedrichs's avatar
Mark Friedrichs committed
243
      }
Mark Friedrichs's avatar
Mark Friedrichs committed
244
*/
Mark Friedrichs's avatar
Mark Friedrichs committed
245

Mark Friedrichs's avatar
Mark Friedrichs committed
246
   } else if( baseType == BrookStreamInternal::Double ){
Mark Friedrichs's avatar
Mark Friedrichs committed
247
248

      double* arrayData = (double*) array;
Mark Friedrichs's avatar
Mark Friedrichs committed
249
250
      for( int ii = 0; ii < totalSize; ii++ ){
         _data[ii] = (BrookOpenMMFloat) arrayData[ii];
251
252
      }

Mark Friedrichs's avatar
Mark Friedrichs committed
253
   } else if( baseType == BrookStreamInternal::Integer ){
254
255

      int* arrayData = (int*) array;
Mark Friedrichs's avatar
Mark Friedrichs committed
256
257
      for( int ii = 0; ii < totalSize; ii++ ){
         _data[ii] = (BrookOpenMMFloat) arrayData[ii];
Mark Friedrichs's avatar
Mark Friedrichs committed
258
      }
259
260
261
262

   } else {
      
      std::stringstream message;
Mark Friedrichs's avatar
Mark Friedrichs committed
263
      message << methodName << " stream=" << getName() << " base type=" << getTypeString( baseType ) << " not recognized.";
264
265
      throw OpenMMException( message.str() );

Mark Friedrichs's avatar
Mark Friedrichs committed
266
267
268
269
270
271
   }

   // set dangling values

   _loadDanglingValues();

272
   // write to GPU
Mark Friedrichs's avatar
Mark Friedrichs committed
273

274
   _aStream.read( _data );
Mark Friedrichs's avatar
Mark Friedrichs committed
275
276
}

Mark Friedrichs's avatar
Mark Friedrichs committed
277
void BrookFloatStreamInternal::saveToArray( void* array ){
278
279

// ---------------------------------------------------------------------------------------
Mark Friedrichs's avatar
Mark Friedrichs committed
280

Mark Friedrichs's avatar
Mark Friedrichs committed
281
   static const std::string methodName      = "BrookFloatStreamInternal::saveToArray";
Mark Friedrichs's avatar
Mark Friedrichs committed
282

283
284
// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mark Friedrichs committed
285
   // get _data from GPU
286

Mark Friedrichs's avatar
Mark Friedrichs committed
287
   _aStream.write( _data );
Mark Friedrichs's avatar
Mark Friedrichs committed
288

Mark Friedrichs's avatar
Mark Friedrichs committed
289
   // load into array
Mark Friedrichs's avatar
Mark Friedrichs committed
290

Mark Friedrichs's avatar
Mark Friedrichs committed
291
292
   int totalSize                             = getSize()*getWidth();
   BrookStreamInternal::DataType  baseType   = getBaseDataType();
293

Mark Friedrichs's avatar
Mark Friedrichs committed
294
   if( baseType == BrookStreamInternal::Float ){
295

Mark Friedrichs's avatar
Mark Friedrichs committed
296
297
298
299
300
301
302
303
304
      memcpy( array, _data, sizeof( float )*totalSize );
/*
      float* arrayData = (float*) array;
      for( int ii = 0; ii < totalSize; ii++ ){
         arrayData[ii] = (float) _data[ii];
      }
*/

   } else if( baseType == BrookStreamInternal::Double ){
305

Mark Friedrichs's avatar
Mark Friedrichs committed
306
      double* arrayData = (double*) array;
Mark Friedrichs's avatar
Mark Friedrichs committed
307
308
      for( int ii = 0; ii < totalSize; ii++ ){
         arrayData[ii] = (double) _data[ii];
Mark Friedrichs's avatar
Mark Friedrichs committed
309
      }
310

Mark Friedrichs's avatar
Mark Friedrichs committed
311
312
313
314
315
316
317
318
319
320
321
322
   } else if( baseType == BrookStreamInternal::Integer ){

      int* arrayData = (int*) array;
      for( int ii = 0; ii < totalSize; ii++ ){
         arrayData[ii] = (int) _data[ii];
      }
   } else {
      
      std::stringstream message;
      message << methodName << " stream=" << getName() << " base type=" << getTypeString( baseType ) << " not recognized.";
      throw OpenMMException( message.str() );

Mark Friedrichs's avatar
Mark Friedrichs committed
323
324
325
   }
}

326
327
328
329
330
331
332
/** 
 * Fill stream w/ specified value
 * 
 * @param value                     value to fill stream w/
 *
 */

Mark Friedrichs's avatar
Mark Friedrichs committed
333
void BrookFloatStreamInternal::fillWithValue( void* value ){
Mark Friedrichs's avatar
Mark Friedrichs committed
334

335
336
// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mark Friedrichs committed
337
   // static const std::string methodName      = "BrookFloatStreamInternal::fillWithValue";
338
339
340
341
342
   // static const int debug                   = 1;

// ---------------------------------------------------------------------------------------

   BrookOpenMMFloat valueData;
Mark Friedrichs's avatar
Mark Friedrichs committed
343
   if( _baseType == BrookStreamInternal::Float) {
344
      valueData = (BrookOpenMMFloat) *((float*) value);
Mark Friedrichs's avatar
Mark Friedrichs committed
345
   } else {
346
347
      valueData = (BrookOpenMMFloat) *((double*) value);
   }
Mark Friedrichs's avatar
Mark Friedrichs committed
348
349
350
351
352
   //memset( _data, valueData, sizeof( float )*getSize()*getWidth() );

   int totalSize = getSize()*getWidth();
   for( int ii = 0; ii < totalSize; ii++ ){
      _data[ii] = valueData;
Mark Friedrichs's avatar
Mark Friedrichs committed
353
   }
354

Mark Friedrichs's avatar
Mark Friedrichs committed
355
   _loadDanglingValues();
356
   _aStream.read( _data );
Mark Friedrichs's avatar
Mark Friedrichs committed
357

Mark Friedrichs's avatar
Mark Friedrichs committed
358
359
}

Mark Friedrichs's avatar
Mark Friedrichs committed
360
361
362
363
364
365
366
367
/** 
 * Get data
 * 
 * @param readFromBoard if set, read values on board 
 *
 * @return data array
 *
 */
368

Mark Friedrichs's avatar
Mark Friedrichs committed
369
void* BrookFloatStreamInternal::getData( int readFromBoard ){
Mark Friedrichs's avatar
Mark Friedrichs committed
370

Mark Friedrichs's avatar
Mark Friedrichs committed
371
// ---------------------------------------------------------------------------------------
Mark Friedrichs's avatar
Mark Friedrichs committed
372

Mark Friedrichs's avatar
Mark Friedrichs committed
373
   // static const std::string methodName      = "BrookFloatStreamInternal::getData";
Mark Friedrichs's avatar
Mark Friedrichs committed
374

Mark Friedrichs's avatar
Mark Friedrichs committed
375
// ---------------------------------------------------------------------------------------
Mark Friedrichs's avatar
Mark Friedrichs committed
376

Mark Friedrichs's avatar
Mark Friedrichs committed
377
378
   if( readFromBoard ){
      _aStream.write( _data );
Mark Friedrichs's avatar
Mark Friedrichs committed
379
   }
Mark Friedrichs's avatar
Mark Friedrichs committed
380
381

   return (void*) _data;
Mark Friedrichs's avatar
Mark Friedrichs committed
382
383
}

384
385
386
387
388
389
390
/** 
 * Get data
 * 
 * @return data array
 *
 */

Mark Friedrichs's avatar
Mark Friedrichs committed
391
void* BrookFloatStreamInternal::getData( void ){
392
393
394

// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mark Friedrichs committed
395
   // static const std::string methodName      = "BrookFloatStreamInternal::getData";
396
397
398

// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mark Friedrichs committed
399
   return getData( 0 );
Mark Friedrichs's avatar
Mark Friedrichs committed
400
401
}

402
403
404
405
406
407
408
/** 
 * Load dangling value into stream
 * 
 * @param danglingValue   dangling value to load
 *
 */

Mark Friedrichs's avatar
Mark Friedrichs committed
409
void BrookFloatStreamInternal::_loadDanglingValues( float danglingValue ){
Mark Friedrichs's avatar
Mark Friedrichs committed
410

411
412
// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mark Friedrichs committed
413
   // static const std::string methodName      = "BrookFloatStreamInternal::_loadDanglingValues";
414
415
416
417
   // static const int debug                   = 1;

// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mark Friedrichs committed
418
419
420
421
422
423
424
425
   int width      = getWidth();

   int arraySize  = getSize()*width;
   int streamSize = getStreamSize()*width;

   if( arraySize < streamSize ){
      for( int ii = arraySize; ii < streamSize; ii++ ){
          _data[ii] = danglingValue;
Mark Friedrichs's avatar
Mark Friedrichs committed
426
427
428
429
       }
    }
}

430
431
432
433
434
/** 
 * Load default dangling value into stream
 * 
 */

Mark Friedrichs's avatar
Mark Friedrichs committed
435
void BrookFloatStreamInternal::_loadDanglingValues( void ){
436
   _loadDanglingValues( _defaultDangleValue );
Mark Friedrichs's avatar
Mark Friedrichs committed
437
}
Mark Friedrichs's avatar
Mark Friedrichs committed
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491

/* 
 * Get contents of object
 *
 * @param level   level of dump
 *
 * @return string containing contents
 *
 * */

const std::string BrookFloatStreamInternal::getContentsString( int level ) const {

// ---------------------------------------------------------------------------------------

   // static const std::string methodName      = "BrookFloatStreamInternal::getContentsString";

   static const unsigned int MAX_LINE_CHARS = 256; 
   char value[MAX_LINE_CHARS];
   //static const char* Set                   = "Set";
   //static const char* NotSet                = "Not set";


// ---------------------------------------------------------------------------------------

   std::stringstream message;
   std::string tab   = "   ";
 
#ifdef WIN32
#define LOCAL_SPRINTF(a,b,c) sprintf_s( (a), MAX_LINE_CHARS, (b), (c) );   
#else
#define LOCAL_SPRINTF(a,b,c) sprintf( (a), (b), (c) );   
#endif

   (void) LOCAL_SPRINTF( value, "%s", getName().c_str() );
   message << _getLine( tab, "Name:", value ); 

   (void) LOCAL_SPRINTF( value, "%d", getWidth() );
   message << _getLine( tab, "Width:", value ); 

   (void) LOCAL_SPRINTF( value, "%d", getStreamSize() );
   message << _getLine( tab, "Stream size:", value ); 

   (void) LOCAL_SPRINTF( value, "%d", getStreamWidth() );
   message << _getLine( tab, "Stream width:", value ); 

   (void) LOCAL_SPRINTF( value, "%d", getStreamHeight() );
   message << _getLine( tab, "Stream height:", value ); 

   (void) LOCAL_SPRINTF( value, "%3e", getDangleValue() );
   message << _getLine( tab, "Dangle value:", value ); 

   return message.str();
}