ansys / pymapdl

Pythonic interface to MAPDL
https://mapdl.docs.pyansys.com
MIT License
419 stars 116 forks source link

`MapdlPool` slower than `launch_mapdl` #3222

Open germa89 opened 5 days ago

germa89 commented 5 days ago

Gather information about a reported issue with MapdlPool speed.

Notes

All the results use v222 on Windows.

Pool uses 8 cores, which are the physical cores of my laptop.

Results

Iteration launch_mapdl MapdlPool
1 141.575 487.243
2 149.290 487.936
3 156.204 488.373
4 153.430 489.259
5 153.133 489.637
6 155.844 490.195
7 154.454 491.174
8 155.081 493.576
9 152.449 469.160
10 149.174 472.584
11 153.367 472.701
12 149.009 481.007
13 158.336 481.815
14 159.143 483.254
15 159.136 480.907
16 158.764 479.020
17 161.264 162.742
18 160.214 164.233
19 159.055 163.783
20 159.422 157.527
Total 3117.357 1137.972

MapdlPool result

Total time: 1137.9721553325653
[487.2430682182312, 487.93626523017883, 488.3732578754425, 489.2591965198517, 489.63740062713623, 490.1950089931488, 491.1746802330017, 493.5765743255615, 469.1609597206116, 472.5841302871704, 472.7011818885803, 481.007390499115, 481.8152985572815, 483.2545311450958, 480.9073061943054, 479.0204613208771, 162.74245071411133, 164.2335982322693, 163.7831094264984, 157.52774477005005]
Full console output

```txt Pool: True PyMAPDL is taking longer than expected to connect to an MAPDL session. Checking if there are any available licenses... PyMAPDL is taking longer than expected to connect to an MAPDL session. Checking if there are any available licenses... PyMAPDL is taking longer than expected to connect to an MAPDL session. Checking if there are any available licenses...PyMAPDL is taking longer than expected to connect to an MAPDL session. Checking if there are any available licenses... PyMAPDL is taking longer than expected to connect to an MAPDL session. Checking if there are any available licenses... PyMAPDL is taking longer than expected to connect to an MAPDL session. Checking if there are any available licenses... PyMAPDL is taking longer than expected to connect to an MAPDL session. Checking if there are any available licenses... PyMAPDL is taking longer than expected to connect to an MAPDL session. Checking if there are any available licenses... Total Time 487.2430682182312 Total Time 487.93626523017883 Total Time 488.3732578754425 Total Time 489.2591965198517 Total Time 489.63740062713623 Total Time 490.1950089931488 Total Time 491.1746802330017 Total Time 493.5765743255615 Total Time 469.1609597206116 Total Time 472.5841302871704 Total Time 472.7011818885803 Total Time 481.007390499115 Total Time 481.8152985572815 Total Time 483.2545311450958 Total Time 480.9073061943054 Total Time 479.0204613208771 Total Time 164.2335982322693 Total Time 162.74245071411133 Total Time 163.7831094264984 Total Time 157.52774477005005 Total time: 1137.9721553325653 [487.2430682182312, 487.93626523017883, 488.3732578754425, 489.2591965198517, 489.63740062713623, 490.1950089931488, 491.1746802330017, 493.5765743255615, 469.1609597206116, 472.5841302871704, 472.7011818885803, 481.007390499115, 481.8152985572815, 483.2545311450958, 480.9073061943054, 479.0204613208771, 162.74245071411133, 164.2335982322693, 163.7831094264984, 157.52774477005005] ```

launch_mapdl result

Total time: 3117.3571031093597
[141.57540607452393, 149.29076719284058, 156.20481204986572, 153.43074774742126, 153.1332221031189, 155.84478402137756, 154.45419192314148, 155.0814709663391, 152.44991850852966, 149.1741588115692, 153.3673119544983, 149.00977158546448, 158.3366515636444, 159.14314198493958, 159.1366572380066, 158.76436352729797, 161.26456499099731, 160.21481370925903, 159.0556252002716, 159.42233037948608]
Full console output

```txt Pool: False PyMAPDL is taking longer than expected to connect to an MAPDL session. Checking if there are any available licenses... Solving 0 model. Total Time 141.57540607452393 Solving 1 model. Total Time 149.29076719284058 Solving 2 model. Total Time 156.20481204986572 Solving 3 model. Total Time 153.43074774742126 Solving 4 model. Total Time 153.1332221031189 Solving 5 model. Total Time 155.84478402137756 Solving 6 model. Total Time 154.45419192314148 Solving 7 model. Total Time 155.0814709663391 Solving 8 model. Total Time 152.44991850852966 Solving 9 model. Total Time 149.1741588115692 Solving 10 model. Total Time 153.3673119544983 Solving 11 model. Total Time 149.00977158546448 Solving 12 model. Total Time 158.3366515636444 Solving 13 model. Total Time 159.14314198493958 Solving 14 model. Total Time 159.1366572380066 Solving 15 model. Total Time 158.76436352729797 Solving 16 model. Total Time 161.26456499099731 Solving 17 model. Total Time 160.21481370925903 Solving 18 model. Total Time 159.0556252002716 Solving 19 model. Total Time 159.42233037948608 Total time: 3117.3571031093597 [141.57540607452393, 149.29076719284058, 156.20481204986572, 153.43074774742126, 153.1332221031189, 155.84478402137756, 154.45419192314148, 155.0814709663391, 152.44991850852966, 149.1741588115692, 153.3673119544983, 149.00977158546448, 158.3366515636444, 159.14314198493958, 159.1366572380066, 158.76436352729797, 161.26456499099731, 160.21481370925903, 159.0556252002716, 159.42233037948608] ```

Code

Do change the variable POOL value to True or False to switch between MapdlPool and launch_mapdl.

Details

```py import time import numpy as np POOL = False solve = True exec_file = r"C:\Program Files\ANSYS Inc\v212\ansys\bin\winx64\ANSYS212.exe" exec_file = r"C:\Program Files\ANSYS Inc\v222\ansys\bin\winx64\ANSYS222.exe" # exec_file = r"C:\Program Files\ANSYS Inc\v231\ansys\bin\winx64\ANSYS231.exe" esize = 10. length = 100. width = 100. depth = 100. numsteps = 1 global total_time total_time = [] def solve_model(mapdl, arg=None): mapdl.clear() if solve: mapdl.fcomp('rst', 0) # Write all data in double precision mapdl.run('/config,resuprec,0') mapdl.prep7() mapdl.k(1, 0.0, 0.0, 0.0) mapdl.k(2, length, 0.0, 0.0) mapdl.k(3, length, width, 0.0) mapdl.k(4, 0.0, width, 0.0) mapdl.k(5, 0.0, 0.0, depth) mapdl.k(6, length, 0.0, depth) mapdl.k(7, length, width, depth) mapdl.k(8, 0.0, width, depth) mapdl.v(1, 2, 3, 4, 5, 6, 7, 8) mapdl.et(1, 186) mapdl.mp('ex', 1, 210000.) mapdl.mp('prxy', 1, .3) mapdl.mp('kxx', 1e-6) mapdl.esize(esize) mapdl.mshape(0, "3D") mapdl.vmesh('all') mapdl.finish() mapdl.slashsolu() # For some reason - with d,all,all - "ENS" block doesn't appear in XPL mapdl.d('all', 'ux', 2.0) mapdl.d('all', 'uy', 2.0) mapdl.d('all', 'uz', 2.0) mapdl.bf('all', 'temp', 100.) mapdl.time(1.) mapdl.nsubst(numsteps, numsteps, numsteps) mapdl.outres('all', 'none') mapdl.outres('strs', 'all') mapdl.outres("epel", "all") mapdl.outres("eppl", "all") mapdl.outres("nsol", "all") mapdl.solve() mapdl.finish() mapdl.aux2() mapdl.combine('FULL') mapdl.finish() xpl = mapdl.xpl mm = mapdl.math t0 = time.time() xpl.open('dummy_solve.rst') header = xpl.read('HEADER', asarray=True) # print(header) num_nodes = header[1] num_elems = header[5] xpl.close() # Get internal Element order xpl.open('dummy_solve.rst') internal_elem_order = xpl.read("ELM", "ELEM_ORDER") xpl.close() stress = [float(id) for id in range(1, 2001)] all_time_steps = [] def get_elem_stress(eid): return stress[eid - 1] t0 = time.time() for i in range(1, numsteps + 1): t_elem = 0. for u_eid in range(1, num_elems + 1): # for index, eid in enumerate(internal_elem_order): i_eid = internal_elem_order[u_eid - 1] xpl.open(r"dummy_solve.rst", "WRIT") xpl.step(f"DSI::SET{i}::ESL::ELEM{u_eid}") t0_elem = time.time() stress_elem = get_elem_stress(i_eid) myvec = np.ones(48, dtype=np.float64) * float(i * stress_elem) mm.set_vec(myvec, 'NEWVEC') xpl.write('ENS', 'NEWVEC') t1_elem = time.time() t_elem = t1_elem - t0_elem all_time_steps.append(t_elem) xpl.up() xpl.close() t1 = time.time() print(f"Total Time {t1 - t0}") total_time.append(t1-t0) print(f"Pool: {POOL}") if POOL: from ansys.mapdl.core import MapdlPool pool = MapdlPool( 8, start_instance=True, exec_file=exec_file, jobname='dummy_solve', override=True, start_timeout=90, loglevel="DEBUG" ) full_0 = time.time() pool.map(func=solve_model, iterable=[None for each in range(20)]) full_1 = time.time() pool.exit() else: from ansys.mapdl.core import launch_mapdl model_path = r"C:\Users\gayuso\pymapdl\tmp\Ayush\pymapdl" mapdl = launch_mapdl(exec_file, run_location=model_path, jobname='dummy_solve', override=True) full_0 = time.time() for i in range(20): print(f"Solving {i} model.") solve_model(mapdl, None) full_1 = time.time() mapdl.exit() print(f"Total time: {full_1-full_0}") print(total_time) ```

germa89 commented 13 hours ago

It is strange that the last four iterations take less time than the previous 16 (8x2). It seems that PyMAPDL is not parallelizing correctly.

In the case of launch_mapdl the time spent is comparable (150s).

germa89 commented 12 hours ago

It seems it is not always performant to use all the CPUs when using multi-threading:

image

Reference: https://www.dabeaz.com/python/UnderstandingGIL.pdf