...
 
......@@ -26,7 +26,7 @@
- Some labels and the title for the SED plots has been improved to avoid overlaps and overflows. (Médéric Boquien)
- Ensure that best models are properly computed when models are computed by blocks and that no fit could be made in one or more blocks. This can be case if all the models in the block are older than the age of the universe. (Médéric)
- Make sure that the parameters are saved with the proper scale (linear or logarithmic) in the χ² files. (Médéric Boquien)
- Some math libraries such as MKL or OpenBLAS sometime try to be (too) smart, starting computation threads on their own. As cigale is already parallel, this just oversubscribes the CPU and can lead to important slowdowns. An environment variable could be set to disable this, but this is cumbersome. Disabling within the code did not seem to work. A different method has been implement, which should address the issue to forcefully disable threading in these libraries. (Médéric Boquien)
- Some math libraries such as MKL or OpenBLAS sometime try to be (too) smart, starting computation threads on their own. As cigale is already parallel, this just oversubscribes the CPU and can lead to important slowdowns. An environment variable could be set by the user to disable this, but this is cumbersome. Rather, we set these variables directly in the code at the startup of cigale. (Yannick Roehlly & Médéric Boquien)
### Optimised
- Slight speedup of the computation of the likelihood from the χ² using a multiplication rather than a division. (Médéric Boquien)
- Speedup of the computation of the χ² by ~10% taking the opposite of a scalar rather than of an array. (Médéric Boquien)
......
......@@ -3,6 +3,15 @@
# Licensed under the CeCILL-v2 licence - see Licence_CeCILL_V2-en.txt
# Author: Yannick Roehlly
import os
# Set environment variables to disable multithreading as users will probably
# want to set the number of cores to the max of their computer.
os.environ["OMP_NUM_THREADS"] = "1"
os.environ["OPENBLAS_NUM_THREADS"] = "1"
os.environ["MKL_NUM_THREADS"] = "1"
os.environ["VECLIB_MAXIMUM_THREADS"] = "1"
os.environ["NUMEXPR_NUM_THREADS"] = "1"
import argparse
import multiprocessing as mp
import sys
......
......@@ -11,7 +11,6 @@ from copy import deepcopy
import numpy as np
from .utils import save_chi2, compute_corr_dz, compute_chi2, weighted_param
from ..utils import nothreading
from ...warehouse import SedWarehouse
......@@ -28,10 +27,6 @@ def init_sed(models, counter):
"""
global gbl_warehouse, gbl_models, gbl_counter
# Limit the number of threads to 1 if we use MKL in order to limit the
# oversubscription of the CPU/RAM.
nothreading()
gbl_warehouse = SedWarehouse()
gbl_models = models
......@@ -53,9 +48,6 @@ def init_analysis(models, results, counter):
"""
global gbl_models, gbl_obs, gbl_results, gbl_counter
# Limit the number of threads to 1 to limit the oversubscription of the CPU
nothreading()
gbl_models = models
gbl_obs = models.obs
gbl_results = results
......@@ -82,9 +74,6 @@ def init_bestfit(conf, params, observations, results, counter):
global gbl_warehouse, gbl_conf, gbl_params, gbl_obs
global gbl_results, gbl_counter
# Limit the number of threads to 1 to limit the oversubscription of the CPU
nothreading()
gbl_warehouse = SedWarehouse()
gbl_conf = conf
......
......@@ -7,7 +7,6 @@
import numpy as np
from ..utils import nothreading
from ...warehouse import SedWarehouse
......@@ -26,9 +25,6 @@ def init_fluxes(models, counter):
"""
global gbl_warehouse, gbl_models, gbl_obs, gbl_save, gbl_counter
# Limit the number of threads to 1 to limit the oversubscription of the CPU
nothreading()
gbl_warehouse = SedWarehouse()
gbl_models = models
......
......@@ -6,52 +6,11 @@
"""
Various utility functions for pcigale analysis modules
"""
import ctypes
from ctypes.util import find_library
import multiprocessing as mp
import time
def nothreading():
"""Some libraries such as Intel's MKL have automatic threading. This is
good when having only one process. However we already do our own
parallelisation. The additional threads created by the MKL increase in
excess the pressure on the CPU and on the RAM slowing everything down.
Parameters
----------
None
Returns
-------
None
"""
for basename in ['iomp', 'gomp', 'omp', 'vcomp']:
try: # Disable threading for OpenMP
name = find_library(basename)
if name:
lib = ctypes.cdll.LoadLibrary(name)
lib.omp_set_num_threads(ctypes.c_int(1))
except:
continue
try: # Disable threading for MKL
name = find_library('mkl_rt')
if name:
lib = ctypes.cdll.LoadLibrary(name)
lib.mkl_set_num_threads(ctypes.byref(ctypes.c_int(1)))
except:
pass
try: # Disable threading for OpenBLAS
name = find_library('openblas')
if name:
lib = ctypes.cdll.LoadLibrary(name)
lib.openblas_set_num_threads(ctypes.c_int(1))
except:
pass
class Counter:
"""Class to count the number of models computers/objects analysed. It has
two internal counters. One is internal to the process and is incremented at
......
......@@ -6,6 +6,15 @@
# Licensed under the CeCILL-v2 licence - see Licence_CeCILL_V2-en.txt
# Author: Yannick Roehlly, Médéric Boquien & Denis Burgarella
import os
# Set environment variables to disable multithreading as users will probably
# want to set the number of cores to the max of their computer.
os.environ["OMP_NUM_THREADS"] = "1"
os.environ["OPENBLAS_NUM_THREADS"] = "1"
os.environ["MKL_NUM_THREADS"] = "1"
os.environ["VECLIB_MAXIMUM_THREADS"] = "1"
os.environ["NUMEXPR_NUM_THREADS"] = "1"
import argparse
import sys
from os import path
......
......@@ -17,7 +17,7 @@ import matplotlib.pyplot as plt
import multiprocessing as mp
import numpy as np
from pcigale.utils import read_table
from pcigale.analysis_modules.utils import Counter, nothreading
from pcigale.analysis_modules.utils import Counter
def pool_initializer(counter):
......@@ -27,9 +27,7 @@ def pool_initializer(counter):
:param counter: Counter class object for the number of models plotted
"""
global gbl_counter
# Limit the number of threads to 1 if we use MKL in order to limit the
# oversubscription of the CPU/RAM.
nothreading()
gbl_counter = counter
......
......@@ -17,7 +17,7 @@ import multiprocessing as mp
import numpy as np
import pkg_resources
from scipy import stats
from pcigale.analysis_modules.utils import Counter, nothreading
from pcigale.analysis_modules.utils import Counter
# Name of the file containing the best models information
BEST_RESULTS = "results.fits"
......@@ -31,9 +31,7 @@ def pool_initializer(counter):
:param counter: Counter class object for the number of models plotted
"""
global gbl_counter
# Limit the number of threads to 1 if we use MKL in order to limit the
# oversubscription of the CPU/RAM.
nothreading()
gbl_counter = counter
......
......@@ -16,7 +16,7 @@ import matplotlib.pyplot as plt
import multiprocessing as mp
import numpy as np
from pcigale.utils import read_table
from pcigale.analysis_modules.utils import Counter, nothreading
from pcigale.analysis_modules.utils import Counter
def pool_initializer(counter):
......@@ -26,9 +26,7 @@ def pool_initializer(counter):
:param counter: Counter class object for the number of models plotted
"""
global gbl_counter
# Limit the number of threads to 1 if we use MKL in order to limit the
# oversubscription of the CPU/RAM.
nothreading()
gbl_counter = counter
......
......@@ -22,7 +22,7 @@ from scipy.constants import c
from pcigale.data import Database
from pcigale.utils import read_table
import matplotlib.gridspec as gridspec
from pcigale.analysis_modules.utils import Counter, nothreading
from pcigale.analysis_modules.utils import Counter
# Name of the file containing the best models information
BEST_RESULTS = "results.fits"
......@@ -46,9 +46,7 @@ def pool_initializer(counter):
:param counter: Counter class object for the number of models plotted
"""
global gbl_counter
# Limit the number of threads to 1 if we use MKL in order to limit the
# oversubscription of the CPU/RAM.
nothreading()
gbl_counter = counter
......