root / ase / test / vtk_data.py @ 4
Historique | Voir | Annoter | Télécharger (18,79 ko)
| 1 | 1 | tkerber | #!/usr/bin/env python
|
|---|---|---|---|
| 2 | 1 | tkerber | |
| 3 | 1 | tkerber | from ase.visualize.vtk import requirevtk, probe_vtk_kilobyte |
| 4 | 1 | tkerber | |
| 5 | 1 | tkerber | requirevtk() |
| 6 | 1 | tkerber | vtk_kilobyte = probe_vtk_kilobyte(1024)
|
| 7 | 1 | tkerber | |
| 8 | 1 | tkerber | import numpy as np |
| 9 | 1 | tkerber | |
| 10 | 1 | tkerber | import sys, unittest, gc |
| 11 | 1 | tkerber | from ase.test import CustomTestCase, CustomTextTestRunner |
| 12 | 1 | tkerber | from ase.utils.memory import MemoryStatistics, MemorySingleton, shapeopt |
| 13 | 1 | tkerber | |
| 14 | 1 | tkerber | from vtk import vtkDataArray |
| 15 | 1 | tkerber | from ase.visualize.vtk.data import vtkFloatArrayFromNumPyArray, \ |
| 16 | 1 | tkerber | vtkDoubleArrayFromNumPyArray, \
|
| 17 | 1 | tkerber | vtkFloatArrayFromNumPyMultiArray, \
|
| 18 | 1 | tkerber | vtkDoubleArrayFromNumPyMultiArray
|
| 19 | 1 | tkerber | |
| 20 | 1 | tkerber | # -------------------------------------------------------------------
|
| 21 | 1 | tkerber | |
| 22 | 1 | tkerber | class UTConversionDataArrayNumPy(CustomTestCase): |
| 23 | 1 | tkerber | """
|
| 24 | 1 | tkerber | Abstract class with test cases for VTK/NumPy data conversion.
|
| 25 | 1 | tkerber |
|
| 26 | 1 | tkerber | Leak tests the six possible permutations of deletion order for the
|
| 27 | 1 | tkerber | objects involved in conversion between VTK and NumPy data formats.
|
| 28 | 1 | tkerber |
|
| 29 | 1 | tkerber | Objects:
|
| 30 | 1 | tkerber |
|
| 31 | 1 | tkerber | conv: instance of vtkDataArrayFromNumPyBuffer of subclass thereof
|
| 32 | 1 | tkerber | The object in charge of the conversion
|
| 33 | 1 | tkerber | data: NumPy array
|
| 34 | 1 | tkerber | NumPy data with a specific memory footprint
|
| 35 | 1 | tkerber | vtk_da: instance of vtkDataArray of subclass thereof
|
| 36 | 1 | tkerber | VTK data array with a similar memory footprint
|
| 37 | 1 | tkerber |
|
| 38 | 1 | tkerber | Permutations:
|
| 39 | 1 | tkerber |
|
| 40 | 1 | tkerber | Case A: 012 i.e. deletion order is conv, data, vtk_da
|
| 41 | 1 | tkerber | Case B: 021 i.e. deletion order is conv, vtk_da, data
|
| 42 | 1 | tkerber | Case C: 102 i.e. deletion order is data, conv, vtk_da
|
| 43 | 1 | tkerber | Case D: 120 i.e. deletion order is data, vtk_da, conv
|
| 44 | 1 | tkerber | Case E: 201 i.e. deletion order is vtk_da, conv, data
|
| 45 | 1 | tkerber | Case F: 210 i.e. deletion order is vtk_da, data, conv
|
| 46 | 1 | tkerber | """
|
| 47 | 1 | tkerber | footprint = 100*1024**2 |
| 48 | 1 | tkerber | dtype = None
|
| 49 | 1 | tkerber | verbose = 0
|
| 50 | 1 | tkerber | gc_threshold = (300,5,5) #default is (700,10,10) |
| 51 | 1 | tkerber | gc_flags = gc.DEBUG_LEAK # | gc.DEBUG_STATS
|
| 52 | 1 | tkerber | ctol = -7 #10MB |
| 53 | 1 | tkerber | etol = -7 #10MB |
| 54 | 1 | tkerber | |
| 55 | 1 | tkerber | def setUp(self): |
| 56 | 1 | tkerber | self.mem_ini = MemorySingleton(self.verbose-1) |
| 57 | 1 | tkerber | self.mem_ref = MemoryStatistics(self.verbose-1) |
| 58 | 1 | tkerber | self.mem_cur = self.mem_ref.copy() |
| 59 | 1 | tkerber | |
| 60 | 1 | tkerber | self.gc_threshold_old = gc.get_threshold()
|
| 61 | 1 | tkerber | self.gc_flags_old = gc.get_debug()
|
| 62 | 1 | tkerber | gc.set_threshold(*self.gc_threshold)
|
| 63 | 1 | tkerber | gc.set_debug(self.gc_flags)
|
| 64 | 1 | tkerber | |
| 65 | 1 | tkerber | # Try to obtain a clean slate
|
| 66 | 1 | tkerber | gc.collect() |
| 67 | 1 | tkerber | self.gc_count = len(gc.garbage) |
| 68 | 1 | tkerber | del gc.garbage[:]
|
| 69 | 1 | tkerber | |
| 70 | 1 | tkerber | def tearDown(self): |
| 71 | 1 | tkerber | gc.collect() |
| 72 | 1 | tkerber | self.assertEqual(len(gc.garbage), self.gc_count) |
| 73 | 1 | tkerber | if len(gc.garbage)>0: |
| 74 | 1 | tkerber | if self.verbose>1: print gc.get_objects() |
| 75 | 1 | tkerber | #TODO be pedantic and fail?
|
| 76 | 1 | tkerber | del gc.garbage[:]
|
| 77 | 1 | tkerber | gc.set_threshold(*self.gc_threshold_old)
|
| 78 | 1 | tkerber | gc.set_debug(self.gc_flags_old)
|
| 79 | 1 | tkerber | |
| 80 | 1 | tkerber | def assertAlmostConsumed(self, bytes, digits=0, key='VmSize'): |
| 81 | 1 | tkerber | self.mem_cur.update()
|
| 82 | 1 | tkerber | dm = self.mem_cur-self.mem_ref |
| 83 | 1 | tkerber | self.assertAlmostEqual(dm[key], bytes, digits) |
| 84 | 1 | tkerber | |
| 85 | 1 | tkerber | def assertAlmostExceeded(self, bytes, digits=0, key='VmPeak'): |
| 86 | 1 | tkerber | self.mem_cur.update()
|
| 87 | 1 | tkerber | dm = self.mem_cur-self.mem_ini |
| 88 | 1 | tkerber | #self.assertAlmostEqual(dm[key], bytes, digits) #TODO what really?
|
| 89 | 1 | tkerber | #self.assertAlmostEqual(max(0, dm[key]-bytes), 0, digits) #TODO ???
|
| 90 | 1 | tkerber | #dm = 200 MB, bytes = 100MB ok
|
| 91 | 1 | tkerber | #dm = 101 MB, bytes = 100MB ok
|
| 92 | 1 | tkerber | #dm = 0 MB, bytes = 100MB bad
|
| 93 | 1 | tkerber | |
| 94 | 1 | tkerber | def convert_to_vtk_array(self, data): |
| 95 | 1 | tkerber | """Convert an ndarray to a VTK data array.
|
| 96 | 1 | tkerber |
|
| 97 | 1 | tkerber | data: NumPy array
|
| 98 | 1 | tkerber | NumPy data with a specific memory footprint
|
| 99 | 1 | tkerber | """
|
| 100 | 1 | tkerber | |
| 101 | 1 | tkerber | raise RuntimeError('Virtual member function.') |
| 102 | 1 | tkerber | |
| 103 | 1 | tkerber | def get_leaktest_scenario(self): |
| 104 | 1 | tkerber | """Construct the necessary conversion objects for leak testing.
|
| 105 | 1 | tkerber |
|
| 106 | 1 | tkerber | Returns tuple of the form (conv, data, vtk_da,) where:
|
| 107 | 1 | tkerber |
|
| 108 | 1 | tkerber | conv: instance of vtkDataArrayFromNumPyBuffer of subclass thereof
|
| 109 | 1 | tkerber | The object in charge of the conversion
|
| 110 | 1 | tkerber | data: NumPy array
|
| 111 | 1 | tkerber | NumPy data with a specific memory footprint
|
| 112 | 1 | tkerber | vtk_da: instance of vtkDataArray of subclass thereof
|
| 113 | 1 | tkerber | VTK data array with a similar memory footprint
|
| 114 | 1 | tkerber | """
|
| 115 | 1 | tkerber | |
| 116 | 1 | tkerber | raise RuntimeError('Virtual member function.') |
| 117 | 1 | tkerber | |
| 118 | 1 | tkerber | # =================================
|
| 119 | 1 | tkerber | |
| 120 | 1 | tkerber | def test_deletion_case_a(self): |
| 121 | 1 | tkerber | # Case A: 012 i.e. deletion order is conv, data, vtk_da
|
| 122 | 1 | tkerber | (conv, data, vtk_da,) = self.get_leaktest_scenario()
|
| 123 | 1 | tkerber | |
| 124 | 1 | tkerber | # Conversion cleanup
|
| 125 | 1 | tkerber | del conv
|
| 126 | 1 | tkerber | self.assertAlmostConsumed(2*self.footprint, self.ctol) |
| 127 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 128 | 1 | tkerber | if self.verbose>=1: print 'Conversion cleanup=', self.mem_cur-self.mem_ref |
| 129 | 1 | tkerber | |
| 130 | 1 | tkerber | # NumPy cleanup
|
| 131 | 1 | tkerber | del data
|
| 132 | 1 | tkerber | self.assertAlmostConsumed(self.footprint, self.ctol) |
| 133 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 134 | 1 | tkerber | if self.verbose>=1: print 'NumPy cleanup=', self.mem_cur-self.mem_ref |
| 135 | 1 | tkerber | |
| 136 | 1 | tkerber | # VTK cleanup
|
| 137 | 1 | tkerber | del vtk_da
|
| 138 | 1 | tkerber | self.assertAlmostConsumed(0, self.ctol) |
| 139 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 140 | 1 | tkerber | if self.verbose>=1: print 'VTK cleanup=', self.mem_cur-self.mem_ref |
| 141 | 1 | tkerber | |
| 142 | 1 | tkerber | def test_deletion_case_b(self): |
| 143 | 1 | tkerber | # Case B: 021 i.e. deletion order is conv, vtk_da, data
|
| 144 | 1 | tkerber | (conv, data, vtk_da,) = self.get_leaktest_scenario()
|
| 145 | 1 | tkerber | |
| 146 | 1 | tkerber | # Conversion cleanup
|
| 147 | 1 | tkerber | del conv
|
| 148 | 1 | tkerber | self.assertAlmostConsumed(2*self.footprint, self.ctol) |
| 149 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 150 | 1 | tkerber | if self.verbose>=1: print 'Conversion cleanup=', self.mem_cur-self.mem_ref |
| 151 | 1 | tkerber | |
| 152 | 1 | tkerber | # VTK cleanup
|
| 153 | 1 | tkerber | del vtk_da
|
| 154 | 1 | tkerber | self.assertAlmostConsumed(self.footprint, self.ctol) |
| 155 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 156 | 1 | tkerber | if self.verbose>=1: print 'VTK cleanup=', self.mem_cur-self.mem_ref |
| 157 | 1 | tkerber | |
| 158 | 1 | tkerber | # Numpy cleanup
|
| 159 | 1 | tkerber | del data
|
| 160 | 1 | tkerber | self.assertAlmostConsumed(0, self.ctol) |
| 161 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 162 | 1 | tkerber | if self.verbose>=1: print 'NumPy cleanup=', self.mem_cur-self.mem_ref |
| 163 | 1 | tkerber | |
| 164 | 1 | tkerber | def test_deletion_case_c(self): |
| 165 | 1 | tkerber | # Case C: 102 i.e. deletion order is data, conv, vtk_da
|
| 166 | 1 | tkerber | (conv, data, vtk_da,) = self.get_leaktest_scenario()
|
| 167 | 1 | tkerber | |
| 168 | 1 | tkerber | # NumPy cleanup
|
| 169 | 1 | tkerber | del data
|
| 170 | 1 | tkerber | self.assertAlmostConsumed(self.footprint, self.ctol) |
| 171 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 172 | 1 | tkerber | if self.verbose>=1: print 'NumPy cleanup=', self.mem_cur-self.mem_ref |
| 173 | 1 | tkerber | |
| 174 | 1 | tkerber | # Conversion cleanup
|
| 175 | 1 | tkerber | del conv
|
| 176 | 1 | tkerber | self.assertAlmostConsumed(self.footprint, self.ctol) |
| 177 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 178 | 1 | tkerber | if self.verbose>=1: print 'Conversion cleanup=', self.mem_cur-self.mem_ref |
| 179 | 1 | tkerber | |
| 180 | 1 | tkerber | # VTK cleanup
|
| 181 | 1 | tkerber | del vtk_da
|
| 182 | 1 | tkerber | self.assertAlmostConsumed(0, self.ctol) |
| 183 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 184 | 1 | tkerber | if self.verbose>=1: print 'VTK cleanup=', self.mem_cur-self.mem_ref |
| 185 | 1 | tkerber | |
| 186 | 1 | tkerber | def test_deletion_case_d(self): |
| 187 | 1 | tkerber | # Case D: 120 i.e. deletion order is data, vtk_da, conv
|
| 188 | 1 | tkerber | (conv, data, vtk_da,) = self.get_leaktest_scenario()
|
| 189 | 1 | tkerber | |
| 190 | 1 | tkerber | # NumPy cleanup
|
| 191 | 1 | tkerber | del data
|
| 192 | 1 | tkerber | self.assertAlmostConsumed(self.footprint, self.ctol) |
| 193 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 194 | 1 | tkerber | if self.verbose>=1: print 'NumPy cleanup=', self.mem_cur-self.mem_ref |
| 195 | 1 | tkerber | |
| 196 | 1 | tkerber | # VTK cleanup
|
| 197 | 1 | tkerber | del vtk_da
|
| 198 | 1 | tkerber | self.assertAlmostConsumed(self.footprint, self.ctol) |
| 199 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 200 | 1 | tkerber | if self.verbose>=1: print 'VTK cleanup=', self.mem_cur-self.mem_ref |
| 201 | 1 | tkerber | |
| 202 | 1 | tkerber | # Conversion cleanup
|
| 203 | 1 | tkerber | del conv
|
| 204 | 1 | tkerber | self.assertAlmostConsumed(0, self.ctol) |
| 205 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 206 | 1 | tkerber | if self.verbose>=1: print 'Conversion cleanup=', self.mem_cur-self.mem_ref |
| 207 | 1 | tkerber | |
| 208 | 1 | tkerber | def test_deletion_case_e(self): |
| 209 | 1 | tkerber | # Case E: 201 i.e. deletion order is vtk_da, conv, data
|
| 210 | 1 | tkerber | (conv, data, vtk_da,) = self.get_leaktest_scenario()
|
| 211 | 1 | tkerber | |
| 212 | 1 | tkerber | # VTK cleanup
|
| 213 | 1 | tkerber | del vtk_da
|
| 214 | 1 | tkerber | self.assertAlmostConsumed(2*self.footprint, self.ctol) |
| 215 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 216 | 1 | tkerber | if self.verbose>=1: print 'VTK cleanup=', self.mem_cur-self.mem_ref |
| 217 | 1 | tkerber | |
| 218 | 1 | tkerber | # Conversion cleanup
|
| 219 | 1 | tkerber | del conv
|
| 220 | 1 | tkerber | self.assertAlmostConsumed(self.footprint, self.ctol) |
| 221 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 222 | 1 | tkerber | if self.verbose>=1: print 'Conversion cleanup=', self.mem_cur-self.mem_ref |
| 223 | 1 | tkerber | |
| 224 | 1 | tkerber | # NumPy cleanup
|
| 225 | 1 | tkerber | del data
|
| 226 | 1 | tkerber | self.assertAlmostConsumed(0, self.ctol) |
| 227 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 228 | 1 | tkerber | if self.verbose>=1: print 'NumPy cleanup=', self.mem_cur-self.mem_ref |
| 229 | 1 | tkerber | |
| 230 | 1 | tkerber | def test_deletion_case_f(self): |
| 231 | 1 | tkerber | # Case F: 210 i.e. deletion order is vtk_da, data, conv
|
| 232 | 1 | tkerber | (conv, data, vtk_da,) = self.get_leaktest_scenario()
|
| 233 | 1 | tkerber | |
| 234 | 1 | tkerber | # VTK cleanup
|
| 235 | 1 | tkerber | del vtk_da
|
| 236 | 1 | tkerber | self.assertAlmostConsumed(2*self.footprint, self.ctol) |
| 237 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 238 | 1 | tkerber | if self.verbose>=1: print 'VTK cleanup=', self.mem_cur-self.mem_ref |
| 239 | 1 | tkerber | |
| 240 | 1 | tkerber | # NumPy cleanup
|
| 241 | 1 | tkerber | del data
|
| 242 | 1 | tkerber | self.assertAlmostConsumed(self.footprint, self.ctol) |
| 243 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 244 | 1 | tkerber | if self.verbose>=1: print 'NumPy cleanup=', self.mem_cur-self.mem_ref |
| 245 | 1 | tkerber | |
| 246 | 1 | tkerber | # Conversion cleanup
|
| 247 | 1 | tkerber | del conv
|
| 248 | 1 | tkerber | self.assertAlmostConsumed(0, self.ctol) |
| 249 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 250 | 1 | tkerber | if self.verbose>=1: print 'Conversion cleanup=', self.mem_cur-self.mem_ref |
| 251 | 1 | tkerber | |
| 252 | 1 | tkerber | # -------------------------------------------------------------------
|
| 253 | 1 | tkerber | |
| 254 | 1 | tkerber | # class UTDataArrayFromNumPyBuffer(...): TODO
|
| 255 | 1 | tkerber | |
| 256 | 1 | tkerber | # -------------------------------------------------------------------
|
| 257 | 1 | tkerber | |
| 258 | 1 | tkerber | class UTDataArrayFromNumPyArray_Scalar(UTConversionDataArrayNumPy): |
| 259 | 1 | tkerber | """
|
| 260 | 1 | tkerber | Test cases for memory leaks during VTK/NumPy data conversion.
|
| 261 | 1 | tkerber | Conversion of 1D NumPy array to VTK data array using buffers."""
|
| 262 | 1 | tkerber | |
| 263 | 1 | tkerber | def setUp(self): |
| 264 | 1 | tkerber | UTConversionDataArrayNumPy.setUp(self)
|
| 265 | 1 | tkerber | self.shape = self.footprint//np.nbytes[self.dtype] |
| 266 | 1 | tkerber | |
| 267 | 1 | tkerber | def get_leaktest_scenario(self): |
| 268 | 1 | tkerber | self.assertAlmostEqual(np.prod(self.shape)*np.nbytes[self.dtype], \ |
| 269 | 1 | tkerber | self.footprint, -2) #100B |
| 270 | 1 | tkerber | |
| 271 | 1 | tkerber | # Update memory reference
|
| 272 | 1 | tkerber | self.mem_ref.update()
|
| 273 | 1 | tkerber | |
| 274 | 1 | tkerber | # NumPy allocation
|
| 275 | 1 | tkerber | data = np.empty(self.shape, self.dtype) |
| 276 | 1 | tkerber | self.assertAlmostConsumed(self.footprint, self.ctol) |
| 277 | 1 | tkerber | self.assertAlmostExceeded(self.footprint, self.etol) |
| 278 | 1 | tkerber | if self.verbose>=1: print 'NumPy allocation=', self.mem_cur-self.mem_ref |
| 279 | 1 | tkerber | |
| 280 | 1 | tkerber | # NumPy to VTK conversion
|
| 281 | 1 | tkerber | np2da = self.convert_to_vtk_array(data)
|
| 282 | 1 | tkerber | self.assertAlmostConsumed(2*self.footprint, self.ctol) |
| 283 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 284 | 1 | tkerber | if self.verbose>=1: print 'Conversion=', self.mem_cur-self.mem_ref |
| 285 | 1 | tkerber | |
| 286 | 1 | tkerber | # VTK retrieval
|
| 287 | 1 | tkerber | vtk_da = np2da.get_output() |
| 288 | 1 | tkerber | self.assertTrue(isinstance(vtk_da, vtkDataArray)) |
| 289 | 1 | tkerber | self.assertAlmostEqual(vtk_da.GetActualMemorySize()*vtk_kilobyte, \
|
| 290 | 1 | tkerber | self.footprint, -3) #1kB |
| 291 | 1 | tkerber | if self.verbose>=1: print 'VTK retrieval=', self.mem_cur-self.mem_ref |
| 292 | 1 | tkerber | |
| 293 | 1 | tkerber | return (np2da, data, vtk_da,)
|
| 294 | 1 | tkerber | |
| 295 | 1 | tkerber | class UTFloatArrayFromNumPyArray_Scalar(UTDataArrayFromNumPyArray_Scalar): |
| 296 | 1 | tkerber | __doc__ = UTDataArrayFromNumPyArray_Scalar.__doc__ |
| 297 | 1 | tkerber | dtype = np.float32 |
| 298 | 1 | tkerber | convert_to_vtk_array = vtkFloatArrayFromNumPyArray |
| 299 | 1 | tkerber | |
| 300 | 1 | tkerber | class UTDoubleArrayFromNumPyArray_Scalar(UTDataArrayFromNumPyArray_Scalar): |
| 301 | 1 | tkerber | __doc__ = UTDataArrayFromNumPyArray_Scalar.__doc__ |
| 302 | 1 | tkerber | dtype = np.float64 |
| 303 | 1 | tkerber | convert_to_vtk_array = vtkDoubleArrayFromNumPyArray |
| 304 | 1 | tkerber | |
| 305 | 1 | tkerber | class UTDataArrayFromNumPyArray_Vector(UTConversionDataArrayNumPy): |
| 306 | 1 | tkerber | """
|
| 307 | 1 | tkerber | Test cases for memory leaks during VTK/NumPy data conversion.
|
| 308 | 1 | tkerber | Conversion of 2D NumPy array to VTK data array using buffers."""
|
| 309 | 1 | tkerber | |
| 310 | 1 | tkerber | def setUp(self): |
| 311 | 1 | tkerber | UTConversionDataArrayNumPy.setUp(self)
|
| 312 | 1 | tkerber | size = self.footprint//np.nbytes[self.dtype] |
| 313 | 1 | tkerber | self.shape = (size//3, 3) |
| 314 | 1 | tkerber | |
| 315 | 1 | tkerber | def get_leaktest_scenario(self): |
| 316 | 1 | tkerber | self.assertAlmostEqual(np.prod(self.shape)*np.nbytes[self.dtype], \ |
| 317 | 1 | tkerber | self.footprint, -2) #100B |
| 318 | 1 | tkerber | |
| 319 | 1 | tkerber | # Update memory reference
|
| 320 | 1 | tkerber | self.mem_ref.update()
|
| 321 | 1 | tkerber | |
| 322 | 1 | tkerber | # NumPy allocation
|
| 323 | 1 | tkerber | data = np.empty(self.shape, self.dtype) |
| 324 | 1 | tkerber | self.assertAlmostConsumed(self.footprint, self.ctol) |
| 325 | 1 | tkerber | self.assertAlmostExceeded(self.footprint, self.etol) |
| 326 | 1 | tkerber | if self.verbose>=1: print 'NumPy allocation=', self.mem_cur-self.mem_ref |
| 327 | 1 | tkerber | |
| 328 | 1 | tkerber | # NumPy to VTK conversion
|
| 329 | 1 | tkerber | np2da = self.convert_to_vtk_array(data)
|
| 330 | 1 | tkerber | self.assertAlmostConsumed(2*self.footprint, self.ctol) |
| 331 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 332 | 1 | tkerber | if self.verbose>=1: print 'Conversion=', self.mem_cur-self.mem_ref |
| 333 | 1 | tkerber | |
| 334 | 1 | tkerber | # VTK retrieval
|
| 335 | 1 | tkerber | vtk_da = np2da.get_output() |
| 336 | 1 | tkerber | self.assertTrue(isinstance(vtk_da, vtkDataArray)) |
| 337 | 1 | tkerber | self.assertAlmostEqual(vtk_da.GetActualMemorySize()*vtk_kilobyte, \
|
| 338 | 1 | tkerber | self.footprint, -3) #1kB |
| 339 | 1 | tkerber | if self.verbose>=1: print 'VTK retrieval=', self.mem_cur-self.mem_ref |
| 340 | 1 | tkerber | |
| 341 | 1 | tkerber | return (np2da, data, vtk_da,)
|
| 342 | 1 | tkerber | |
| 343 | 1 | tkerber | class UTFloatArrayFromNumPyArray_Vector(UTDataArrayFromNumPyArray_Vector): |
| 344 | 1 | tkerber | __doc__ = UTDataArrayFromNumPyArray_Vector.__doc__ |
| 345 | 1 | tkerber | dtype = np.float32 |
| 346 | 1 | tkerber | convert_to_vtk_array = vtkFloatArrayFromNumPyArray |
| 347 | 1 | tkerber | |
| 348 | 1 | tkerber | class UTDoubleArrayFromNumPyArray_Vector(UTDataArrayFromNumPyArray_Vector): |
| 349 | 1 | tkerber | __doc__ = UTDataArrayFromNumPyArray_Vector.__doc__ |
| 350 | 1 | tkerber | dtype = np.float64 |
| 351 | 1 | tkerber | convert_to_vtk_array = vtkDoubleArrayFromNumPyArray |
| 352 | 1 | tkerber | |
| 353 | 1 | tkerber | # -------------------------------------------------------------------
|
| 354 | 1 | tkerber | |
| 355 | 1 | tkerber | class UTDataArrayFromNumPyMultiArray_Scalar(UTConversionDataArrayNumPy): |
| 356 | 1 | tkerber | """
|
| 357 | 1 | tkerber | Test cases for memory leaks during VTK/NumPy data conversion.
|
| 358 | 1 | tkerber | Conversion of NumPy grid scalars to VTK data array using buffers."""
|
| 359 | 1 | tkerber | |
| 360 | 1 | tkerber | def setUp(self): |
| 361 | 1 | tkerber | UTConversionDataArrayNumPy.setUp(self)
|
| 362 | 1 | tkerber | size = self.footprint//np.nbytes[self.dtype] |
| 363 | 1 | tkerber | digits, shape = shapeopt(1000, size, ndims=3, ecc=0.3) |
| 364 | 1 | tkerber | if self.verbose>=1: print 'digits=%8.3f, shape=%s' % (digits,shape) |
| 365 | 1 | tkerber | self.shape = shape + (1,) |
| 366 | 1 | tkerber | self.assertAlmostEqual(np.prod(self.shape)*np.nbytes[self.dtype], \ |
| 367 | 1 | tkerber | self.footprint, -4) #10kB |
| 368 | 1 | tkerber | |
| 369 | 1 | tkerber | def get_leaktest_scenario(self): |
| 370 | 1 | tkerber | |
| 371 | 1 | tkerber | # Update memory reference
|
| 372 | 1 | tkerber | self.mem_ref.update()
|
| 373 | 1 | tkerber | |
| 374 | 1 | tkerber | # NumPy allocation
|
| 375 | 1 | tkerber | data = np.empty(self.shape, self.dtype) |
| 376 | 1 | tkerber | self.assertAlmostConsumed(self.footprint, self.ctol) |
| 377 | 1 | tkerber | self.assertAlmostExceeded(self.footprint, self.etol) |
| 378 | 1 | tkerber | if self.verbose>=1: print 'NumPy allocation=', self.mem_cur-self.mem_ref |
| 379 | 1 | tkerber | |
| 380 | 1 | tkerber | # NumPy to VTK conversion
|
| 381 | 1 | tkerber | np2da = self.convert_to_vtk_array(data)
|
| 382 | 1 | tkerber | self.assertAlmostConsumed(2*self.footprint, self.ctol) |
| 383 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 384 | 1 | tkerber | if self.verbose>=1: print 'Conversion=', self.mem_cur-self.mem_ref |
| 385 | 1 | tkerber | |
| 386 | 1 | tkerber | # VTK retrieval
|
| 387 | 1 | tkerber | vtk_da = np2da.get_output() |
| 388 | 1 | tkerber | self.assertTrue(isinstance(vtk_da, vtkDataArray)) |
| 389 | 1 | tkerber | self.assertAlmostEqual(vtk_da.GetActualMemorySize()*vtk_kilobyte, \
|
| 390 | 1 | tkerber | self.footprint, -4) #10kB |
| 391 | 1 | tkerber | if self.verbose>=1: print 'VTK retrieval=', self.mem_cur-self.mem_ref |
| 392 | 1 | tkerber | |
| 393 | 1 | tkerber | return (np2da, data, vtk_da,)
|
| 394 | 1 | tkerber | |
| 395 | 1 | tkerber | class UTFloatArrayFromNumPyMultiArray_Scalar(UTDataArrayFromNumPyMultiArray_Scalar): |
| 396 | 1 | tkerber | __doc__ = UTDataArrayFromNumPyMultiArray_Scalar.__doc__ |
| 397 | 1 | tkerber | dtype = np.float32 |
| 398 | 1 | tkerber | convert_to_vtk_array = vtkFloatArrayFromNumPyMultiArray |
| 399 | 1 | tkerber | |
| 400 | 1 | tkerber | class UTDoubleArrayFromNumPyMultiArray_Scalar(UTDataArrayFromNumPyMultiArray_Scalar): |
| 401 | 1 | tkerber | __doc__ = UTDataArrayFromNumPyMultiArray_Scalar.__doc__ |
| 402 | 1 | tkerber | dtype = np.float64 |
| 403 | 1 | tkerber | convert_to_vtk_array = vtkDoubleArrayFromNumPyMultiArray |
| 404 | 1 | tkerber | |
| 405 | 1 | tkerber | class UTDataArrayFromNumPyMultiArray_Vector(UTConversionDataArrayNumPy): |
| 406 | 1 | tkerber | """
|
| 407 | 1 | tkerber | Test cases for memory leaks during VTK/NumPy data conversion.
|
| 408 | 1 | tkerber | Conversion of NumPy grid vectors to VTK data array using buffers."""
|
| 409 | 1 | tkerber | |
| 410 | 1 | tkerber | def setUp(self): |
| 411 | 1 | tkerber | UTConversionDataArrayNumPy.setUp(self)
|
| 412 | 1 | tkerber | size = self.footprint//np.nbytes[self.dtype] |
| 413 | 1 | tkerber | digits, shape = shapeopt(1000, size//3, ndims=3, ecc=0.3) |
| 414 | 1 | tkerber | if self.verbose>=1: print 'digits=%8.3f, shape=%s' % (digits,shape) |
| 415 | 1 | tkerber | self.shape = shape + (3,) |
| 416 | 1 | tkerber | self.assertAlmostEqual(np.prod(self.shape)*np.nbytes[self.dtype], \ |
| 417 | 1 | tkerber | self.footprint, -4) #10kB |
| 418 | 1 | tkerber | |
| 419 | 1 | tkerber | def get_leaktest_scenario(self): |
| 420 | 1 | tkerber | |
| 421 | 1 | tkerber | # Update memory reference
|
| 422 | 1 | tkerber | self.mem_ref.update()
|
| 423 | 1 | tkerber | |
| 424 | 1 | tkerber | # NumPy allocation
|
| 425 | 1 | tkerber | data = np.empty(self.shape, self.dtype) |
| 426 | 1 | tkerber | self.assertAlmostConsumed(self.footprint, self.ctol) |
| 427 | 1 | tkerber | self.assertAlmostExceeded(self.footprint, self.etol) |
| 428 | 1 | tkerber | if self.verbose>=1: print 'NumPy allocation=', self.mem_cur-self.mem_ref |
| 429 | 1 | tkerber | |
| 430 | 1 | tkerber | # NumPy to VTK conversion
|
| 431 | 1 | tkerber | np2da = self.convert_to_vtk_array(data)
|
| 432 | 1 | tkerber | self.assertAlmostConsumed(2*self.footprint, self.ctol) |
| 433 | 1 | tkerber | self.assertAlmostExceeded(2*self.footprint, self.etol) |
| 434 | 1 | tkerber | if self.verbose>=1: print 'Conversion=', self.mem_cur-self.mem_ref |
| 435 | 1 | tkerber | |
| 436 | 1 | tkerber | # VTK retrieval
|
| 437 | 1 | tkerber | vtk_da = np2da.get_output() |
| 438 | 1 | tkerber | self.assertTrue(isinstance(vtk_da, vtkDataArray)) |
| 439 | 1 | tkerber | self.assertAlmostEqual(vtk_da.GetActualMemorySize()*vtk_kilobyte, \
|
| 440 | 1 | tkerber | self.footprint, -4) #10kB |
| 441 | 1 | tkerber | if self.verbose>=1: print 'VTK retrieval=', self.mem_cur-self.mem_ref |
| 442 | 1 | tkerber | |
| 443 | 1 | tkerber | return (np2da, data, vtk_da,)
|
| 444 | 1 | tkerber | |
| 445 | 1 | tkerber | class UTFloatArrayFromNumPyMultiArray_Vector(UTDataArrayFromNumPyMultiArray_Vector): |
| 446 | 1 | tkerber | __doc__ = UTDataArrayFromNumPyMultiArray_Vector.__doc__ |
| 447 | 1 | tkerber | dtype = np.float32 |
| 448 | 1 | tkerber | convert_to_vtk_array = vtkFloatArrayFromNumPyMultiArray |
| 449 | 1 | tkerber | |
| 450 | 1 | tkerber | class UTDoubleArrayFromNumPyMultiArray_Vector(UTDataArrayFromNumPyMultiArray_Vector): |
| 451 | 1 | tkerber | __doc__ = UTDataArrayFromNumPyMultiArray_Vector.__doc__ |
| 452 | 1 | tkerber | dtype = np.float64 |
| 453 | 1 | tkerber | convert_to_vtk_array = vtkDoubleArrayFromNumPyMultiArray |
| 454 | 1 | tkerber | |
| 455 | 1 | tkerber | # -------------------------------------------------------------------
|
| 456 | 1 | tkerber | |
| 457 | 1 | tkerber | if __name__ in ['__main__', '__builtin__']: |
| 458 | 1 | tkerber | # We may have been imported by test.py, if so we should redirect to logfile
|
| 459 | 1 | tkerber | if __name__ == '__builtin__': |
| 460 | 1 | tkerber | testrunner = CustomTextTestRunner('vtk_data.log', verbosity=2) |
| 461 | 1 | tkerber | else:
|
| 462 | 1 | tkerber | testrunner = unittest.TextTestRunner(stream=sys.stdout, verbosity=2)
|
| 463 | 1 | tkerber | |
| 464 | 1 | tkerber | testcases = [UTFloatArrayFromNumPyArray_Scalar, \ |
| 465 | 1 | tkerber | UTDoubleArrayFromNumPyArray_Scalar, \ |
| 466 | 1 | tkerber | UTFloatArrayFromNumPyArray_Vector, \ |
| 467 | 1 | tkerber | UTDoubleArrayFromNumPyArray_Vector, \ |
| 468 | 1 | tkerber | UTFloatArrayFromNumPyMultiArray_Scalar, \ |
| 469 | 1 | tkerber | UTDoubleArrayFromNumPyMultiArray_Scalar, \ |
| 470 | 1 | tkerber | UTFloatArrayFromNumPyMultiArray_Vector, \ |
| 471 | 1 | tkerber | UTDoubleArrayFromNumPyMultiArray_Vector] |
| 472 | 1 | tkerber | |
| 473 | 1 | tkerber | for test in testcases: |
| 474 | 1 | tkerber | info = '\n' + test.__name__ + '\n' + test.__doc__.strip('\n') + '\n' |
| 475 | 1 | tkerber | testsuite = unittest.defaultTestLoader.loadTestsFromTestCase(test) |
| 476 | 1 | tkerber | testrunner.stream.writeln(info) |
| 477 | 1 | tkerber | testresult = testrunner.run(testsuite) |
| 478 | 1 | tkerber | # Provide feedback on failed tests if imported by test.py
|
| 479 | 1 | tkerber | if __name__ == '__builtin__' and not testresult.wasSuccessful(): |
| 480 | 1 | tkerber | raise SystemExit('Test failed. Check vtk_data.log for details.') |