vtkMaterialInterfaceUtilities.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Kitware Inc.
2 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 #ifndef vtkMaterialInterfaceUtilities_h
6 #define vtkMaterialInterfaceUtilities_h
7 
8 // Vtk
9 #include "vtkCommunicator.h" // for vtkCommunicator
10 // Vtk containers
11 #include "vtkDoubleArray.h" // for vtkDoubleArray
12 #include "vtkFloatArray.h" // for vtkFloatArray
13 #include "vtkIntArray.h" // for vtkIntArray
14 #include "vtkUnsignedIntArray.h" // for vtkUnsignedIntArray
15 // STL
16 #include <fstream> // for file operations
17 using std::ifstream;
18 using std::ofstream;
19 #include <sstream> // for std::ostringstream
20 using std::ostringstream;
21 #include <vector> // for std::vector
22 using std::vector;
23 #include <string> // for std::string
24 using std::string;
25 // other
26 #include <cassert> // for assert
27 
28 // some useful functionality that stradles multiple filters
29 // and has file scope.
30 namespace
31 {
32 // vector memory management helper
33 template <class T>
34 void ClearVectorOfPointers(vector<T*>& V)
35 {
36  size_t n = V.size();
37  for (size_t i = 0; i < n; ++i)
38  {
39  if (V[i] != 0)
40  {
41  delete V[i];
42  }
43  }
44  V.clear();
45 }
46 // vector memory management helper
47 template <class T>
48 void ClearVectorOfVtkPointers(vector<T*>& V)
49 {
50  size_t n = V.size();
51  for (size_t i = 0; i < n; ++i)
52  {
53  if (V[i] != nullptr)
54  {
55  V[i]->Delete();
56  }
57  }
58  V.clear();
59 }
60 // vector memory management helper
61 template <class T>
62 void ClearVectorOfArrayPointers(vector<T*>& V)
63 {
64  size_t n = V.size();
65  for (size_t i = 0; i < n; ++i)
66  {
67  if (V[i] != 0)
68  {
69  delete[] V[i];
70  }
71  }
72  V.clear();
73 }
74 // vector memory management helper
75 template <class T>
76 void ResizeVectorOfVtkPointers(vector<T*>& V, int n)
77 {
78  ClearVectorOfVtkPointers(V);
79 
80  V.resize(n);
81  for (int i = 0; i < n; ++i)
82  {
83  V[i] = T::New();
84  }
85 }
86 // vector memory management helper
87 template <class T>
88 void ResizeVectorOfArrayPointers(vector<T*>& V, int nV, int nA)
89 {
90  ClearVectorOfArrayPointers(V);
91 
92  V.resize(nV);
93  for (int i = 0; i < nV; ++i)
94  {
95  V[i] = new T[nA];
96  }
97 }
98 // vector memory management helper
99 template <class T>
100 void ResizeVectorOfVtkArrayPointers(vector<T*>& V, int nComps, vtkIdType nTups, string name, int nv)
101 {
102  ClearVectorOfVtkPointers(V);
103 
104  V.resize(nv);
105  for (int i = 0; i < nv; ++i)
106  {
107  V[i] = T::New();
108  V[i]->SetNumberOfComponents(nComps);
109  V[i]->SetNumberOfTuples(nTups);
110  V[i]->SetName(name.c_str());
111  }
112 }
113 // vector memory management helper
114 template <class T>
115 void ResizeVectorOfVtkArrayPointers(vector<T*>& V, int nComps, int nv)
116 {
117  ResizeVectorOfVtkArrayPointers(V, nComps, 0, "", nv);
118 }
119 // vector memory management helper
120 template <class T>
121 void ResizeVectorOfVtkArrayPointers(vector<T*>& V, int nComps, int nTups, int nv)
122 {
123  ResizeVectorOfVtkArrayPointers(V, nComps, nTups, "", nv);
124 }
125 
126 // vtk object memory management helper
127 template <class T>
128 inline void ReNewVtkPointer(T*& pv)
129 {
130  if (pv != nullptr)
131  {
132  pv->Delete();
133  }
134  pv = T::New();
135 }
136 // vtk object memory management helper
137 template <class T>
138 inline void NewVtkArrayPointer(T*& pv, int nComps, vtkIdType nTups, std::string name)
139 {
140  pv = T::New();
141  pv->SetNumberOfComponents(nComps);
142  pv->SetNumberOfTuples(nTups);
143  pv->SetName(name.c_str());
144 }
145 // vtk object memory management helper
146 template <class T>
147 inline void ReNewVtkArrayPointer(T*& pv, int nComps, vtkIdType nTups, std::string name)
148 {
149  if (pv != nullptr)
150  {
151  pv->Delete();
152  }
153  NewVtkArrayPointer(pv, nComps, nTups, name);
154 }
155 // vtk object memory management helper
156 template <class T>
157 inline void ReNewVtkArrayPointer(T*& pv, std::string name)
158 {
159  ReNewVtkArrayPointer(pv, 1, 0, name);
160 }
161 // vtk object memory management helper
162 template <class T>
163 inline void ReleaseVtkPointer(T*& pv)
164 {
165  assert("Attempted to release a 0 pointer." && pv != 0);
166  pv->Delete();
167  pv = nullptr;
168 }
169 // vtk object memory management helper
170 template <class T>
171 inline void CheckAndReleaseVtkPointer(T*& pv)
172 {
173  if (pv == nullptr)
174  {
175  return;
176  }
177  pv->Delete();
178  pv = nullptr;
179 }
180 // memory management helper
181 template <class T>
182 inline void CheckAndReleaseArrayPointer(T*& pv)
183 {
184  if (pv == nullptr)
185  {
186  return;
187  }
188  delete[] pv;
189  pv = nullptr;
190 }
191 // memory management helper
192 template <class T>
193 inline void CheckAndReleaseCArrayPointer(T*& pv)
194 {
195  if (pv == 0)
196  {
197  return;
198  }
199  free(pv);
200  pv = 0;
201 }
202 // zero vector
203 template <class T>
204 inline void FillVector(vector<T>& V, const T& v)
205 {
206  size_t n = V.size();
207  for (size_t i = 0; i < n; ++i)
208  {
209  V[i] = v;
210  }
211 }
212 // Copier to copy from an array where type is not known
213 // into a destination buffer.
214 // returns 0 if the type of the source array
215 // is not supported.
216 template <class T>
217 inline int CopyTuple(T* dest, // scalar/vector
218  vtkDataArray* src, //
219  int nComps, //
220  int srcCellIndex) //
221 {
222  // convert cell index to array index
223  int srcIndex = nComps * srcCellIndex;
224  // copy
225  switch (src->GetDataType())
226  {
227  case VTK_FLOAT:
228  {
229  float* thisTuple = dynamic_cast<vtkFloatArray*>(src)->GetPointer(srcIndex);
230  for (int q = 0; q < nComps; ++q)
231  {
232  dest[q] = static_cast<T>(thisTuple[q]);
233  }
234  }
235  break;
236  case VTK_DOUBLE:
237  {
238  double* thisTuple = dynamic_cast<vtkDoubleArray*>(src)->GetPointer(srcIndex);
239  for (int q = 0; q < nComps; ++q)
240  {
241  dest[q] = static_cast<T>(thisTuple[q]);
242  }
243  }
244  break;
245  case VTK_INT:
246  {
247  int* thisTuple = dynamic_cast<vtkIntArray*>(src)->GetPointer(srcIndex);
248  for (int q = 0; q < nComps; ++q)
249  {
250  dest[q] = static_cast<T>(thisTuple[q]);
251  }
252  }
253  break;
254  case VTK_UNSIGNED_INT:
255  {
256  unsigned int* thisTuple = dynamic_cast<vtkUnsignedIntArray*>(src)->GetPointer(srcIndex);
257  for (int q = 0; q < nComps; ++q)
258  {
259  dest[q] = static_cast<T>(thisTuple[q]);
260  }
261  }
262  break;
263  default:
264  assert("This data type is unsupported." && 0);
265  return 0;
266  break;
267  }
268  return 1;
269 }
270 
271 #ifdef vtkMaterialInterfaceFilterDEBUG
272 //
273 int WritePidFile(vtkCommunicator* comm, string pidFileName)
274 {
275  // build an identifier string
276  // "host : rank : pid"
277  int nProcs = comm->GetNumberOfProcesses();
278  int myProcId = comm->GetLocalProcessId();
279  const int hostNameSize = 256;
280  char hostname[hostNameSize] = { '\0' };
281  gethostname(hostname, hostNameSize);
282  int pid = getpid();
283  const int hrpSize = 512;
284  char hrp[hrpSize] = { '\0' };
285  sprintf(hrp, "%s : %d : %d", hostname, myProcId, pid);
286  // move all identifiers to controller
287  char* hrpBuffer = 0;
288  if (myProcId == 0)
289  {
290  hrpBuffer = new char[nProcs * hrpSize];
291  }
292  comm->Gather(hrp, hrpBuffer, hrpSize, 0);
293  // put identifiers into a file
294  if (myProcId == 0)
295  {
296  // open a file in the current working directory
297  ofstream hrpFile;
298  hrpFile.open(pidFileName.c_str());
299  char* thisHrp = hrpBuffer;
300  if (hrpFile.is_open())
301  {
302  for (int procId = 0; procId < nProcs; ++procId)
303  {
304  hrpFile << thisHrp << endl;
305  thisHrp += hrpSize;
306  };
307  hrpFile.close();
308  }
309  // if we can't open a file send to stderr
310  else
311  {
312  for (int procId = 0; procId < nProcs; ++procId)
313  {
314  cerr << thisHrp << endl;
315  thisHrp += hrpSize;
316  }
317  }
318  delete[] hrpBuffer;
319  }
320 
321  return pid;
322 }
323 //
324 string GetMemoryUsage(int pid, int line, int procId)
325 {
326  ostringstream memoryUsage;
327 
328  ostringstream statusFileName;
329  statusFileName << "/proc/" << pid << "/status";
330  ifstream statusFile;
331  statusFile.open(statusFileName.str().c_str());
332  if (statusFile.is_open())
333  {
334  const int cbufSize = 1024;
335  char cbuf[cbufSize] = { '\0' };
336  while (statusFile.good())
337  {
338  statusFile.getline(cbuf, cbufSize);
339  string content(cbuf);
340  if (content.find("VmSize") != string::npos || content.find("VmRSS") != string::npos ||
341  content.find("VmData") != string::npos)
342  {
343  int tabStart = content.find_first_of("\t ");
344  int tabSpan = 1;
345  while (content[tabStart + tabSpan] == '\t' || content[tabStart + tabSpan] == ' ')
346  {
347  ++tabSpan;
348  }
349  string formattedContent =
350  content.substr(0, tabStart - 1) + " " + content.substr(tabStart + tabSpan);
351  memoryUsage << "[" << line << "] " << procId << " " << formattedContent << endl;
352  }
353  }
354  statusFile.close();
355  }
356  else
357  {
358  cerr << "[" << line << "] " << procId << " could not open " << statusFileName << "." << endl;
359  }
360 
361  return memoryUsage.str();
362 }
363 
364 template <class T>
365 void writeTuple(ostream& sout, T* tup, int nComp)
366 {
367  if (nComp == 1)
368  {
369  sout << tup[0];
370  }
371  else
372  {
373  sout << "(" << tup[0];
374  for (int q = 1; q < nComp; ++q)
375  {
376  sout << ", " << tup[q];
377  }
378  sout << ")";
379  }
380 }
381 //
382 ostream& operator<<(ostream& sout, vtkDoubleArray& da)
383 {
384  sout << "Name: " << da.GetName() << endl;
385 
386  int nTup = da.GetNumberOfTuples();
387  int nComp = da.GetNumberOfComponents();
388 
389  sout << "NumberOfComps: " << nComp << endl;
390  sout << "NumberOfTuples:" << nTup << endl;
391  if (nTup == 0)
392  {
393  sout << "{}" << endl;
394  }
395  else
396  {
397  sout << "{";
398  double* thisTup = da.GetTuple(0);
399  writeTuple(sout, thisTup, nComp);
400  for (int i = 1; i < nTup; ++i)
401  {
402  thisTup = da.GetTuple(i);
403  sout << ", ";
404  writeTuple(sout, thisTup, nComp);
405  }
406  sout << "}" << endl;
407  }
408  return sout;
409 }
410 //
411 ostream& operator<<(ostream& sout, vector<vtkDoubleArray*>& vda)
412 {
413  size_t nda = vda.size();
414  for (size_t i = 0; i < nda; ++i)
415  {
416  sout << "[" << i << "]\n" << *vda[i] << endl;
417  }
418  return sout;
419 }
420 //
421 ostream& operator<<(ostream& sout, vector<vector<int>>& vvi)
422 {
423  size_t nv = vvi.size();
424  for (size_t i = 0; i < nv; ++i)
425  {
426  sout << "[" << i << "]{";
427  size_t ni = vvi[i].size();
428  if (ni < 1)
429  {
430  sout << "}" << endl;
431  continue;
432  }
433  sout << vvi[i][0];
434  for (size_t j = 1; j < ni; ++j)
435  {
436  sout << "," << vvi[i][j];
437  }
438  sout << "}" << endl;
439  }
440  return sout;
441 }
442 //
443 ostream& operator<<(ostream& sout, vector<int>& vi)
444 {
445  sout << "{";
446  size_t ni = vi.size();
447  if (ni < 1)
448  {
449  sout << "}";
450  return sout;
451  }
452  sout << vi[0];
453  for (size_t j = 1; j < ni; ++j)
454  {
455  sout << "," << vi[j];
456  }
457  sout << "}";
458 
459  return sout;
460 }
461 // //
462 // ostream &operator<<(ostream &sout, vtkDoubleArray &da)
463 // {
464 // sout << "Name: " << da.GetName() << endl;
465 //
466 // vtkIdType nTup = da.GetNumberOfTuples();
467 // int nComp = da.GetNumberOfComponents();
468 //
469 // sout << "NumberOfComps: " << nComp << endl;
470 // sout << "NumberOfTuples:" << nTup << endl;
471 // sout << "{\n";
472 // for (int i=0; i<nTup; ++i)
473 // {
474 // double *thisTup=da.GetTuple(i);
475 // for (int q=0; q<nComp; ++q)
476 // {
477 // sout << thisTup[q] << ",";
478 // }
479 // sout << (char)0x08 << "\n";
480 // }
481 // sout << "}\n";
482 //
483 // return sout;
484 // }
485 // write a set of loading arrays
486 // ostream &operator<<(ostream &sout,
487 // vector<vector<vtkIdType> > &pla)
488 // {
489 // int nProcs=pla.size();
490 // for (int procId=0; procId<nProcs; ++procId)
491 // {
492 // cerr << "Fragment loading on process " << procId << ":" << endl;
493 // int nLocalFragments=pla[procId].size();
494 // for (int fragmentIdx=0; fragmentIdx<nLocalFragments; ++fragmentIdx)
495 // {
496 // if (pla[procId][fragmentIdx]>0)
497 // {
498 // sout << "("
499 // << fragmentIdx
500 // << ","
501 // << pla[procId][fragmentIdx]
502 // << "), ";
503 // }
504 // }
505 // sout << endl;
506 // }
507 // return sout;
508 // }
509 #endif
510 //
511 template <typename TCnt, typename TLabel>
512 void PrintHistogram(vector<TCnt>& bins, vector<TLabel>& binIds)
513 {
514  const int maxWidth = 40;
515  const size_t n = bins.size();
516  if (n == 0)
517  {
518  return;
519  }
520  int maxBin = *max_element(bins.begin(), bins.end());
521  for (size_t i = 0; i < n; ++i)
522  {
523  if (bins[i] == 0)
524  {
525  continue;
526  }
527  // clip at width of 40.
528  int wid = maxBin < maxWidth ? bins[i] : bins[i] * maxWidth / maxBin;
529  cerr << "{" << setw(12) << std::left << binIds[i] << "}*";
530  for (int j = 1; j < wid; ++j)
531  {
532  cerr << "*";
533  }
534  cerr << "(" << bins[i] << ")" << endl;
535  }
536 }
537 //
538 template <typename TCnt>
539 void PrintHistogram(vector<TCnt>& bins)
540 {
541  // generate default labels, 0...n
542  const int n = static_cast<int>(bins.size());
543  vector<int> binIds(n);
544  for (int i = 0; i < n; ++i)
545  {
546  binIds[i] = i;
547  }
548  //
549  PrintHistogram(bins, binIds);
550 }
551 };
552 #endif
int Gather(const int *sendBuffer, int *recvBuffer, vtkIdType length, int destProcessId)
content
#define VTK_UNSIGNED_INT
vtkIdType GetNumberOfTuples()
virtual int GetNumberOfProcesses()
virtual double * GetTuple(vtkIdType tupleIdx)=0
virtual int GetDataType()=0
int vtkIdType
int GetNumberOfComponents()
T * operator<<(T *LHS, const pqConnect &RHS)
Makes a Qt connection.
Definition: pqConnect.h:36
#define VTK_DOUBLE
#define VTK_FLOAT
virtual int GetLocalProcessId()
virtual char * GetName()
VTKWRAPPINGJAVA_EXPORT jlong q(JNIEnv *env, jobject obj)
#define VTK_INT