Mantid
Loading...
Searching...
No Matches
AlgorithmManager.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 +
11
12#include <boost/python/class.hpp>
13#include <boost/python/def.hpp>
14#include <boost/python/list.hpp>
15#include <boost/python/overloads.hpp>
16
17#include <chrono>
18#include <thread>
19
20using namespace Mantid::API;
23using namespace boost::python;
24
25namespace {
26
27std::once_flag INIT_FLAG;
28
35AlgorithmManagerImpl &instance() {
36 // start the framework (if necessary)
37 auto &mgr = AlgorithmManager::Instance();
38 std::call_once(INIT_FLAG, []() {
39 PyRun_SimpleString("import atexit\n"
40 "def cleanupAlgorithmManager():\n"
41 " from mantid.api import AlgorithmManager\n"
42 " AlgorithmManager.shutdown()\n"
43 "atexit.register(cleanupAlgorithmManager)");
44 });
45 return mgr;
46}
47
48IAlgorithm_sptr create(AlgorithmManagerImpl *self, const std::string &algName, const int &version = -1) {
50 return self->create(algName, version);
51}
52
53std::shared_ptr<Algorithm> createUnmanaged(AlgorithmManagerImpl *self, const std::string &algName,
54 const int &version = -1) {
56 return self->createUnmanaged(algName, version);
57}
58
59void clear(AlgorithmManagerImpl *self) {
63 // ReleaseGlobalInterpreterLock releaseGIL;
64 return self->clear();
65}
66
67constexpr auto SLEEP_100_MS = std::chrono::milliseconds(100);
68
69void shutdown(AlgorithmManagerImpl *self) {
70 {
72 self->cancelAll();
73 }
74 while (!self->runningInstances().empty()) {
75 // A Python algorithm needs the GIL to finish after its execution method returns.
77 std::this_thread::sleep_for(SLEEP_100_MS);
78 }
79 // Keep the GIL while clearing because managed algorithms can own Python objects. See #33924.
80 self->clear();
81}
82
83void cancelAll(AlgorithmManagerImpl *self) {
85 return self->cancelAll();
86}
87
95IAlgorithm_sptr getAlgorithm(AlgorithmManagerImpl const *const self, AlgorithmIDProxy idHolder) {
97 return self->getAlgorithm(idHolder.id);
98}
99
107void removeById(AlgorithmManagerImpl &self, AlgorithmIDProxy idHolder) {
109 return self.removeById(idHolder.id);
110}
111
117boost::python::list runningInstancesOf(AlgorithmManagerImpl const *const self, const std::string &algName) {
118 std::vector<IAlgorithm_const_sptr> mgrAlgs;
119
120 {
122 mgrAlgs = self->runningInstancesOf(algName);
123 }
124
125 boost::python::list algs;
126 for (auto &mgrAlg : mgrAlgs) {
127 algs.append(mgrAlg);
128 }
129
130 return algs;
131}
132
134//------------------------------------------------------------------------------------------------------
135GNU_DIAG_OFF("unused-local-typedef")
136// Ignore -Wconversion warnings coming from boost::python
137// Seen with GCC 7.1.1 and Boost 1.63.0
138GNU_DIAG_OFF("conversion")
140// cppcheck-suppress unknownMacro
141BOOST_PYTHON_FUNCTION_OVERLOADS(create_overloads, create, 2, 3)
142BOOST_PYTHON_FUNCTION_OVERLOADS(createUnmanaged_overloads, createUnmanaged, 2, 3)
143
144GNU_DIAG_ON("conversion")
145GNU_DIAG_ON("unused-local-typedef")
147} // namespace
148
150
151 class_<AlgorithmManagerImpl, boost::noncopyable>("AlgorithmManagerImpl", no_init)
152 .def("create", &create, create_overloads((arg("name"), arg("version")), "Creates a managed algorithm."))
153 .def("createUnmanaged", &createUnmanaged,
154 createUnmanaged_overloads((arg("name"), arg("version")), "Creates an unmanaged algorithm."))
155 .def("size", &AlgorithmManagerImpl::size, arg("self"), "Returns the number of managed algorithms")
156 .def("getAlgorithm", &getAlgorithm, (arg("self"), arg("id_holder")),
157 "Return the algorithm instance identified by the given id.")
158 .def("removeById", &removeById, (arg("self"), arg("id_holder")), "Remove an algorithm from the managed list")
159 .def("runningInstancesOf", &runningInstancesOf, (arg("self"), arg("algorithm_name")),
160 "Returns a list of managed algorithm instances that are "
161 "currently executing")
162 .def("clear", &clear, arg("self"), "Clears the current list of managed algorithms")
163 .def("shutdown", &shutdown, arg("self"), "Cancels all running algorithms and waits for them to exit")
164 .def("cancelAll", &cancelAll, arg("self"), "Requests that all currently running algorithms be cancelled")
165 .def("Instance", instance, return_value_policy<reference_existing_object>(),
166 "Return a reference to the singleton instance")
167 .staticmethod("Instance");
168}
void export_AlgorithmManager()
#define GNU_DIAG_ON(x)
#define GNU_DIAG_OFF(x)
This is a collection of macros for turning compiler warnings off in a controlled manner.
The AlgorithmManagerImpl class is responsible for controlling algorithm instances.
std::shared_ptr< Algorithm > createUnmanaged(const std::string &algName, const int &version=-1) const
Creates an unmanaged algorithm with the option of choosing a version.
IAlgorithm_sptr getAlgorithm(AlgorithmID id) const
Returns a shared pointer by algorithm id.
void removeById(AlgorithmID id)
Removes the given algorithm from the managed list.
IAlgorithm_sptr create(const std::string &algName, const int &version=-1)
Creates a managed algorithm with the option of choosing a version.
std::vector< IAlgorithm_const_sptr > runningInstances() const
Returns all running (& managed) occurances of any algorithm, oldest first.
std::vector< IAlgorithm_const_sptr > runningInstancesOf(const std::string &algorithmName) const
Returns all running (& managed) occurances of the named algorithm, oldest first.
void cancelAll()
Requests cancellation of all running algorithms.
void clear()
Clears all managed algorithm objects that are not currently running.
Defines a structure for releasing the Python GIL using the RAII pattern.
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm
std::unique_ptr< T > create(const P &parent, const IndexArg &indexArg, const HistArg &histArg)
This is the create() method that all the other create() methods call.
Provides a concrete type to wrap & return AlgorithmIDs that are actually just typedefs for void*.