BrookFloatStreamInternal.cpp 22.2 KB
Newer Older
Mark Friedrichs's avatar
Mark Friedrichs committed
1
2
3
4
5
6
7
8
/* -------------------------------------------------------------------------- *
 *                                   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.               *
 *                                                                            *
9
10
 * Portions copyright (c) 2009 Stanford University and the Authors.           *
 * Authors: Mark Friedrichs, Mike Houston                                     *
Mark Friedrichs's avatar
Mark Friedrichs committed
11
12
 * Contributors:                                                              *
 *                                                                            *
13
14
15
16
 * This program is free software: you can redistribute it and/or modify       *
 * it under the terms of the GNU Lesser General Public License as published   *
 * by the Free Software Foundation, either version 3 of the License, or       *
 * (at your option) any later version.                                        *
Mark Friedrichs's avatar
Mark Friedrichs committed
17
 *                                                                            *
18
19
20
21
 * This program is distributed in the hope that it will be useful,            *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
 * GNU Lesser General Public License for more details.                        *
Mark Friedrichs's avatar
Mark Friedrichs committed
22
 *                                                                            *
23
24
 * You should have received a copy of the GNU Lesser General Public License   *
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.      *
Mark Friedrichs's avatar
Mark Friedrichs committed
25
26
 * -------------------------------------------------------------------------- */

27

28
#include <sstream>
Mark Friedrichs's avatar
Mark Friedrichs committed
29
30
#include "BrookFloatStreamInternal.h"
#include "BrookPlatform.h"
31
#include "openmm/OpenMMException.h"
Mark Friedrichs's avatar
Mark Friedrichs committed
32
33
34

using namespace OpenMM;

35
/** 
Mark Friedrichs's avatar
Mark Friedrichs committed
36
 * BrookFloatStreamInternal constructor
37
38
39
40
41
42
43
44
 * 
 * @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
Mods  
Mark Friedrichs committed
45
46
 * @throw exception if stream type not recognized or stream width < 1
 *
47
48
 */

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

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

Mark Friedrichs's avatar
Mark Friedrichs committed
54
   static const std::string methodName      = "BrookFloatStreamInternal::BrookFloatStreamInternal";
55
56
57

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

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
58
59
60
//fprintf( stderr,"%s %s\n", methodName.c_str(), getName().c_str() );
//fflush( stderr );

61
62
63
64
   // 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

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

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

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

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

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

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

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

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

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

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

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

159
160
161
//printf( "%s %s data=%u stream=%d [%d %d] width=%d\n", methodName.c_str(), getName().c_str(), (unsigned int) _data, streamSize, _streamHeight, _streamWidth, _width );
//fflush( stdout );

162
163
164
}

/** 
Mark Friedrichs's avatar
Mark Friedrichs committed
165
 * BrookFloatStreamInternal destructor
166
167
168
 * 
 */

Mark Friedrichs's avatar
Mark Friedrichs committed
169
BrookFloatStreamInternal::~BrookFloatStreamInternal( ){
170
171
172

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

173
   static const std::string methodName      = "BrookFloatStreamInternal::~BrookFloatStreamInternal";
174
175
176

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

177
178
179
//printf( "%s %s data=%u stream=%d [%d %d] width=%d\n", methodName.c_str(), getName().c_str(), (unsigned int) _data, getStreamSize(), _streamHeight, _streamWidth, _width );
//fflush( stdout );

180
181
   delete[] _data;

Mark Friedrichs's avatar
Mark Friedrichs committed
182
183
184
185
186
187
188
}

/** 
 * Get dangle value
 * 
 * @return  dangle value
 */
189

Mark Friedrichs's avatar
Mark Friedrichs committed
190
191
double BrookFloatStreamInternal::getDangleValue( void ) const {
   return _defaultDangleValue;
192
193
194
}

/** 
Mark Friedrichs's avatar
Mark Friedrichs committed
195
 * Load data from input array
196
197
198
199
200
201
 * 
 * @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
202
203
 * @throw exception if baseType not recognized
 *
204
205
 */

Mark Friedrichs's avatar
Mark Friedrichs committed
206
void BrookFloatStreamInternal::loadFromArray( const void* array ){
207
208
209

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

Mark Friedrichs's avatar
Mark Friedrichs committed
210
   //static const std::string methodName      = "BrookFloatStreamInternal::loadFromArray";
211
212
213

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

Mark Friedrichs's avatar
Mark Friedrichs committed
214
   return loadFromArray( array, getBaseDataType() );
215

Mark Friedrichs's avatar
Mark Friedrichs committed
216
217
}

218
/** 
Mark Friedrichs's avatar
Mark Friedrichs committed
219
 * Load data from input array
220
221
222
223
224
225
 * 
 * @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.
 *
226
 * @throw exception if baseType not float, double, or integer
227
228
 *
 */
Mark Friedrichs's avatar
Mark Friedrichs committed
229

Mark Friedrichs's avatar
Mark Friedrichs committed
230
void BrookFloatStreamInternal::loadFromArray( const void* array, BrookStreamInternal::DataType baseType ){
231
232
233

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

Mark Friedrichs's avatar
Mark Friedrichs committed
234
   static const std::string methodName      = "BrookFloatStreamInternal::loadFromArray";
235
236
237

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

Mark Friedrichs's avatar
Mark Friedrichs committed
238
   int totalSize                           = getSize()*getWidth();
239
   //int totalSize                           = getSize();
240

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
241
242
243
244
245
246
/*
fprintf( stderr, "%s %s data=%p stream=%d [%d %d] width=%d type=%d\n",
          methodName.c_str(), getName().c_str(), _data, getStreamSize(), _streamHeight, _streamWidth, _width, baseType );
fflush( stderr );
*/

Mark Friedrichs's avatar
Mark Friedrichs committed
247
248
249
250
251
252
253
   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
254
      }
Mark Friedrichs's avatar
Mark Friedrichs committed
255
*/
Mark Friedrichs's avatar
Mark Friedrichs committed
256

Mark Friedrichs's avatar
Mark Friedrichs committed
257
   } else if( baseType == BrookStreamInternal::Double ){
Mark Friedrichs's avatar
Mark Friedrichs committed
258
259

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

Mark Friedrichs's avatar
Mark Friedrichs committed
264
   } else if( baseType == BrookStreamInternal::Integer ){
265
266

      int* arrayData = (int*) array;
Mark Friedrichs's avatar
Mark Friedrichs committed
267
268
      for( int ii = 0; ii < totalSize; ii++ ){
         _data[ii] = (BrookOpenMMFloat) arrayData[ii];
Mark Friedrichs's avatar
Mark Friedrichs committed
269
      }
270
271
272
273

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

Mark Friedrichs's avatar
Mark Friedrichs committed
277
278
279
280
281
282
   }

   // set dangling values

   _loadDanglingValues();

283
   // write to GPU
Mark Friedrichs's avatar
Mark Friedrichs committed
284

285
   _aStream.read( _data );
Mark Friedrichs's avatar
Mark Friedrichs committed
286
287
}

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
288
289
290
291
292
293
294
295
296
297
298
299
/** 
 * Save data to input array
 * 
 * @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.
 *
 * @throw exception if baseType not float, double, or integer
 *
 */

Mark Friedrichs's avatar
Mark Friedrichs committed
300
void BrookFloatStreamInternal::saveToArray( void* array ){
301
302

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

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

306
307
// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mark Friedrichs committed
308
   // get _data from GPU
309

Mark Friedrichs's avatar
Mark Friedrichs committed
310
   _aStream.write( _data );
Mark Friedrichs's avatar
Mark Friedrichs committed
311

Mark Friedrichs's avatar
Mark Friedrichs committed
312
   // load into array
Mark Friedrichs's avatar
Mark Friedrichs committed
313

Mark Friedrichs's avatar
Mark Friedrichs committed
314
315
   int totalSize                             = getSize()*getWidth();
   BrookStreamInternal::DataType  baseType   = getBaseDataType();
316

Mark Friedrichs's avatar
Mark Friedrichs committed
317
   if( baseType == BrookStreamInternal::Float ){
318

319
320
//printf( "%s Basetype is float\n", methodName.c_str() );
//fflush( stdout );
Mark Friedrichs's avatar
Mark Friedrichs committed
321
322
323
324
325
326
327
328
329
      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 ){
330

331
332
333
//printf( "%s Basetype is double\n", methodName.c_str() );
//fflush( stdout );

Mark Friedrichs's avatar
Mark Friedrichs committed
334
      double* arrayData = (double*) array;
Mark Friedrichs's avatar
Mark Friedrichs committed
335
336
      for( int ii = 0; ii < totalSize; ii++ ){
         arrayData[ii] = (double) _data[ii];
Mark Friedrichs's avatar
Mark Friedrichs committed
337
      }
338

Mark Friedrichs's avatar
Mark Friedrichs committed
339
340
   } else if( baseType == BrookStreamInternal::Integer ){

341
342
343
//printf( "%s Basetype is int\n", methodName.c_str() );
//fflush( stdout );

Mark Friedrichs's avatar
Mark Friedrichs committed
344
345
346
347
348
349
350
351
352
353
      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
354
355
356
   }
}

357
358
359
360
361
362
363
/** 
 * Fill stream w/ specified value
 * 
 * @param value                     value to fill stream w/
 *
 */

Mark Friedrichs's avatar
Mark Friedrichs committed
364
void BrookFloatStreamInternal::fillWithValue( void* value ){
Mark Friedrichs's avatar
Mark Friedrichs committed
365

366
367
// ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Mark Friedrichs committed
368
   // static const std::string methodName      = "BrookFloatStreamInternal::fillWithValue";
369
370
371
372
373
   // static const int debug                   = 1;

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

   BrookOpenMMFloat valueData;
Mark Friedrichs's avatar
Mark Friedrichs committed
374
   if( _baseType == BrookStreamInternal::Float) {
375
      valueData = (BrookOpenMMFloat) *((float*) value);
Mark Friedrichs's avatar
Mark Friedrichs committed
376
   } else {
377
378
      valueData = (BrookOpenMMFloat) *((double*) value);
   }
Mark Friedrichs's avatar
Mark Friedrichs committed
379
380
381
382
383
   //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
384
   }
385

Mark Friedrichs's avatar
Mark Friedrichs committed
386
   _loadDanglingValues();
387
   _aStream.read( _data );
Mark Friedrichs's avatar
Mark Friedrichs committed
388

Mark Friedrichs's avatar
Mark Friedrichs committed
389
390
}

Mark Friedrichs's avatar
Mark Friedrichs committed
391
392
393
394
395
396
397
398
/** 
 * Get data
 * 
 * @param readFromBoard if set, read values on board 
 *
 * @return data array
 *
 */
399

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

Mark Friedrichs's avatar
Mark Friedrichs committed
402
// ---------------------------------------------------------------------------------------
Mark Friedrichs's avatar
Mark Friedrichs committed
403

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

Mark Friedrichs's avatar
Mark Friedrichs committed
406
// ---------------------------------------------------------------------------------------
Mark Friedrichs's avatar
Mark Friedrichs committed
407

Mark Friedrichs's avatar
Mark Friedrichs committed
408
409
   if( readFromBoard ){
      _aStream.write( _data );
Mark Friedrichs's avatar
Mark Friedrichs committed
410
   }
Mark Friedrichs's avatar
Mark Friedrichs committed
411
412

   return (void*) _data;
Mark Friedrichs's avatar
Mark Friedrichs committed
413
414
}

415
416
417
418
419
420
421
/** 
 * Get data
 * 
 * @return data array
 *
 */

Mark Friedrichs's avatar
Mark Friedrichs committed
422
void* BrookFloatStreamInternal::getData( void ){
423
424
425

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

Mark Friedrichs's avatar
Mark Friedrichs committed
426
   // static const std::string methodName      = "BrookFloatStreamInternal::getData";
427
428
429

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

Mark Friedrichs's avatar
Mark Friedrichs committed
430
   return getData( 0 );
Mark Friedrichs's avatar
Mark Friedrichs committed
431
432
}

433
434
435
436
437
438
439
/** 
 * Load dangling value into stream
 * 
 * @param danglingValue   dangling value to load
 *
 */

Mark Friedrichs's avatar
Mark Friedrichs committed
440
void BrookFloatStreamInternal::_loadDanglingValues( float danglingValue ){
Mark Friedrichs's avatar
Mark Friedrichs committed
441

442
443
// ---------------------------------------------------------------------------------------

444
    static const std::string methodName      = "BrookFloatStreamInternal::_loadDanglingValues";
445
446
447

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

Mark Friedrichs's avatar
Mark Friedrichs committed
448
449
450
451
452
   int width      = getWidth();

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

453
454
455
//printf( "%s array=%d stream=%d width=%d %s\n", methodName.c_str(), arraySize, streamSize, width, getName().c_str() );
//fflush( stdout );

Mark Friedrichs's avatar
Mark Friedrichs committed
456
457
458
   if( arraySize < streamSize ){
      for( int ii = arraySize; ii < streamSize; ii++ ){
          _data[ii] = danglingValue;
Mark Friedrichs's avatar
Mark Friedrichs committed
459
460
461
462
       }
    }
}

463
464
465
466
467
/** 
 * Load default dangling value into stream
 * 
 */

Mark Friedrichs's avatar
Mark Friedrichs committed
468
void BrookFloatStreamInternal::_loadDanglingValues( void ){
469
   _loadDanglingValues( _defaultDangleValue );
Mark Friedrichs's avatar
Mark Friedrichs committed
470
}
Mark Friedrichs's avatar
Mark Friedrichs committed
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524

/* 
 * 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();
}

525
526
527
528
529
530
531
532
533
/* 
 * Print array contents of object to file
 *
 * @param log         file to print to
 *
 * @return DefaultReturnValue
 *
 * */

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
534
int BrookFloatStreamInternal::_bodyPrintToFile( FILE* log, int maxPrint ){
535
536
537
538

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

   //static const std::string methodName      = "BrookStreamInternal::_bodyPrintToFile";
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
539
540
541
   static const unsigned int MAX_LINE_CHARS = 256;
   char value[MAX_LINE_CHARS];

542
543
544

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

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
545
   assert( log );
546

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
547
   void* dataArrayV = getData( 1 );
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
548
549
550
551
552
553

#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
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
554
555
556
557

   int streamSize         = getStreamSize();
   int width              = getWidth();
   int index              = 0;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
558
559
   maxPrint               = maxPrint < 0 ? streamSize : maxPrint;
   maxPrint              *= width;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
560
   const float* dataArray = (float*) dataArrayV;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
561
562
   for( int ii = 0; ii < streamSize && ii < maxPrint; ii++ ){

563
      std::stringstream message;
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
564
565
566
      (void) LOCAL_SPRINTF( value, "%6d ", ii );
      message << value << " [ ";

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
567
      for( int jj = 0; jj < width; jj++ ){
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
568
569
570
         (void) LOCAL_SPRINTF( value, "%16.7e ", dataArray[index++] );
         message << value;
      }   
571
      message << "]\n";
Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
572
573
574
      if( index == (_size+1)*width ){
         (void) fprintf( log, "\n" );
      }
575
576
577
      (void) fprintf( log, "%s", message.str().c_str() );    
   }

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
   return DefaultReturnValue;

}

/* 
 * Get stats
 *
 * @return statistics vector
 *
 * */

int  BrookFloatStreamInternal::getStatistics( std::vector<std::vector<double> >& statistics, int maxScan ){

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

   static const std::string methodName      = "BrookStreamInternal::getStatistics";
   static const int MinIndex                = 4;
   static const int MinIndexIndex           = 5;
   static const int MaxIndex                = 6;
   static const int MaxIndexIndex           = 7;
   static const int CountIndex              = 8;
   static const int vectorSize              = CountIndex + 1;
   static const double bigValue             = 1.0e+10;

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

   void* dataArrayV = getData( 1 );

   statistics.resize( vectorSize );
   int streamSize         = getStreamSize();
   int width              = getWidth();
   int index              = 0;
   const float* dataArray = (float*) dataArrayV;
   
   for( int ii = 0; ii < vectorSize; ii++ ){
      for( int jj = 0; jj < width; jj++ ){
         if( ii == MinIndex ){
            statistics[ii].push_back( bigValue );
         } else if( ii == MaxIndex ){
            statistics[ii].push_back( -bigValue );
         } else {
            statistics[ii].push_back( 0.0 );
         }
      }
   }

   for( int ii = 0; ii < streamSize && ii < maxScan; ii++ ){
      for( int jj = 0; jj < width; jj++ ){

         double value                  =  (double) dataArray[index++];

         statistics[0][jj]            += value;
         statistics[1][jj]            += value*value;

         statistics[2][jj]            += fabs( value );

         statistics[CountIndex][jj]   += 1.0;
         if( value < statistics[MinIndex][jj] ){
            statistics[MinIndex][jj]       = value;
            statistics[MinIndexIndex][jj]  = ii;
         }

         if( value > statistics[MaxIndex][jj] ){
            statistics[MaxIndex][jj]       = value;
            statistics[MaxIndexIndex][jj]  = ii;
         }
      }
   }


   for( int jj = 0; jj < width; jj++ ){
      if( statistics[CountIndex][jj] > 0.0 ){
         statistics[3][jj]   = statistics[0][jj];
         statistics[0][jj]  /= statistics[CountIndex][jj];
         statistics[2][jj]  /= statistics[CountIndex][jj];
         statistics[1][jj]   = statistics[1][jj] - statistics[0][jj]*statistics[0][jj]*statistics[CountIndex][jj];
         if( statistics[CountIndex][jj] > 1.0 ){
            statistics[1][jj] = sqrt( statistics[1][jj]/( statistics[CountIndex][jj] - 1.0 ) );
         }
      }
   }
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686

   return DefaultReturnValue;

}

/** 
 * Get array of appropritate size for loading data
 *
 * @return data array -- user's responsibility to free
 */

void* BrookFloatStreamInternal::getDataArray( void ){

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

   //static const std::string methodName      = "BrookStreamInternal::getDataArray";

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

   int totalSize                          = getStreamSize()*getWidth();
   BrookStreamInternal::DataType baseType = getBaseDataType();
   
   if( baseType == Double || baseType == Double2 ||  baseType == Double3 ||  baseType == Double4 ){
      totalSize *= 2;
   }
   return new float[totalSize];
}

Mark Friedrichs's avatar
Mods  
Mark Friedrichs committed
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
/** 
 * BrookFloatStreamInternal constructor
 * 
 * @param stopIndex                 index to stop sum
 * @param sum                       array of size=getWidth()
 *
 * @return DefaultReturnValue
 *
 * @throw exception if stopIndex is too large
 */

int BrookFloatStreamInternal::sumByDimension( int stopIndex, double* sum ){

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

   static const std::string methodName      = "BrookFloatStreamInternal::sumByDimension";

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

   if( stopIndex > getSize() ){
      std::stringstream message;
      message << methodName << " stream=" << getName() << " input topIndex" << stopIndex << " is too large: stream size=" << getSize();
      throw OpenMMException( message.str() );
   }
   
   // get _data from GPU

   _aStream.write( _data );

   int width                                 = getWidth();
   int widthM1                               = getWidth() - 1;
   stopIndex                                *= width;

   for( int ii = 0; ii < width; ii++ ){
      sum[ii] = 0.0;
   }

   int index = 0;
   for( int ii = 0; ii < stopIndex; ii++ ){
      sum[index] += (double) _data[ii];
      if( index == widthM1 ){
         index = 0;
      } else {
         index++;
      }
   }

   return DefaultReturnValue;
}