fastatomstruct 1.5.0__cp314-cp314-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,103 @@
1
+ from typing import Any, Callable, Dict, List
2
+ from time import time
3
+
4
+ import ase
5
+ import numpy as np
6
+ from .fastatomstruct import *
7
+
8
+ rank = None
9
+
10
+
11
+ def is_root() -> bool:
12
+ """Check if the current process is the root process."""
13
+ if rank is None:
14
+ return True
15
+ return rank == 0
16
+
17
+
18
+ def chunks(indices: List[int], n: int):
19
+ """Yield successive chunks from list of atoms."""
20
+ for i in range(0, len(indices), n):
21
+ yield indices[i : i + n]
22
+
23
+
24
+ def ipar(
25
+ func: Callable, atoms: List[ase.Atoms], *args: List[Any], **kwargs: Dict[Any, Any]
26
+ ) -> List[Any]:
27
+ """Image-based parallelization.
28
+
29
+ The calculation of many structural quantities is parallelized over atoms.
30
+ However, image-based parallelization (or a mixture of both) can be more efficient
31
+ in some cases. This function makes using this parallelization layer quite easy.
32
+ You can just use it as a simple wrapper around other functions implemented in
33
+ `fastatomstruct` (see example below). **This function needs a working installation
34
+ of the MPI4Py package!** You can set the `RAYON_NUM_THREADS` enviroment variable
35
+ to control the number of threads.
36
+
37
+ Arguments:
38
+ func (Callable): Some function from the `fastatomstruct` package
39
+ atoms (List[ase.Atoms]): List of ASE configurations
40
+
41
+ Returns:
42
+ List of results; type depends on the output of func
43
+
44
+ Examples
45
+ --------
46
+
47
+ The exemplary file "Sb-1.00-300-100.traj" `can be found here <https://zivgitlab.uni-muenster.de/ag-salinga/fastatomstruct/-/raw/master/tests/structures/Sb-1.00-300-100.traj>`__.
48
+ The code below needs to be run e.g. with `mpirun -n 2 test.py`. In this case,
49
+ two processes will be used.
50
+
51
+ .. plot::
52
+
53
+ >>> import matplotlib.pyplot as plt
54
+ >>> import fastatomstruct as fs
55
+ >>> from ase import io
56
+ >>> if fs.is_root():
57
+ >>> atoms = io.read("Sb-1.00-300-100.traj", index="::200")
58
+ >>> q = fs.ipar(fs.q_tetrahedral, atoms, fs.CutoffMode.Fixed(3.2), 3)
59
+ >>> if fs.is_root():
60
+ >>> plt.hist(q[0], bins=25, alpha=0.5)
61
+ >>> plt.hist(q[1], bins=25, color="C3", alpha=0.5)
62
+ """
63
+ from mpi4py import MPI
64
+
65
+ comm = MPI.COMM_WORLD
66
+ global rank
67
+ rank = comm.Get_rank()
68
+
69
+ if rank == 0:
70
+ print("\nImage parallelization report\n" + "----------------------------")
71
+
72
+ if rank == 0:
73
+ res_full, t0_f = [], time()
74
+
75
+ for i, c in enumerate(chunks(list(range(len(atoms))), comm.size)):
76
+ while len(c) < comm.size:
77
+ c.append(None)
78
+
79
+ if rank == 0:
80
+ per = (len(c) - np.count_nonzero([ci is None for ci in c])) / len(c)
81
+ t0 = time()
82
+ if c[rank] is not None:
83
+ a = atoms[c[rank]]
84
+ res = func(a, *args, **kwargs)
85
+ else:
86
+ res = None
87
+
88
+ res = comm.gather(res, root=0)
89
+ if rank == 0:
90
+ t = time() - t0
91
+ print(f"Chunk {i + 1}: {per * 100:03.2f}% | {t:.2f} s")
92
+ res_full.extend(res)
93
+
94
+ if rank == 0:
95
+ for i in range(len(res_full) - 1, -1, -1):
96
+ if res_full[i] is None:
97
+ del res_full[i]
98
+ print("----------------------------")
99
+ print(f"Total: {(time() - t0_f):.2f} s\n")
100
+ else:
101
+ res_full = None
102
+
103
+ return res_full
@@ -0,0 +1,60 @@
1
+ """
2
+ This type stub file was generated by pyright.
3
+ """
4
+
5
+ import ase
6
+ from typing import Any, Callable, Dict, List
7
+ from .fastatomstruct import *
8
+
9
+ """
10
+ This type stub file was generated by pyright.
11
+ """
12
+ rank = ...
13
+
14
+ def is_root() -> bool:
15
+ """Check if the current process is the root process."""
16
+ ...
17
+
18
+ def chunks(indices: List[int], n: int):
19
+ """Yield successive chunks from list of atoms."""
20
+ ...
21
+
22
+ def ipar(
23
+ func: Callable, atoms: List[ase.Atoms], *args: List[Any], **kwargs: Dict[Any, Any]
24
+ ) -> List[Any]:
25
+ """Image-based parallelization.
26
+
27
+ The calculation of many structural quantities is parallelized over atoms.
28
+ However, image-based parallelization (or a mixture of both) can be more efficient
29
+ in some cases. This function makes using this parallelization layer quite easy.
30
+ You can just use it as a simple wrapper around other functions implemented in
31
+ `fastatomstruct` (see example below). **This function needs a working installation
32
+ of the MPI4Py package!** You can set the `RAYON_NUM_THREADS` enviroment variable
33
+ to control the number of threads.
34
+
35
+ Arguments:
36
+ func (Callable): Some function from the `fastatomstruct` package
37
+ atoms (List[ase.Atoms]): List of ASE configurations
38
+
39
+ Returns:
40
+ List of results; type depends on the output of func
41
+
42
+ Examples:
43
+
44
+ The exemplary file "Sb-1.00-300-100.traj" `can be found here <https://zivgitlab.uni-muenster.de/ag-salinga/fastatomstruct/-/raw/master/python/test/structures/Sb-1.00-300-100.traj>`__.
45
+ The code below needs to be run e.g. with `mpirun -n 2 test.py`. In this case,
46
+ two processes will be used.
47
+
48
+ .. plot::
49
+
50
+ >>> import matplotlib.pyplot as plt
51
+ >>> import fastatomstruct as fs
52
+ >>> from ase import io
53
+ >>> if fs.is_root():
54
+ >>> atoms = io.read("Sb-1.00-300-100.traj", index="::200")
55
+ >>> q = fs.ipar(fs.q_tetrahedral, atoms, fs.CutoffMode.Fixed(3.2), 3)
56
+ >>> if fs.is_root():
57
+ >>> plt.hist(q[0], bins=25, alpha=0.5)
58
+ >>> plt.hist(q[1], bins=25, color="C3", alpha=0.5)
59
+ """
60
+ ...