Skip to content

Commit d563d64

Browse files
authored
Merge pull request #71 from Tieqiong/examples
correct parrallel example for all platforms
2 parents aef124b + 20f943f commit d563d64

File tree

2 files changed

+103
-63
lines changed

2 files changed

+103
-63
lines changed

docs/examples/parallelPDF.py

Lines changed: 80 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -20,68 +20,85 @@
2020
from diffpy.srreal.pdfcalculator import PDFCalculator
2121
from diffpy.structure import Structure
2222

23-
mydir = os.path.dirname(os.path.abspath(__file__))
24-
mentholcif = os.path.join(mydir, "datafiles", "menthol.cif")
25-
Uisodefault = 0.005
26-
27-
# configure options parsing
28-
parser = optparse.OptionParser("%prog [options]\n" + __doc__)
29-
parser.add_option(
30-
"--pyobjcryst",
31-
action="store_true",
32-
help="Use pyobjcryst to load the CIF file.",
33-
)
34-
parser.allow_interspersed_args = True
35-
opts, args = parser.parse_args(sys.argv[1:])
3623

3724
# load menthol structure and make sure Uiso values are non-zero
38-
if opts.pyobjcryst:
39-
# use pyobjcryst if requested by the user
40-
from numpy import pi
41-
from pyobjcryst.crystal import create_crystal_from_cif
42-
43-
menthol = create_crystal_from_cif(mentholcif)
44-
for sc in menthol.GetScatteringComponentList():
45-
sp = sc.mpScattPow
46-
sp.Biso = sp.Biso or 8 * pi**2 * Uisodefault
47-
else:
48-
# or use diffpy.structure by default
49-
menthol = Structure(filename=mentholcif)
50-
for a in menthol:
51-
a.Uisoequiv = a.Uisoequiv or Uisodefault
52-
53-
# configuration of a PDF calculator
54-
cfg = {
55-
"qmax": 25,
56-
"rmin": 0,
57-
"rmax": 30,
58-
}
59-
60-
# number of CPUs for parallel calculation
61-
ncpu = multiprocessing.cpu_count()
62-
63-
# calculate PDF on a single core
64-
t0 = time.time()
65-
pc0 = PDFCalculator(**cfg)
66-
r0, g0 = pc0(menthol)
67-
t0 = time.time() - t0
68-
print("Calculation time on 1 CPU: %g" % t0)
69-
70-
# create a pool of workers
71-
pool = multiprocessing.Pool(processes=ncpu)
72-
73-
t1 = time.time()
74-
# create a proxy parallel calculator to PDFCalculator pc0,
75-
# that uses ncpu parallel jobs submitted via pool.imap_unordered
76-
pc1 = createParallelCalculator(pc0, ncpu, pool.imap_unordered)
77-
r1, g1 = pc1(menthol)
78-
t1 = time.time() - t1
79-
print("Calculation time on %i CPUs: %g" % (ncpu, t1))
80-
print("Time ratio: %g" % (t0 / t1))
81-
82-
# plot both results and the difference curve
83-
84-
clf()
85-
gd = g0 - g1
86-
plot(r0, g0, r1, g1, r0, gd - 3)
87-
show()
25+
def load_structure(opts, mentholcif, Uisodefault):
26+
if opts.pyobjcryst:
27+
# use pyobjcryst if requested by the user
28+
from numpy import pi
29+
from pyobjcryst.crystal import create_crystal_from_cif
30+
31+
menthol = create_crystal_from_cif(mentholcif)
32+
for sc in menthol.GetScatteringComponentList():
33+
sp = sc.mpScattPow
34+
sp.Biso = sp.Biso or 8 * pi**2 * Uisodefault
35+
else:
36+
# or use diffpy.structure by default
37+
menthol = Structure(filename=mentholcif)
38+
for a in menthol:
39+
a.Uisoequiv = a.Uisoequiv or Uisodefault
40+
return menthol
41+
42+
43+
def calculate_pdf(menthol, cfg, ncpu):
44+
# calculate PDF on a single core
45+
t0 = time.time()
46+
pc0 = PDFCalculator(**cfg)
47+
r0, g0 = pc0(menthol)
48+
t0 = time.time() - t0
49+
print(f"Calculation time on 1 CPU: {t0:g}")
50+
51+
# create a pool of workers
52+
pool = multiprocessing.Pool(processes=ncpu)
53+
54+
t1 = time.time()
55+
# create a proxy parallel calculator to PDFCalculator pc0,
56+
# that uses ncpu parallel jobs submitted via pool.imap_unordered
57+
pc1 = createParallelCalculator(pc0, ncpu, pool.imap_unordered)
58+
r1, g1 = pc1(menthol)
59+
t1 = time.time() - t1
60+
pool.close()
61+
pool.join()
62+
63+
print(f"Calculation time on {ncpu} CPUs: {t1:g}")
64+
print(f"Time ratio: {t0 / t1:g}")
65+
66+
# plot both results and the difference curve
67+
68+
clf()
69+
gd = g0 - g1
70+
plot(r0, g0, label="1 CPU")
71+
plot(r1, g1, label=f"{ncpu} CPUs")
72+
plot(r0, gd - 3, label="Difference − 3")
73+
show()
74+
75+
76+
def main():
77+
mydir = os.path.dirname(os.path.abspath(__file__))
78+
mentholcif = os.path.join(mydir, "datafiles", "menthol.cif")
79+
Uisodefault = 0.005
80+
81+
# configure options parsing
82+
parser = optparse.OptionParser("%prog [options]\n" + __doc__)
83+
parser.add_option(
84+
"--pyobjcryst",
85+
action="store_true",
86+
help="Use pyobjcryst to load the CIF file.",
87+
)
88+
parser.allow_interspersed_args = True
89+
opts, args = parser.parse_args(sys.argv[1:])
90+
91+
# load the structure
92+
menthol = load_structure(opts, mentholcif, Uisodefault)
93+
94+
# configuration of a PDF calculator
95+
cfg = {"qmax": 25, "rmin": 0, "rmax": 30}
96+
97+
# number of CPUs for parallel calculation
98+
ncpu = multiprocessing.cpu_count()
99+
calculate_pdf(menthol, cfg, ncpu)
100+
101+
102+
if __name__ == "__main__":
103+
multiprocessing.freeze_support()
104+
main()

news/examples.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
**Added:**
2+
3+
* <news item>
4+
5+
**Changed:**
6+
7+
* <news item>
8+
9+
**Deprecated:**
10+
11+
* <news item>
12+
13+
**Removed:**
14+
15+
* <news item>
16+
17+
**Fixed:**
18+
19+
* Fixed `parallelPDF.py` example multiprocessing safe importing of main module issue.
20+
21+
**Security:**
22+
23+
* <news item>

0 commit comments

Comments
 (0)