Mantid
Loading...
Searching...
No Matches
FrameworkManager.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
13
14#include <boost/python/class.hpp>
15#include <boost/python/import.hpp>
16#include <boost/python/reference_existing_object.hpp>
17#include <boost/python/return_value_policy.hpp>
18
19#include <mutex>
20
26using namespace boost::python;
28
29namespace {
30
31std::once_flag INIT_FLAG;
32bool INSTANCE_CALLED = false;
33constexpr auto PYTHONPATHS_KEY = "pythonscripts.directories";
34constexpr auto PATH_SEPARATOR = ";";
35
42void declareCPPAlgorithms() { AlgorithmFactory::Instance().subscribe<Mantid::PythonInterface::RunPythonScript>(); }
43
48void updatePythonPaths() {
49 // if the script directory is defined, get it
50 auto python_scripts_dir = ConfigService::Instance().getValue<std::string>(PYTHONPATHS_KEY).value_or("");
51
52 if (!python_scripts_dir.empty()) {
53 // import sys module once - boost can only import proper modules
54 object sys_pkg = import("sys");
55
56 // split based on ";" because that is what is allowed in the configuration
57 StringTokenizer tokens(python_scripts_dir, PATH_SEPARATOR);
58 for (auto python_dir : tokens) {
59 // sys.path doesn't like trailing slashes - do this with simple string parsing
60 if (python_dir.ends_with("\\"))
61 python_dir = python_dir.substr(0, python_dir.size() - 1);
62 if (python_dir.ends_with("/"))
63 python_dir = python_dir.substr(0, python_dir.size() - 1);
64
65 // nothing to do unless the path is non-empty
66 if (!python_dir.empty()) {
67 // call sys.path.append(python_dir)
68 sys_pkg.attr("path").attr("append")(python_dir);
69 }
70 }
71 }
72}
73
86FrameworkManagerImpl &instance() {
87 // start the framework (if necessary)
88 auto &frameworkMgr = []() -> auto & {
89 // We need to release the GIL here to prevent a deadlock when using Python log channels
91 return FrameworkManager::Instance();
92 }();
93 std::call_once(INIT_FLAG, []() {
94 INSTANCE_CALLED = true;
95 declareCPPAlgorithms();
96 updatePythonPaths();
97 import("mantid.simpleapi");
98 // Without a python-based exit handler the singletons are only cleaned
99 // up after main() and this is too late to acquire the GIL to be able to
100 // delete any python objects still stored in other singletons like the
101 // ADS or AlgorithmManager.
102 PyRun_SimpleString("import atexit\n"
103 "def cleanupFrameworkManager():\n"
104 " from mantid.api import FrameworkManager\n"
105 " FrameworkManager.shutdown()\n"
106 "atexit.register(cleanupFrameworkManager)");
107 });
108 return frameworkMgr;
109}
110
114bool hasInstance() { return INSTANCE_CALLED; }
115} // namespace
116
118 class_<FrameworkManagerImpl, boost::noncopyable>("FrameworkManagerImpl", no_init)
119 .def("setNumOMPThreadsToConfigValue", &FrameworkManagerImpl::setNumOMPThreadsToConfigValue, arg("self"),
120 "Sets the number of OpenMP threads to the value "
121 "specified in the "
122 "config file")
123
124 .def("setNumOMPThreads", &FrameworkManagerImpl::setNumOMPThreads, (arg("self"), arg("nthread")),
125 "Set the number of OpenMP threads to the given value")
126
127 .def("getNumOMPThreads", &FrameworkManagerImpl::getNumOMPThreads, arg("self"),
128 "Returns the number of OpenMP threads that will be used.")
129
130 .def("clear", &FrameworkManagerImpl::clear, arg("self"), "Clear all memory held by Mantid")
131
132 .def("clearAlgorithms", &FrameworkManagerImpl::clearAlgorithms, arg("self"),
133 "Clear memory held by algorithms (does not include workspaces)")
134
135 .def("clearData", &FrameworkManagerImpl::clearData, arg("self"),
136 "Clear memory held by the data service (essentially all "
137 "workspaces, "
138 "including hidden)")
139
140 .def("clearInstruments", &FrameworkManagerImpl::clearInstruments, arg("self"),
141 "Clear memory held by the cached instruments")
142
143 .def("clearPropertyManagers", &FrameworkManagerImpl::clearPropertyManagers, arg("self"),
144 "Clear memory held by the PropertyManagerDataService")
145
146 .def("shutdown", &FrameworkManagerImpl::shutdown, arg("self"), "Effectively shutdown this service")
147
148 .def("hasInstance", hasInstance, "Returns True if Instance has been called, false otherwise")
149 .staticmethod("hasInstance")
150
151 .def("Instance", instance, "Return a reference to the singleton instance",
152 return_value_policy<reference_existing_object>())
153 .staticmethod("Instance");
154}
void export_FrameworkManager()
The main public API via which users interact with the Mantid framework.
void clearPropertyManagers()
Clear memory associated with the PropertyManagers.
void setNumOMPThreads(const int nthreads)
Set the number of OpenMP threads to the given value.
void clearInstruments()
Clear memory associated with the IDS.
void clearData()
Clear memory associated with the ADS.
void shutdown()
shuts down and performs clean up tasks
int getNumOMPThreads() const
Returns the number of OpenMP threads that will be used.
void setNumOMPThreadsToConfigValue()
Set the number of OpenMP threads to use based on the config value.
void clear()
Clears all memory associated with the AlgorithmManager, ADS & IDS.
void clearAlgorithms()
Clear memory associated with the AlgorithmManager.
T getValue(const std::string &name) const
Templated method to get the value of a property.
Defines a structure for releasing the Python GIL using the RAII pattern.
Mantid::Kernel::SingletonHolder< AlgorithmFactoryImpl > AlgorithmFactory
Mantid::Kernel::SingletonHolder< FrameworkManagerImpl > FrameworkManager
Mantid::Kernel::SingletonHolder< ConfigServiceImpl > ConfigService