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