Skip to content

Commit 98f0cfc

Browse files
committed
feat: allow generator to run in parallel
1 parent 95703af commit 98f0cfc

2 files changed

Lines changed: 50 additions & 5 deletions

File tree

‎src/diffpy/apps/refinebase/parametric_model.py‎

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from pathlib import Path
55

66
import networkx as nx
7+
import numpy
78
from pyobjcryst import loadCrystal
89

910
from diffpy.srfit.fitbase import FitContribution
@@ -245,7 +246,14 @@ def evaluate(self):
245246
class ParametricModelPDF(ParametricModel):
246247
# NOTE: qmin, qmax, stype(scattering type) are meta handled
247248
# throughout the loaded profile in the refinement session
248-
def __init__(self, name, structure, spacegroup_symbol="P1", finite=False):
249+
def __init__(
250+
self,
251+
name,
252+
structure,
253+
spacegroup_symbol="P1",
254+
finite=False,
255+
run_parallel=True,
256+
):
249257
"""
250258
Create a ParametricModelPDF instance from a structure object.
251259
@@ -269,6 +277,25 @@ def __init__(self, name, structure, spacegroup_symbol="P1", finite=False):
269277
self.space_group_symbol = spacegroup_symbol
270278
self.sgpar_names = []
271279
self._rebuild_graph()
280+
if run_parallel:
281+
try:
282+
import multiprocessing
283+
from multiprocessing import Pool
284+
285+
import psutil
286+
except ImportError:
287+
print(
288+
"\nYou don't appear to have the "
289+
"necessary packages for parallelization"
290+
)
291+
syst_cores = multiprocessing.cpu_count()
292+
cpu_percent = psutil.cpu_percent()
293+
avail_cores = numpy.floor(
294+
(100 - cpu_percent) / (100.0 / syst_cores)
295+
)
296+
ncpu = int(numpy.max([1, avail_cores]))
297+
pool = Pool(processes=ncpu)
298+
self.calc_obj.parallel(ncpu=ncpu, mapfunc=pool.map)
272299

273300
def _hide_dependent_parameters(self, use_uiso=True):
274301
if use_uiso:
@@ -545,7 +572,11 @@ def residual(self):
545572

546573

547574
def create_pdf_model_from_file(
548-
name, structure_file_path, library="Diffpy", finite=False
575+
name,
576+
structure_file_path,
577+
library="Diffpy",
578+
finite=False,
579+
run_parallel=True,
549580
):
550581
"""Create a ParametricModelPDF by parsing a structure file."""
551582
stru_parser = get_parser("auto")
@@ -557,16 +588,21 @@ def create_pdf_model_from_file(
557588
) or library == "ObjCryst":
558589
structure = loadCrystal(structure_file_path)
559590
return ParametricModelPDF(
560-
name, structure, spacegroup_symbol=spacegroup_symbol, finite=finite
591+
name,
592+
structure,
593+
spacegroup_symbol=spacegroup_symbol,
594+
finite=finite,
595+
run_parallel=run_parallel,
561596
)
562597

563598

564-
def create_pdf_model_from_model(name, from_model):
599+
def create_pdf_model_from_model(name, from_model, run_parallel=True):
565600
"""Create a ParametricModelPDF sharing the phase of from_model."""
566601
return ParametricModelPDF(
567602
name,
568603
from_model.calc_obj.phase,
569604
spacegroup_symbol=from_model.space_group_symbol,
605+
run_parallel=run_parallel,
570606
)
571607

572608

@@ -577,6 +613,7 @@ def create_pdf_model_from_code(
577613
global_namespace={},
578614
local_structure_name="structure",
579615
finite=False,
616+
run_parallel=True,
580617
):
581618
"""Create a ParametricModelPDF by executing code that builds a structure.
582619
@@ -618,5 +655,9 @@ def create_pdf_model_from_code(
618655
)
619656

620657
return ParametricModelPDF(
621-
name, structure, spacegroup_symbol=spacegroup_symbol, finite=finite
658+
name,
659+
structure,
660+
spacegroup_symbol=spacegroup_symbol,
661+
finite=finite,
662+
run_parallel=run_parallel,
622663
)

‎src/diffpy/apps/refinebase/refinement_session.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ def add_pdf_model(
128128
global_namespace={},
129129
local_structure_name="structure",
130130
finite=False,
131+
run_parallel=True,
131132
):
132133
from diffpy.apps.refinebase.parametric_model import (
133134
create_pdf_model_from_code,
@@ -143,6 +144,7 @@ def add_pdf_model(
143144
structure_file_path,
144145
library=library,
145146
finite=finite,
147+
run_parallel=run_parallel,
146148
)
147149
elif from_model_name is not None:
148150
if from_model_name not in self.models_dict:
@@ -153,6 +155,7 @@ def add_pdf_model(
153155
pdf_model = create_pdf_model_from_model(
154156
model_name,
155157
from_model,
158+
run_parallel=run_parallel,
156159
)
157160
elif code is not None:
158161
pdf_model = create_pdf_model_from_code(
@@ -161,6 +164,7 @@ def add_pdf_model(
161164
global_namespace=global_namespace,
162165
local_structure_name=local_structure_name,
163166
finite=finite,
167+
run_parallel=run_parallel,
164168
)
165169
else:
166170
raise ValueError(

0 commit comments

Comments
 (0)