From 8e7045fb136af58d891e35d4e95517ba81dab8b2 Mon Sep 17 00:00:00 2001 From: noabauma Date: Fri, 16 May 2025 15:40:56 +0200 Subject: [PATCH 01/27] adding pybind11 as an extern libary --- .gitmodules | 4 ++++ examples/local/fibonacci/meson.build | 4 ++-- extern/pybind11 | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) create mode 160000 extern/pybind11 diff --git a/.gitmodules b/.gitmodules index 0edcdb2..4710bc1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,3 +6,7 @@ path = extern/hicr url = https://github.com/Algebraic-Programming/HiCR.git branch = master +[submodule "extern/pybind11"] + path = extern/pybind11 + url = ../../pybind/pybind11 + branch = stable diff --git a/examples/local/fibonacci/meson.build b/examples/local/fibonacci/meson.build index a53babe..664190b 100644 --- a/examples/local/fibonacci/meson.build +++ b/examples/local/fibonacci/meson.build @@ -3,11 +3,11 @@ testSuite = [ 'examples', 'local', 'fibonacci' ] threading = executable('threading', [ 'source/pthreads.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') - test('threading', threading, args : [ '10' ], suite: testSuite, workdir: threading.path() + '.p' ) + test('threading', threading, args : [ '15' ], suite: testSuite, workdir: threading.path() + '.p' ) endif nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') - test('nosv', nosv, args : [ '10' ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) + test('nosv', nosv, args : [ '15' ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) endif \ No newline at end of file diff --git a/extern/pybind11 b/extern/pybind11 new file mode 160000 index 0000000..58c382a --- /dev/null +++ b/extern/pybind11 @@ -0,0 +1 @@ +Subproject commit 58c382a8e3d7081364d2f5c62e7f429f0412743b From 95931870a0ddad45adbf1f6ea9a5a29caed6f8fe Mon Sep 17 00:00:00 2001 From: noabauma Date: Mon, 19 May 2025 16:51:28 +0200 Subject: [PATCH 02/27] adding meson stuff for pybind11 --- include/python_api/README.md | 32 ++++++++++++++++++++++++++++ include/python_api/example.cpp | 11 ++++++++++ include/python_api/meson.build | 12 +++++++++++ include/python_api/pyproject.toml | 3 +++ include/python_api/taskr_modules.hpp | 0 meson.build | 4 ++++ meson_options.txt | 4 ++++ 7 files changed, 66 insertions(+) create mode 100644 include/python_api/README.md create mode 100644 include/python_api/example.cpp create mode 100644 include/python_api/meson.build create mode 100644 include/python_api/pyproject.toml create mode 100644 include/python_api/taskr_modules.hpp diff --git a/include/python_api/README.md b/include/python_api/README.md new file mode 100644 index 0000000..7926e2d --- /dev/null +++ b/include/python_api/README.md @@ -0,0 +1,32 @@ +# pybind11 installation + +To install pybind11 go inside `extern/pybind11` and type + +``` +mkdir build +cd build +cmake .. +make check -j$(nproc) +``` + +Be sure all the tests are passing! + +Now, inside the `build` folder it will create another folder called `mock_install/share/pkgconfig` and this pkg-config file `pybind11.pc` type this: + +``` +prefix=/taskr/extern/pybind11/ +includedir=${prefix}/include + +Name: pybind11 +Description: Seamless operability between C++11 and Python +Version: 2.13.6 +Cflags: -I${includedir} +``` + +and add the PKG-CONFIG PATH in your `.bashrc` file: + +``` +export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/taskr/extern/pybind11/build/mock_install/share/pkgconfig +``` + +run `source ~/.bashrc` and now, you should be good-to-go with running `meson setup`. diff --git a/include/python_api/example.cpp b/include/python_api/example.cpp new file mode 100644 index 0000000..f5c6536 --- /dev/null +++ b/include/python_api/example.cpp @@ -0,0 +1,11 @@ +#include + +int add(int i, int j) { + return i + j; +} + +PYBIND11_MODULE(example, m) { + m.doc() = "pybind11 example plugin"; // optional module docstring + + m.def("add", &add, "A function that adds two numbers"); +} \ No newline at end of file diff --git a/include/python_api/meson.build b/include/python_api/meson.build new file mode 100644 index 0000000..078636d --- /dev/null +++ b/include/python_api/meson.build @@ -0,0 +1,12 @@ +# pybind11 stuff with the compiler flags +# Manually compile like this: +# c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3-config --includes) -Iextern/pybind11/include example.cpp -o example$(python3-config --extension-suffix) + +py = import('python').find_installation(pure: false) +pybind11_dep = dependency('pybind11', required: true) + +py.extension_module('example', + 'example.cpp', + install: true, + dependencies : [pybind11_dep], +) \ No newline at end of file diff --git a/include/python_api/pyproject.toml b/include/python_api/pyproject.toml new file mode 100644 index 0000000..ece15b2 --- /dev/null +++ b/include/python_api/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["meson-python", "pybind11"] +build-backend = "mesonpy" diff --git a/include/python_api/taskr_modules.hpp b/include/python_api/taskr_modules.hpp new file mode 100644 index 0000000..e69de29 diff --git a/meson.build b/meson.build index a38cb0c..501c7a9 100644 --- a/meson.build +++ b/meson.build @@ -63,6 +63,10 @@ taskrDependencies += InstrumentationBuildDep # add_project_arguments('-DENABLE_DEBUG', language: 'cpp') endif +if get_option('buildPythonAPI') + subdir('include/python_api') +endif + ####### Collect the dependencies TaskRBuildDep = declare_dependency( diff --git a/meson_options.txt b/meson_options.txt index 094af32..9e3b460 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -16,6 +16,10 @@ option('buildInstrumentation', type : 'boolean', value : false, description: 'Indicates whether to build the instrumentation using TraCR', ) +option('buildPythonAPI', type : 'boolean', value : false, + description: 'Indicates whether to build the TaskR Python API', +) + option('compileWarningsAsErrors', type : 'boolean', value : false, description: 'Indicates whether a compilation warning should result in a fatal error. This is useful for CI testing but may result in inconveniences for normal users, hence it should be false by default' ) From fbfea43415efd2b237ed6155b95103dfa59469bc Mon Sep 17 00:00:00 2001 From: noabauma Date: Thu, 22 May 2025 11:03:20 +0200 Subject: [PATCH 03/27] creating a PyRuntime wrapper class for pybind11 --- examples/local/simple/meson.build | 9 ++ examples/local/simple/py_source/main.py | 14 ++ examples/local/simple/py_source/simple.py | 29 ++++ examples/local/simple/source/nosv.cpp | 2 +- examples/local/simple/source/pthreads.cpp | 2 +- examples/local/simple/source/pyruntime.cpp | 34 +++++ include/python_api/taskr_modules.hpp | 162 +++++++++++++++++++++ meson.build | 6 +- 8 files changed, 253 insertions(+), 5 deletions(-) create mode 100644 examples/local/simple/py_source/main.py create mode 100644 examples/local/simple/py_source/simple.py create mode 100644 examples/local/simple/source/pyruntime.cpp diff --git a/examples/local/simple/meson.build b/examples/local/simple/meson.build index 1f78352..5d101f9 100644 --- a/examples/local/simple/meson.build +++ b/examples/local/simple/meson.build @@ -11,3 +11,12 @@ nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) endif + +if get_option('buildTests') and get_option('buildPythonAPI') + pyruntime = executable('pyruntime', [ 'source/pyruntime.cpp'], dependencies: [ TaskRBuildDep ]) + + test('pyruntime', pyruntime, args : [ ], suite: testSuite, workdir: pyruntime.path() + '.p' ) + + # python_script = find_program('py_source/main.py', required: true) + # test('python_script', python_script, args : [ ], suite: testSuite) +endif \ No newline at end of file diff --git a/examples/local/simple/py_source/main.py b/examples/local/simple/py_source/main.py new file mode 100644 index 0000000..7c55e12 --- /dev/null +++ b/examples/local/simple/py_source/main.py @@ -0,0 +1,14 @@ +import taskr +import simple + +def main(): + # maybe get resources as well as initializing number of PUs + + # + runtime = taskr.Runtime(ComputeManager, ComputeManager, []) + + # Running simple example + simple(runtime) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/local/simple/py_source/simple.py b/examples/local/simple/py_source/simple.py new file mode 100644 index 0000000..1a1042d --- /dev/null +++ b/examples/local/simple/py_source/simple.py @@ -0,0 +1,29 @@ +import taskr + +def simple(runtime): + # Setting onTaskFinish callback to free up task memory when it finishes (not sure if we will have this) + #runtime.setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskFinish, [&taskr](taskr::Task *task) { delete task; }) + + # Initializing taskr + runtime.initialize + + fc = lambda task : print(f"Hello, I am task {task.getLabel()}") + + # Create the taskr Tasks + taskfc = taskr.Function(fc) + + # Creating the execution units (functions that the tasks will run) + for i in range(1): + task = taskr.Task(i, taskfc) + + # Adding to taskr + runtime.addTask = task + + # Running taskr for the current repetition + runtime.run + + # Waiting current repetition to end + runtime.await_ + + # Finalizing taskr + runtime.finalize \ No newline at end of file diff --git a/examples/local/simple/source/nosv.cpp b/examples/local/simple/source/nosv.cpp index 8a1e72c..26c31d7 100644 --- a/examples/local/simple/source/nosv.cpp +++ b/examples/local/simple/source/nosv.cpp @@ -65,7 +65,7 @@ int main(int argc, char **argv) // Creating taskr taskr::Runtime taskr(&computeManager, &computeManager, computeResources); - // Running ABCtasks example + // Running simple example simple(&taskr); // Freeing up memory diff --git a/examples/local/simple/source/pthreads.cpp b/examples/local/simple/source/pthreads.cpp index 72a4c66..485c9a5 100644 --- a/examples/local/simple/source/pthreads.cpp +++ b/examples/local/simple/source/pthreads.cpp @@ -57,7 +57,7 @@ int main(int argc, char **argv) // Creating taskr taskr::Runtime taskr(&boostComputeManager, &pthreadsComputeManager, computeResources); - // Running ABCtasks example + // Running simple example simple(&taskr); // Freeing up memory diff --git a/examples/local/simple/source/pyruntime.cpp b/examples/local/simple/source/pyruntime.cpp new file mode 100644 index 0000000..2a8ce1a --- /dev/null +++ b/examples/local/simple/source/pyruntime.cpp @@ -0,0 +1,34 @@ +/* + * Copyright 2025 Huawei Technologies Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "python_api/taskr_modules.hpp" + +#include "simple.hpp" + +int main(int argc, char **argv) +{ + // Creating taskr + taskr::PyRuntime pytaskr("nosv", 2); + + // Running simple example + simple(pytaskr.get_runtime()); + + return 0; +} diff --git a/include/python_api/taskr_modules.hpp b/include/python_api/taskr_modules.hpp index e69de29..7e6b195 100644 --- a/include/python_api/taskr_modules.hpp +++ b/include/python_api/taskr_modules.hpp @@ -0,0 +1,162 @@ +/* + * Copyright 2025 Huawei Technologies Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include +#include + +#include + +// #include + +namespace taskr +{ + +class PyRuntime +{ +public: + PyRuntime(const std::string& str, size_t num_workers = 0) : _str(str) + { + // Specify the compute Managers + if(_str == "nosv") + { + // Initialize nosv + check(nosv_init()); + + // nosv task instance for the main thread + nosv_task_t mainTask; + + // Attaching the main thread + check(nosv_attach(&mainTask, NULL, NULL, NOSV_ATTACH_NONE)); + + _executionStateComputeManager = std::make_unique(); + _processingUnitComputeManager = std::make_unique(); + } + else if(_str == "threading") + { + _executionStateComputeManager = std::make_unique(); + _processingUnitComputeManager = std::make_unique(); + } + else + { + HICR_THROW_LOGIC("'%s' is not a known HiCR backend. Try 'nosv' or 'threading'\n", str); + } + + // Reserving memory for hwloc + hwloc_topology_init(&_topology); + + // Initializing HWLoc-based host (CPU) topology manager + HiCR::backend::hwloc::TopologyManager tm(&_topology); + + // Asking backend to check the available devices + const auto t = tm.queryTopology(); + + // Compute resources to use + HiCR::Device::computeResourceList_t _computeResources; + + // Getting compute resources in this device + auto cr = (*(t.getDevices().begin()))->getComputeResourceList(); + + auto itr = cr.begin(); + + // Specify allocate the compute resources (i.e. PUs) + if(num_workers == 0) + { + num_workers = cr.size(); + } + else if(num_workers >= 1 || num_workers <= cr.size()) + { + // valid, do nothing + } + else + { + HICR_THROW_LOGIC("num_workers = %d is not a legal number. We can have at most %d workers.\n", num_workers, cr.size()); + } + + for (size_t i = 0; i < num_workers; i++) + { + _computeResources.push_back(*itr); + itr++; + } + + _runtime = std::make_unique(_executionStateComputeManager.get(), _processingUnitComputeManager.get(), _computeResources); + } + + ~PyRuntime() + { + // Freeing up memory + hwloc_topology_destroy(_topology); + + if(_str == "nosv") + { + // Detaching the main thread + check(nosv_detach(NOSV_DETACH_NONE)); + + // Shutdown nosv + check(nosv_shutdown()); + } + } + + Runtime* get_runtime() + { + return _runtime.get(); + } + + private: + + const std::string _str; + + std::unique_ptr _executionStateComputeManager; + + std::unique_ptr _processingUnitComputeManager; + + hwloc_topology_t _topology; + + const HiCR::Device::computeResourceList_t _computeResources; + + std::unique_ptr _runtime; +}; + +} // namespace taskr + +/* +PYBIND11_MODULE(taskr, m) +{ + m.doc() = "pybind11 plugin for TaskR"; + + // TaskR's Runtime class + py::class_(m, "PyRuntime") + .def(py::init()) + .def("setTaskCallbackHandler", &Runtime::setTaskCallbackHandler) + .def("initialize", &Runtime::initialize) + .def("addTask", &Runtime::addTask) + .def("run", &Runtime::run) + .def("await_", &Runtime::await) + .def("finalize", &Runtime::finalize) + + // TaskR's Function class + py::class_(m, "Function") + .def(py::init()) + + // TaskR's Task class + py::class_(m, "Task") + .def(py::init()) +} +*/ \ No newline at end of file diff --git a/meson.build b/meson.build index 501c7a9..6046dfb 100644 --- a/meson.build +++ b/meson.build @@ -53,9 +53,9 @@ TaskRBuildIncludes = include_directories([ if get_option('buildInstrumentation') -InstrumentationProject = subproject('tracr', required: true) -InstrumentationBuildDep = InstrumentationProject.get_variable('InstrumentationBuildDep') -taskrDependencies += InstrumentationBuildDep + InstrumentationProject = subproject('tracr', required: true) + InstrumentationBuildDep = InstrumentationProject.get_variable('InstrumentationBuildDep') + taskrDependencies += InstrumentationBuildDep add_project_arguments('-DENABLE_INSTRUMENTATION', language: 'cpp') From b2f5bef2e94735645ef7c96ba6f09f7ffd066fa1 Mon Sep 17 00:00:00 2001 From: noabauma Date: Thu, 22 May 2025 13:32:09 +0200 Subject: [PATCH 04/27] naming the whole thing pyTaskR and minor code improvements --- examples/local/simple/meson.build | 2 +- examples/local/simple/source/pyruntime.cpp | 8 +--- include/{python_api => pytaskr}/README.md | 0 include/{python_api => pytaskr}/example.cpp | 0 include/{python_api => pytaskr}/meson.build | 0 .../{python_api => pytaskr}/pyproject.toml | 0 .../pyruntime.hpp} | 34 +++---------- include/pytaskr/pytaskr.hpp | 48 +++++++++++++++++++ meson.build | 4 +- meson_options.txt | 2 +- 10 files changed, 60 insertions(+), 38 deletions(-) rename include/{python_api => pytaskr}/README.md (100%) rename include/{python_api => pytaskr}/example.cpp (100%) rename include/{python_api => pytaskr}/meson.build (100%) rename include/{python_api => pytaskr}/pyproject.toml (100%) rename include/{python_api/taskr_modules.hpp => pytaskr/pyruntime.hpp} (84%) create mode 100644 include/pytaskr/pytaskr.hpp diff --git a/examples/local/simple/meson.build b/examples/local/simple/meson.build index 5d101f9..f4f8927 100644 --- a/examples/local/simple/meson.build +++ b/examples/local/simple/meson.build @@ -12,7 +12,7 @@ if get_option('buildTests') test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) endif -if get_option('buildTests') and get_option('buildPythonAPI') +if get_option('buildTests') and get_option('buildPyTaskR') pyruntime = executable('pyruntime', [ 'source/pyruntime.cpp'], dependencies: [ TaskRBuildDep ]) test('pyruntime', pyruntime, args : [ ], suite: testSuite, workdir: pyruntime.path() + '.p' ) diff --git a/examples/local/simple/source/pyruntime.cpp b/examples/local/simple/source/pyruntime.cpp index 2a8ce1a..1a9b1b8 100644 --- a/examples/local/simple/source/pyruntime.cpp +++ b/examples/local/simple/source/pyruntime.cpp @@ -14,18 +14,14 @@ * limitations under the License. */ -#include -#include -#include - -#include "python_api/taskr_modules.hpp" +#include #include "simple.hpp" int main(int argc, char **argv) { // Creating taskr - taskr::PyRuntime pytaskr("nosv", 2); + taskr::PyRuntime pytaskr("threading", 8); // Running simple example simple(pytaskr.get_runtime()); diff --git a/include/python_api/README.md b/include/pytaskr/README.md similarity index 100% rename from include/python_api/README.md rename to include/pytaskr/README.md diff --git a/include/python_api/example.cpp b/include/pytaskr/example.cpp similarity index 100% rename from include/python_api/example.cpp rename to include/pytaskr/example.cpp diff --git a/include/python_api/meson.build b/include/pytaskr/meson.build similarity index 100% rename from include/python_api/meson.build rename to include/pytaskr/meson.build diff --git a/include/python_api/pyproject.toml b/include/pytaskr/pyproject.toml similarity index 100% rename from include/python_api/pyproject.toml rename to include/pytaskr/pyproject.toml diff --git a/include/python_api/taskr_modules.hpp b/include/pytaskr/pyruntime.hpp similarity index 84% rename from include/python_api/taskr_modules.hpp rename to include/pytaskr/pyruntime.hpp index 7e6b195..24e3a9f 100644 --- a/include/python_api/taskr_modules.hpp +++ b/include/pytaskr/pyruntime.hpp @@ -14,18 +14,21 @@ * limitations under the License. */ +#pragma once + #include #include #include +#include +#include + #include #include #include #include -// #include - namespace taskr { @@ -134,29 +137,4 @@ class PyRuntime std::unique_ptr _runtime; }; -} // namespace taskr - -/* -PYBIND11_MODULE(taskr, m) -{ - m.doc() = "pybind11 plugin for TaskR"; - - // TaskR's Runtime class - py::class_(m, "PyRuntime") - .def(py::init()) - .def("setTaskCallbackHandler", &Runtime::setTaskCallbackHandler) - .def("initialize", &Runtime::initialize) - .def("addTask", &Runtime::addTask) - .def("run", &Runtime::run) - .def("await_", &Runtime::await) - .def("finalize", &Runtime::finalize) - - // TaskR's Function class - py::class_(m, "Function") - .def(py::init()) - - // TaskR's Task class - py::class_(m, "Task") - .def(py::init()) -} -*/ \ No newline at end of file +} // namespace taskr \ No newline at end of file diff --git a/include/pytaskr/pytaskr.hpp b/include/pytaskr/pytaskr.hpp new file mode 100644 index 0000000..187f0a6 --- /dev/null +++ b/include/pytaskr/pytaskr.hpp @@ -0,0 +1,48 @@ +/* + * Copyright 2025 Huawei Technologies Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +/* +#include + + +PYBIND11_MODULE(taskr, m) +{ + m.doc() = "pybind11 plugin for TaskR"; + + // TaskR's Runtime class + py::class_(m, "PyRuntime") + .def(py::init()) + .def("setTaskCallbackHandler", &Runtime::setTaskCallbackHandler) + .def("initialize", &Runtime::initialize) + .def("addTask", &Runtime::addTask) + .def("run", &Runtime::run) + .def("await_", &Runtime::await) + .def("finalize", &Runtime::finalize) + + // TaskR's Function class + py::class_(m, "Function") + .def(py::init()) + + // TaskR's Task class + py::class_(m, "Task") + .def(py::init()) +} +*/ \ No newline at end of file diff --git a/meson.build b/meson.build index 6046dfb..d0a2911 100644 --- a/meson.build +++ b/meson.build @@ -63,8 +63,8 @@ if get_option('buildInstrumentation') # add_project_arguments('-DENABLE_DEBUG', language: 'cpp') endif -if get_option('buildPythonAPI') - subdir('include/python_api') +if get_option('buildPyTaskR') + subdir('include/pytaskr') endif ####### Collect the dependencies diff --git a/meson_options.txt b/meson_options.txt index 9e3b460..7d468a7 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -16,7 +16,7 @@ option('buildInstrumentation', type : 'boolean', value : false, description: 'Indicates whether to build the instrumentation using TraCR', ) -option('buildPythonAPI', type : 'boolean', value : false, +option('buildPyTaskR', type : 'boolean', value : false, description: 'Indicates whether to build the TaskR Python API', ) From b3626aed417941cbd7f8c27a3f4a02b9b23ddf3c Mon Sep 17 00:00:00 2001 From: noabauma Date: Fri, 23 May 2025 11:53:35 +0200 Subject: [PATCH 05/27] adding first little example in 'simple' --- .gitignore | 1 + examples/local/simple/meson.build | 16 ++++-- .../proc.992751/thread.992751/stream.json | 14 +++++ .../proc.992751/thread.992751/stream.obs | Bin 0 -> 8 bytes .../proc.998152/thread.998152/stream.json | 14 +++++ .../proc.998152/thread.998152/stream.obs | Bin 0 -> 8 bytes .../proc.999875/thread.999875/stream.json | 14 +++++ .../proc.999875/thread.999875/stream.obs | Bin 0 -> 8 bytes examples/local/simple/py_source/main.py | 10 ++-- examples/local/simple/py_source/simple.py | 38 +++++++------ .../source/{pyruntime.cpp => pysimple.cpp} | 4 +- include/pytaskr/example.cpp | 11 ---- include/pytaskr/meson.build | 6 +- include/pytaskr/pyruntime.hpp | 4 +- include/pytaskr/pytaskr.cpp | 53 ++++++++++++++++++ include/pytaskr/pytaskr.hpp | 48 ---------------- meson.build | 9 +-- 17 files changed, 145 insertions(+), 97 deletions(-) create mode 100644 examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.992751/thread.992751/stream.json create mode 100644 examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.992751/thread.992751/stream.obs create mode 100644 examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.998152/thread.998152/stream.json create mode 100644 examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.998152/thread.998152/stream.obs create mode 100644 examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.999875/thread.999875/stream.json create mode 100644 examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.999875/thread.999875/stream.obs rename examples/local/simple/source/{pyruntime.cpp => pysimple.cpp} (91%) delete mode 100644 include/pytaskr/example.cpp create mode 100644 include/pytaskr/pytaskr.cpp delete mode 100644 include/pytaskr/pytaskr.hpp diff --git a/.gitignore b/.gitignore index 84788f4..ce0bd60 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ build .vscode atlas_*.sh **/matrix/ +**/__pycache__/ \ No newline at end of file diff --git a/examples/local/simple/meson.build b/examples/local/simple/meson.build index f4f8927..bc02b5c 100644 --- a/examples/local/simple/meson.build +++ b/examples/local/simple/meson.build @@ -12,11 +12,17 @@ if get_option('buildTests') test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) endif -if get_option('buildTests') and get_option('buildPyTaskR') - pyruntime = executable('pyruntime', [ 'source/pyruntime.cpp'], dependencies: [ TaskRBuildDep ]) +if get_option('buildPyTaskR') + pysimple_cpp = executable('pysimple_cpp', [ 'source/pysimple.cpp'], dependencies: [ TaskRBuildDep ]) - test('pyruntime', pyruntime, args : [ ], suite: testSuite, workdir: pyruntime.path() + '.p' ) + if get_option('buildTests') + test('pysimple_cpp', pysimple_cpp, args : [ ], suite: testSuite, workdir: pysimple_cpp.path() + '.p' ) - # python_script = find_program('py_source/main.py', required: true) - # test('python_script', python_script, args : [ ], suite: testSuite) + test('pysimple', + py, + args : [ 'py_source/main.py' ], + env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + suite: testSuite, + workdir: meson.current_source_dir()) + endif endif \ No newline at end of file diff --git a/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.992751/thread.992751/stream.json b/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.992751/thread.992751/stream.json new file mode 100644 index 0000000..a5f468b --- /dev/null +++ b/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.992751/thread.992751/stream.json @@ -0,0 +1,14 @@ +{ + "version": 3, + "ovni": { + "lib": { + "version": "1.12.0", + "commit": "unknown" + }, + "part": "thread", + "tid": 992751, + "pid": 992751, + "loom": "nbaumann-ThinkStation-P340.9", + "app_id": 1 + } +} \ No newline at end of file diff --git a/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.992751/thread.992751/stream.obs b/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.992751/thread.992751/stream.obs new file mode 100644 index 0000000000000000000000000000000000000000..6c6ad4ff41fa797a1b4e969662e66177c5c4c3b1 GIT binary patch literal 8 Pcmc~V%gbbBU|;|M3ts`g literal 0 HcmV?d00001 diff --git a/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.998152/thread.998152/stream.json b/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.998152/thread.998152/stream.json new file mode 100644 index 0000000..bccd70d --- /dev/null +++ b/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.998152/thread.998152/stream.json @@ -0,0 +1,14 @@ +{ + "version": 3, + "ovni": { + "lib": { + "version": "1.12.0", + "commit": "unknown" + }, + "part": "thread", + "tid": 998152, + "pid": 998152, + "loom": "nbaumann-ThinkStation-P340.9", + "app_id": 1 + } +} \ No newline at end of file diff --git a/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.998152/thread.998152/stream.obs b/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.998152/thread.998152/stream.obs new file mode 100644 index 0000000000000000000000000000000000000000..6c6ad4ff41fa797a1b4e969662e66177c5c4c3b1 GIT binary patch literal 8 Pcmc~V%gbbBU|;|M3ts`g literal 0 HcmV?d00001 diff --git a/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.999875/thread.999875/stream.json b/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.999875/thread.999875/stream.json new file mode 100644 index 0000000..c3688f1 --- /dev/null +++ b/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.999875/thread.999875/stream.json @@ -0,0 +1,14 @@ +{ + "version": 3, + "ovni": { + "lib": { + "version": "1.12.0", + "commit": "unknown" + }, + "part": "thread", + "tid": 999875, + "pid": 999875, + "loom": "nbaumann-ThinkStation-P340.9", + "app_id": 1 + } +} \ No newline at end of file diff --git a/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.999875/thread.999875/stream.obs b/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.999875/thread.999875/stream.obs new file mode 100644 index 0000000000000000000000000000000000000000..6c6ad4ff41fa797a1b4e969662e66177c5c4c3b1 GIT binary patch literal 8 Pcmc~V%gbbBU|;|M3ts`g literal 0 HcmV?d00001 diff --git a/examples/local/simple/py_source/main.py b/examples/local/simple/py_source/main.py index 7c55e12..2c0f1a1 100644 --- a/examples/local/simple/py_source/main.py +++ b/examples/local/simple/py_source/main.py @@ -2,13 +2,15 @@ import simple def main(): - # maybe get resources as well as initializing number of PUs - # - runtime = taskr.Runtime(ComputeManager, ComputeManager, []) + # Initialize taskr with the wanted compute manager backend and number of PUs + t = taskr.taskr("threading", 1) + + # Get the runtime + runtime = t.get_runtime # Running simple example - simple(runtime) + simple.simple(runtime) if __name__ == "__main__": main() \ No newline at end of file diff --git a/examples/local/simple/py_source/simple.py b/examples/local/simple/py_source/simple.py index 1a1042d..90b30a4 100644 --- a/examples/local/simple/py_source/simple.py +++ b/examples/local/simple/py_source/simple.py @@ -1,29 +1,31 @@ import taskr def simple(runtime): - # Setting onTaskFinish callback to free up task memory when it finishes (not sure if we will have this) - #runtime.setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskFinish, [&taskr](taskr::Task *task) { delete task; }) + print(f"hello I am {runtime}") + + # # Setting onTaskFinish callback to free up task memory when it finishes (not sure if we will have this) + # #runtime.setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskFinish, [&taskr](taskr::Task *task) { delete task; }) - # Initializing taskr - runtime.initialize + # # Initializing taskr + # runtime.initialize - fc = lambda task : print(f"Hello, I am task {task.getLabel()}") + # fc = lambda task : print(f"Hello, I am task {task.getLabel()}") - # Create the taskr Tasks - taskfc = taskr.Function(fc) + # # Create the taskr Tasks + # taskfc = taskr.Function(fc) - # Creating the execution units (functions that the tasks will run) - for i in range(1): - task = taskr.Task(i, taskfc) + # # Creating the execution units (functions that the tasks will run) + # for i in range(1): + # task = taskr.Task(i, taskfc) - # Adding to taskr - runtime.addTask = task + # # Adding to taskr + # runtime.addTask = task - # Running taskr for the current repetition - runtime.run + # # Running taskr for the current repetition + # runtime.run - # Waiting current repetition to end - runtime.await_ + # # Waiting current repetition to end + # runtime.await_ - # Finalizing taskr - runtime.finalize \ No newline at end of file + # # Finalizing taskr + # runtime.finalize \ No newline at end of file diff --git a/examples/local/simple/source/pyruntime.cpp b/examples/local/simple/source/pysimple.cpp similarity index 91% rename from examples/local/simple/source/pyruntime.cpp rename to examples/local/simple/source/pysimple.cpp index 1a9b1b8..e4b972d 100644 --- a/examples/local/simple/source/pyruntime.cpp +++ b/examples/local/simple/source/pysimple.cpp @@ -14,14 +14,14 @@ * limitations under the License. */ -#include +#include #include "simple.hpp" int main(int argc, char **argv) { // Creating taskr - taskr::PyRuntime pytaskr("threading", 8); + taskr::PyRuntime pytaskr("nosv", 8); // Running simple example simple(pytaskr.get_runtime()); diff --git a/include/pytaskr/example.cpp b/include/pytaskr/example.cpp deleted file mode 100644 index f5c6536..0000000 --- a/include/pytaskr/example.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include - -int add(int i, int j) { - return i + j; -} - -PYBIND11_MODULE(example, m) { - m.doc() = "pybind11 example plugin"; // optional module docstring - - m.def("add", &add, "A function that adds two numbers"); -} \ No newline at end of file diff --git a/include/pytaskr/meson.build b/include/pytaskr/meson.build index 078636d..0c69e5a 100644 --- a/include/pytaskr/meson.build +++ b/include/pytaskr/meson.build @@ -5,8 +5,8 @@ py = import('python').find_installation(pure: false) pybind11_dep = dependency('pybind11', required: true) -py.extension_module('example', - 'example.cpp', +py.extension_module('taskr', + 'pytaskr.cpp', install: true, - dependencies : [pybind11_dep], + dependencies : [TaskRBuildDep, pybind11_dep], ) \ No newline at end of file diff --git a/include/pytaskr/pyruntime.hpp b/include/pytaskr/pyruntime.hpp index 24e3a9f..d6944db 100644 --- a/include/pytaskr/pyruntime.hpp +++ b/include/pytaskr/pyruntime.hpp @@ -79,7 +79,7 @@ class PyRuntime auto itr = cr.begin(); - // Specify allocate the compute resources (i.e. PUs) + // Allocate the compute resources (i.e. PUs) if(num_workers == 0) { num_workers = cr.size(); @@ -90,7 +90,7 @@ class PyRuntime } else { - HICR_THROW_LOGIC("num_workers = %d is not a legal number. We can have at most %d workers.\n", num_workers, cr.size()); + HICR_THROW_LOGIC("num_workers = %d is not a legal number. FYI, we can have at most %d workers.\n", num_workers, cr.size()); } for (size_t i = 0; i < num_workers; i++) diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp new file mode 100644 index 0000000..9400489 --- /dev/null +++ b/include/pytaskr/pytaskr.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2025 Huawei Technologies Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include +#include + +namespace py = pybind11; + +namespace taskr +{ + +PYBIND11_MODULE(taskr, m) +{ + m.doc() = "pybind11 plugin for TaskR"; + + // pyTaskR's PyRuntime class + py::class_(m, "taskr") + .def(py::init()) + .def("get_runtime", &PyRuntime::get_runtime); + + // // TaskR's Runtime class + // py::class_(m, "Runtime") + // .def("setTaskCallbackHandler", &Runtime::setTaskCallbackHandler) + // .def("initialize", &Runtime::initialize) + // .def("addTask", &Runtime::addTask) + // .def("run", &Runtime::run) + // .def("await_", &Runtime::await) + // .def("finalize", &Runtime::finalize); + + // // TaskR's Function class + // py::class_(m, "Function") + // .def(py::init()); + + // // TaskR's Task class + // py::class_(m, "Task") + // .def(py::init()); +} + +} \ No newline at end of file diff --git a/include/pytaskr/pytaskr.hpp b/include/pytaskr/pytaskr.hpp deleted file mode 100644 index 187f0a6..0000000 --- a/include/pytaskr/pytaskr.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2025 Huawei Technologies Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -/* -#include - - -PYBIND11_MODULE(taskr, m) -{ - m.doc() = "pybind11 plugin for TaskR"; - - // TaskR's Runtime class - py::class_(m, "PyRuntime") - .def(py::init()) - .def("setTaskCallbackHandler", &Runtime::setTaskCallbackHandler) - .def("initialize", &Runtime::initialize) - .def("addTask", &Runtime::addTask) - .def("run", &Runtime::run) - .def("await_", &Runtime::await) - .def("finalize", &Runtime::finalize) - - // TaskR's Function class - py::class_(m, "Function") - .def(py::init()) - - // TaskR's Task class - py::class_(m, "Task") - .def(py::init()) -} -*/ \ No newline at end of file diff --git a/meson.build b/meson.build index d0a2911..23f5371 100644 --- a/meson.build +++ b/meson.build @@ -63,10 +63,6 @@ if get_option('buildInstrumentation') # add_project_arguments('-DENABLE_DEBUG', language: 'cpp') endif -if get_option('buildPyTaskR') - subdir('include/pytaskr') -endif - ####### Collect the dependencies TaskRBuildDep = declare_dependency( @@ -75,6 +71,11 @@ TaskRBuildDep = declare_dependency( dependencies: taskrDependencies ) +####### Build PyTaskR +if get_option('buildPyTaskR') + subdir('include/pytaskr') +endif + ####### Build test / example targets only if TaskR is being loaded as a subproject if meson.is_subproject() == false From c785535adf46761c3f63d971453f6c66663d037e Mon Sep 17 00:00:00 2001 From: noabauma Date: Mon, 26 May 2025 13:54:56 +0200 Subject: [PATCH 06/27] PyRuntime and Runtime working, now it is up to the Task class to be pybind11 --- .gitignore | 3 +- examples/local/simple/meson.build | 4 +- .../proc.992751/thread.992751/stream.json | 14 ------- .../proc.992751/thread.992751/stream.obs | Bin 8 -> 0 bytes .../proc.998152/thread.998152/stream.json | 14 ------- .../proc.998152/thread.998152/stream.obs | Bin 8 -> 0 bytes .../proc.999875/thread.999875/stream.json | 14 ------- .../proc.999875/thread.999875/stream.obs | Bin 8 -> 0 bytes examples/local/simple/py_source/main.py | 2 +- examples/local/simple/py_source/simple.py | 38 +++++++++--------- .../source/{pysimple.cpp => pyruntime.cpp} | 7 +++- include/pytaskr/pyruntime.hpp | 4 +- include/pytaskr/pytaskr.cpp | 33 +++++++-------- 13 files changed, 47 insertions(+), 86 deletions(-) delete mode 100644 examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.992751/thread.992751/stream.json delete mode 100644 examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.992751/thread.992751/stream.obs delete mode 100644 examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.998152/thread.998152/stream.json delete mode 100644 examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.998152/thread.998152/stream.obs delete mode 100644 examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.999875/thread.999875/stream.json delete mode 100644 examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.999875/thread.999875/stream.obs rename examples/local/simple/source/{pysimple.cpp => pyruntime.cpp} (84%) diff --git a/.gitignore b/.gitignore index ce0bd60..9d449eb 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ build .vscode atlas_*.sh **/matrix/ -**/__pycache__/ \ No newline at end of file +**/__pycache__/ +**/ovni/ \ No newline at end of file diff --git a/examples/local/simple/meson.build b/examples/local/simple/meson.build index bc02b5c..bc2dd97 100644 --- a/examples/local/simple/meson.build +++ b/examples/local/simple/meson.build @@ -13,10 +13,10 @@ if get_option('buildTests') endif if get_option('buildPyTaskR') - pysimple_cpp = executable('pysimple_cpp', [ 'source/pysimple.cpp'], dependencies: [ TaskRBuildDep ]) + pyruntime = executable('pyruntime', [ 'source/pyruntime.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') - test('pysimple_cpp', pysimple_cpp, args : [ ], suite: testSuite, workdir: pysimple_cpp.path() + '.p' ) + test('pyruntime', pyruntime, args : [ ], suite: testSuite, workdir: pyruntime.path() + '.p' ) test('pysimple', py, diff --git a/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.992751/thread.992751/stream.json b/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.992751/thread.992751/stream.json deleted file mode 100644 index a5f468b..0000000 --- a/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.992751/thread.992751/stream.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "version": 3, - "ovni": { - "lib": { - "version": "1.12.0", - "commit": "unknown" - }, - "part": "thread", - "tid": 992751, - "pid": 992751, - "loom": "nbaumann-ThinkStation-P340.9", - "app_id": 1 - } -} \ No newline at end of file diff --git a/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.992751/thread.992751/stream.obs b/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.992751/thread.992751/stream.obs deleted file mode 100644 index 6c6ad4ff41fa797a1b4e969662e66177c5c4c3b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 Pcmc~V%gbbBU|;|M3ts`g diff --git a/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.998152/thread.998152/stream.json b/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.998152/thread.998152/stream.json deleted file mode 100644 index bccd70d..0000000 --- a/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.998152/thread.998152/stream.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "version": 3, - "ovni": { - "lib": { - "version": "1.12.0", - "commit": "unknown" - }, - "part": "thread", - "tid": 998152, - "pid": 998152, - "loom": "nbaumann-ThinkStation-P340.9", - "app_id": 1 - } -} \ No newline at end of file diff --git a/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.998152/thread.998152/stream.obs b/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.998152/thread.998152/stream.obs deleted file mode 100644 index 6c6ad4ff41fa797a1b4e969662e66177c5c4c3b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 Pcmc~V%gbbBU|;|M3ts`g diff --git a/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.999875/thread.999875/stream.json b/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.999875/thread.999875/stream.json deleted file mode 100644 index c3688f1..0000000 --- a/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.999875/thread.999875/stream.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "version": 3, - "ovni": { - "lib": { - "version": "1.12.0", - "commit": "unknown" - }, - "part": "thread", - "tid": 999875, - "pid": 999875, - "loom": "nbaumann-ThinkStation-P340.9", - "app_id": 1 - } -} \ No newline at end of file diff --git a/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.999875/thread.999875/stream.obs b/examples/local/simple/ovni/loom.nbaumann-ThinkStation-P340.9/proc.999875/thread.999875/stream.obs deleted file mode 100644 index 6c6ad4ff41fa797a1b4e969662e66177c5c4c3b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 Pcmc~V%gbbBU|;|M3ts`g diff --git a/examples/local/simple/py_source/main.py b/examples/local/simple/py_source/main.py index 2c0f1a1..2eb3fea 100644 --- a/examples/local/simple/py_source/main.py +++ b/examples/local/simple/py_source/main.py @@ -7,7 +7,7 @@ def main(): t = taskr.taskr("threading", 1) # Get the runtime - runtime = t.get_runtime + runtime = t.get_runtime() # Running simple example simple.simple(runtime) diff --git a/examples/local/simple/py_source/simple.py b/examples/local/simple/py_source/simple.py index 90b30a4..83bcaef 100644 --- a/examples/local/simple/py_source/simple.py +++ b/examples/local/simple/py_source/simple.py @@ -1,31 +1,29 @@ import taskr def simple(runtime): - print(f"hello I am {runtime}") - - # # Setting onTaskFinish callback to free up task memory when it finishes (not sure if we will have this) - # #runtime.setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskFinish, [&taskr](taskr::Task *task) { delete task; }) + # Setting onTaskFinish callback to free up task memory when it finishes (not sure if we will have this) + #runtime.setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskFinish, [&taskr](taskr::Task *task) { delete task; }) - # # Initializing taskr - # runtime.initialize + # Initializing taskr + runtime.initialize() - # fc = lambda task : print(f"Hello, I am task {task.getLabel()}") + fc = lambda task : print(f"Hello, I am task {task.getLabel()}") - # # Create the taskr Tasks - # taskfc = taskr.Function(fc) + # Create the taskr Tasks + taskfc = taskr.Function(fc) - # # Creating the execution units (functions that the tasks will run) - # for i in range(1): - # task = taskr.Task(i, taskfc) + # Creating the execution units (functions that the tasks will run) + for i in range(1): + task = taskr.Task(i, taskfc) - # # Adding to taskr - # runtime.addTask = task + # Adding to taskr + runtime.addTask(task) - # # Running taskr for the current repetition - # runtime.run + # Running taskr for the current repetition + runtime.run() - # # Waiting current repetition to end - # runtime.await_ + # Waiting current repetition to end + runtime.await_() - # # Finalizing taskr - # runtime.finalize \ No newline at end of file + # Finalizing taskr + runtime.finalize() \ No newline at end of file diff --git a/examples/local/simple/source/pysimple.cpp b/examples/local/simple/source/pyruntime.cpp similarity index 84% rename from examples/local/simple/source/pysimple.cpp rename to examples/local/simple/source/pyruntime.cpp index e4b972d..8ed72e9 100644 --- a/examples/local/simple/source/pysimple.cpp +++ b/examples/local/simple/source/pyruntime.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include "simple.hpp" @@ -21,10 +22,12 @@ int main(int argc, char **argv) { // Creating taskr - taskr::PyRuntime pytaskr("nosv", 8); + taskr::PyRuntime pytaskr("threading", 8); + + taskr::Runtime& runtime = pytaskr.get_runtime(); // Running simple example - simple(pytaskr.get_runtime()); + simple(&runtime); return 0; } diff --git a/include/pytaskr/pyruntime.hpp b/include/pytaskr/pyruntime.hpp index d6944db..4e3a7fc 100644 --- a/include/pytaskr/pyruntime.hpp +++ b/include/pytaskr/pyruntime.hpp @@ -117,9 +117,9 @@ class PyRuntime } } - Runtime* get_runtime() + Runtime& get_runtime() { - return _runtime.get(); + return *_runtime; } private: diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index 9400489..45abe51 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ #include +#include #include #include @@ -27,27 +28,27 @@ PYBIND11_MODULE(taskr, m) { m.doc() = "pybind11 plugin for TaskR"; + // TaskR's Runtime class + py::class_(m, "Runtime") + .def("setTaskCallbackHandler", &Runtime::setTaskCallbackHandler) + .def("initialize", &Runtime::initialize) + .def("addTask", &Runtime::addTask) + .def("run", &Runtime::run) + .def("await_", &Runtime::await) + .def("finalize", &Runtime::finalize); + // pyTaskR's PyRuntime class py::class_(m, "taskr") .def(py::init()) - .def("get_runtime", &PyRuntime::get_runtime); - - // // TaskR's Runtime class - // py::class_(m, "Runtime") - // .def("setTaskCallbackHandler", &Runtime::setTaskCallbackHandler) - // .def("initialize", &Runtime::initialize) - // .def("addTask", &Runtime::addTask) - // .def("run", &Runtime::run) - // .def("await_", &Runtime::await) - // .def("finalize", &Runtime::finalize); + .def("get_runtime", &PyRuntime::get_runtime, py::return_value_policy::reference_internal); - // // TaskR's Function class - // py::class_(m, "Function") - // .def(py::init()); + // TaskR's Function class + py::class_(m, "Function") + .def(py::init()); - // // TaskR's Task class - // py::class_(m, "Task") - // .def(py::init()); + // TaskR's Task class + py::class_(m, "Task") + .def(py::init()); } } \ No newline at end of file From 5e5c44cb778916a44cbe4968316f5d8adafaf11e Mon Sep 17 00:00:00 2001 From: noabauma Date: Wed, 28 May 2025 16:40:06 +0200 Subject: [PATCH 07/27] finally working, now, more tests and more methods --- examples/local/simple/py_source/main.py | 2 +- examples/local/simple/py_source/simple.py | 18 ++++++++++++++++-- include/pytaskr/pyruntime.hpp | 8 ++------ include/pytaskr/pytaskr.cpp | 11 ++++++----- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/examples/local/simple/py_source/main.py b/examples/local/simple/py_source/main.py index 2eb3fea..f03c2de 100644 --- a/examples/local/simple/py_source/main.py +++ b/examples/local/simple/py_source/main.py @@ -4,7 +4,7 @@ def main(): # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("threading", 1) + t = taskr.taskr("threading", 2) # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/simple/py_source/simple.py b/examples/local/simple/py_source/simple.py index 83bcaef..e82dddb 100644 --- a/examples/local/simple/py_source/simple.py +++ b/examples/local/simple/py_source/simple.py @@ -1,29 +1,43 @@ import taskr def simple(runtime): - # Setting onTaskFinish callback to free up task memory when it finishes (not sure if we will have this) + # TODO: Setting onTaskFinish callback to free up task memory when it finishes (not sure if we will have this) #runtime.setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskFinish, [&taskr](taskr::Task *task) { delete task; }) + print("runtime.initialize()", flush=True) + # Initializing taskr runtime.initialize() fc = lambda task : print(f"Hello, I am task {task.getLabel()}") + print("taskr.Function(fc)", flush=True) + # Create the taskr Tasks taskfc = taskr.Function(fc) # Creating the execution units (functions that the tasks will run) - for i in range(1): + for i in range(10): + print("create task", flush=True) + task = taskr.Task(i, taskfc) + print("add task", flush=True) + # Adding to taskr runtime.addTask(task) + print("runtime.run()", flush=True) + # Running taskr for the current repetition runtime.run() + print("runtime.await_()", flush=True) + # Waiting current repetition to end runtime.await_() + print("runtime.finalize()", flush=True) + # Finalizing taskr runtime.finalize() \ No newline at end of file diff --git a/include/pytaskr/pyruntime.hpp b/include/pytaskr/pyruntime.hpp index 4e3a7fc..193bd46 100644 --- a/include/pytaskr/pyruntime.hpp +++ b/include/pytaskr/pyruntime.hpp @@ -35,7 +35,7 @@ namespace taskr class PyRuntime { public: - PyRuntime(const std::string& str, size_t num_workers = 0) : _str(str) + PyRuntime(const std::string& str = "threading", size_t num_workers = 0) : _str(str) { // Specify the compute Managers if(_str == "nosv") @@ -84,11 +84,7 @@ class PyRuntime { num_workers = cr.size(); } - else if(num_workers >= 1 || num_workers <= cr.size()) - { - // valid, do nothing - } - else + else if(num_workers > cr.size()) { HICR_THROW_LOGIC("num_workers = %d is not a legal number. FYI, we can have at most %d workers.\n", num_workers, cr.size()); } diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index 45abe51..341e194 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -32,14 +32,14 @@ PYBIND11_MODULE(taskr, m) py::class_(m, "Runtime") .def("setTaskCallbackHandler", &Runtime::setTaskCallbackHandler) .def("initialize", &Runtime::initialize) - .def("addTask", &Runtime::addTask) - .def("run", &Runtime::run) - .def("await_", &Runtime::await) + .def("addTask", &Runtime::addTask, py::keep_alive<1, 2>()) + .def("run", &Runtime::run, py::call_guard()) + .def("await_", &Runtime::await, py::call_guard()) .def("finalize", &Runtime::finalize); // pyTaskR's PyRuntime class py::class_(m, "taskr") - .def(py::init()) + .def(py::init(), py::arg("backend") = "threading", py::arg("num_workers") = 0) .def("get_runtime", &PyRuntime::get_runtime, py::return_value_policy::reference_internal); // TaskR's Function class @@ -48,7 +48,8 @@ PYBIND11_MODULE(taskr, m) // TaskR's Task class py::class_(m, "Task") - .def(py::init()); + .def(py::init(), py::arg("label"), py::arg("fc"), py::arg("workerAffinity") = -1) + .def("getLabel", &Task::getLabel); } } \ No newline at end of file From 942e08a143d0275d03f7e05f5f1705152cbce760 Mon Sep 17 00:00:00 2001 From: noabauma Date: Mon, 2 Jun 2025 17:08:40 +0200 Subject: [PATCH 08/27] updating the extern submodules and adding ABC example --- examples/local/abcTasks/meson.build | 9 ++++ examples/local/abcTasks/py_source/abcTasks.py | 53 +++++++++++++++++++ examples/local/abcTasks/py_source/main.py | 16 ++++++ examples/local/simple/meson.build | 2 +- examples/local/simple/py_source/simple.py | 17 +----- extern/hicr | 2 +- extern/tracr | 2 +- include/pytaskr/pytaskr.cpp | 3 +- 8 files changed, 85 insertions(+), 19 deletions(-) create mode 100644 examples/local/abcTasks/py_source/abcTasks.py create mode 100644 examples/local/abcTasks/py_source/main.py diff --git a/examples/local/abcTasks/meson.build b/examples/local/abcTasks/meson.build index 7be6dab..f73d676 100644 --- a/examples/local/abcTasks/meson.build +++ b/examples/local/abcTasks/meson.build @@ -11,3 +11,12 @@ nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p') endif + +if get_option('buildPyTaskR') and get_option('buildTests') + test('pyTaskR', + py, + args : [ 'py_source/main.py' ], + env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + suite: testSuite, + workdir: meson.current_source_dir()) +endif \ No newline at end of file diff --git a/examples/local/abcTasks/py_source/abcTasks.py b/examples/local/abcTasks/py_source/abcTasks.py new file mode 100644 index 0000000..ddecdf4 --- /dev/null +++ b/examples/local/abcTasks/py_source/abcTasks.py @@ -0,0 +1,53 @@ +import taskr + +REPETITIONS = 5 +ITERATIONS = 100 + +def abcTasks(runtime): + # TODO: Setting onTaskFinish callback to free up task memory when it finishes (not sure if we will have this) + # runtime.setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskFinish, [&taskr](taskr::Task *task) { delete task; }) + # runtime.setTaskCallbackHandler(taskr.onTaskFinish, lambda task : del task) + + # Create the taskr Tasks + taskAfc = taskr.Function(lambda task : print(f"Task A {task.getLabel()}")) + taskBfc = taskr.Function(lambda task : print(f"Task B {task.getLabel()}")) + taskCfc = taskr.Function(lambda task : print(f"Task C {task.getLabel()}")) + + # Initializing taskr + runtime.initialize() + + # Our connection with the previous iteration is the last task C, null in the first iteration + prevTaskC = taskr.Task(0, taskCfc) + + # Creating the execution units (functions that the tasks will run) + for r in range(REPETITIONS): + # Calculating the base task id for this repetition + repetitionLabel = r * ITERATIONS * 3 + + for i in range(ITERATIONS): + + taskA = taskr.Task(repetitionLabel + i * 3 + 0, taskAfc) + taskB = taskr.Task(repetitionLabel + i * 3 + 1, taskBfc) + taskC = taskr.Task(repetitionLabel + i * 3 + 2, taskCfc) + + # Creating dependencies + if i > 0: taskA.addDependency(prevTaskC) + taskB.addDependency(taskA) + taskC.addDependency(taskB) + + # Adding to taskr runtime + runtime.addTask(taskA) + runtime.addTask(taskB) + runtime.addTask(taskC) + + # Refreshing previous task C + prevTaskC = taskC + + # Running taskr for the current repetition + runtime.run() + + # Waiting current repetition to end + runtime.await_() + + # Finalizing taskr + runtime.finalize() \ No newline at end of file diff --git a/examples/local/abcTasks/py_source/main.py b/examples/local/abcTasks/py_source/main.py new file mode 100644 index 0000000..e63d2be --- /dev/null +++ b/examples/local/abcTasks/py_source/main.py @@ -0,0 +1,16 @@ +import taskr +import abcTasks + +def main(): + + # Initialize taskr with the wanted compute manager backend and number of PUs + t = taskr.taskr("threading", 2) + + # Get the runtime + runtime = t.get_runtime() + + # Running simple example + abcTasks.abcTasks(runtime) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/local/simple/meson.build b/examples/local/simple/meson.build index bc2dd97..0aaf940 100644 --- a/examples/local/simple/meson.build +++ b/examples/local/simple/meson.build @@ -18,7 +18,7 @@ if get_option('buildPyTaskR') if get_option('buildTests') test('pyruntime', pyruntime, args : [ ], suite: testSuite, workdir: pyruntime.path() + '.p' ) - test('pysimple', + test('pyTaskR', py, args : [ 'py_source/main.py' ], env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], diff --git a/examples/local/simple/py_source/simple.py b/examples/local/simple/py_source/simple.py index e82dddb..db2820e 100644 --- a/examples/local/simple/py_source/simple.py +++ b/examples/local/simple/py_source/simple.py @@ -2,42 +2,29 @@ def simple(runtime): # TODO: Setting onTaskFinish callback to free up task memory when it finishes (not sure if we will have this) - #runtime.setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskFinish, [&taskr](taskr::Task *task) { delete task; }) - - print("runtime.initialize()", flush=True) + # runtime.setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskFinish, [&taskr](taskr::Task *task) { delete task; }) + # runtime.setTaskCallbackHandler(taskr.onTaskFinish, lambda task : del task) # Initializing taskr runtime.initialize() fc = lambda task : print(f"Hello, I am task {task.getLabel()}") - print("taskr.Function(fc)", flush=True) - # Create the taskr Tasks taskfc = taskr.Function(fc) # Creating the execution units (functions that the tasks will run) for i in range(10): - print("create task", flush=True) - task = taskr.Task(i, taskfc) - print("add task", flush=True) - # Adding to taskr runtime.addTask(task) - print("runtime.run()", flush=True) - # Running taskr for the current repetition runtime.run() - print("runtime.await_()", flush=True) - # Waiting current repetition to end runtime.await_() - print("runtime.finalize()", flush=True) - # Finalizing taskr runtime.finalize() \ No newline at end of file diff --git a/extern/hicr b/extern/hicr index e31ef4e..d7939f7 160000 --- a/extern/hicr +++ b/extern/hicr @@ -1 +1 @@ -Subproject commit e31ef4ec287dde6c8c88f9977d5ae5772e788955 +Subproject commit d7939f71f5fd50ac3f6903246c9f118667a180b6 diff --git a/extern/tracr b/extern/tracr index 984f5d7..9818518 160000 --- a/extern/tracr +++ b/extern/tracr @@ -1 +1 @@ -Subproject commit 984f5d750531199a5cbf13e54d10f45a0f28c107 +Subproject commit 98185182f468e44d895da2b507f66254fb793421 diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index 341e194..d689fdc 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -49,7 +49,8 @@ PYBIND11_MODULE(taskr, m) // TaskR's Task class py::class_(m, "Task") .def(py::init(), py::arg("label"), py::arg("fc"), py::arg("workerAffinity") = -1) - .def("getLabel", &Task::getLabel); + .def("getLabel", &Task::getLabel) + .def("addDependency", &Task::addDependency); } } \ No newline at end of file From e1d62311b47d167ac0f8e0e4eeb608cef0a7ec7d Mon Sep 17 00:00:00 2001 From: noabauma Date: Wed, 4 Jun 2025 16:32:31 +0200 Subject: [PATCH 09/27] suspend works (if only one task, now it should work for multiple tasks)! --- examples/local/conditionVariable/meson.build | 30 ++++ .../py_source/conditionVariableWait.py | 72 +++++++++ .../conditionVariableWaitCondition.py | 96 ++++++++++++ .../py_source/conditionVariableWaitFor.py | 99 +++++++++++++ .../conditionVariableWaitForCondition.py | 138 ++++++++++++++++++ .../local/conditionVariable/py_source/main.py | 47 ++++++ examples/local/simple/meson.build | 20 +-- examples/local/simple/py_source/main.py | 2 + examples/local/simple/py_source/simple.py | 9 +- examples/local/simple/source/simple.hpp | 2 +- include/pytaskr/pytaskr.cpp | 36 ++++- tests/meson.build | 11 +- .../simple/source => tests}/pyruntime.cpp | 17 +-- 13 files changed, 551 insertions(+), 28 deletions(-) create mode 100644 examples/local/conditionVariable/py_source/conditionVariableWait.py create mode 100644 examples/local/conditionVariable/py_source/conditionVariableWaitCondition.py create mode 100644 examples/local/conditionVariable/py_source/conditionVariableWaitFor.py create mode 100644 examples/local/conditionVariable/py_source/conditionVariableWaitForCondition.py create mode 100644 examples/local/conditionVariable/py_source/main.py rename {examples/local/simple/source => tests}/pyruntime.cpp (80%) diff --git a/examples/local/conditionVariable/meson.build b/examples/local/conditionVariable/meson.build index db7f17d..de09692 100644 --- a/examples/local/conditionVariable/meson.build +++ b/examples/local/conditionVariable/meson.build @@ -23,3 +23,33 @@ if get_option('buildTests') test('nosv_conditionVariableWaitCondition', nosv_conditionVariableWaitCondition, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv_conditionVariableWaitCondition.path() + '.p' ) test('nosv_conditionVariableWaitForCondition', nosv_conditionVariableWaitForCondition, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv_conditionVariableWaitForCondition.path() + '.p' ) endif + +if get_option('buildPyTaskR') and get_option('buildTests') + test('pyTaskR_conditionVariableWait', + py, + args : [ 'py_source/main.py' ], + env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWait'], + suite: testSuite, + workdir: meson.current_source_dir()) + + test('pyTaskR_conditionVariableWaitFor', + py, + args : [ 'py_source/main.py' ], + env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWaitFor'], + suite: testSuite, + workdir: meson.current_source_dir()) + + test('pyTaskR_conditionVariableWaitCondition', + py, + args : [ 'py_source/main.py' ], + env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWaitCondition'], + suite: testSuite, + workdir: meson.current_source_dir()) + + test('pyTaskR_conditionVariableWaitForCondition', + py, + args : [ 'py_source/main.py' ], + env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWaitForCondition'], + suite: testSuite, + workdir: meson.current_source_dir()) +endif \ No newline at end of file diff --git a/examples/local/conditionVariable/py_source/conditionVariableWait.py b/examples/local/conditionVariable/py_source/conditionVariableWait.py new file mode 100644 index 0000000..ef74397 --- /dev/null +++ b/examples/local/conditionVariable/py_source/conditionVariableWait.py @@ -0,0 +1,72 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import taskr + +def conditionVariableWait(runtime): + # Contention value + value = 0 + + # Mutex for the condition variable + mutex = taskr.Mutex() + + # Task-aware conditional variable + cv = taskr.ConditionVariable() + + def fc(task): + nonlocal value + # Waiting for the other task's notification + print("Thread 1: I wait for a notification") + mutex.lock(task) + print("before cv.wait(task, mutex)", flush=True) + cv.wait(task, mutex) + print("after cv.wait(task, mutex)", flush=True) + mutex.unlock(task) + value = 1 + print("Thread 1: I have been notified") + + # Creating task functions + waitFc = taskr.Function(fc) + + def fc(task): + nonlocal value + # Notifying the other task + print("Thread 2: Notifying anybody interested") + while value != 1: + cv.notifyOne(task) + print("cv.notifyOne(task)", flush=True) + task.suspend() + print("task.suspend()", flush=True) + + notifyFc = taskr.Function(fc) + + task1 = taskr.Task(0, waitFc) + task2 = taskr.Task(1, notifyFc) + + runtime.addTask(task1) + runtime.addTask(task2) + + # Initializing taskr + runtime.initialize() + + # Running taskr + runtime.run() + + # Waiting for task to finish + runtime.await_() + + # Finalizing taskr + runtime.finalize() diff --git a/examples/local/conditionVariable/py_source/conditionVariableWaitCondition.py b/examples/local/conditionVariable/py_source/conditionVariableWaitCondition.py new file mode 100644 index 0000000..42e2c6a --- /dev/null +++ b/examples/local/conditionVariable/py_source/conditionVariableWaitCondition.py @@ -0,0 +1,96 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import taskr + +def conditionVariableWaitCondition(runtime): + # Contention value + value = 0 + + # Mutex for the condition variable + mutex = taskr.Mutex() + + # Task-aware conditional variable + cv = taskr.ConditionVariable() + + def fc(task): + nonlocal value + # Using lock to update the value + print("Thread 1: I go first and set value to 1") + mutex.lock(task) + value += 1 + mutex.unlock(task) + + # Notifiying the other thread + print("Thread 1: Now I notify anybody waiting") + while value != 1: + cv.notifyOne(task) + task.suspend() + + # Waiting for the other thread's update now + print("Thread 1: I wait for the value to turn 2") + mutex.lock(task) + cv.wait(task, mutex, lambda: value == 2) + mutex.unlock(task) + print("Thread 1: The condition (value == 2) is satisfied now") + + # Creating task functions + thread1Fc = taskr.Function(fc) + + def fc(task): + nonlocal value + # Waiting for the other thread to set the first value + print("Thread 2: First, I'll wait for the value to become 1") + mutex.lock(task) + cv.wait(task, mutex, lambda: value == 1) + mutex.unlock(task) + print("Thread 2: The condition (value == 1) is satisfied now") + + # Now updating the value ourselves + print("Thread 2: Now I update the value to 2") + mutex.lock(task) + value += 1 + mutex.unlock(task) + + # Notifying the other thread + print("Thread 2: Notifying anybody interested") + cv.notifyOne(task) + + thread2Fc = taskr.Function(fc) + + task1 = taskr.Task(0, thread1Fc) + task2 = taskr.Task(1, thread2Fc) + + runtime.addTask(task1) + runtime.addTask(task2) + + # Initializing taskr + runtime.initialize() + + # Running taskr + runtime.run() + + # Waiting for task to finish + runtime.await_() + + # Finalizing taskr + runtime.finalize() + + # Value should be equal to concurrent task count + expectedValue = 2 + print(f"Value {value} / Expected {expectedValue}") + + assert value == expectedValue diff --git a/examples/local/conditionVariable/py_source/conditionVariableWaitFor.py b/examples/local/conditionVariable/py_source/conditionVariableWaitFor.py new file mode 100644 index 0000000..0c4e0c2 --- /dev/null +++ b/examples/local/conditionVariable/py_source/conditionVariableWaitFor.py @@ -0,0 +1,99 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import sys +import time +import taskr + +def conditionVariableWaitFor(runtime): + # Contention value + value = 0 + + # Mutex for the condition variable + mutex = taskr.Mutex() + + # Task-aware conditional variable + cv = taskr.ConditionVariable() + + # Time for timeout checking (Microseconds) + timeoutTimeUs = 100 * 1000 + + # Forever time to wait (for notification-only waits) + forever = 1000 * 1000 * 1000 + + def fc(task): + # Waiting for the other task's notification + print("Thread 1: I wait for a notification (Waiting for an hour)") + + mutex.lock(task) + wasNotified = cv.waitFor(task, mutex, forever) + mutex.unlock(task) + if not was_notified: + sys.stderr.write("Error: I have returned due to a timeout!") + sys.exit(1) + + print("Thread 1: I have been notified (as expected)") + + value = 1 + + # Waiting for a timeout + print(f"Thread 1: I wait for a timeout (Waiting for {timeoutTimeUs}ms) ") + + mutex.lock(task) + startTime = time.time_ns()*1e-3 + wasNotified = cv.waitFor(task, mutex, timeoutTimeUs) + currentTime = time.time_ns()*1e-3 + elapsedTime = currentTime - startTime + mutex.unlock(task) + if wasNotified: + sys.stderr.write("Error: I have returned do to a notification!") + sys.exit(1) + + if elapsedTime < timeoutTimeUs: + sys.stderr.write("Error: I have returned earlier than expected!") + sys.exit(1) + + print(f"Thread 1: I've exited by timeout (as expected in {elapsedTime}us >= {timeoutTimeUs}us)") + + # Creating task functions + waitFc = taskr.Function(fc) + + def fc(task): + # Notifying the other task + print("Thread 2: Notifying anybody interested (only once)") + while value != 1: + cv.notifyOne(task) + task.suspend() + + notifyFc = taskr.Function(fc) + + task1 = taskr.Task(0, waitFc) + task2 = taskr.Task(1, notifyFc) + + runtime.addTask(task1) + runtime.addTask(task2) + + # Initializing taskr + runtime.initialize() + + # Running taskr + runtime.run() + + # Waiting for task to finish + runtime.await_() + + # Finalizing taskr + runtime.finalize() diff --git a/examples/local/conditionVariable/py_source/conditionVariableWaitForCondition.py b/examples/local/conditionVariable/py_source/conditionVariableWaitForCondition.py new file mode 100644 index 0000000..3a82a85 --- /dev/null +++ b/examples/local/conditionVariable/py_source/conditionVariableWaitForCondition.py @@ -0,0 +1,138 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License") + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import sys +import time +import taskr + +def conditionVariableWaitForCondition(runtime): + # Contention value + value = 0 + + # Mutex for the condition variable + mutex = taskr.Mutex() + + # Task-aware conditional variable + cv = taskr.ConditionVariable() + + # Time for timeout checking (Microseconds) + timeoutTimeUs = 100 * 1000 + + # Forever time to wait + forever = 1000 * 1000 * 1000 + + def fc(task): + # Using lock to update the value + print("Thread 1: I go first and set value to 1") + mutex.lock(task) + value = 1 + mutex.unlock(task) + + # Notifiying the other thread + print("Thread 1: Now I notify anybody waiting") + while value != 2: + cv.notifyOne(task) + task.suspend() + + # Waiting for the other thread's update now + print("Thread 1: I wait (forever) for the value to turn 2") + mutex.lock(task) + wasNotified = cv.waitFor(task, mutex, lambda : value == 2, forever) + mutex.unlock(task) + + if not wasNotified: + sys.stderr.write("Error: I have returned due to a timeout!") + sys.exit(1) + + print("Thread 1: The condition (value == 2) is satisfied now") + + # Now waiting for a condition that won't be met, although we'll get notifications + print("Thread 1: I wait (with timeout) for the value to turn 3 (won't happen)") + mutex.lock(task) + startTime = time.time_ns()*1e-3 + wasNotified = cv.waitFor(task, mutex, lambda : value == 3, timeoutTimeUs) + currentTime = time.time_ns()*1e-3 + elapsedTime = currentTime - startTime + mutex.unlock(task) + + if wasNotified: + sys.stderr.write("Error: I have returned do to a notification!") + sys.exit(1) + + if elapsedTime < timeoutTimeUs: + sys.stderr.write("Error: I have returned earlier than expected!") + sys.exit(1) + + print(f"Thread 1: I've exited by timeout (as expected in {elapsedTime}us >= {timeoutTimeUs}us)") + + # Updating value to 3 now, to release the other thread + mutex.lock(task) + value = 3 + mutex.unlock(task) + + # Creating task functions + thread1Fc = taskr.Function(fc) + + def fc(task): + # Waiting for the other thread to set the first value + print("Thread 2: First, I'll wait for the value to become 1") + mutex.lock(task) + wasNotified = cv.waitFor(task, mutex, lambda : value == 1, forever) + mutex.unlock(task) + if not wasNotified: + sys.stderr.write("Error: I have returned do to a timeout!") + sys.exit(1) + + print("Thread 2: The condition (value == 1) is satisfied now") + + # Now updating the value ourselves + print("Thread 2: Now I update the value to 2") + mutex.lock(task) + value = 2 + mutex.unlock(task) + + # Notifying the other thread + print("Thread 2: Notifying constantly until the value is 3") + while value != 3: + cv.notifyOne(task) + task.suspend() + + + thread2Fc = taskr.Function(fc) + + task1 = taskr.Task(0, thread1Fc) + task2 = taskr.Task(1, thread2Fc) + + runtime.addTask(task1) + runtime.addTask(task2) + + # Initializing taskr + runtime.initialize() + + # Running taskr + runtime.run() + + # Waiting for task to finish + runtime.await_() + + # Finalizing taskr + runtime.finalize() + + # Value should be equal to concurrent task count + expectedValue = 3 + print(f"Value {value} / Expected {expectedValue}") + + assert value == expectedValue diff --git a/examples/local/conditionVariable/py_source/main.py b/examples/local/conditionVariable/py_source/main.py new file mode 100644 index 0000000..32ad001 --- /dev/null +++ b/examples/local/conditionVariable/py_source/main.py @@ -0,0 +1,47 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import os + +import taskr + +from conditionVariableWait import conditionVariableWait +from conditionVariableWaitCondition import conditionVariableWaitCondition +from conditionVariableWaitFor import conditionVariableWaitFor +from conditionVariableWaitForCondition import conditionVariableWaitForCondition + +def main(): + + # Initialize taskr with the wanted compute manager backend and number of PUs + t = taskr.taskr("threading") + + # Get the runtime + runtime = t.get_runtime() + + runtime.setTaskCallbackHandler(taskr.TaskCallback.onTaskSuspend, lambda task : runtime.resumeTask(task)) + + # Get the enviromnent variable for which function to call + test_function_name = os.getenv('__TEST_FUNCTION_') + + # Get the function from the global namespace + test_function = globals()[test_function_name] + + # Call the function + test_function(runtime) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/local/simple/meson.build b/examples/local/simple/meson.build index 0aaf940..6d8fe4b 100644 --- a/examples/local/simple/meson.build +++ b/examples/local/simple/meson.build @@ -12,17 +12,11 @@ if get_option('buildTests') test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) endif -if get_option('buildPyTaskR') - pyruntime = executable('pyruntime', [ 'source/pyruntime.cpp'], dependencies: [ TaskRBuildDep ]) - - if get_option('buildTests') - test('pyruntime', pyruntime, args : [ ], suite: testSuite, workdir: pyruntime.path() + '.p' ) - - test('pyTaskR', - py, - args : [ 'py_source/main.py' ], - env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], - suite: testSuite, - workdir: meson.current_source_dir()) - endif +if get_option('buildPyTaskR') and get_option('buildTests') + test('pyTaskR', + py, + args : [ 'py_source/main.py' ], + env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + suite: testSuite, + workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/simple/py_source/main.py b/examples/local/simple/py_source/main.py index f03c2de..2e79f4a 100644 --- a/examples/local/simple/py_source/main.py +++ b/examples/local/simple/py_source/main.py @@ -9,6 +9,8 @@ def main(): # Get the runtime runtime = t.get_runtime() + runtime.setTaskCallbackHandler(taskr.TaskCallback.onTaskSuspend, lambda task : runtime.resumeTask(task)) + # Running simple example simple.simple(runtime) diff --git a/examples/local/simple/py_source/simple.py b/examples/local/simple/py_source/simple.py index db2820e..0097936 100644 --- a/examples/local/simple/py_source/simple.py +++ b/examples/local/simple/py_source/simple.py @@ -8,13 +8,18 @@ def simple(runtime): # Initializing taskr runtime.initialize() - fc = lambda task : print(f"Hello, I am task {task.getLabel()}") + # fc = lambda task : print(f"Hello, I am task {task.getLabel()}") + + def fc(task): + print(f"Before suspend task {task.getLabel()}") + task.suspend() + print(f"After suspend task {task.getLabel()}") # Create the taskr Tasks taskfc = taskr.Function(fc) # Creating the execution units (functions that the tasks will run) - for i in range(10): + for i in range(2): task = taskr.Task(i, taskfc) # Adding to taskr diff --git a/examples/local/simple/source/simple.hpp b/examples/local/simple/source/simple.hpp index 0192905..49cf183 100644 --- a/examples/local/simple/source/simple.hpp +++ b/examples/local/simple/source/simple.hpp @@ -26,7 +26,7 @@ void simple(taskr::Runtime *taskr) // Initializing taskr taskr->initialize(); - auto fc = [](taskr::Task *task) { printf("Hello, I am task %ld\n", task->getLabel()); }; + auto fc = [](taskr::Task *task) { printf("Hello, I am task %ld\n", task->getLabel());}; // Create the taskr Tasks auto taskfc = taskr::Function(fc); diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index d689fdc..e263bb5 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -24,6 +24,12 @@ namespace py = pybind11; namespace taskr { +void lockWrapper(Mutex& self, Task& task) { + self.lock(&task); +} + +// TODO: add all methods of all classes + PYBIND11_MODULE(taskr, m) { m.doc() = "pybind11 plugin for TaskR"; @@ -32,7 +38,8 @@ PYBIND11_MODULE(taskr, m) py::class_(m, "Runtime") .def("setTaskCallbackHandler", &Runtime::setTaskCallbackHandler) .def("initialize", &Runtime::initialize) - .def("addTask", &Runtime::addTask, py::keep_alive<1, 2>()) + .def("addTask", &Runtime::addTask, py::keep_alive<1, 2>()) // keep_alive as the task should be alive until runtime's destructor + .def("resumeTask", &Runtime::resumeTask) .def("run", &Runtime::run, py::call_guard()) .def("await_", &Runtime::await, py::call_guard()) .def("finalize", &Runtime::finalize); @@ -50,7 +57,32 @@ PYBIND11_MODULE(taskr, m) py::class_(m, "Task") .def(py::init(), py::arg("label"), py::arg("fc"), py::arg("workerAffinity") = -1) .def("getLabel", &Task::getLabel) - .def("addDependency", &Task::addDependency); + .def("addDependency", &Task::addDependency) + .def("suspend", &Task::suspend); + + py::enum_(m, "TaskCallback") + .value("onTaskExecute", Task::callback_t::onTaskExecute) + .value("onTaskSuspend", Task::callback_t::onTaskSuspend) + .value("onTaskFinish", Task::callback_t::onTaskFinish) + .value("onTaskSync", Task::callback_t::onTaskSync) + .export_values(); + + // TaskR's Mutex class + py::class_(m, "Mutex") + .def(py::init<>()) + .def("lock", &Mutex::lock) + .def("unlock", &Mutex::unlock); + + // TaskR's ConditionVariable class + py::class_(m, "ConditionVariable") + .def(py::init<>()) + .def("wait", py::overload_cast(&ConditionVariable::wait), "cv wait") + .def("wait", py::overload_cast&>(&ConditionVariable::wait), "cv wait with condition") + .def("waitFor", py::overload_cast&, size_t>(&ConditionVariable::waitFor), "cv waitFor with condition") + .def("waitFor", py::overload_cast(&ConditionVariable::waitFor), "cv waitFor") + .def("notifyOne", &ConditionVariable::notifyOne) + .def("notifyAll", &ConditionVariable::notifyAll) + .def("getWaitingTaskCount", &ConditionVariable::getWaitingTaskCount); } } \ No newline at end of file diff --git a/tests/meson.build b/tests/meson.build index 491c8fe..5a4231a 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -23,4 +23,13 @@ TaskRTestDep = declare_dependency( compile_args: TaskRTestCppFlags, dependencies: gtest_dep - ) \ No newline at end of file + ) + +#### Testing if the python interface of pytaskr is working + +if get_option('buildPyTaskR') + testSuite = ['tests', 'pyruntime'] + pyruntime = executable('pyruntime', [ 'pyruntime.cpp'], dependencies: [ TaskRBuildDep ]) + + test('pyruntime', pyruntime, args : [ ], suite: testSuite, workdir: pyruntime.path() + '.p' ) +endif \ No newline at end of file diff --git a/examples/local/simple/source/pyruntime.cpp b/tests/pyruntime.cpp similarity index 80% rename from examples/local/simple/source/pyruntime.cpp rename to tests/pyruntime.cpp index 8ed72e9..b6f0546 100644 --- a/examples/local/simple/source/pyruntime.cpp +++ b/tests/pyruntime.cpp @@ -17,17 +17,16 @@ #include #include -#include "simple.hpp" - int main(int argc, char **argv) { - // Creating taskr - taskr::PyRuntime pytaskr("threading", 8); - + // Creating taskr instance + taskr::PyRuntime pytaskr("nosv", 0); + + // Getting the runtime taskr::Runtime& runtime = pytaskr.get_runtime(); - - // Running simple example - simple(&runtime); - + + // Printing runtime + printf("I got the runtime with nOS-V backend: %p\n", &runtime); + return 0; } From edd528f6bc4246ee3d14a9ee929c4089017ec808 Mon Sep 17 00:00:00 2001 From: noabauma Date: Thu, 5 Jun 2025 17:04:47 +0200 Subject: [PATCH 10/27] added conditionVariable example (xxWaitCondition works atm) --- .../py_source/conditionVariableWait.py | 4 ++++ .../py_source/conditionVariableWaitFor.py | 6 +++++- .../py_source/conditionVariableWaitForCondition.py | 4 ++++ examples/local/simple/py_source/main.py | 2 +- examples/local/simple/py_source/simple.py | 4 ---- include/pytaskr/pytaskr.cpp | 11 +++++------ 6 files changed, 19 insertions(+), 12 deletions(-) diff --git a/examples/local/conditionVariable/py_source/conditionVariableWait.py b/examples/local/conditionVariable/py_source/conditionVariableWait.py index ef74397..b05ebfa 100644 --- a/examples/local/conditionVariable/py_source/conditionVariableWait.py +++ b/examples/local/conditionVariable/py_source/conditionVariableWait.py @@ -28,6 +28,8 @@ def conditionVariableWait(runtime): def fc(task): nonlocal value + print(f"Hello I am Task: {task.getLabel()} on PID: {task.getWorkerAffinity()}") + # Waiting for the other task's notification print("Thread 1: I wait for a notification") mutex.lock(task) @@ -43,6 +45,8 @@ def fc(task): def fc(task): nonlocal value + print(f"Hello I am Task: {task.getLabel()} on PID: {task.getWorkerAffinity()}") + # Notifying the other task print("Thread 2: Notifying anybody interested") while value != 1: diff --git a/examples/local/conditionVariable/py_source/conditionVariableWaitFor.py b/examples/local/conditionVariable/py_source/conditionVariableWaitFor.py index 0c4e0c2..7d4e118 100644 --- a/examples/local/conditionVariable/py_source/conditionVariableWaitFor.py +++ b/examples/local/conditionVariable/py_source/conditionVariableWaitFor.py @@ -35,13 +35,15 @@ def conditionVariableWaitFor(runtime): forever = 1000 * 1000 * 1000 def fc(task): + nonlocal value + # Waiting for the other task's notification print("Thread 1: I wait for a notification (Waiting for an hour)") mutex.lock(task) wasNotified = cv.waitFor(task, mutex, forever) mutex.unlock(task) - if not was_notified: + if not wasNotified: sys.stderr.write("Error: I have returned due to a timeout!") sys.exit(1) @@ -72,6 +74,8 @@ def fc(task): waitFc = taskr.Function(fc) def fc(task): + nonlocal value + # Notifying the other task print("Thread 2: Notifying anybody interested (only once)") while value != 1: diff --git a/examples/local/conditionVariable/py_source/conditionVariableWaitForCondition.py b/examples/local/conditionVariable/py_source/conditionVariableWaitForCondition.py index 3a82a85..93b107b 100644 --- a/examples/local/conditionVariable/py_source/conditionVariableWaitForCondition.py +++ b/examples/local/conditionVariable/py_source/conditionVariableWaitForCondition.py @@ -35,6 +35,8 @@ def conditionVariableWaitForCondition(runtime): forever = 1000 * 1000 * 1000 def fc(task): + nonlocal value + # Using lock to update the value print("Thread 1: I go first and set value to 1") mutex.lock(task) @@ -87,6 +89,8 @@ def fc(task): thread1Fc = taskr.Function(fc) def fc(task): + nonlocal value + # Waiting for the other thread to set the first value print("Thread 2: First, I'll wait for the value to become 1") mutex.lock(task) diff --git a/examples/local/simple/py_source/main.py b/examples/local/simple/py_source/main.py index 2e79f4a..db95bb7 100644 --- a/examples/local/simple/py_source/main.py +++ b/examples/local/simple/py_source/main.py @@ -4,7 +4,7 @@ def main(): # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("threading", 2) + t = taskr.taskr("threading") # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/simple/py_source/simple.py b/examples/local/simple/py_source/simple.py index 0097936..ac75484 100644 --- a/examples/local/simple/py_source/simple.py +++ b/examples/local/simple/py_source/simple.py @@ -1,10 +1,6 @@ import taskr def simple(runtime): - # TODO: Setting onTaskFinish callback to free up task memory when it finishes (not sure if we will have this) - # runtime.setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskFinish, [&taskr](taskr::Task *task) { delete task; }) - # runtime.setTaskCallbackHandler(taskr.onTaskFinish, lambda task : del task) - # Initializing taskr runtime.initialize() diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index e263bb5..0cc6477 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -23,11 +23,7 @@ namespace py = pybind11; namespace taskr { - -void lockWrapper(Mutex& self, Task& task) { - self.lock(&task); -} - + // TODO: add all methods of all classes PYBIND11_MODULE(taskr, m) @@ -41,7 +37,7 @@ PYBIND11_MODULE(taskr, m) .def("addTask", &Runtime::addTask, py::keep_alive<1, 2>()) // keep_alive as the task should be alive until runtime's destructor .def("resumeTask", &Runtime::resumeTask) .def("run", &Runtime::run, py::call_guard()) - .def("await_", &Runtime::await, py::call_guard()) + .def("await_", &Runtime::await) .def("finalize", &Runtime::finalize); // pyTaskR's PyRuntime class @@ -57,6 +53,9 @@ PYBIND11_MODULE(taskr, m) py::class_(m, "Task") .def(py::init(), py::arg("label"), py::arg("fc"), py::arg("workerAffinity") = -1) .def("getLabel", &Task::getLabel) + .def("setLabel", &Task::setLabel) + .def("getWorkerAffinity", &Task::getWorkerAffinity) + .def("setWorkerAffinity", &Task::setWorkerAffinity) .def("addDependency", &Task::addDependency) .def("suspend", &Task::suspend); From 66d34405883331e2542bc481a991333b18f33b14 Mon Sep 17 00:00:00 2001 From: noabauma Date: Fri, 6 Jun 2025 15:35:34 +0200 Subject: [PATCH 11/27] example energySaver and Fibonacci included. Fib(n>3) fails. --- examples/local/energySaver/meson.build | 9 ++ .../energySaver/py_source/energySaver.py | 88 ++++++++++++++ examples/local/energySaver/py_source/main.py | 42 +++++++ examples/local/fibonacci/meson.build | 9 ++ .../local/fibonacci/py_source/fibonacci.py | 107 ++++++++++++++++++ examples/local/fibonacci/py_source/main.py | 40 +++++++ examples/local/simple/py_source/main.py | 17 +++ examples/local/simple/py_source/simple.py | 28 ++++- include/pytaskr/pytaskr.cpp | 2 +- 9 files changed, 335 insertions(+), 7 deletions(-) create mode 100644 examples/local/energySaver/py_source/energySaver.py create mode 100644 examples/local/energySaver/py_source/main.py create mode 100644 examples/local/fibonacci/py_source/fibonacci.py create mode 100644 examples/local/fibonacci/py_source/main.py diff --git a/examples/local/energySaver/meson.build b/examples/local/energySaver/meson.build index 3af5d73..5e6a53d 100644 --- a/examples/local/energySaver/meson.build +++ b/examples/local/energySaver/meson.build @@ -10,4 +10,13 @@ nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') test('nosv', nosv, args : [ '3', '1', '100' ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) +endif + +if get_option('buildPyTaskR') and get_option('buildTests') + test('pyTaskR', + py, + args : [ 'py_source/main.py'], + env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + suite: testSuite, + workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/energySaver/py_source/energySaver.py b/examples/local/energySaver/py_source/energySaver.py new file mode 100644 index 0000000..f404aa5 --- /dev/null +++ b/examples/local/energySaver/py_source/energySaver.py @@ -0,0 +1,88 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License") + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import time +import taskr + +def workFc(iterations): + value = 2.0 + for i in range(iterations): + for j in range(iterations): + value = (value + i)**0.5 + value = value * value + +def waitFc(taskr, secondsDelay): + print("Starting long task...\n", flush=True) + time.sleep(secondsDelay) + print("Finished long task...\n", flush=True) + +def energySaver(runtime, workTaskCount, secondsDelay, iterations): + # Creating task work function + workFunction = taskr.Function(lambda task : workFc(iterations)) + + # Creating task wait function + waitFunction = taskr.Function(lambda task : waitFc(runtime, secondsDelay)) + + # Creating a single wait task that suspends all workers except for one + waitTask1 = taskr.Task(0, waitFunction) + + # Building task graph. First a lot of pure work tasks. The wait task depends on these + for i in range(workTaskCount): + workTask = taskr.Task(i + 1, workFunction) + waitTask1.addDependency(workTask) + runtime.addTask(workTask) + + # Creating another wait task + waitTask2 = taskr.Task(2 * workTaskCount + 1, waitFunction) + + # Then creating another batch of work tasks that depends on the wait task + for i in range(workTaskCount): + workTask = taskr.Task(workTaskCount + i + 1, workFunction) + + # This work task waits on the first wait task + workTask.addDependency(waitTask1) + + # The second wait task depends on this work task + waitTask2.addDependency(workTask) + + # Adding work task + runtime.addTask(workTask) + + # Last set of work tasks + for i in range(workTaskCount): + workTask = taskr.Task(2 * workTaskCount + i + 2, workFunction) + + # This work task depends on the second wait task + workTask.addDependency(waitTask2) + + # Adding work task + runtime.addTask(workTask) + + # Adding work tasks + runtime.addTask(waitTask1) + runtime.addTask(waitTask2) + + # Initializing taskr + runtime.initialize() + + # Running taskr + print("Starting (open 'htop' in another console to see the workers going to sleep during the long task)...\n") + runtime.run() + runtime.await_() + print("Finished.\n") + + # Finalizing taskr + runtime.finalize() \ No newline at end of file diff --git a/examples/local/energySaver/py_source/main.py b/examples/local/energySaver/py_source/main.py new file mode 100644 index 0000000..f20b728 --- /dev/null +++ b/examples/local/energySaver/py_source/main.py @@ -0,0 +1,42 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import sys +import taskr +import energySaver + +def main(): + # Getting arguments, if provided + workTaskCount = 3 + secondsDelay = 1 + iterations = 100 + if len(sys.argv) > 1: workTaskCount = int(sys.argv[1]) + if len(sys.argv) > 2: secondsDelay = int(sys.argv[2]) + if len(sys.argv) > 3: iterations = int(sys.argv[3]) + + print(sys.argv, workTaskCount, secondsDelay, iterations) + + # Initialize taskr with the wanted compute manager backend and number of PUs + t = taskr.taskr("threading") + + # Get the runtime + runtime = t.get_runtime() + + # Running simple example + energySaver.energySaver(runtime, workTaskCount, secondsDelay, iterations) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/local/fibonacci/meson.build b/examples/local/fibonacci/meson.build index 664190b..9a46ae6 100644 --- a/examples/local/fibonacci/meson.build +++ b/examples/local/fibonacci/meson.build @@ -10,4 +10,13 @@ nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') test('nosv', nosv, args : [ '15' ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) +endif + +if get_option('buildPyTaskR') and get_option('buildTests') + test('pyTaskR', + py, + args : [ 'py_source/main.py'], + env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + suite: testSuite, + workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/fibonacci/py_source/fibonacci.py b/examples/local/fibonacci/py_source/fibonacci.py new file mode 100644 index 0000000..3ec66c8 --- /dev/null +++ b/examples/local/fibonacci/py_source/fibonacci.py @@ -0,0 +1,107 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License") + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +from atomic import AtomicLong +import time +import taskr + +# Globally assigned variables +_runtime = None +_taskCounter = AtomicLong(0) + +# Fibonacci without memoization to stress the tasking runtime +def fibonacci(currentTask, x): + if x == 0: return 0 + if x == 1: return 1 + + global _taskCounter + global _runtime + + result1 = 0 + result2 = 0 + + # Creating task functions + def Fc1(task): + nonlocal result1 + result1 = fibonacci(task, x - 1) + + def Fc2(task): + nonlocal result2 + result2 = fibonacci(task, x - 2) + + fibFc1 = taskr.Function(Fc1) + fibFc2 = taskr.Function(Fc2) + + # Creating two new tasks + subTask1 = taskr.Task(_taskCounter.value, fibFc1) + _taskCounter += 1 + subTask2 = taskr.Task(_taskCounter.value, fibFc2) + _taskCounter += 1 + + # Adding dependencies with the newly created tasks + currentTask.addDependency(subTask1) + currentTask.addDependency(subTask2) + + # Adding new tasks to TaskR + _runtime.addTask(subTask1) + _runtime.addTask(subTask2) + + # Suspending current task + currentTask.suspend() + + return result1 + result2 + +def fibonacciDriver(initialValue, runtime): + # Setting global variables + global _taskCounter + global _runtime + _runtime = runtime + + # Storage for result + result = 0 + + # Creating task functions + def Fc(task): + nonlocal result + result = fibonacci(task, initialValue) + + initialFc = taskr.Function(Fc) + + # Now creating tasks and their dependency graph + initialTask = taskr.Task(_taskCounter.value, initialFc) + _taskCounter += 1 + + runtime.addTask(initialTask) + + # Initializing taskR + runtime.initialize() + + # Running taskr + startTime = time.time() + runtime.run() + runtime.await_() + endTime = time.time() + + computeTime = endTime - startTime + + print(f"Running Time: {computeTime:.5f}s") + print(f"Total Tasks: {_taskCounter.value}") + + # Finalizing taskR + runtime.finalize() + + # Returning fibonacci value + return result diff --git a/examples/local/fibonacci/py_source/main.py b/examples/local/fibonacci/py_source/main.py new file mode 100644 index 0000000..0b61d3a --- /dev/null +++ b/examples/local/fibonacci/py_source/main.py @@ -0,0 +1,40 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import sys +import taskr +import fibonacci + +def main(): + # Define the Fibonacci number to compute. + initialValue = 10 + if len(sys.argv) > 1: initialValue = int(sys.argv[1]) + + # Initialize taskr with the wanted compute manager backend and number of PUs + t = taskr.taskr("threading") + + # Get the runtime + global runtime + runtime = t.get_runtime() + + # Running Fibonacci example + result = fibonacci.fibonacciDriver(initialValue, runtime) + + # Printing result + print(f"Fib({initialValue}) = {result}") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/local/simple/py_source/main.py b/examples/local/simple/py_source/main.py index db95bb7..05c50a6 100644 --- a/examples/local/simple/py_source/main.py +++ b/examples/local/simple/py_source/main.py @@ -1,3 +1,19 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + import taskr import simple @@ -9,6 +25,7 @@ def main(): # Get the runtime runtime = t.get_runtime() + # FOR TESTING: checking if a task resumes after being suspended (nosv doesn't work) runtime.setTaskCallbackHandler(taskr.TaskCallback.onTaskSuspend, lambda task : runtime.resumeTask(task)) # Running simple example diff --git a/examples/local/simple/py_source/simple.py b/examples/local/simple/py_source/simple.py index ac75484..ffaaaa3 100644 --- a/examples/local/simple/py_source/simple.py +++ b/examples/local/simple/py_source/simple.py @@ -1,21 +1,37 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + import taskr def simple(runtime): # Initializing taskr runtime.initialize() - # fc = lambda task : print(f"Hello, I am task {task.getLabel()}") + fc = lambda task : print(f"Hello, I am task {task.getLabel()}") - def fc(task): - print(f"Before suspend task {task.getLabel()}") - task.suspend() - print(f"After suspend task {task.getLabel()}") + # def fc(task): + # print(f"Before suspend task {task.getLabel()}") + # task.suspend() + # print(f"After suspend task {task.getLabel()}") # Create the taskr Tasks taskfc = taskr.Function(fc) # Creating the execution units (functions that the tasks will run) - for i in range(2): + for i in range(1): task = taskr.Task(i, taskfc) # Adding to taskr diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index 0cc6477..ba6eeba 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -37,7 +37,7 @@ PYBIND11_MODULE(taskr, m) .def("addTask", &Runtime::addTask, py::keep_alive<1, 2>()) // keep_alive as the task should be alive until runtime's destructor .def("resumeTask", &Runtime::resumeTask) .def("run", &Runtime::run, py::call_guard()) - .def("await_", &Runtime::await) + .def("await_", &Runtime::await, py::call_guard()) // Release GIL is important otherwise non-finished tasks are getting blocked .def("finalize", &Runtime::finalize); // pyTaskR's PyRuntime class From 2411cf9a70e773fac95a6ce76908fad3858a3477 Mon Sep 17 00:00:00 2001 From: noabauma Date: Tue, 10 Jun 2025 17:29:59 +0200 Subject: [PATCH 12/27] created more examples --- examples/local/fibonacci/py_source/main.py | 1 - examples/local/manyParallel/meson.build | 9 ++ examples/local/manyParallel/py_source/main.py | 38 ++++++++ .../manyParallel/py_source/manyParallel.py | 53 +++++++++++ examples/local/multiJob/meson.build | 9 ++ examples/local/multiJob/py_source/job1.py | 49 +++++++++++ examples/local/multiJob/py_source/job2.py | 49 +++++++++++ examples/local/multiJob/py_source/main.py | 47 ++++++++++ examples/local/mutex/meson.build | 9 ++ examples/local/mutex/py_source/main.py | 32 +++++++ examples/local/mutex/py_source/mutex.py | 62 +++++++++++++ examples/local/pendingOperation/meson.build | 9 ++ .../local/pendingOperation/py_source/main.py | 32 +++++++ .../py_source/pendingOperation.py | 79 +++++++++++++++++ examples/local/resourceList/meson.build | 9 ++ examples/local/resourceList/py_source/main.py | 74 ++++++++++++++++ .../local/resourceList/py_source/workTask.py | 24 +++++ examples/local/suspend/meson.build | 9 ++ examples/local/suspend/py_source/main.py | 41 +++++++++ examples/local/suspend/py_source/suspend.py | 62 +++++++++++++ examples/local/workerSpecific/meson.build | 9 ++ .../local/workerSpecific/py_source/main.py | 34 ++++++++ .../py_source/workerSpecific.py | 76 ++++++++++++++++ include/pytaskr/pyruntime.hpp | 87 +++++++++++++++++++ include/pytaskr/pytaskr.cpp | 8 +- 25 files changed, 908 insertions(+), 3 deletions(-) create mode 100644 examples/local/manyParallel/py_source/main.py create mode 100644 examples/local/manyParallel/py_source/manyParallel.py create mode 100644 examples/local/multiJob/py_source/job1.py create mode 100644 examples/local/multiJob/py_source/job2.py create mode 100644 examples/local/multiJob/py_source/main.py create mode 100644 examples/local/mutex/py_source/main.py create mode 100644 examples/local/mutex/py_source/mutex.py create mode 100644 examples/local/pendingOperation/py_source/main.py create mode 100644 examples/local/pendingOperation/py_source/pendingOperation.py create mode 100644 examples/local/resourceList/py_source/main.py create mode 100644 examples/local/resourceList/py_source/workTask.py create mode 100644 examples/local/suspend/py_source/main.py create mode 100644 examples/local/suspend/py_source/suspend.py create mode 100644 examples/local/workerSpecific/py_source/main.py create mode 100644 examples/local/workerSpecific/py_source/workerSpecific.py diff --git a/examples/local/fibonacci/py_source/main.py b/examples/local/fibonacci/py_source/main.py index 0b61d3a..511a8a7 100644 --- a/examples/local/fibonacci/py_source/main.py +++ b/examples/local/fibonacci/py_source/main.py @@ -27,7 +27,6 @@ def main(): t = taskr.taskr("threading") # Get the runtime - global runtime runtime = t.get_runtime() # Running Fibonacci example diff --git a/examples/local/manyParallel/meson.build b/examples/local/manyParallel/meson.build index 169e552..2d7267d 100644 --- a/examples/local/manyParallel/meson.build +++ b/examples/local/manyParallel/meson.build @@ -10,4 +10,13 @@ nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ] if get_option('buildTests') test('nosv', nosv, args : [ '2', '100' ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) +endif + +if get_option('buildPyTaskR') and get_option('buildTests') + test('pyTaskR', + py, + args : [ 'py_source/main.py' ], + env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + suite: testSuite, + workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/manyParallel/py_source/main.py b/examples/local/manyParallel/py_source/main.py new file mode 100644 index 0000000..3dc9957 --- /dev/null +++ b/examples/local/manyParallel/py_source/main.py @@ -0,0 +1,38 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import sys +import taskr +import manyParallel + +def main(): + # Getting arguments, if provided + taskCount = 2 + branchCount = 100 + if len(sys.argv) > 1: taskCount = int(sys.argv[1]) + if len(sys.argv) > 2: branchCount = int(sys.argv[2]) + + # Initialize taskr with the wanted compute manager backend and number of PUs + t = taskr.taskr("threading") + + # Get the runtime + runtime = t.get_runtime() + + # Running simple example + manyParallel.manyParallel(runtime, taskCount, branchCount) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/local/manyParallel/py_source/manyParallel.py b/examples/local/manyParallel/py_source/manyParallel.py new file mode 100644 index 0000000..0b55372 --- /dev/null +++ b/examples/local/manyParallel/py_source/manyParallel.py @@ -0,0 +1,53 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License") + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import time +import taskr + +def manyParallel(runtime, branchCount, taskCount): + # Creating the execution units (functions that the tasks will run) + taskfc = taskr.Function(lambda task : None) + + # Initializing taskr + runtime.initialize() + + # Store a pointer to the previous task to generate a long chain + prevTask = None + + # Each run consists of several iterations of ABC + for b in range(branchCount): + for i in range(taskCount): + task = taskr.Task(b * taskCount + i, taskfc) + + # Creating dependencies + if i > 0: task.addDependency(prevTask) + + # Adding to taskr + runtime.addTask(task) + + # Setting as new previous task + prevTask = task + + # Running taskr for the current repetition + startTime = time.time() + runtime.run() + runtime.await_() + endTime = time.time() + computeTime = endTime - startTime + print(f"Running Time: {computeTime:0.5f}s") + + # Finalizing taskr + runtime.finalize() \ No newline at end of file diff --git a/examples/local/multiJob/meson.build b/examples/local/multiJob/meson.build index 1ac5c43..559dff9 100644 --- a/examples/local/multiJob/meson.build +++ b/examples/local/multiJob/meson.build @@ -10,4 +10,13 @@ nosv = executable('nosv', [ 'source/nosv.cpp', 'source/job1.cpp', 'source/job2.c if get_option('buildTests') test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) +endif + +if get_option('buildPyTaskR') and get_option('buildTests') + test('pyTaskR', + py, + args : [ 'py_source/main.py' ], + env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + suite: testSuite, + workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/multiJob/py_source/job1.py b/examples/local/multiJob/py_source/job1.py new file mode 100644 index 0000000..5ffd2bb --- /dev/null +++ b/examples/local/multiJob/py_source/job1.py @@ -0,0 +1,49 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License") + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import taskr +from main import ITERATIONS +JOB_ID = 0 + +def job1(runtime): + # Creating a storage for all the tasks we will create in this example + tasks = [None] * (3 * ITERATIONS) + + # Creating the execution units (functions that the tasks will run) + taskAfc = taskr.Function(lambda task : print(f"Job 1 - Task A {task.getLabel()}")) + taskBfc = taskr.Function(lambda task : print(f"Job 1 - Task B {task.getLabel()}")) + taskCfc = taskr.Function(lambda task : print(f"Job 1 - Task C {task.getLabel()}")) + + # Now creating tasks + for i in range(ITERATIONS): + taskId = i * 3 + 1 + tasks[taskId] = taskr.Task(3 * ITERATIONS * JOB_ID + taskId, taskBfc) + + for i in range(ITERATIONS): + taskId = i * 3 + 0 + tasks[taskId] = taskr.Task(3 * ITERATIONS * JOB_ID + taskId, taskAfc) + + for i in range(ITERATIONS): + taskId = i * 3 + 2 + tasks[taskId] = taskr.Task(3 * ITERATIONS * JOB_ID + taskId, taskCfc) + + # Now creating the dependency graph + for i in range(ITERATIONS): tasks[i * 3 + 2].addDependency(tasks[i * 3 + 1]) + for i in range(ITERATIONS): tasks[i * 3 + 1].addDependency(tasks[i * 3 + 0]) + for i in range(1, ITERATIONS): tasks[i * 3 + 0].addDependency(tasks[i * 3 - 1]) + + # Adding tasks to TaskR runtime + for task in tasks: runtime.addTask(task) \ No newline at end of file diff --git a/examples/local/multiJob/py_source/job2.py b/examples/local/multiJob/py_source/job2.py new file mode 100644 index 0000000..1a0adbd --- /dev/null +++ b/examples/local/multiJob/py_source/job2.py @@ -0,0 +1,49 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import taskr +from main import ITERATIONS +JOB_ID = 1 + +def job2(runtime): + # Creating a storage for all the tasks we will create in this example + tasks = [None] * (3 * ITERATIONS) + + # Creating the execution units (functions that the tasks will run) + taskAfc = taskr.Function(lambda task : print(f"Job 1 - Task A {task.getLabel()}")) + taskBfc = taskr.Function(lambda task : print(f"Job 1 - Task B {task.getLabel()}")) + taskCfc = taskr.Function(lambda task : print(f"Job 1 - Task C {task.getLabel()}")) + + # Now creating tasks + for i in range(ITERATIONS): + taskId = i * 3 + 1 + tasks[taskId] = taskr.Task(3 * ITERATIONS * JOB_ID + taskId, taskBfc) + + for i in range(ITERATIONS): + taskId = i * 3 + 0 + tasks[taskId] = taskr.Task(3 * ITERATIONS * JOB_ID + taskId, taskAfc) + + for i in range(ITERATIONS): + taskId = i * 3 + 2 + tasks[taskId] = taskr.Task(3 * ITERATIONS * JOB_ID + taskId, taskCfc) + + # Now creating the dependency graph + for i in range(ITERATIONS): tasks[i * 3 + 2].addDependency(tasks[i * 3 + 1]) + for i in range(ITERATIONS): tasks[i * 3 + 1].addDependency(tasks[i * 3 + 0]) + for i in range(1, ITERATIONS): tasks[i * 3 + 0].addDependency(tasks[i * 3 - 1]) + + # Adding tasks to TaskR runtime + for task in tasks: runtime.addTask(task) \ No newline at end of file diff --git a/examples/local/multiJob/py_source/main.py b/examples/local/multiJob/py_source/main.py new file mode 100644 index 0000000..22af784 --- /dev/null +++ b/examples/local/multiJob/py_source/main.py @@ -0,0 +1,47 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" +ITERATIONS = 100 + +import taskr +import job1 +import job2 + +def main(): + + # Initialize taskr with the wanted compute manager backend and number of PUs + t = taskr.taskr("threading") + + # Get the runtime + runtime = t.get_runtime() + + # Running multiJob example + job1.job1(runtime) + job2.job2(runtime) + + # Initializing taskr + runtime.initialize() + + # Running taskr for the current repetition + runtime.run() + + # Waiting current repetition to end + runtime.await_() + + # Finalizing taskr + runtime.finalize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/local/mutex/meson.build b/examples/local/mutex/meson.build index c533416..27639f5 100644 --- a/examples/local/mutex/meson.build +++ b/examples/local/mutex/meson.build @@ -10,4 +10,13 @@ nosv = executable('nosv', [ 'source/pthreads.cpp'], dependencies: [ TaskRBuildDe if get_option('buildTests') test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) +endif + +if get_option('buildPyTaskR') and get_option('buildTests') + test('pyTaskR', + py, + args : [ 'py_source/main.py' ], + env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + suite: testSuite, + workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/mutex/py_source/main.py b/examples/local/mutex/py_source/main.py new file mode 100644 index 0000000..1ea2e8b --- /dev/null +++ b/examples/local/mutex/py_source/main.py @@ -0,0 +1,32 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import taskr +import mutex + +def main(): + + # Initialize taskr with the wanted compute manager backend and number of PUs + t = taskr.taskr("threading") + + # Get the runtime + runtime = t.get_runtime() + + # Running mutex example + mutex.mutex(runtime) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/local/mutex/py_source/mutex.py b/examples/local/mutex/py_source/mutex.py new file mode 100644 index 0000000..f6d9539 --- /dev/null +++ b/examples/local/mutex/py_source/mutex.py @@ -0,0 +1,62 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import taskr + +_CONCURRENT_TASKS = 32 +_ITERATIONS_ = 1000 + +def mutex(runtime): + + # Contention value + value = 0 + + # Task-aware mutex + m = taskr.Mutex() + + def fc(task): + nonlocal value + + for i in range(_ITERATIONS_): + m.lock(task) + value += 1 + m.unlock(task) + + # Create the taskr Tasks + taskfc = taskr.Function(fc) + + # Creating the execution units (functions that the tasks will run) + for i in range(_CONCURRENT_TASKS): + task = taskr.Task(i, taskfc) + + # Adding to taskr + runtime.addTask(task) + + # Initializing taskr + runtime.initialize() + + # Running taskr for the current repetition + runtime.run() + + # Waiting current repetition to end + runtime.await_() + + # Finalizing taskr + runtime.finalize() + + # Value should be equal to concurrent task count + print(f"Value {value} / Expected {_CONCURRENT_TASKS * _ITERATIONS_}") + assert value == _CONCURRENT_TASKS * _ITERATIONS_ \ No newline at end of file diff --git a/examples/local/pendingOperation/meson.build b/examples/local/pendingOperation/meson.build index 7ec3684..93e81e7 100644 --- a/examples/local/pendingOperation/meson.build +++ b/examples/local/pendingOperation/meson.build @@ -10,4 +10,13 @@ nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ] if get_option('buildTests') test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) +endif + +if get_option('buildPyTaskR') and get_option('buildTests') + test('pyTaskR', + py, + args : [ 'py_source/main.py' ], + env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + suite: testSuite, + workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/pendingOperation/py_source/main.py b/examples/local/pendingOperation/py_source/main.py new file mode 100644 index 0000000..6027984 --- /dev/null +++ b/examples/local/pendingOperation/py_source/main.py @@ -0,0 +1,32 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import taskr +import pendingOperation + +def main(): + + # Initialize taskr with the wanted compute manager backend and number of PUs + t = taskr.taskr("threading") + + # Get the runtime + runtime = t.get_runtime() + + # Running pendingOperation example + pendingOperation.pendingOperation(runtime) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/local/pendingOperation/py_source/pendingOperation.py b/examples/local/pendingOperation/py_source/pendingOperation.py new file mode 100644 index 0000000..45f78a3 --- /dev/null +++ b/examples/local/pendingOperation/py_source/pendingOperation.py @@ -0,0 +1,79 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License") + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import time +import taskr + +def heavyTask(currentTask): + # Printing starting message + print(f"Task {currentTask.getLabel()} -- Starting 1 second-long operation.") + + # Getting initial time + t0 = time.time() + + # Now registering operation + def operation(): + # Getting current time + t1 = time.time() + + # Getting difference in ms + dt = (t1 - t0)*1e3 + + # If difference higher than 1 second, the operation is finished + if dt > 1000: + return True + + # Otherwise not + return False + + # Now registering pending operation + currentTask.addPendingOperation(operation) + + # Suspending task until the operation is finished + currentTask.suspend() + + # Printing finished message + print(f"Task {currentTask.getLabel()} - operation finished") + + +def pendingOperation(runtime): + # Allowing tasks to immediately resume upon suspension -- they won't execute until their pending operation is finished + runtime.setTaskCallbackHandler(taskr.TaskCallback.onTaskSuspend, lambda task : runtime.resumeTask(task)) + + # Creating the execution units (functions that the tasks will run) + fc = lambda task : heavyTask(task) + + # Create the taskr Tasks + taskfc = taskr.Function(fc) + + # Now creating heavy many tasks task + for i in range(100): + task = taskr.Task(i, taskfc) + + # Adding to taskr + runtime.addTask(task) + + # Initializing taskr + runtime.initialize() + + # Running taskr for the current repetition + runtime.run() + + # Waiting current repetition to end + runtime.await_() + + # Finalizing taskr + runtime.finalize() \ No newline at end of file diff --git a/examples/local/resourceList/meson.build b/examples/local/resourceList/meson.build index f9dbd19..9a7e7e7 100644 --- a/examples/local/resourceList/meson.build +++ b/examples/local/resourceList/meson.build @@ -10,4 +10,13 @@ nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') test('nosv', nosv, args : [ '4', '100', '0', '1', '2', '3' ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) +endif + +if get_option('buildPyTaskR') and get_option('buildTests') + test('pyTaskR', + py, + args : [ 'py_source/main.py' ], + env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + suite: testSuite, + workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/resourceList/py_source/main.py b/examples/local/resourceList/py_source/main.py new file mode 100644 index 0000000..984c1e3 --- /dev/null +++ b/examples/local/resourceList/py_source/main.py @@ -0,0 +1,74 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License") + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" +import sys +import time +import taskr +import workTask + +def main(): + # Getting work task count + workTaskCount = 4 + iterations = 100 + if len(sys.argv) > 1: workTaskCount = int(sys.argv[1]) + if len(sys.argv) > 2: iterations = int(sys.argv[2]) + + + + + # Getting the core subset from the argument list (could be from a file too) + coreSubset = {0, 1, 2, 3} + if len(sys.argv) > 3: + coreSubset = {} + for i in range(3, len(sys.argv)): + coreSubset.add(int(sys.argv[i])) + + # Sanity check + if not len(coreSubset): + sys.stderr.write("Launch error: no compute resources provided") + sys.exit(1) + + # Initialize taskr with the wanted compute manager backend and number of PUs + t = taskr.taskr("threading", coreSubset) + + # Get the runtime + runtime = t.get_runtime() + + # Creating task function + taskFunction = taskr.Function(lambda task : workTask.work(iterations)) + + # Adding multiple compute tasks + print(f"Running {workTaskCount} work tasks with {len(coreSubset)} processing units...") + for i in range(workTaskCount): + task = taskr.Task(i, taskFunction) + runtime.addTask(task) + + # Initializing taskR + runtime.initialize() + + # Running taskr only on the core subset + t0 = time.time() + runtime.run() + runtime.await_() + tf = time.time() + + dt = tf - t0 + print(f"Finished in {dt:.3} seconds.") + + # Finalizing taskR + runtime.finalize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/local/resourceList/py_source/workTask.py b/examples/local/resourceList/py_source/workTask.py new file mode 100644 index 0000000..4614746 --- /dev/null +++ b/examples/local/resourceList/py_source/workTask.py @@ -0,0 +1,24 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import taskr + +def work(iterations): + value = 2.0 + for i in range(iterations): + for j in range(iterations): + value = (value + i)**0.5 + value **= 2 \ No newline at end of file diff --git a/examples/local/suspend/meson.build b/examples/local/suspend/meson.build index dc065df..30d98e7 100644 --- a/examples/local/suspend/meson.build +++ b/examples/local/suspend/meson.build @@ -10,4 +10,13 @@ nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ] if get_option('buildTests') test('nosv', nosv, args : [ '2', '100' ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) +endif + +if get_option('buildPyTaskR') and get_option('buildTests') + test('pyTaskR', + py, + args : [ 'py_source/main.py' ], + env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + suite: testSuite, + workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/suspend/py_source/main.py b/examples/local/suspend/py_source/main.py new file mode 100644 index 0000000..bfeca76 --- /dev/null +++ b/examples/local/suspend/py_source/main.py @@ -0,0 +1,41 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import sys + +import taskr +import suspend + +def main(): + + + # Getting arguments, if provided + taskCount = 2 + branchCount = 100 + if len(sys.argv) > 1: taskCount = int(sys.argv[1]) + if len(sys.argv) > 2: branchCount = int(sys.argv[2]) + + # Initialize taskr with the wanted compute manager backend and number of PUs + t = taskr.taskr("threading") + + # Get the runtime + runtime = t.get_runtime() + + # Running simple example + suspend.suspend(runtime, branchCount, taskCount) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/local/suspend/py_source/suspend.py b/examples/local/suspend/py_source/suspend.py new file mode 100644 index 0000000..2ac6830 --- /dev/null +++ b/examples/local/suspend/py_source/suspend.py @@ -0,0 +1,62 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import time + +import taskr + +NSUSPENDS = 1000 + +def suspend(runtime, branchCount, taskCount): + # Allowing tasks to immediately resume upon suspension -- they won't execute until their pending operation is finished + runtime.setTaskCallbackHandler(taskr.TaskCallback.onTaskSuspend, lambda task : runtime.resumeTask(task)) + + def fc(task): + for _ in range(NSUSPENDS): task.suspend() + + # Creating the execution units (functions that the tasks will run) + taskfc = taskr.Function(fc) + + # Initializing taskr + runtime.initialize() + + # Creating the execution units (functions that the tasks will run) + prevTask = None + for b in range(branchCount): + for i in range(taskCount): + task = taskr.Task(b * taskCount + i, taskfc) + + # Creating dependencies + if i > 0: task.addDependency(prevTask) + + # Adding to taskr + runtime.addTask(task) + + # Setting as new previous task + prevTask = task + + # Running taskr for the current repetition + startTime = time.time() + runtime.run() + runtime.await_() + + endTime = time.time() + computeTime = endTime - startTime + + print(f"Running Time: {computeTime:0.5f}s") + + # Finalizing taskr + runtime.finalize() \ No newline at end of file diff --git a/examples/local/workerSpecific/meson.build b/examples/local/workerSpecific/meson.build index 6969030..50a8ebb 100644 --- a/examples/local/workerSpecific/meson.build +++ b/examples/local/workerSpecific/meson.build @@ -10,4 +10,13 @@ nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ] if get_option('buildTests') test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) +endif + +if get_option('buildPyTaskR') and get_option('buildTests') + test('pyTaskR', + py, + args : [ 'py_source/main.py' ], + env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + suite: testSuite, + workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/workerSpecific/py_source/main.py b/examples/local/workerSpecific/py_source/main.py new file mode 100644 index 0000000..555a51f --- /dev/null +++ b/examples/local/workerSpecific/py_source/main.py @@ -0,0 +1,34 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import taskr +import workerSpecific + +def main(): + + # Initialize taskr with the wanted compute manager backend and number of PUs + t = taskr.taskr("threading") + + # Get the runtime + runtime = t.get_runtime() + + num_workers = t.get_num_workers() + + # Running workerSpecific example + workerSpecific.workerSpecific(runtime, num_workers) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/local/workerSpecific/py_source/workerSpecific.py b/examples/local/workerSpecific/py_source/workerSpecific.py new file mode 100644 index 0000000..92d4f78 --- /dev/null +++ b/examples/local/workerSpecific/py_source/workerSpecific.py @@ -0,0 +1,76 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License") + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import ctypes + +libc = ctypes.CDLL("libc.so.6") +libc.sched_getcpu.restype = ctypes.c_int + +import sys + +import taskr + +def workFc(currentTask): + taskLabel = currentTask.getLabel() + currentCPUId = libc.sched_getcpu() + + #### First launched on even cpus + + print(f"Task {taskLabel} first run running on CPU {currentCPUId}") + + # Sanity check + if int(2 * taskLabel) != currentCPUId: + sys.stderr.write(f"Task label ({taskLabel}) does not coincide with the current CPU id! ({currentCPUId})") + sys.exit(1) + + # Changing to odd cpus + currentTask.setWorkerAffinity(currentTask.getWorkerAffinity() + 1) + + # Suspending + currentTask.suspend() + + #### Now launched in odd cpus + + currentCPUId = libc.sched_getcpu() + print(f"Task {taskLabel} second run running on CPU {currentCPUId}") + + # Sanity check + if int(2 * taskLabel) + 1 != currentCPUId: + sys.stderr.write(f"Task label ({taskLabel}) + 1 does not coincide with the current CPU id! ({currentCPUId})") + sys.exit(1) + + +def workerSpecific(runtime, workerCount): + # Auto-adding task when it suspends. + runtime.setTaskCallbackHandler(taskr.TaskCallback.onTaskSuspend, lambda task : runtime.resumeTask(task)) + + # Creating the execution units (functions that the tasks will run) + workTaskfc = taskr.Function(lambda task : workFc(task)) + + # Initializing taskr + runtime.initialize() + + # Run only on even worker ids + for i in range(workerCount // 2): runtime.addTask(taskr.Task(i, workTaskfc, 2 * i)) + + # Running taskr for the current repetition + runtime.run() + + # Waiting for taskr to finish + runtime.await_() + + # Finalizing taskr + runtime.finalize() \ No newline at end of file diff --git a/include/pytaskr/pyruntime.hpp b/include/pytaskr/pyruntime.hpp index 193bd46..1eaf3c4 100644 --- a/include/pytaskr/pyruntime.hpp +++ b/include/pytaskr/pyruntime.hpp @@ -17,6 +17,8 @@ #pragma once #include +#include +#include #include #include @@ -35,6 +37,9 @@ namespace taskr class PyRuntime { public: + /** + * + */ PyRuntime(const std::string& str = "threading", size_t num_workers = 0) : _str(str) { // Specify the compute Managers @@ -95,9 +100,84 @@ class PyRuntime itr++; } + _num_workers = num_workers; + _runtime = std::make_unique(_executionStateComputeManager.get(), _processingUnitComputeManager.get(), _computeResources); } + /** + * + */ + PyRuntime(const std::string& str, const std::set& workersSet) : _str(str) + { + // Check if the workerSet is not empty + if (workersSet.empty()) + { + HICR_THROW_LOGIC("Error: no compute resources provided\n"); + } + + // Specify the compute Managers + if(_str == "nosv") + { + // Initialize nosv + check(nosv_init()); + + // nosv task instance for the main thread + nosv_task_t mainTask; + + // Attaching the main thread + check(nosv_attach(&mainTask, NULL, NULL, NOSV_ATTACH_NONE)); + + _executionStateComputeManager = std::make_unique(); + _processingUnitComputeManager = std::make_unique(); + } + else if(_str == "threading") + { + _executionStateComputeManager = std::make_unique(); + _processingUnitComputeManager = std::make_unique(); + } + else + { + HICR_THROW_LOGIC("'%s' is not a known HiCR backend. Try 'nosv' or 'threading'\n", str); + } + + // Reserving memory for hwloc + hwloc_topology_init(&_topology); + + // Initializing HWLoc-based host (CPU) topology manager + HiCR::backend::hwloc::TopologyManager tm(&_topology); + + // Asking backend to check the available devices + const auto t = tm.queryTopology(); + + // Getting compute resource lists from devices + std::vector computeResourceLists; + for (auto d : t.getDevices()) computeResourceLists.push_back(d->getComputeResourceList()); + + // Create processing units from the detected compute resource list and giving them to taskr + HiCR::Device::computeResourceList_t _computeResources; + for (auto computeResourceList : computeResourceLists) + for (auto computeResource : computeResourceList) + { + // Interpreting compute resource as core + auto core = dynamic_pointer_cast(computeResource); + + // If the core affinity is included in the list, Add it to the list + if (workersSet.contains(core->getProcessorId())) _computeResources.push_back(computeResource); + } + + if(!_computeResources.size()){ + HICR_THROW_LOGIC("Error: non-existing compute resources provided\n"); + } + + _num_workers = _computeResources.size(); + + _runtime = std::make_unique(_executionStateComputeManager.get(), _processingUnitComputeManager.get(), _computeResources); + } + + /** + * + */ ~PyRuntime() { // Freeing up memory @@ -117,11 +197,18 @@ class PyRuntime { return *_runtime; } + + const size_t get_num_workers() + { + return _num_workers; + } private: const std::string _str; + size_t _num_workers; + std::unique_ptr _executionStateComputeManager; std::unique_ptr _processingUnitComputeManager; diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index ba6eeba..51c5176 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -14,7 +14,8 @@ * limitations under the License. */ #include -#include +#include // std::function +#include // std::set #include #include @@ -43,7 +44,9 @@ PYBIND11_MODULE(taskr, m) // pyTaskR's PyRuntime class py::class_(m, "taskr") .def(py::init(), py::arg("backend") = "threading", py::arg("num_workers") = 0) - .def("get_runtime", &PyRuntime::get_runtime, py::return_value_policy::reference_internal); + .def(py::init&>(), py::arg("backend") = "threading", py::arg("workersSet")) + .def("get_runtime", &PyRuntime::get_runtime, py::return_value_policy::reference_internal) + .def("get_num_workers", &PyRuntime::get_num_workers); // TaskR's Function class py::class_(m, "Function") @@ -57,6 +60,7 @@ PYBIND11_MODULE(taskr, m) .def("getWorkerAffinity", &Task::getWorkerAffinity) .def("setWorkerAffinity", &Task::setWorkerAffinity) .def("addDependency", &Task::addDependency) + .def("addPendingOperation", &Task::addPendingOperation) .def("suspend", &Task::suspend); py::enum_(m, "TaskCallback") From 6006f0342daa2a63122f377e659feeb9a93b19b6 Mon Sep 17 00:00:00 2001 From: noabauma Date: Thu, 12 Jun 2025 15:22:58 +0200 Subject: [PATCH 13/27] adding some working examples --- examples/local/abcTasks/meson.build | 3 ++- examples/local/conditionVariable/meson.build | 12 ++++++---- .../local/conditionVariable/py_source/main.py | 2 +- examples/local/energySaver/meson.build | 3 ++- examples/local/fibonacci/meson.build | 3 ++- examples/local/fibonacci/py_source/main.py | 2 +- examples/local/manyParallel/meson.build | 3 ++- examples/local/multiJob/meson.build | 3 ++- examples/local/mutex/meson.build | 3 ++- examples/local/pendingOperation/meson.build | 3 ++- .../local/pendingOperation/py_source/main.py | 2 +- examples/local/resourceList/meson.build | 3 ++- examples/local/simple/meson.build | 3 ++- examples/local/simple/py_source/main.py | 6 +---- examples/local/simple/py_source/simple.py | 21 ++++++++--------- examples/local/suspend/meson.build | 3 ++- examples/local/suspend/py_source/main.py | 2 +- examples/local/workerSpecific/meson.build | 3 ++- .../local/workerSpecific/py_source/main.py | 2 +- include/pytaskr/pyruntime.hpp | 16 +++++++++---- include/pytaskr/pytaskr.cpp | 23 ++++++++++++------- 21 files changed, 71 insertions(+), 50 deletions(-) diff --git a/examples/local/abcTasks/meson.build b/examples/local/abcTasks/meson.build index f73d676..b437357 100644 --- a/examples/local/abcTasks/meson.build +++ b/examples/local/abcTasks/meson.build @@ -15,7 +15,8 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'py_source/main.py' ], + is_parallel : false, env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) diff --git a/examples/local/conditionVariable/meson.build b/examples/local/conditionVariable/meson.build index de09692..6f0f859 100644 --- a/examples/local/conditionVariable/meson.build +++ b/examples/local/conditionVariable/meson.build @@ -27,28 +27,32 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR_conditionVariableWait', py, - args : [ 'py_source/main.py' ], + args : [ 'py_source/main.py' ], + is_parallel : false, env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWait'], suite: testSuite, workdir: meson.current_source_dir()) test('pyTaskR_conditionVariableWaitFor', py, - args : [ 'py_source/main.py' ], + args : [ 'py_source/main.py' ], + is_parallel : false, env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWaitFor'], suite: testSuite, workdir: meson.current_source_dir()) test('pyTaskR_conditionVariableWaitCondition', py, - args : [ 'py_source/main.py' ], + args : [ 'py_source/main.py' ], + is_parallel : false, env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWaitCondition'], suite: testSuite, workdir: meson.current_source_dir()) test('pyTaskR_conditionVariableWaitForCondition', py, - args : [ 'py_source/main.py' ], + args : [ 'py_source/main.py' ], + is_parallel : false, env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWaitForCondition'], suite: testSuite, workdir: meson.current_source_dir()) diff --git a/examples/local/conditionVariable/py_source/main.py b/examples/local/conditionVariable/py_source/main.py index 32ad001..01ba2ac 100644 --- a/examples/local/conditionVariable/py_source/main.py +++ b/examples/local/conditionVariable/py_source/main.py @@ -26,7 +26,7 @@ def main(): # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("threading") + t = taskr.taskr("nosv") # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/energySaver/meson.build b/examples/local/energySaver/meson.build index 5e6a53d..8d655e4 100644 --- a/examples/local/energySaver/meson.build +++ b/examples/local/energySaver/meson.build @@ -15,7 +15,8 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py'], + args : [ 'py_source/main.py'], + is_parallel : false, env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) diff --git a/examples/local/fibonacci/meson.build b/examples/local/fibonacci/meson.build index 9a46ae6..6f331ba 100644 --- a/examples/local/fibonacci/meson.build +++ b/examples/local/fibonacci/meson.build @@ -15,7 +15,8 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py'], + args : [ 'py_source/main.py'], + is_parallel : false, env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) diff --git a/examples/local/fibonacci/py_source/main.py b/examples/local/fibonacci/py_source/main.py index 511a8a7..4426d85 100644 --- a/examples/local/fibonacci/py_source/main.py +++ b/examples/local/fibonacci/py_source/main.py @@ -24,7 +24,7 @@ def main(): if len(sys.argv) > 1: initialValue = int(sys.argv[1]) # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("threading") + t = taskr.taskr("nosv") # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/manyParallel/meson.build b/examples/local/manyParallel/meson.build index 2d7267d..6313ff8 100644 --- a/examples/local/manyParallel/meson.build +++ b/examples/local/manyParallel/meson.build @@ -15,7 +15,8 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'py_source/main.py' ], + is_parallel : false, env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) diff --git a/examples/local/multiJob/meson.build b/examples/local/multiJob/meson.build index 559dff9..d9ad718 100644 --- a/examples/local/multiJob/meson.build +++ b/examples/local/multiJob/meson.build @@ -15,7 +15,8 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'py_source/main.py' ], + is_parallel : false, env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) diff --git a/examples/local/mutex/meson.build b/examples/local/mutex/meson.build index 27639f5..63aea1b 100644 --- a/examples/local/mutex/meson.build +++ b/examples/local/mutex/meson.build @@ -15,7 +15,8 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'py_source/main.py' ], + is_parallel : false, env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) diff --git a/examples/local/pendingOperation/meson.build b/examples/local/pendingOperation/meson.build index 93e81e7..4f7d3d6 100644 --- a/examples/local/pendingOperation/meson.build +++ b/examples/local/pendingOperation/meson.build @@ -15,7 +15,8 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'py_source/main.py' ], + is_parallel : false, env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) diff --git a/examples/local/pendingOperation/py_source/main.py b/examples/local/pendingOperation/py_source/main.py index 6027984..0ef713b 100644 --- a/examples/local/pendingOperation/py_source/main.py +++ b/examples/local/pendingOperation/py_source/main.py @@ -20,7 +20,7 @@ def main(): # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("threading") + t = taskr.taskr("nosv") # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/resourceList/meson.build b/examples/local/resourceList/meson.build index 9a7e7e7..e153a06 100644 --- a/examples/local/resourceList/meson.build +++ b/examples/local/resourceList/meson.build @@ -15,7 +15,8 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'py_source/main.py' ], + is_parallel : false, env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) diff --git a/examples/local/simple/meson.build b/examples/local/simple/meson.build index 6d8fe4b..d3013fb 100644 --- a/examples/local/simple/meson.build +++ b/examples/local/simple/meson.build @@ -15,7 +15,8 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'py_source/main.py' ], + is_parallel : false, env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) diff --git a/examples/local/simple/py_source/main.py b/examples/local/simple/py_source/main.py index 05c50a6..94b88e1 100644 --- a/examples/local/simple/py_source/main.py +++ b/examples/local/simple/py_source/main.py @@ -18,16 +18,12 @@ import simple def main(): - # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("threading") + t = taskr.taskr("nosv") # Get the runtime runtime = t.get_runtime() - # FOR TESTING: checking if a task resumes after being suspended (nosv doesn't work) - runtime.setTaskCallbackHandler(taskr.TaskCallback.onTaskSuspend, lambda task : runtime.resumeTask(task)) - # Running simple example simple.simple(runtime) diff --git a/examples/local/simple/py_source/simple.py b/examples/local/simple/py_source/simple.py index ffaaaa3..f11bdb9 100644 --- a/examples/local/simple/py_source/simple.py +++ b/examples/local/simple/py_source/simple.py @@ -13,29 +13,26 @@ See the License for the specific language governing permissions and limitations under the License. """ +import ctypes + +libc = ctypes.CDLL("libc.so.6") +libc.sched_getcpu.restype = ctypes.c_int import taskr +NTASKS = 2 + def simple(runtime): # Initializing taskr runtime.initialize() fc = lambda task : print(f"Hello, I am task {task.getLabel()}") - # def fc(task): - # print(f"Before suspend task {task.getLabel()}") - # task.suspend() - # print(f"After suspend task {task.getLabel()}") - - # Create the taskr Tasks taskfc = taskr.Function(fc) - # Creating the execution units (functions that the tasks will run) - for i in range(1): - task = taskr.Task(i, taskfc) - - # Adding to taskr - runtime.addTask(task) + # Adding to tasks to taskr + for i in range(NTASKS): + runtime.addTask(taskr.Task(i, taskfc)) # Running taskr for the current repetition runtime.run() diff --git a/examples/local/suspend/meson.build b/examples/local/suspend/meson.build index 30d98e7..758ca4c 100644 --- a/examples/local/suspend/meson.build +++ b/examples/local/suspend/meson.build @@ -15,7 +15,8 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'py_source/main.py' ], + is_parallel : false, env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) diff --git a/examples/local/suspend/py_source/main.py b/examples/local/suspend/py_source/main.py index bfeca76..59f3d30 100644 --- a/examples/local/suspend/py_source/main.py +++ b/examples/local/suspend/py_source/main.py @@ -29,7 +29,7 @@ def main(): if len(sys.argv) > 2: branchCount = int(sys.argv[2]) # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("threading") + t = taskr.taskr("nosv") # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/workerSpecific/meson.build b/examples/local/workerSpecific/meson.build index 50a8ebb..d726f7d 100644 --- a/examples/local/workerSpecific/meson.build +++ b/examples/local/workerSpecific/meson.build @@ -15,7 +15,8 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'py_source/main.py' ], + is_parallel : false, env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) diff --git a/examples/local/workerSpecific/py_source/main.py b/examples/local/workerSpecific/py_source/main.py index 555a51f..cb6f8bc 100644 --- a/examples/local/workerSpecific/py_source/main.py +++ b/examples/local/workerSpecific/py_source/main.py @@ -20,7 +20,7 @@ def main(): # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("threading") + t = taskr.taskr("nosv") # Get the runtime runtime = t.get_runtime() diff --git a/include/pytaskr/pyruntime.hpp b/include/pytaskr/pyruntime.hpp index 1eaf3c4..8f47c3f 100644 --- a/include/pytaskr/pyruntime.hpp +++ b/include/pytaskr/pyruntime.hpp @@ -42,6 +42,7 @@ class PyRuntime */ PyRuntime(const std::string& str = "threading", size_t num_workers = 0) : _str(str) { + printf("Constructor being called for %s\n", _str.c_str()); // Specify the compute Managers if(_str == "nosv") { @@ -103,6 +104,8 @@ class PyRuntime _num_workers = num_workers; _runtime = std::make_unique(_executionStateComputeManager.get(), _processingUnitComputeManager.get(), _computeResources); + + // _runtime->setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskSuspend, [this](taskr::Task *task) { printf("resume task\n"); fflush(stdout); this->_runtime->resumeTask(task); }); } /** @@ -173,6 +176,8 @@ class PyRuntime _num_workers = _computeResources.size(); _runtime = std::make_unique(_executionStateComputeManager.get(), _processingUnitComputeManager.get(), _computeResources); + + // _runtime->setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskSuspend, [this](taskr::Task *task) { this->_runtime->resumeTask(task); }); } /** @@ -180,6 +185,7 @@ class PyRuntime */ ~PyRuntime() { + printf("Destructor being called for %s\n", _str.c_str()); // Freeing up memory hwloc_topology_destroy(_topology); @@ -203,12 +209,14 @@ class PyRuntime return _num_workers; } - private: + std::unique_ptr _runtime; + private: + const std::string _str; - + size_t _num_workers; - + std::unique_ptr _executionStateComputeManager; std::unique_ptr _processingUnitComputeManager; @@ -216,8 +224,6 @@ class PyRuntime hwloc_topology_t _topology; const HiCR::Device::computeResourceList_t _computeResources; - - std::unique_ptr _runtime; }; } // namespace taskr \ No newline at end of file diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index 51c5176..610d645 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -27,9 +27,23 @@ namespace taskr // TODO: add all methods of all classes +void call_python_callback(py::function callback, Task* task) { + py::gil_scoped_acquire acquire; + callback(task); // Call the Python function safely +} + PYBIND11_MODULE(taskr, m) { m.doc() = "pybind11 plugin for TaskR"; + + m.def("call_python_callback", &call_python_callback, "blabla"); + + // pyTaskR's PyRuntime class + py::class_(m, "taskr") + .def(py::init(), py::arg("backend") = "threading", py::arg("num_workers") = 0) + .def(py::init&>(), py::arg("backend") = "threading", py::arg("workersSet")) + .def("get_runtime", &PyRuntime::get_runtime, py::return_value_policy::reference_internal) + .def("get_num_workers", &PyRuntime::get_num_workers); // TaskR's Runtime class py::class_(m, "Runtime") @@ -40,13 +54,6 @@ PYBIND11_MODULE(taskr, m) .def("run", &Runtime::run, py::call_guard()) .def("await_", &Runtime::await, py::call_guard()) // Release GIL is important otherwise non-finished tasks are getting blocked .def("finalize", &Runtime::finalize); - - // pyTaskR's PyRuntime class - py::class_(m, "taskr") - .def(py::init(), py::arg("backend") = "threading", py::arg("num_workers") = 0) - .def(py::init&>(), py::arg("backend") = "threading", py::arg("workersSet")) - .def("get_runtime", &PyRuntime::get_runtime, py::return_value_policy::reference_internal) - .def("get_num_workers", &PyRuntime::get_num_workers); // TaskR's Function class py::class_(m, "Function") @@ -61,7 +68,7 @@ PYBIND11_MODULE(taskr, m) .def("setWorkerAffinity", &Task::setWorkerAffinity) .def("addDependency", &Task::addDependency) .def("addPendingOperation", &Task::addPendingOperation) - .def("suspend", &Task::suspend); + .def("suspend", &Task::suspend, py::call_guard()); py::enum_(m, "TaskCallback") .value("onTaskExecute", Task::callback_t::onTaskExecute) From 9ef9c2155348b27e355057593cb3a5ec80d2ecb4 Mon Sep 17 00:00:00 2001 From: noabauma Date: Thu, 12 Jun 2025 15:53:48 +0200 Subject: [PATCH 14/27] minor correction on some examples --- .../conditionVariable/py_source/conditionVariableWait.py | 2 -- examples/local/conditionVariable/py_source/main.py | 4 ++++ examples/local/fibonacci/py_source/fibonacci.py | 3 +++ .../local/pendingOperation/py_source/pendingOperation.py | 6 +++++- examples/local/suspend/py_source/main.py | 2 -- examples/local/suspend/py_source/suspend.py | 6 +++++- examples/local/workerSpecific/py_source/workerSpecific.py | 6 +++++- include/pytaskr/meson.build | 2 +- 8 files changed, 23 insertions(+), 8 deletions(-) diff --git a/examples/local/conditionVariable/py_source/conditionVariableWait.py b/examples/local/conditionVariable/py_source/conditionVariableWait.py index b05ebfa..8a8e75f 100644 --- a/examples/local/conditionVariable/py_source/conditionVariableWait.py +++ b/examples/local/conditionVariable/py_source/conditionVariableWait.py @@ -28,7 +28,6 @@ def conditionVariableWait(runtime): def fc(task): nonlocal value - print(f"Hello I am Task: {task.getLabel()} on PID: {task.getWorkerAffinity()}") # Waiting for the other task's notification print("Thread 1: I wait for a notification") @@ -45,7 +44,6 @@ def fc(task): def fc(task): nonlocal value - print(f"Hello I am Task: {task.getLabel()} on PID: {task.getWorkerAffinity()}") # Notifying the other task print("Thread 2: Notifying anybody interested") diff --git a/examples/local/conditionVariable/py_source/main.py b/examples/local/conditionVariable/py_source/main.py index 01ba2ac..44813cf 100644 --- a/examples/local/conditionVariable/py_source/main.py +++ b/examples/local/conditionVariable/py_source/main.py @@ -42,6 +42,10 @@ def main(): # Call the function test_function(runtime) + # Overwrite the onTaskSuspend fc to be None such that runtime no longer has + # a dependency to the previous fc and runtime can call the destructor + runtime.setTaskCallbackHandler(taskr.TaskCallback.onTaskSuspend, None) + if __name__ == "__main__": main() \ No newline at end of file diff --git a/examples/local/fibonacci/py_source/fibonacci.py b/examples/local/fibonacci/py_source/fibonacci.py index 3ec66c8..1ef6175 100644 --- a/examples/local/fibonacci/py_source/fibonacci.py +++ b/examples/local/fibonacci/py_source/fibonacci.py @@ -103,5 +103,8 @@ def Fc(task): # Finalizing taskR runtime.finalize() + # Dereferencing this global instance to let runtime call his Destructor + _runtime = None + # Returning fibonacci value return result diff --git a/examples/local/pendingOperation/py_source/pendingOperation.py b/examples/local/pendingOperation/py_source/pendingOperation.py index 45f78a3..81208a0 100644 --- a/examples/local/pendingOperation/py_source/pendingOperation.py +++ b/examples/local/pendingOperation/py_source/pendingOperation.py @@ -76,4 +76,8 @@ def pendingOperation(runtime): runtime.await_() # Finalizing taskr - runtime.finalize() \ No newline at end of file + runtime.finalize() + + # Overwrite the onTaskSuspend fc to be None such that runtime no longer has + # a dependency to the previous fc and runtime can call the destructor + runtime.setTaskCallbackHandler(taskr.TaskCallback.onTaskSuspend, None) \ No newline at end of file diff --git a/examples/local/suspend/py_source/main.py b/examples/local/suspend/py_source/main.py index 59f3d30..0cb600a 100644 --- a/examples/local/suspend/py_source/main.py +++ b/examples/local/suspend/py_source/main.py @@ -20,8 +20,6 @@ import suspend def main(): - - # Getting arguments, if provided taskCount = 2 branchCount = 100 diff --git a/examples/local/suspend/py_source/suspend.py b/examples/local/suspend/py_source/suspend.py index 2ac6830..dd50854 100644 --- a/examples/local/suspend/py_source/suspend.py +++ b/examples/local/suspend/py_source/suspend.py @@ -59,4 +59,8 @@ def fc(task): print(f"Running Time: {computeTime:0.5f}s") # Finalizing taskr - runtime.finalize() \ No newline at end of file + runtime.finalize() + + # Overwrite the onTaskSuspend fc to be None such that runtime no longer has + # a dependency to the previous fc and runtime can call the destructor + runtime.setTaskCallbackHandler(taskr.TaskCallback.onTaskSuspend, None) \ No newline at end of file diff --git a/examples/local/workerSpecific/py_source/workerSpecific.py b/examples/local/workerSpecific/py_source/workerSpecific.py index 92d4f78..6513640 100644 --- a/examples/local/workerSpecific/py_source/workerSpecific.py +++ b/examples/local/workerSpecific/py_source/workerSpecific.py @@ -73,4 +73,8 @@ def workerSpecific(runtime, workerCount): runtime.await_() # Finalizing taskr - runtime.finalize() \ No newline at end of file + runtime.finalize() + + # Overwrite the onTaskSuspend fc to be None such that runtime no longer has + # a dependency to the previous fc and runtime can call the destructor + runtime.setTaskCallbackHandler(taskr.TaskCallback.onTaskSuspend, None) \ No newline at end of file diff --git a/include/pytaskr/meson.build b/include/pytaskr/meson.build index 0c69e5a..c3db9c6 100644 --- a/include/pytaskr/meson.build +++ b/include/pytaskr/meson.build @@ -2,7 +2,7 @@ # Manually compile like this: # c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3-config --includes) -Iextern/pybind11/include example.cpp -o example$(python3-config --extension-suffix) -py = import('python').find_installation(pure: false) +py = import('python').find_installation('/home/nbaumann/myenv/bin/python3', pure: false) pybind11_dep = dependency('pybind11', required: true) py.extension_module('taskr', From 5f8182621262b2a1b07c7ad89c85560023f40e53 Mon Sep 17 00:00:00 2001 From: noabauma Date: Thu, 12 Jun 2025 16:37:37 +0200 Subject: [PATCH 15/27] all the current examples work if nosv is used --- include/pytaskr/meson.build | 2 +- include/pytaskr/pytaskr.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/pytaskr/meson.build b/include/pytaskr/meson.build index c3db9c6..0c69e5a 100644 --- a/include/pytaskr/meson.build +++ b/include/pytaskr/meson.build @@ -2,7 +2,7 @@ # Manually compile like this: # c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3-config --includes) -Iextern/pybind11/include example.cpp -o example$(python3-config --extension-suffix) -py = import('python').find_installation('/home/nbaumann/myenv/bin/python3', pure: false) +py = import('python').find_installation(pure: false) pybind11_dep = dependency('pybind11', required: true) py.extension_module('taskr', diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index 610d645..723f189 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -86,10 +86,10 @@ PYBIND11_MODULE(taskr, m) // TaskR's ConditionVariable class py::class_(m, "ConditionVariable") .def(py::init<>()) - .def("wait", py::overload_cast(&ConditionVariable::wait), "cv wait") - .def("wait", py::overload_cast&>(&ConditionVariable::wait), "cv wait with condition") - .def("waitFor", py::overload_cast&, size_t>(&ConditionVariable::waitFor), "cv waitFor with condition") - .def("waitFor", py::overload_cast(&ConditionVariable::waitFor), "cv waitFor") + .def("wait", py::overload_cast(&ConditionVariable::wait), py::call_guard(), "cv wait") + .def("wait", py::overload_cast&>(&ConditionVariable::wait), py::call_guard(), "cv wait with condition") + .def("waitFor", py::overload_cast&, size_t>(&ConditionVariable::waitFor), py::call_guard(), "cv waitFor with condition") + .def("waitFor", py::overload_cast(&ConditionVariable::waitFor), py::call_guard(), "cv waitFor") .def("notifyOne", &ConditionVariable::notifyOne) .def("notifyAll", &ConditionVariable::notifyAll) .def("getWaitingTaskCount", &ConditionVariable::getWaitingTaskCount); From b2ea6b5177da7f4db27976463f9d308a11484225 Mon Sep 17 00:00:00 2001 From: noabauma Date: Fri, 13 Jun 2025 10:47:00 +0200 Subject: [PATCH 16/27] fibonacci also with mutex.lock? --- .../fibonacci/py_source/fibonacci_mutex.py | 115 ++++++++++++++++++ examples/local/fibonacci/py_source/main.py | 6 +- include/pytaskr/pytaskr.cpp | 4 +- 3 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 examples/local/fibonacci/py_source/fibonacci_mutex.py diff --git a/examples/local/fibonacci/py_source/fibonacci_mutex.py b/examples/local/fibonacci/py_source/fibonacci_mutex.py new file mode 100644 index 0000000..024c39a --- /dev/null +++ b/examples/local/fibonacci/py_source/fibonacci_mutex.py @@ -0,0 +1,115 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License") + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + + +import time +import taskr + +# Globally assigned variables +_runtime = None +_taskCounter = 0 +_m = taskr.Mutex() + +# Fibonacci without memoization to stress the tasking runtime +def fibonacci(currentTask, x): + if x == 0: return 0 + if x == 1: return 1 + + global _taskCounter + global _runtime + + result1 = 0 + result2 = 0 + + # Creating task functions + def Fc1(task): + nonlocal result1 + result1 = fibonacci(task, x - 1) + + def Fc2(task): + nonlocal result2 + result2 = fibonacci(task, x - 2) + + fibFc1 = taskr.Function(Fc1) + fibFc2 = taskr.Function(Fc2) + + # Creating two new tasks + subTask1 = taskr.Task(_taskCounter, fibFc1) + _m.lock(currentTask) + _taskCounter += 1 + _m.unlock(currentTask) + subTask2 = taskr.Task(_taskCounter, fibFc2) + _m.lock(currentTask) + _taskCounter += 1 + _m.unlock(currentTask) + + # Adding dependencies with the newly created tasks + currentTask.addDependency(subTask1) + currentTask.addDependency(subTask2) + + # Adding new tasks to TaskR + _runtime.addTask(subTask1) + _runtime.addTask(subTask2) + + # Suspending current task + currentTask.suspend() + + return result1 + result2 + +def fibonacciDriver(initialValue, runtime): + # Setting global variables + global _taskCounter + global _runtime + _runtime = runtime + + # Storage for result + result = 0 + + # Creating task functions + def Fc(task): + nonlocal result + result = fibonacci(task, initialValue) + + initialFc = taskr.Function(Fc) + + # Now creating tasks and their dependency graph + initialTask = taskr.Task(_taskCounter, initialFc) + _taskCounter += 1 + + runtime.addTask(initialTask) + + # Initializing taskR + runtime.initialize() + + # Running taskr + startTime = time.time() + runtime.run() + runtime.await_() + endTime = time.time() + + computeTime = endTime - startTime + + print(f"Running Time: {computeTime:.5f}s") + print(f"Total Tasks: {_taskCounter}") + + # Finalizing taskR + runtime.finalize() + + # Dereferencing this global instance to let runtime call his Destructor + _runtime = None + + # Returning fibonacci value + return result diff --git a/examples/local/fibonacci/py_source/main.py b/examples/local/fibonacci/py_source/main.py index 4426d85..0644270 100644 --- a/examples/local/fibonacci/py_source/main.py +++ b/examples/local/fibonacci/py_source/main.py @@ -16,7 +16,8 @@ import sys import taskr -import fibonacci +# import fibonacci +import fibonacci_mutex def main(): # Define the Fibonacci number to compute. @@ -30,7 +31,8 @@ def main(): runtime = t.get_runtime() # Running Fibonacci example - result = fibonacci.fibonacciDriver(initialValue, runtime) + # result = fibonacci.fibonacciDriver(initialValue, runtime) + result = fibonacci_mutex.fibonacciDriver(initialValue, runtime) # Printing result print(f"Fib({initialValue}) = {result}") diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index 723f189..2d3b0e5 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -90,8 +90,8 @@ PYBIND11_MODULE(taskr, m) .def("wait", py::overload_cast&>(&ConditionVariable::wait), py::call_guard(), "cv wait with condition") .def("waitFor", py::overload_cast&, size_t>(&ConditionVariable::waitFor), py::call_guard(), "cv waitFor with condition") .def("waitFor", py::overload_cast(&ConditionVariable::waitFor), py::call_guard(), "cv waitFor") - .def("notifyOne", &ConditionVariable::notifyOne) - .def("notifyAll", &ConditionVariable::notifyAll) + .def("notifyOne", &ConditionVariable::notifyOne) // Not sure if I need to release the GIL here as this function also uses the intern mutex lock + .def("notifyAll", &ConditionVariable::notifyAll) // Same here .def("getWaitingTaskCount", &ConditionVariable::getWaitingTaskCount); } From eed04231bd19d59f414154680aab009ef6c4beea Mon Sep 17 00:00:00 2001 From: noabauma Date: Fri, 13 Jun 2025 17:06:47 +0200 Subject: [PATCH 17/27] redundant python path removed --- examples/local/abcTasks/meson.build | 2 +- examples/local/conditionVariable/meson.build | 8 ++++---- examples/local/energySaver/meson.build | 2 +- examples/local/fibonacci/meson.build | 2 +- examples/local/manyParallel/meson.build | 2 +- examples/local/multiJob/meson.build | 2 +- examples/local/mutex/meson.build | 2 +- examples/local/pendingOperation/meson.build | 2 +- examples/local/resourceList/meson.build | 2 +- examples/local/simple/meson.build | 2 +- examples/local/suspend/meson.build | 2 +- examples/local/workerSpecific/meson.build | 2 +- 12 files changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/local/abcTasks/meson.build b/examples/local/abcTasks/meson.build index b437357..73c8ee5 100644 --- a/examples/local/abcTasks/meson.build +++ b/examples/local/abcTasks/meson.build @@ -17,7 +17,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') py, args : [ 'py_source/main.py' ], is_parallel : false, - env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/conditionVariable/meson.build b/examples/local/conditionVariable/meson.build index 6f0f859..22b3305 100644 --- a/examples/local/conditionVariable/meson.build +++ b/examples/local/conditionVariable/meson.build @@ -29,7 +29,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') py, args : [ 'py_source/main.py' ], is_parallel : false, - env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWait'], + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWait'], suite: testSuite, workdir: meson.current_source_dir()) @@ -37,7 +37,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') py, args : [ 'py_source/main.py' ], is_parallel : false, - env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWaitFor'], + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWaitFor'], suite: testSuite, workdir: meson.current_source_dir()) @@ -45,7 +45,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') py, args : [ 'py_source/main.py' ], is_parallel : false, - env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWaitCondition'], + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWaitCondition'], suite: testSuite, workdir: meson.current_source_dir()) @@ -53,7 +53,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') py, args : [ 'py_source/main.py' ], is_parallel : false, - env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWaitForCondition'], + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWaitForCondition'], suite: testSuite, workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/energySaver/meson.build b/examples/local/energySaver/meson.build index 8d655e4..b62d263 100644 --- a/examples/local/energySaver/meson.build +++ b/examples/local/energySaver/meson.build @@ -17,7 +17,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') py, args : [ 'py_source/main.py'], is_parallel : false, - env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/fibonacci/meson.build b/examples/local/fibonacci/meson.build index 6f331ba..0f46692 100644 --- a/examples/local/fibonacci/meson.build +++ b/examples/local/fibonacci/meson.build @@ -17,7 +17,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') py, args : [ 'py_source/main.py'], is_parallel : false, - env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/manyParallel/meson.build b/examples/local/manyParallel/meson.build index 6313ff8..494b8ad 100644 --- a/examples/local/manyParallel/meson.build +++ b/examples/local/manyParallel/meson.build @@ -17,7 +17,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') py, args : [ 'py_source/main.py' ], is_parallel : false, - env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/multiJob/meson.build b/examples/local/multiJob/meson.build index d9ad718..4433c5f 100644 --- a/examples/local/multiJob/meson.build +++ b/examples/local/multiJob/meson.build @@ -17,7 +17,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') py, args : [ 'py_source/main.py' ], is_parallel : false, - env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/mutex/meson.build b/examples/local/mutex/meson.build index 63aea1b..412c47b 100644 --- a/examples/local/mutex/meson.build +++ b/examples/local/mutex/meson.build @@ -17,7 +17,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') py, args : [ 'py_source/main.py' ], is_parallel : false, - env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/pendingOperation/meson.build b/examples/local/pendingOperation/meson.build index 4f7d3d6..190f4ac 100644 --- a/examples/local/pendingOperation/meson.build +++ b/examples/local/pendingOperation/meson.build @@ -17,7 +17,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') py, args : [ 'py_source/main.py' ], is_parallel : false, - env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/resourceList/meson.build b/examples/local/resourceList/meson.build index e153a06..f54834e 100644 --- a/examples/local/resourceList/meson.build +++ b/examples/local/resourceList/meson.build @@ -17,7 +17,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') py, args : [ 'py_source/main.py' ], is_parallel : false, - env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/simple/meson.build b/examples/local/simple/meson.build index d3013fb..9486ae7 100644 --- a/examples/local/simple/meson.build +++ b/examples/local/simple/meson.build @@ -17,7 +17,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') py, args : [ 'py_source/main.py' ], is_parallel : false, - env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/suspend/meson.build b/examples/local/suspend/meson.build index 758ca4c..3ff574e 100644 --- a/examples/local/suspend/meson.build +++ b/examples/local/suspend/meson.build @@ -17,7 +17,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') py, args : [ 'py_source/main.py' ], is_parallel : false, - env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/local/workerSpecific/meson.build b/examples/local/workerSpecific/meson.build index d726f7d..4cf6a27 100644 --- a/examples/local/workerSpecific/meson.build +++ b/examples/local/workerSpecific/meson.build @@ -17,7 +17,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') py, args : [ 'py_source/main.py' ], is_parallel : false, - env: ['PYTHONPATH=' + meson.current_source_dir() + ':' + meson.project_build_root() + '/include/pytaskr/'], + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, workdir: meson.current_source_dir()) endif \ No newline at end of file From 4c70dc6019de9e6e2a2ec4d29b71c07580aa94db Mon Sep 17 00:00:00 2001 From: noabauma Date: Fri, 13 Jun 2025 17:20:40 +0200 Subject: [PATCH 18/27] merging main --- examples/local/abcTasks/meson.build | 5 +++-- extern/tracr | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/local/abcTasks/meson.build b/examples/local/abcTasks/meson.build index 59dac48..70d8e4f 100644 --- a/examples/local/abcTasks/meson.build +++ b/examples/local/abcTasks/meson.build @@ -11,8 +11,9 @@ endif if 'nosv' in get_option('executionStateType') and 'nosv' in get_option('processingUnitType') nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ]) -if get_option('buildTests') - test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p') + if get_option('buildTests') + test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p') + endif endif if get_option('buildPyTaskR') and get_option('buildTests') diff --git a/extern/tracr b/extern/tracr index 9818518..f60f505 160000 --- a/extern/tracr +++ b/extern/tracr @@ -1 +1 @@ -Subproject commit 98185182f468e44d895da2b507f66254fb793421 +Subproject commit f60f505f13ad6b56e607c555ef239af2d238c3b6 From 8747407c4c43f599e7bb906bc2e0e0eab9000704 Mon Sep 17 00:00:00 2001 From: noabauma Date: Fri, 13 Jun 2025 17:22:11 +0200 Subject: [PATCH 19/27] fixing code style --- examples/local/simple/source/simple.hpp | 2 +- include/pytaskr/pyruntime.hpp | 324 +++++++++++------------- include/pytaskr/pytaskr.cpp | 82 +++--- tests/pyruntime.cpp | 8 +- 4 files changed, 198 insertions(+), 218 deletions(-) diff --git a/examples/local/simple/source/simple.hpp b/examples/local/simple/source/simple.hpp index 49cf183..0192905 100644 --- a/examples/local/simple/source/simple.hpp +++ b/examples/local/simple/source/simple.hpp @@ -26,7 +26,7 @@ void simple(taskr::Runtime *taskr) // Initializing taskr taskr->initialize(); - auto fc = [](taskr::Task *task) { printf("Hello, I am task %ld\n", task->getLabel());}; + auto fc = [](taskr::Task *task) { printf("Hello, I am task %ld\n", task->getLabel()); }; // Create the taskr Tasks auto taskfc = taskr::Function(fc); diff --git a/include/pytaskr/pyruntime.hpp b/include/pytaskr/pyruntime.hpp index 8f47c3f..f5c2663 100644 --- a/include/pytaskr/pyruntime.hpp +++ b/include/pytaskr/pyruntime.hpp @@ -36,194 +36,174 @@ namespace taskr class PyRuntime { -public: - /** + public: + + /** * */ - PyRuntime(const std::string& str = "threading", size_t num_workers = 0) : _str(str) + PyRuntime(const std::string &str = "threading", size_t num_workers = 0) + : _str(str) + { + printf("Constructor being called for %s\n", _str.c_str()); + // Specify the compute Managers + if (_str == "nosv") + { + // Initialize nosv + check(nosv_init()); + + // nosv task instance for the main thread + nosv_task_t mainTask; + + // Attaching the main thread + check(nosv_attach(&mainTask, NULL, NULL, NOSV_ATTACH_NONE)); + + _executionStateComputeManager = std::make_unique(); + _processingUnitComputeManager = std::make_unique(); + } + else if (_str == "threading") { - printf("Constructor being called for %s\n", _str.c_str()); - // Specify the compute Managers - if(_str == "nosv") - { - // Initialize nosv - check(nosv_init()); - - // nosv task instance for the main thread - nosv_task_t mainTask; - - // Attaching the main thread - check(nosv_attach(&mainTask, NULL, NULL, NOSV_ATTACH_NONE)); - - _executionStateComputeManager = std::make_unique(); - _processingUnitComputeManager = std::make_unique(); - } - else if(_str == "threading") - { - _executionStateComputeManager = std::make_unique(); - _processingUnitComputeManager = std::make_unique(); - } - else - { - HICR_THROW_LOGIC("'%s' is not a known HiCR backend. Try 'nosv' or 'threading'\n", str); - } - - // Reserving memory for hwloc - hwloc_topology_init(&_topology); - - // Initializing HWLoc-based host (CPU) topology manager - HiCR::backend::hwloc::TopologyManager tm(&_topology); - - // Asking backend to check the available devices - const auto t = tm.queryTopology(); - - // Compute resources to use - HiCR::Device::computeResourceList_t _computeResources; - - // Getting compute resources in this device - auto cr = (*(t.getDevices().begin()))->getComputeResourceList(); - - auto itr = cr.begin(); - - // Allocate the compute resources (i.e. PUs) - if(num_workers == 0) - { - num_workers = cr.size(); - } - else if(num_workers > cr.size()) - { - HICR_THROW_LOGIC("num_workers = %d is not a legal number. FYI, we can have at most %d workers.\n", num_workers, cr.size()); - } - - for (size_t i = 0; i < num_workers; i++) - { - _computeResources.push_back(*itr); - itr++; - } - - _num_workers = num_workers; - - _runtime = std::make_unique(_executionStateComputeManager.get(), _processingUnitComputeManager.get(), _computeResources); - - // _runtime->setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskSuspend, [this](taskr::Task *task) { printf("resume task\n"); fflush(stdout); this->_runtime->resumeTask(task); }); + _executionStateComputeManager = std::make_unique(); + _processingUnitComputeManager = std::make_unique(); } + else { HICR_THROW_LOGIC("'%s' is not a known HiCR backend. Try 'nosv' or 'threading'\n", str); } - /** - * - */ - PyRuntime(const std::string& str, const std::set& workersSet) : _str(str) + // Reserving memory for hwloc + hwloc_topology_init(&_topology); + + // Initializing HWLoc-based host (CPU) topology manager + HiCR::backend::hwloc::TopologyManager tm(&_topology); + + // Asking backend to check the available devices + const auto t = tm.queryTopology(); + + // Compute resources to use + HiCR::Device::computeResourceList_t _computeResources; + + // Getting compute resources in this device + auto cr = (*(t.getDevices().begin()))->getComputeResourceList(); + + auto itr = cr.begin(); + + // Allocate the compute resources (i.e. PUs) + if (num_workers == 0) { num_workers = cr.size(); } + else if (num_workers > cr.size()) { HICR_THROW_LOGIC("num_workers = %d is not a legal number. FYI, we can have at most %d workers.\n", num_workers, cr.size()); } + + for (size_t i = 0; i < num_workers; i++) { - // Check if the workerSet is not empty - if (workersSet.empty()) - { - HICR_THROW_LOGIC("Error: no compute resources provided\n"); - } - - // Specify the compute Managers - if(_str == "nosv") - { - // Initialize nosv - check(nosv_init()); - - // nosv task instance for the main thread - nosv_task_t mainTask; - - // Attaching the main thread - check(nosv_attach(&mainTask, NULL, NULL, NOSV_ATTACH_NONE)); - - _executionStateComputeManager = std::make_unique(); - _processingUnitComputeManager = std::make_unique(); - } - else if(_str == "threading") - { - _executionStateComputeManager = std::make_unique(); - _processingUnitComputeManager = std::make_unique(); - } - else - { - HICR_THROW_LOGIC("'%s' is not a known HiCR backend. Try 'nosv' or 'threading'\n", str); - } - - // Reserving memory for hwloc - hwloc_topology_init(&_topology); - - // Initializing HWLoc-based host (CPU) topology manager - HiCR::backend::hwloc::TopologyManager tm(&_topology); - - // Asking backend to check the available devices - const auto t = tm.queryTopology(); - - // Getting compute resource lists from devices - std::vector computeResourceLists; - for (auto d : t.getDevices()) computeResourceLists.push_back(d->getComputeResourceList()); - - // Create processing units from the detected compute resource list and giving them to taskr - HiCR::Device::computeResourceList_t _computeResources; - for (auto computeResourceList : computeResourceLists) - for (auto computeResource : computeResourceList) - { - // Interpreting compute resource as core - auto core = dynamic_pointer_cast(computeResource); - - // If the core affinity is included in the list, Add it to the list - if (workersSet.contains(core->getProcessorId())) _computeResources.push_back(computeResource); - } - - if(!_computeResources.size()){ - HICR_THROW_LOGIC("Error: non-existing compute resources provided\n"); - } - - _num_workers = _computeResources.size(); - - _runtime = std::make_unique(_executionStateComputeManager.get(), _processingUnitComputeManager.get(), _computeResources); - - // _runtime->setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskSuspend, [this](taskr::Task *task) { this->_runtime->resumeTask(task); }); + _computeResources.push_back(*itr); + itr++; } - /** + _num_workers = num_workers; + + _runtime = std::make_unique(_executionStateComputeManager.get(), _processingUnitComputeManager.get(), _computeResources); + + // _runtime->setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskSuspend, [this](taskr::Task *task) { printf("resume task\n"); fflush(stdout); this->_runtime->resumeTask(task); }); + } + + /** * - */ - ~PyRuntime() + */ + PyRuntime(const std::string &str, const std::set &workersSet) + : _str(str) + { + // Check if the workerSet is not empty + if (workersSet.empty()) { HICR_THROW_LOGIC("Error: no compute resources provided\n"); } + + // Specify the compute Managers + if (_str == "nosv") { - printf("Destructor being called for %s\n", _str.c_str()); - // Freeing up memory - hwloc_topology_destroy(_topology); - - if(_str == "nosv") - { - // Detaching the main thread - check(nosv_detach(NOSV_DETACH_NONE)); - - // Shutdown nosv - check(nosv_shutdown()); - } + // Initialize nosv + check(nosv_init()); + + // nosv task instance for the main thread + nosv_task_t mainTask; + + // Attaching the main thread + check(nosv_attach(&mainTask, NULL, NULL, NOSV_ATTACH_NONE)); + + _executionStateComputeManager = std::make_unique(); + _processingUnitComputeManager = std::make_unique(); } - - Runtime& get_runtime() + else if (_str == "threading") { - return *_runtime; + _executionStateComputeManager = std::make_unique(); + _processingUnitComputeManager = std::make_unique(); } + else { HICR_THROW_LOGIC("'%s' is not a known HiCR backend. Try 'nosv' or 'threading'\n", str); } + + // Reserving memory for hwloc + hwloc_topology_init(&_topology); - const size_t get_num_workers() + // Initializing HWLoc-based host (CPU) topology manager + HiCR::backend::hwloc::TopologyManager tm(&_topology); + + // Asking backend to check the available devices + const auto t = tm.queryTopology(); + + // Getting compute resource lists from devices + std::vector computeResourceLists; + for (auto d : t.getDevices()) computeResourceLists.push_back(d->getComputeResourceList()); + + // Create processing units from the detected compute resource list and giving them to taskr + HiCR::Device::computeResourceList_t _computeResources; + for (auto computeResourceList : computeResourceLists) + for (auto computeResource : computeResourceList) + { + // Interpreting compute resource as core + auto core = dynamic_pointer_cast(computeResource); + + // If the core affinity is included in the list, Add it to the list + if (workersSet.contains(core->getProcessorId())) _computeResources.push_back(computeResource); + } + + if (!_computeResources.size()) { HICR_THROW_LOGIC("Error: non-existing compute resources provided\n"); } + + _num_workers = _computeResources.size(); + + _runtime = std::make_unique(_executionStateComputeManager.get(), _processingUnitComputeManager.get(), _computeResources); + + // _runtime->setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskSuspend, [this](taskr::Task *task) { this->_runtime->resumeTask(task); }); + } + + /** + * + */ + ~PyRuntime() + { + printf("Destructor being called for %s\n", _str.c_str()); + // Freeing up memory + hwloc_topology_destroy(_topology); + + if (_str == "nosv") { - return _num_workers; + // Detaching the main thread + check(nosv_detach(NOSV_DETACH_NONE)); + + // Shutdown nosv + check(nosv_shutdown()); } - - std::unique_ptr _runtime; - - private: - - const std::string _str; - - size_t _num_workers; - - std::unique_ptr _executionStateComputeManager; - - std::unique_ptr _processingUnitComputeManager; - - hwloc_topology_t _topology; - - const HiCR::Device::computeResourceList_t _computeResources; + } + + Runtime &get_runtime() { return *_runtime; } + + const size_t get_num_workers() { return _num_workers; } + + std::unique_ptr _runtime; + + private: + + const std::string _str; + + size_t _num_workers; + + std::unique_ptr _executionStateComputeManager; + + std::unique_ptr _processingUnitComputeManager; + + hwloc_topology_t _topology; + + const HiCR::Device::computeResourceList_t _computeResources; }; } // namespace taskr \ No newline at end of file diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index 2d3b0e5..650af1e 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -14,8 +14,8 @@ * limitations under the License. */ #include -#include // std::function -#include // std::set +#include // std::function +#include // std::set #include #include @@ -24,44 +24,44 @@ namespace py = pybind11; namespace taskr { - + // TODO: add all methods of all classes -void call_python_callback(py::function callback, Task* task) { - py::gil_scoped_acquire acquire; - callback(task); // Call the Python function safely +void call_python_callback(py::function callback, Task *task) +{ + py::gil_scoped_acquire acquire; + callback(task); // Call the Python function safely } PYBIND11_MODULE(taskr, m) { - m.doc() = "pybind11 plugin for TaskR"; + m.doc() = "pybind11 plugin for TaskR"; - m.def("call_python_callback", &call_python_callback, "blabla"); - - // pyTaskR's PyRuntime class - py::class_(m, "taskr") - .def(py::init(), py::arg("backend") = "threading", py::arg("num_workers") = 0) - .def(py::init&>(), py::arg("backend") = "threading", py::arg("workersSet")) + m.def("call_python_callback", &call_python_callback, "blabla"); + + // pyTaskR's PyRuntime class + py::class_(m, "taskr") + .def(py::init(), py::arg("backend") = "threading", py::arg("num_workers") = 0) + .def(py::init &>(), py::arg("backend") = "threading", py::arg("workersSet")) .def("get_runtime", &PyRuntime::get_runtime, py::return_value_policy::reference_internal) .def("get_num_workers", &PyRuntime::get_num_workers); - - // TaskR's Runtime class - py::class_(m, "Runtime") + + // TaskR's Runtime class + py::class_(m, "Runtime") .def("setTaskCallbackHandler", &Runtime::setTaskCallbackHandler) .def("initialize", &Runtime::initialize) - .def("addTask", &Runtime::addTask, py::keep_alive<1, 2>()) // keep_alive as the task should be alive until runtime's destructor + .def("addTask", &Runtime::addTask, py::keep_alive<1, 2>()) // keep_alive as the task should be alive until runtime's destructor .def("resumeTask", &Runtime::resumeTask) .def("run", &Runtime::run, py::call_guard()) .def("await_", &Runtime::await, py::call_guard()) // Release GIL is important otherwise non-finished tasks are getting blocked .def("finalize", &Runtime::finalize); - - // TaskR's Function class - py::class_(m, "Function") - .def(py::init()); - - // TaskR's Task class - py::class_(m, "Task") - .def(py::init(), py::arg("label"), py::arg("fc"), py::arg("workerAffinity") = -1) + + // TaskR's Function class + py::class_(m, "Function").def(py::init()); + + // TaskR's Task class + py::class_(m, "Task") + .def(py::init(), py::arg("label"), py::arg("fc"), py::arg("workerAffinity") = -1) .def("getLabel", &Task::getLabel) .def("setLabel", &Task::setLabel) .def("getWorkerAffinity", &Task::getWorkerAffinity) @@ -69,30 +69,30 @@ PYBIND11_MODULE(taskr, m) .def("addDependency", &Task::addDependency) .def("addPendingOperation", &Task::addPendingOperation) .def("suspend", &Task::suspend, py::call_guard()); - - py::enum_(m, "TaskCallback") + + py::enum_(m, "TaskCallback") .value("onTaskExecute", Task::callback_t::onTaskExecute) .value("onTaskSuspend", Task::callback_t::onTaskSuspend) .value("onTaskFinish", Task::callback_t::onTaskFinish) .value("onTaskSync", Task::callback_t::onTaskSync) .export_values(); - // TaskR's Mutex class - py::class_(m, "Mutex") - .def(py::init<>()) - .def("lock", &Mutex::lock) - .def("unlock", &Mutex::unlock); + // TaskR's Mutex class + py::class_(m, "Mutex").def(py::init<>()).def("lock", &Mutex::lock).def("unlock", &Mutex::unlock); - // TaskR's ConditionVariable class - py::class_(m, "ConditionVariable") + // TaskR's ConditionVariable class + py::class_(m, "ConditionVariable") .def(py::init<>()) - .def("wait", py::overload_cast(&ConditionVariable::wait), py::call_guard(), "cv wait") - .def("wait", py::overload_cast&>(&ConditionVariable::wait), py::call_guard(), "cv wait with condition") - .def("waitFor", py::overload_cast&, size_t>(&ConditionVariable::waitFor), py::call_guard(), "cv waitFor with condition") - .def("waitFor", py::overload_cast(&ConditionVariable::waitFor), py::call_guard(), "cv waitFor") - .def("notifyOne", &ConditionVariable::notifyOne) // Not sure if I need to release the GIL here as this function also uses the intern mutex lock - .def("notifyAll", &ConditionVariable::notifyAll) // Same here + .def("wait", py::overload_cast(&ConditionVariable::wait), py::call_guard(), "cv wait") + .def("wait", py::overload_cast &>(&ConditionVariable::wait), py::call_guard(), "cv wait with condition") + .def("waitFor", + py::overload_cast &, size_t>(&ConditionVariable::waitFor), + py::call_guard(), + "cv waitFor with condition") + .def("waitFor", py::overload_cast(&ConditionVariable::waitFor), py::call_guard(), "cv waitFor") + .def("notifyOne", &ConditionVariable::notifyOne) // Not sure if I need to release the GIL here as this function also uses the intern mutex lock + .def("notifyAll", &ConditionVariable::notifyAll) // Same here .def("getWaitingTaskCount", &ConditionVariable::getWaitingTaskCount); } -} \ No newline at end of file +} // namespace taskr \ No newline at end of file diff --git a/tests/pyruntime.cpp b/tests/pyruntime.cpp index b6f0546..0618fd5 100644 --- a/tests/pyruntime.cpp +++ b/tests/pyruntime.cpp @@ -21,12 +21,12 @@ int main(int argc, char **argv) { // Creating taskr instance taskr::PyRuntime pytaskr("nosv", 0); - + // Getting the runtime - taskr::Runtime& runtime = pytaskr.get_runtime(); - + taskr::Runtime &runtime = pytaskr.get_runtime(); + // Printing runtime printf("I got the runtime with nOS-V backend: %p\n", &runtime); - + return 0; } From eca18246159a8ffcf3467fb3c5fb609d4016c189 Mon Sep 17 00:00:00 2001 From: noabauma Date: Tue, 17 Jun 2025 15:00:25 +0200 Subject: [PATCH 20/27] adding enumerate method for choosing backend --- examples/local/abcTasks/py_source/main.py | 2 +- .../local/conditionVariable/py_source/main.py | 2 +- examples/local/energySaver/py_source/main.py | 2 +- examples/local/fibonacci/py_source/main.py | 2 +- examples/local/manyParallel/py_source/main.py | 2 +- examples/local/multiJob/py_source/main.py | 2 +- examples/local/mutex/py_source/main.py | 2 +- .../local/pendingOperation/py_source/main.py | 2 +- examples/local/resourceList/py_source/main.py | 2 +- examples/local/simple/py_source/main.py | 2 +- examples/local/suspend/py_source/main.py | 2 +- .../local/workerSpecific/py_source/main.py | 2 +- extern/tracr | 2 +- include/pytaskr/pyruntime.hpp | 53 +++++++++++-------- include/pytaskr/pytaskr.cpp | 19 +++---- meson.build | 15 ++++-- tests/pyruntime.cpp | 2 +- 17 files changed, 63 insertions(+), 52 deletions(-) diff --git a/examples/local/abcTasks/py_source/main.py b/examples/local/abcTasks/py_source/main.py index e63d2be..f98711d 100644 --- a/examples/local/abcTasks/py_source/main.py +++ b/examples/local/abcTasks/py_source/main.py @@ -4,7 +4,7 @@ def main(): # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("threading", 2) + t = taskr.taskr(taskr.HiCRBackend.threading, 2) # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/conditionVariable/py_source/main.py b/examples/local/conditionVariable/py_source/main.py index 44813cf..cba7c78 100644 --- a/examples/local/conditionVariable/py_source/main.py +++ b/examples/local/conditionVariable/py_source/main.py @@ -26,7 +26,7 @@ def main(): # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("nosv") + t = taskr.taskr() # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/energySaver/py_source/main.py b/examples/local/energySaver/py_source/main.py index f20b728..c74f87c 100644 --- a/examples/local/energySaver/py_source/main.py +++ b/examples/local/energySaver/py_source/main.py @@ -30,7 +30,7 @@ def main(): print(sys.argv, workTaskCount, secondsDelay, iterations) # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("threading") + t = taskr.taskr(taskr.HiCRBackend.threading) # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/fibonacci/py_source/main.py b/examples/local/fibonacci/py_source/main.py index 0644270..4da0092 100644 --- a/examples/local/fibonacci/py_source/main.py +++ b/examples/local/fibonacci/py_source/main.py @@ -25,7 +25,7 @@ def main(): if len(sys.argv) > 1: initialValue = int(sys.argv[1]) # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("nosv") + t = taskr.taskr(taskr.HiCRBackend.nosv) # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/manyParallel/py_source/main.py b/examples/local/manyParallel/py_source/main.py index 3dc9957..92932be 100644 --- a/examples/local/manyParallel/py_source/main.py +++ b/examples/local/manyParallel/py_source/main.py @@ -26,7 +26,7 @@ def main(): if len(sys.argv) > 2: branchCount = int(sys.argv[2]) # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("threading") + t = taskr.taskr(taskr.HiCRBackend.threading) # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/multiJob/py_source/main.py b/examples/local/multiJob/py_source/main.py index 22af784..a653ff6 100644 --- a/examples/local/multiJob/py_source/main.py +++ b/examples/local/multiJob/py_source/main.py @@ -22,7 +22,7 @@ def main(): # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("threading") + t = taskr.taskr(taskr.HiCRBackend.threading) # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/mutex/py_source/main.py b/examples/local/mutex/py_source/main.py index 1ea2e8b..6a7f00a 100644 --- a/examples/local/mutex/py_source/main.py +++ b/examples/local/mutex/py_source/main.py @@ -20,7 +20,7 @@ def main(): # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("threading") + t = taskr.taskr(taskr.HiCRBackend.threading) # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/pendingOperation/py_source/main.py b/examples/local/pendingOperation/py_source/main.py index 0ef713b..10fd765 100644 --- a/examples/local/pendingOperation/py_source/main.py +++ b/examples/local/pendingOperation/py_source/main.py @@ -20,7 +20,7 @@ def main(): # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("nosv") + t = taskr.taskr(taskr.HiCRBackend.nosv) # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/resourceList/py_source/main.py b/examples/local/resourceList/py_source/main.py index 984c1e3..bca700c 100644 --- a/examples/local/resourceList/py_source/main.py +++ b/examples/local/resourceList/py_source/main.py @@ -41,7 +41,7 @@ def main(): sys.exit(1) # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("threading", coreSubset) + t = taskr.taskr(taskr.HiCRBackend.threading, coreSubset) # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/simple/py_source/main.py b/examples/local/simple/py_source/main.py index 94b88e1..63efd91 100644 --- a/examples/local/simple/py_source/main.py +++ b/examples/local/simple/py_source/main.py @@ -19,7 +19,7 @@ def main(): # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("nosv") + t = taskr.taskr(taskr.HiCRBackend.nosv, 2) # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/suspend/py_source/main.py b/examples/local/suspend/py_source/main.py index 0cb600a..aed145d 100644 --- a/examples/local/suspend/py_source/main.py +++ b/examples/local/suspend/py_source/main.py @@ -27,7 +27,7 @@ def main(): if len(sys.argv) > 2: branchCount = int(sys.argv[2]) # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("nosv") + t = taskr.taskr(taskr.HiCRBackend.nosv) # Get the runtime runtime = t.get_runtime() diff --git a/examples/local/workerSpecific/py_source/main.py b/examples/local/workerSpecific/py_source/main.py index cb6f8bc..9c53839 100644 --- a/examples/local/workerSpecific/py_source/main.py +++ b/examples/local/workerSpecific/py_source/main.py @@ -20,7 +20,7 @@ def main(): # Initialize taskr with the wanted compute manager backend and number of PUs - t = taskr.taskr("nosv") + t = taskr.taskr() # Get the runtime runtime = t.get_runtime() diff --git a/extern/tracr b/extern/tracr index f60f505..5f46dca 160000 --- a/extern/tracr +++ b/extern/tracr @@ -1 +1 @@ -Subproject commit f60f505f13ad6b56e607c555ef239af2d238c3b6 +Subproject commit 5f46dca3692c210516d7b8415cb6aa172e8e13ba diff --git a/include/pytaskr/pyruntime.hpp b/include/pytaskr/pyruntime.hpp index f5c2663..8d25b8e 100644 --- a/include/pytaskr/pyruntime.hpp +++ b/include/pytaskr/pyruntime.hpp @@ -34,19 +34,32 @@ namespace taskr { +enum backend_t +{ + /** + * HiCR's nOS-V backend with the executionStates and ProcessingUnits being nOS-V + */ + nosv, + + /** + * executionStates are Boost and ProcessingUnits are Pthreads + */ + threading +}; + + class PyRuntime { public: /** - * + * */ - PyRuntime(const std::string &str = "threading", size_t num_workers = 0) - : _str(str) + PyRuntime(const backend_t& backend_type = backend_t::nosv, size_t num_workers = 0) + : _backend_type(backend_type) { - printf("Constructor being called for %s\n", _str.c_str()); // Specify the compute Managers - if (_str == "nosv") + if (_backend_type == backend_t::nosv) { // Initialize nosv check(nosv_init()); @@ -60,12 +73,12 @@ class PyRuntime _executionStateComputeManager = std::make_unique(); _processingUnitComputeManager = std::make_unique(); } - else if (_str == "threading") + else if (_backend_type == backend_t::threading) { _executionStateComputeManager = std::make_unique(); _processingUnitComputeManager = std::make_unique(); } - else { HICR_THROW_LOGIC("'%s' is not a known HiCR backend. Try 'nosv' or 'threading'\n", str); } + else { HICR_THROW_LOGIC("'%d' is not a known HiCR backend. Try 'nosv' or 'threading'\n", _backend_type); } // Reserving memory for hwloc hwloc_topology_init(&_topology); @@ -97,21 +110,19 @@ class PyRuntime _num_workers = num_workers; _runtime = std::make_unique(_executionStateComputeManager.get(), _processingUnitComputeManager.get(), _computeResources); - - // _runtime->setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskSuspend, [this](taskr::Task *task) { printf("resume task\n"); fflush(stdout); this->_runtime->resumeTask(task); }); } /** - * + * */ - PyRuntime(const std::string &str, const std::set &workersSet) - : _str(str) + PyRuntime(const backend_t& backend_type, const std::set &workersSet) + : _backend_type(backend_type) { // Check if the workerSet is not empty if (workersSet.empty()) { HICR_THROW_LOGIC("Error: no compute resources provided\n"); } // Specify the compute Managers - if (_str == "nosv") + if (_backend_type == backend_t::nosv) { // Initialize nosv check(nosv_init()); @@ -125,12 +136,12 @@ class PyRuntime _executionStateComputeManager = std::make_unique(); _processingUnitComputeManager = std::make_unique(); } - else if (_str == "threading") + else if (_backend_type == backend_t::threading) { _executionStateComputeManager = std::make_unique(); _processingUnitComputeManager = std::make_unique(); } - else { HICR_THROW_LOGIC("'%s' is not a known HiCR backend. Try 'nosv' or 'threading'\n", str); } + else { HICR_THROW_LOGIC("'%d' is not a known HiCR backend. Try 'nosv' or 'threading'\n", _backend_type); } // Reserving memory for hwloc hwloc_topology_init(&_topology); @@ -162,20 +173,18 @@ class PyRuntime _num_workers = _computeResources.size(); _runtime = std::make_unique(_executionStateComputeManager.get(), _processingUnitComputeManager.get(), _computeResources); - - // _runtime->setTaskCallbackHandler(HiCR::tasking::Task::callback_t::onTaskSuspend, [this](taskr::Task *task) { this->_runtime->resumeTask(task); }); } /** - * - */ + * Destructor + * Destroying topology and shutting down nOS-V if nosv backend have been used. + */ ~PyRuntime() { - printf("Destructor being called for %s\n", _str.c_str()); // Freeing up memory hwloc_topology_destroy(_topology); - if (_str == "nosv") + if (_backend_type == backend_t::nosv) { // Detaching the main thread check(nosv_detach(NOSV_DETACH_NONE)); @@ -193,7 +202,7 @@ class PyRuntime private: - const std::string _str; + backend_t _backend_type; size_t _num_workers; diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index 650af1e..6138291 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -27,22 +27,19 @@ namespace taskr // TODO: add all methods of all classes -void call_python_callback(py::function callback, Task *task) -{ - py::gil_scoped_acquire acquire; - callback(task); // Call the Python function safely -} - PYBIND11_MODULE(taskr, m) { m.doc() = "pybind11 plugin for TaskR"; - - m.def("call_python_callback", &call_python_callback, "blabla"); + + py::enum_(m, "HiCRBackend") + .value("nosv", backend_t::nosv) + .value("threading", backend_t::threading) + .export_values(); // pyTaskR's PyRuntime class py::class_(m, "taskr") - .def(py::init(), py::arg("backend") = "threading", py::arg("num_workers") = 0) - .def(py::init &>(), py::arg("backend") = "threading", py::arg("workersSet")) + .def(py::init(), py::arg("backend") = backend_t::nosv, py::arg("num_workers") = 0) + .def(py::init &>(), py::arg("backend") = backend_t::nosv, py::arg("workersSet")) .def("get_runtime", &PyRuntime::get_runtime, py::return_value_policy::reference_internal) .def("get_num_workers", &PyRuntime::get_num_workers); @@ -57,7 +54,7 @@ PYBIND11_MODULE(taskr, m) .def("finalize", &Runtime::finalize); // TaskR's Function class - py::class_(m, "Function").def(py::init()); + py::class_(m, "Function").def(py::init(), py::call_guard()); // TODO: experimental // TaskR's Task class py::class_(m, "Task") diff --git a/meson.build b/meson.build index 6694798..91f1afa 100644 --- a/meson.build +++ b/meson.build @@ -20,24 +20,26 @@ if meson.is_subproject() == false # Selecting default HiCR Backends HiCRBackends = ['hwloc'] + HiCR_ES_PU_Backends = [] if 'boost' in get_option('executionStateType') - HiCRBackends += ['boost'] + HiCR_ES_PU_Backends += ['boost'] endif if 'nosv' in get_option('executionStateType') - HiCRBackends += ['nosv'] + HiCR_ES_PU_Backends += ['nosv'] endif if 'pthreads' in get_option('processingUnitType') - HiCRBackends += ['pthreads'] + HiCR_ES_PU_Backends += ['pthreads'] endif if 'nosv' in get_option('processingUnitType') - if 'nosv' not in HiCRBackends - HiCRBackends += ['nosv'] + if 'nosv' not in HiCR_ES_PU_Backends + HiCR_ES_PU_Backends += ['nosv'] endif endif endif + HiCRBackends += HiCR_ES_PU_Backends # Getting selected distributed engine distributedEngine = get_option('distributedEngine') @@ -94,6 +96,9 @@ TaskRBuildDep = declare_dependency( ####### Build PyTaskR if get_option('buildPyTaskR') + message(HiCR_ES_PU_Backends) + assert(HiCR_ES_PU_Backends.length() == 3, 'To use pyTaskr, one has to enable all 4 backends: -DexecutionStateType=nosv,boost -DprocessingUnitType=nosv,pthreads') + subdir('include/pytaskr') endif diff --git a/tests/pyruntime.cpp b/tests/pyruntime.cpp index 0618fd5..52664a7 100644 --- a/tests/pyruntime.cpp +++ b/tests/pyruntime.cpp @@ -20,7 +20,7 @@ int main(int argc, char **argv) { // Creating taskr instance - taskr::PyRuntime pytaskr("nosv", 0); + taskr::PyRuntime pytaskr(taskr::backend_t::nosv, 0); // Getting the runtime taskr::Runtime &runtime = pytaskr.get_runtime(); From b4e038e90f6fc473a4589d50317263a70ab4292e Mon Sep 17 00:00:00 2001 From: noabauma Date: Mon, 23 Jun 2025 16:30:45 +0200 Subject: [PATCH 21/27] adding a method to add your own cpp functions to be executed over pytaskr --- examples/local/meson.build | 3 +- examples/local/mmm/README.rst | 7 +++ examples/local/mmm/meson.build | 11 ++++ examples/local/mmm/py_source/main.py | 33 ++++++++++ examples/local/mmm/py_source/mmm.py | 63 +++++++++++++++++++ examples/local/mmm/py_source/mmm_cpp.py | 41 +++++++++++++ examples/local/simple/py_source/simple.py | 4 -- extern/hicr | 2 +- include/pytaskr/meson.build | 2 +- include/pytaskr/mmm.cpp | 67 +++++++++++++++++++++ include/pytaskr/pyruntime.hpp | 8 +-- include/pytaskr/pytaskr.cpp | 44 ++++++++++++-- include/pytaskr/pytaskr.hpp | 35 +++++++++++ meson.build | 3 +- tests/meson.build | 4 +- tests/{pyruntime.cpp => pyruntime_test.cpp} | 0 16 files changed, 308 insertions(+), 19 deletions(-) create mode 100644 examples/local/mmm/README.rst create mode 100644 examples/local/mmm/meson.build create mode 100644 examples/local/mmm/py_source/main.py create mode 100644 examples/local/mmm/py_source/mmm.py create mode 100644 examples/local/mmm/py_source/mmm_cpp.py create mode 100644 include/pytaskr/mmm.cpp create mode 100644 include/pytaskr/pytaskr.hpp rename tests/{pyruntime.cpp => pyruntime_test.cpp} (100%) diff --git a/examples/local/meson.build b/examples/local/meson.build index f3188a4..ddf490b 100644 --- a/examples/local/meson.build +++ b/examples/local/meson.build @@ -10,4 +10,5 @@ subdir('pendingOperation') subdir('workerSpecific') subdir('manyParallel') subdir('suspend') -subdir('simple') \ No newline at end of file +subdir('simple') +subdir('mmm') \ No newline at end of file diff --git a/examples/local/mmm/README.rst b/examples/local/mmm/README.rst new file mode 100644 index 0000000..3211e05 --- /dev/null +++ b/examples/local/mmm/README.rst @@ -0,0 +1,7 @@ +ABC Tasks +============ + +A simple example for creating a task dependency-based runtime system using HiCR + +It creates and adds tasks in an arbitrary order. However, given the dependencies should force the output to always be an ordered sequence of A->B->C. This example makes sure TaskR is handling these dependencies correctly. + diff --git a/examples/local/mmm/meson.build b/examples/local/mmm/meson.build new file mode 100644 index 0000000..6673c02 --- /dev/null +++ b/examples/local/mmm/meson.build @@ -0,0 +1,11 @@ +testSuite = [ 'examples', 'local', 'mmmm' ] + +if get_option('buildPyTaskR') and get_option('buildTests') + test('pyTaskR', + py, + args : [ 'py_source/main.py' ], + is_parallel : false, + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], + suite: testSuite, + workdir: meson.current_source_dir()) +endif \ No newline at end of file diff --git a/examples/local/mmm/py_source/main.py b/examples/local/mmm/py_source/main.py new file mode 100644 index 0000000..756f8fd --- /dev/null +++ b/examples/local/mmm/py_source/main.py @@ -0,0 +1,33 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import taskr +# from mmm import mmmDriver +from mmm_cpp import mmm_cpp_Driver + +def main(): + # Initialize taskr with the wanted compute manager backend and number of PUs + t = taskr.taskr(taskr.HiCRBackend.nosv, 2) + + # Get the runtime + runtime = t.get_runtime() + + # Running mmm example + # mmmDriver(runtime) + mmm_cpp_Driver(runtime) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/local/mmm/py_source/mmm.py b/examples/local/mmm/py_source/mmm.py new file mode 100644 index 0000000..1ddc346 --- /dev/null +++ b/examples/local/mmm/py_source/mmm.py @@ -0,0 +1,63 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import time +import numpy as np +import taskr + +NTASKS = 2 + +N = 1000 + +def mmm(task): + A = np.zeros((N,N)) + B = np.empty((N,N)) + C = np.empty((N,N)) + + for i in range(N): + for j in range(N): + B[i, j] = i + C[i, j] = j + + B += task.getLabel()+1 + C += task.getLabel()+1 + + A = B @ C + print(f"Hello, I am task {task.getLabel()}") + + +def mmmDriver(runtime): + # Initializing taskr + runtime.initialize() + + taskfc = taskr.Function(mmm) + + # Adding to tasks to taskr + for i in range(NTASKS): + runtime.addTask(taskr.Task(i, taskfc, i)) + + # Running taskr for the current repetition + t_start = time.time() + runtime.run() + + # Waiting current repetition to end + runtime.await_() + t_duration = time.time() - t_start + + print(f"total time: {t_duration}s") + + # Finalizing taskr + runtime.finalize() \ No newline at end of file diff --git a/examples/local/mmm/py_source/mmm_cpp.py b/examples/local/mmm/py_source/mmm_cpp.py new file mode 100644 index 0000000..7f01a02 --- /dev/null +++ b/examples/local/mmm/py_source/mmm_cpp.py @@ -0,0 +1,41 @@ +""" + Copyright 2025 Huawei Technologies Co., Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import time +import taskr + +NTASKS = 2 + +def mmm_cpp_Driver(runtime): + # Initializing taskr + runtime.initialize() + + taskfc = taskr.get_cpp_function("cpp_mmm") + + # Adding to tasks to taskr + for i in range(NTASKS): + runtime.addTask(taskr.Task(i, taskfc)) + + # Running taskr for the current repetition + t_start = time.time() + runtime.run() + + # Waiting current repetition to end + runtime.await_() + print(f"total time: {time.time() - t_start}") + + # Finalizing taskr + runtime.finalize() \ No newline at end of file diff --git a/examples/local/simple/py_source/simple.py b/examples/local/simple/py_source/simple.py index f11bdb9..bcf9ef9 100644 --- a/examples/local/simple/py_source/simple.py +++ b/examples/local/simple/py_source/simple.py @@ -13,10 +13,6 @@ See the License for the specific language governing permissions and limitations under the License. """ -import ctypes - -libc = ctypes.CDLL("libc.so.6") -libc.sched_getcpu.restype = ctypes.c_int import taskr diff --git a/extern/hicr b/extern/hicr index d7939f7..de89eec 160000 --- a/extern/hicr +++ b/extern/hicr @@ -1 +1 @@ -Subproject commit d7939f71f5fd50ac3f6903246c9f118667a180b6 +Subproject commit de89eec1c608feda79d6139511612437e64eece7 diff --git a/include/pytaskr/meson.build b/include/pytaskr/meson.build index 0c69e5a..7328282 100644 --- a/include/pytaskr/meson.build +++ b/include/pytaskr/meson.build @@ -6,7 +6,7 @@ py = import('python').find_installation(pure: false) pybind11_dep = dependency('pybind11', required: true) py.extension_module('taskr', - 'pytaskr.cpp', + ['pytaskr.cpp', 'mmm.cpp'], install: true, dependencies : [TaskRBuildDep, pybind11_dep], ) \ No newline at end of file diff --git a/include/pytaskr/mmm.cpp b/include/pytaskr/mmm.cpp new file mode 100644 index 0000000..e0c96e2 --- /dev/null +++ b/include/pytaskr/mmm.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2025 Huawei Technologies Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include + +#define mytype float + +#define NTASKS 2 + +/** + * Compute mmm locally + */ +void mmm(taskr::Task *) { + const size_t N = 1000; + + // Allocate memory + volatile mytype *A = (mytype *)calloc(1, N * N * sizeof(mytype)); + volatile mytype *B = (mytype *)malloc(N * N * sizeof(mytype)); + volatile mytype *C = (mytype *)malloc(N * N * sizeof(mytype)); + + // Filling matrices B and C + for (size_t i = 0; i < N; ++i) { + for (size_t j = 0; j < N; ++j) { + B[i * N + j] = 1.0/(mytype(i + 1)); + C[i * N + j] = 1.0/(mytype(j + 1)); + } + } + + // mmm + for (size_t i = 0; i < N; ++i) { + for (size_t j = 0; j < N; ++j) { + for (size_t k = 0; k < N; ++k) { + A[i * N + j] += B[i * N + k] * C[k * N + j]; + } + } + } + + // free memory + free((mytype*)A); + free((mytype*)B); + free((mytype*)C); +} + +namespace taskr { + +__attribute__((constructor)) // GCC/Clang: Run before main/init +void register_my_func() { + register_function("cpp_mmm", mmm); +} + +} \ No newline at end of file diff --git a/include/pytaskr/pyruntime.hpp b/include/pytaskr/pyruntime.hpp index 8d25b8e..d2503f7 100644 --- a/include/pytaskr/pyruntime.hpp +++ b/include/pytaskr/pyruntime.hpp @@ -198,13 +198,13 @@ class PyRuntime const size_t get_num_workers() { return _num_workers; } - std::unique_ptr _runtime; - private: - + backend_t _backend_type; - + size_t _num_workers; + + std::unique_ptr _runtime; std::unique_ptr _executionStateComputeManager; diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index 6138291..701dd09 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include #include // std::function #include // std::set @@ -20,17 +21,45 @@ #include #include +#include "pytaskr.hpp" + namespace py = pybind11; namespace taskr { +std::vector& get_registry() { + static std::vector reg; + return reg; +} + +void register_function(const std::string& name, function_t fc) { + get_registry().push_back({name, fc}); +} + // TODO: add all methods of all classes PYBIND11_MODULE(taskr, m) { m.doc() = "pybind11 plugin for TaskR"; - + + // Register any other user defined functions + m.def("get_cpp_function", [](const std::string& name) { + auto& reg = taskr::get_registry(); + + // check if this function even exists + auto it = std::find_if(reg.begin(), reg.end(), + [&](const auto& e) { return e.name == name; }); + + if (it == reg.end()) HICR_THROW_RUNTIME("Function not found: %s\n", name); + + return std::make_unique(it->fc); + // [fc = it->fc](Task* task) { + + // fc(task); + // }); + }); + py::enum_(m, "HiCRBackend") .value("nosv", backend_t::nosv) .value("threading", backend_t::threading) @@ -54,7 +83,8 @@ PYBIND11_MODULE(taskr, m) .def("finalize", &Runtime::finalize); // TaskR's Function class - py::class_(m, "Function").def(py::init(), py::call_guard()); // TODO: experimental + py::class_(m, "Function") + .def(py::init()); // TaskR's Task class py::class_(m, "Task") @@ -80,8 +110,14 @@ PYBIND11_MODULE(taskr, m) // TaskR's ConditionVariable class py::class_(m, "ConditionVariable") .def(py::init<>()) - .def("wait", py::overload_cast(&ConditionVariable::wait), py::call_guard(), "cv wait") - .def("wait", py::overload_cast &>(&ConditionVariable::wait), py::call_guard(), "cv wait with condition") + .def("wait", + py::overload_cast(&ConditionVariable::wait), + py::call_guard(), + "cv wait") + .def("wait", + py::overload_cast &>(&ConditionVariable::wait), + py::call_guard(), + "cv wait with condition") .def("waitFor", py::overload_cast &, size_t>(&ConditionVariable::waitFor), py::call_guard(), diff --git a/include/pytaskr/pytaskr.hpp b/include/pytaskr/pytaskr.hpp new file mode 100644 index 0000000..c142874 --- /dev/null +++ b/include/pytaskr/pytaskr.hpp @@ -0,0 +1,35 @@ +/* + * Copyright 2025 Huawei Technologies Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace taskr +{ + +struct FunctionRegistration { + std::string name; + function_t fc; +}; + +std::vector& get_registry(); + +void register_function(const std::string& name, function_t fc); + + +} \ No newline at end of file diff --git a/meson.build b/meson.build index 91f1afa..e88ec4b 100644 --- a/meson.build +++ b/meson.build @@ -96,7 +96,6 @@ TaskRBuildDep = declare_dependency( ####### Build PyTaskR if get_option('buildPyTaskR') - message(HiCR_ES_PU_Backends) assert(HiCR_ES_PU_Backends.length() == 3, 'To use pyTaskr, one has to enable all 4 backends: -DexecutionStateType=nosv,boost -DprocessingUnitType=nosv,pthreads') subdir('include/pytaskr') @@ -116,4 +115,4 @@ if meson.is_subproject() == false subdir('tests') endif -endif +endif \ No newline at end of file diff --git a/tests/meson.build b/tests/meson.build index 5a4231a..0447553 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -29,7 +29,7 @@ if get_option('buildPyTaskR') testSuite = ['tests', 'pyruntime'] - pyruntime = executable('pyruntime', [ 'pyruntime.cpp'], dependencies: [ TaskRBuildDep ]) + pyruntime = executable('pyruntime_test', [ 'pyruntime_test.cpp'], dependencies: [ TaskRBuildDep ]) - test('pyruntime', pyruntime, args : [ ], suite: testSuite, workdir: pyruntime.path() + '.p' ) + test('pyruntime_test', pyruntime, args : [ ], suite: testSuite, workdir: pyruntime.path() + '.p' ) endif \ No newline at end of file diff --git a/tests/pyruntime.cpp b/tests/pyruntime_test.cpp similarity index 100% rename from tests/pyruntime.cpp rename to tests/pyruntime_test.cpp From e6c56b1597a92cebef5ab8d2823b21dae6f1662a Mon Sep 17 00:00:00 2001 From: noabauma Date: Mon, 23 Jun 2025 16:31:42 +0200 Subject: [PATCH 22/27] fixing style --- include/pytaskr/mmm.cpp | 39 ++++++++++++++++------------- include/pytaskr/pyruntime.hpp | 11 ++++----- include/pytaskr/pytaskr.cpp | 46 +++++++++++++---------------------- include/pytaskr/pytaskr.hpp | 16 ++++++------ 4 files changed, 52 insertions(+), 60 deletions(-) diff --git a/include/pytaskr/mmm.cpp b/include/pytaskr/mmm.cpp index e0c96e2..3f0730b 100644 --- a/include/pytaskr/mmm.cpp +++ b/include/pytaskr/mmm.cpp @@ -26,7 +26,8 @@ /** * Compute mmm locally */ -void mmm(taskr::Task *) { +void mmm(taskr::Task *) +{ const size_t N = 1000; // Allocate memory @@ -35,33 +36,37 @@ void mmm(taskr::Task *) { volatile mytype *C = (mytype *)malloc(N * N * sizeof(mytype)); // Filling matrices B and C - for (size_t i = 0; i < N; ++i) { - for (size_t j = 0; j < N; ++j) { - B[i * N + j] = 1.0/(mytype(i + 1)); - C[i * N + j] = 1.0/(mytype(j + 1)); + for (size_t i = 0; i < N; ++i) + { + for (size_t j = 0; j < N; ++j) + { + B[i * N + j] = 1.0 / (mytype(i + 1)); + C[i * N + j] = 1.0 / (mytype(j + 1)); } } // mmm - for (size_t i = 0; i < N; ++i) { - for (size_t j = 0; j < N; ++j) { - for (size_t k = 0; k < N; ++k) { - A[i * N + j] += B[i * N + k] * C[k * N + j]; - } + for (size_t i = 0; i < N; ++i) + { + for (size_t j = 0; j < N; ++j) + { + for (size_t k = 0; k < N; ++k) { A[i * N + j] += B[i * N + k] * C[k * N + j]; } } } // free memory - free((mytype*)A); - free((mytype*)B); - free((mytype*)C); + free((mytype *)A); + free((mytype *)B); + free((mytype *)C); } -namespace taskr { +namespace taskr +{ __attribute__((constructor)) // GCC/Clang: Run before main/init -void register_my_func() { - register_function("cpp_mmm", mmm); +void register_my_func() +{ + register_function("cpp_mmm", mmm); } -} \ No newline at end of file +} // namespace taskr \ No newline at end of file diff --git a/include/pytaskr/pyruntime.hpp b/include/pytaskr/pyruntime.hpp index d2503f7..854d12d 100644 --- a/include/pytaskr/pyruntime.hpp +++ b/include/pytaskr/pyruntime.hpp @@ -47,7 +47,6 @@ enum backend_t threading }; - class PyRuntime { public: @@ -55,7 +54,7 @@ class PyRuntime /** * */ - PyRuntime(const backend_t& backend_type = backend_t::nosv, size_t num_workers = 0) + PyRuntime(const backend_t &backend_type = backend_t::nosv, size_t num_workers = 0) : _backend_type(backend_type) { // Specify the compute Managers @@ -115,7 +114,7 @@ class PyRuntime /** * */ - PyRuntime(const backend_t& backend_type, const std::set &workersSet) + PyRuntime(const backend_t &backend_type, const std::set &workersSet) : _backend_type(backend_type) { // Check if the workerSet is not empty @@ -199,11 +198,11 @@ class PyRuntime const size_t get_num_workers() { return _num_workers; } private: - + backend_t _backend_type; - + size_t _num_workers; - + std::unique_ptr _runtime; std::unique_ptr _executionStateComputeManager; diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index 701dd09..4a4068c 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -28,14 +28,13 @@ namespace py = pybind11; namespace taskr { -std::vector& get_registry() { - static std::vector reg; - return reg; +std::vector &get_registry() +{ + static std::vector reg; + return reg; } -void register_function(const std::string& name, function_t fc) { - get_registry().push_back({name, fc}); -} +void register_function(const std::string &name, function_t fc) { get_registry().push_back({name, fc}); } // TODO: add all methods of all classes @@ -44,31 +43,27 @@ PYBIND11_MODULE(taskr, m) m.doc() = "pybind11 plugin for TaskR"; // Register any other user defined functions - m.def("get_cpp_function", [](const std::string& name) { - auto& reg = taskr::get_registry(); + m.def("get_cpp_function", [](const std::string &name) { + auto ® = taskr::get_registry(); // check if this function even exists - auto it = std::find_if(reg.begin(), reg.end(), - [&](const auto& e) { return e.name == name; }); + auto it = std::find_if(reg.begin(), reg.end(), [&](const auto &e) { return e.name == name; }); if (it == reg.end()) HICR_THROW_RUNTIME("Function not found: %s\n", name); return std::make_unique(it->fc); - // [fc = it->fc](Task* task) { + // [fc = it->fc](Task* task) { - // fc(task); - // }); + // fc(task); + // }); }); - py::enum_(m, "HiCRBackend") - .value("nosv", backend_t::nosv) - .value("threading", backend_t::threading) - .export_values(); + py::enum_(m, "HiCRBackend").value("nosv", backend_t::nosv).value("threading", backend_t::threading).export_values(); // pyTaskR's PyRuntime class py::class_(m, "taskr") - .def(py::init(), py::arg("backend") = backend_t::nosv, py::arg("num_workers") = 0) - .def(py::init &>(), py::arg("backend") = backend_t::nosv, py::arg("workersSet")) + .def(py::init(), py::arg("backend") = backend_t::nosv, py::arg("num_workers") = 0) + .def(py::init &>(), py::arg("backend") = backend_t::nosv, py::arg("workersSet")) .def("get_runtime", &PyRuntime::get_runtime, py::return_value_policy::reference_internal) .def("get_num_workers", &PyRuntime::get_num_workers); @@ -83,8 +78,7 @@ PYBIND11_MODULE(taskr, m) .def("finalize", &Runtime::finalize); // TaskR's Function class - py::class_(m, "Function") - .def(py::init()); + py::class_(m, "Function").def(py::init()); // TaskR's Task class py::class_(m, "Task") @@ -110,14 +104,8 @@ PYBIND11_MODULE(taskr, m) // TaskR's ConditionVariable class py::class_(m, "ConditionVariable") .def(py::init<>()) - .def("wait", - py::overload_cast(&ConditionVariable::wait), - py::call_guard(), - "cv wait") - .def("wait", - py::overload_cast &>(&ConditionVariable::wait), - py::call_guard(), - "cv wait with condition") + .def("wait", py::overload_cast(&ConditionVariable::wait), py::call_guard(), "cv wait") + .def("wait", py::overload_cast &>(&ConditionVariable::wait), py::call_guard(), "cv wait with condition") .def("waitFor", py::overload_cast &, size_t>(&ConditionVariable::waitFor), py::call_guard(), diff --git a/include/pytaskr/pytaskr.hpp b/include/pytaskr/pytaskr.hpp index c142874..b6b5ab4 100644 --- a/include/pytaskr/pytaskr.hpp +++ b/include/pytaskr/pytaskr.hpp @@ -19,17 +19,17 @@ #include #include -namespace taskr +namespace taskr { -struct FunctionRegistration { - std::string name; - function_t fc; +struct FunctionRegistration +{ + std::string name; + function_t fc; }; -std::vector& get_registry(); - -void register_function(const std::string& name, function_t fc); +std::vector &get_registry(); +void register_function(const std::string &name, function_t fc); -} \ No newline at end of file +} // namespace taskr \ No newline at end of file From bcad9f607960a11d5d8a2d0a1b5542df432f0da2 Mon Sep 17 00:00:00 2001 From: noabauma Date: Mon, 23 Jun 2025 16:41:50 +0200 Subject: [PATCH 23/27] removing redundant code --- include/pytaskr/pytaskr.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index 4a4068c..67d44d3 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -52,10 +52,6 @@ PYBIND11_MODULE(taskr, m) if (it == reg.end()) HICR_THROW_RUNTIME("Function not found: %s\n", name); return std::make_unique(it->fc); - // [fc = it->fc](Task* task) { - - // fc(task); - // }); }); py::enum_(m, "HiCRBackend").value("nosv", backend_t::nosv).value("threading", backend_t::threading).export_values(); From 75091e8945e6e16c46e6eea7ce1dcc7f63fb911c Mon Sep 17 00:00:00 2001 From: noabauma Date: Tue, 24 Jun 2025 10:16:46 +0200 Subject: [PATCH 24/27] code documentation and binding more TaskR methods --- .gitlab-ci.yml | 2 +- include/pytaskr/pyruntime.hpp | 12 +++++++++--- include/pytaskr/pytaskr.cpp | 26 ++++++++++++++++++++++---- include/pytaskr/pytaskr.hpp | 9 +++++++++ 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f3d169d..b1f7e11 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,7 +11,7 @@ build: - source /home/hicr/.hicr-env.sh - echo "Building TaskR..." - mkdir build - - meson setup build -Dbuildtype=debug -Db_coverage=true -DbuildTests=true -DbuildExamples=true -DdistributedEngine=mpi -DexecutionStateType=boost,nosv -DprocessingUnitType=pthreads,nosv -DbuildInstrumentation=true -DcompileWarningsAsErrors=true + - meson setup build -Dbuildtype=debug -Db_coverage=true -DbuildTests=true -DbuildExamples=true -DdistributedEngine=mpi -DexecutionStateType=boost,nosv -DprocessingUnitType=pthreads,nosv -DbuildInstrumentation=true -DbuildPyTaskR=true -DcompileWarningsAsErrors=true - meson compile -C build - echo "Running tests..." - meson test -C build diff --git a/include/pytaskr/pyruntime.hpp b/include/pytaskr/pyruntime.hpp index 854d12d..42b7d13 100644 --- a/include/pytaskr/pyruntime.hpp +++ b/include/pytaskr/pyruntime.hpp @@ -47,12 +47,15 @@ enum backend_t threading }; +/** + * TaskR Runtime class python wrapper. It simplifies the user for constructing the TaskR Runtime + */ class PyRuntime { public: /** - * + * Constructor with num_workers being an interger value. If 0, initialize all. */ PyRuntime(const backend_t &backend_type = backend_t::nosv, size_t num_workers = 0) : _backend_type(backend_type) @@ -112,7 +115,7 @@ class PyRuntime } /** - * + * Constructor with num_workers being a set of integers. The set specifies which process affinity to use (if available). */ PyRuntime(const backend_t &backend_type, const std::set &workersSet) : _backend_type(backend_type) @@ -169,13 +172,16 @@ class PyRuntime if (!_computeResources.size()) { HICR_THROW_LOGIC("Error: non-existing compute resources provided\n"); } + // Store the number of initialized workers _num_workers = _computeResources.size(); + // Initialize the runtime _runtime = std::make_unique(_executionStateComputeManager.get(), _processingUnitComputeManager.get(), _computeResources); } /** - * Destructor + * Destructor of PyRuntime + * * Destroying topology and shutting down nOS-V if nosv backend have been used. */ ~PyRuntime() diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index 67d44d3..02d241e 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -28,16 +28,23 @@ namespace py = pybind11; namespace taskr { +/** + * Vector to keep track which cpp functions to register + */ std::vector &get_registry() { static std::vector reg; return reg; } +/** + * Function to store the cpp function with a given naming + */ void register_function(const std::string &name, function_t fc) { get_registry().push_back({name, fc}); } -// TODO: add all methods of all classes - +/** + * Pybind11 module for binding taskr stuff + */ PYBIND11_MODULE(taskr, m) { m.doc() = "pybind11 plugin for TaskR"; @@ -66,25 +73,36 @@ PYBIND11_MODULE(taskr, m) // TaskR's Runtime class py::class_(m, "Runtime") .def("setTaskCallbackHandler", &Runtime::setTaskCallbackHandler) + .def("setServiceWorkerCallbackHandler", &Runtime::setServiceWorkerCallbackHandler) + .def("setTaskWorkerCallbackHandler", &Runtime::setTaskWorkerCallbackHandler) .def("initialize", &Runtime::initialize) .def("addTask", &Runtime::addTask, py::keep_alive<1, 2>()) // keep_alive as the task should be alive until runtime's destructor .def("resumeTask", &Runtime::resumeTask) .def("run", &Runtime::run, py::call_guard()) .def("await_", &Runtime::await, py::call_guard()) // Release GIL is important otherwise non-finished tasks are getting blocked - .def("finalize", &Runtime::finalize); + .def("finalize", &Runtime::finalize) + .def("setFinishedTask", &Runtime::setFinishedTask) + .def("addService", &Runtime::addService); // TaskR's Function class py::class_(m, "Function").def(py::init()); // TaskR's Task class py::class_(m, "Task") + .def(py::init(), py::arg("fc"), py::arg("workerAffinity") = -1) .def(py::init(), py::arg("label"), py::arg("fc"), py::arg("workerAffinity") = -1) .def("getLabel", &Task::getLabel) .def("setLabel", &Task::setLabel) .def("getWorkerAffinity", &Task::getWorkerAffinity) .def("setWorkerAffinity", &Task::setWorkerAffinity) .def("addDependency", &Task::addDependency) + .def("getDependencyCount", &Task::getDependencyCount) + .def("incrementDependencyCount", &Task::incrementDependencyCount) + .def("decrementDependencyCount", &Task::decrementDependencyCount) + .def("addOutputDependency", &Task::addOutputDependency) + .def("getOutputDependencies", &Task::getOutputDependencies) .def("addPendingOperation", &Task::addPendingOperation) + .def("getPendingOperations", &Task::getPendingOperations) .def("suspend", &Task::suspend, py::call_guard()); py::enum_(m, "TaskCallback") @@ -95,7 +113,7 @@ PYBIND11_MODULE(taskr, m) .export_values(); // TaskR's Mutex class - py::class_(m, "Mutex").def(py::init<>()).def("lock", &Mutex::lock).def("unlock", &Mutex::unlock); + py::class_(m, "Mutex").def(py::init<>()).def("lock", &Mutex::lock).def("unlock", &Mutex::unlock).def("ownsLock", &Mutex::ownsLock).def("trylock", &Mutex::trylock); // TaskR's ConditionVariable class py::class_(m, "ConditionVariable") diff --git a/include/pytaskr/pytaskr.hpp b/include/pytaskr/pytaskr.hpp index b6b5ab4..981f07d 100644 --- a/include/pytaskr/pytaskr.hpp +++ b/include/pytaskr/pytaskr.hpp @@ -22,14 +22,23 @@ namespace taskr { +/** + * Struct with the cpp funcion and the given name + */ struct FunctionRegistration { std::string name; function_t fc; }; +/** + * Vector to keep track which cpp functions to register + */ std::vector &get_registry(); +/** + * Function to store the cpp function with a given naming + */ void register_function(const std::string &name, function_t fc); } // namespace taskr \ No newline at end of file From c6f298c663d215db5e3c19ef4b1b8b01418461f0 Mon Sep 17 00:00:00 2001 From: noabauma Date: Wed, 2 Jul 2025 11:29:51 +0200 Subject: [PATCH 25/27] renamed a lot of files and minor corrections (all from the first review) --- .gitmodules | 2 +- examples/{local => }/abcTasks/README.rst | 0 .../source => abcTasks/cpp}/abcTasks.hpp | 0 .../abcTasks/source => abcTasks/cpp}/nosv.cpp | 0 .../source => abcTasks/cpp}/pthreads.cpp | 0 examples/{local => }/abcTasks/meson.build | 8 +-- .../py_source => abcTasks/python}/abcTasks.py | 0 .../py_source => abcTasks/python}/main.py | 0 examples/{local => }/cholesky/README.md | 0 examples/{local => }/cholesky/meson.build | 2 +- .../{local => }/cholesky/ompss/cholesky.hpp | 0 examples/{local => }/cholesky/ompss/init.hpp | 0 examples/{local => }/cholesky/ompss/main.cpp | 0 .../{local => }/cholesky/ompss/meson.build | 2 +- .../{local => }/cholesky/ompss/verify.hpp | 0 .../cholesky/sequential/cholesky.hpp | 0 .../{local => }/cholesky/sequential/init.hpp | 0 .../{local => }/cholesky/sequential/main.cpp | 0 .../cholesky/sequential/meson.build | 2 +- .../cholesky/sequential/verify.hpp | 0 .../{local => }/cholesky/source/cholesky.hpp | 0 examples/{local => }/cholesky/source/init.hpp | 0 examples/{local => }/cholesky/source/nosv.cpp | 0 .../{local => }/cholesky/source/pthreads.cpp | 0 .../{local => }/cholesky/source/verify.hpp | 0 examples/{local => }/cholesky/utils.hpp | 0 .../{local => }/conditionVariable/README.rst | 0 .../cpp}/conditionVariableWait.hpp | 0 .../cpp}/conditionVariableWaitCondition.hpp | 0 .../cpp}/conditionVariableWaitFor.hpp | 0 .../conditionVariableWaitForCondition.hpp | 0 .../source => conditionVariable/cpp}/nosv.cpp | 0 .../cpp}/pthreads.cpp | 0 .../{local => }/conditionVariable/meson.build | 26 +++---- .../python}/conditionVariableWait.py | 0 .../python}/conditionVariableWaitCondition.py | 0 .../python}/conditionVariableWaitFor.py | 0 .../conditionVariableWaitForCondition.py | 0 .../python}/main.py | 0 examples/distributed/meson.build | 15 ---- examples/distributed/pingPong/meson.build | 9 --- examples/{local => }/energySaver/README.rst | 0 .../source => energySaver/cpp}/nosv.cpp | 0 .../source => energySaver/cpp}/pthreads.cpp | 0 examples/{local => }/energySaver/meson.build | 8 +-- .../python}/energySaver.py | 0 .../py_source => energySaver/python}/main.py | 0 examples/{local => }/fibonacci/README.md | 0 .../source => fibonacci/cpp}/fibonacci.hpp | 0 .../source => fibonacci/cpp}/nosv.cpp | 0 .../source => fibonacci/cpp}/pthreads.cpp | 0 examples/{local => }/fibonacci/meson.build | 8 +-- .../python}/fibonacci.py | 0 .../python}/fibonacci_mutex.py | 0 .../py_source => fibonacci/python}/main.py | 0 .../{distributed => }/jacobi3d/.gitignore | 0 examples/{distributed => }/jacobi3d/README.md | 0 .../{distributed => }/jacobi3d/meson.build | 2 +- .../{distributed => }/jacobi3d/mpi/Makefile | 0 .../{distributed => }/jacobi3d/mpi/grid.cpp | 0 .../{distributed => }/jacobi3d/mpi/grid.hpp | 0 .../{distributed => }/jacobi3d/mpi/jacobi.cpp | 0 .../jacobi3d/source/grid.cpp | 0 .../jacobi3d/source/grid.hpp | 0 .../jacobi3d/source/nosv.cpp | 0 .../jacobi3d/source/pthreads.cpp | 0 .../jacobi3d/source/task.hpp | 0 examples/local/meson.build | 14 ---- examples/local/mmm/py_source/mmm.py | 63 ----------------- examples/local/multiJob/meson.build | 27 ------- examples/local/simple/README.rst | 7 -- examples/{local => }/manyParallel/README.rst | 0 .../cpp}/manyParallel.hpp | 0 .../source => manyParallel/cpp}/nosv.cpp | 0 .../source => manyParallel/cpp}/pthreads.cpp | 0 .../suspend => manyParallel}/meson.build | 8 +-- .../py_source => manyParallel/python}/main.py | 0 .../python}/manyParallel.py | 0 examples/matmul/README.rst | 8 +++ examples/{local/mmm => matmul}/meson.build | 4 +- .../mmm/py_source => matmul/python}/main.py | 11 +-- examples/matmul/python/matmul.cpp | 70 +++++++++++++++++++ .../mmm_cpp.py => matmul/python/matmul.py} | 46 +++++++++++- examples/meson.build | 32 ++++++++- examples/{local/mmm => multiJob}/README.rst | 0 .../multiJob/source => multiJob/cpp}/job1.cpp | 0 .../multiJob/source => multiJob/cpp}/job2.cpp | 0 .../multiJob/source => multiJob/cpp}/jobs.hpp | 0 .../multiJob/source => multiJob/cpp}/nosv.cpp | 0 .../source => multiJob/cpp}/pthreads.cpp | 0 examples/multiJob/meson.build | 27 +++++++ .../py_source => multiJob/python}/job1.py | 0 .../py_source => multiJob/python}/job2.py | 0 .../py_source => multiJob/python}/main.py | 0 examples/{local/multiJob => mutex}/README.rst | 0 .../mutex/source => mutex/cpp}/mutex.hpp | 0 .../mutex/source => mutex/cpp}/nosv.cpp | 0 .../mutex/source => mutex/cpp}/pthreads.cpp | 0 examples/{local/simple => mutex}/meson.build | 8 +-- .../mutex/py_source => mutex/python}/main.py | 0 .../mutex/py_source => mutex/python}/mutex.py | 0 .../{local => }/pendingOperation/README.rst | 0 .../source => pendingOperation/cpp}/nosv.cpp | 0 .../cpp}/pendingOperation.hpp | 0 .../cpp}/pthreads.cpp | 0 .../mutex => pendingOperation}/meson.build | 8 +-- .../python}/main.py | 0 .../python}/pendingOperation.py | 0 examples/{local => }/resourceList/README.rst | 0 .../source => resourceList/cpp}/nosv.cpp | 2 +- .../source => resourceList/cpp}/pthreads.cpp | 2 +- .../source => resourceList/cpp}/workTask.hpp | 0 examples/{local => }/resourceList/meson.build | 8 +-- .../py_source => resourceList/python}/main.py | 0 .../python}/workTask.py | 0 examples/{local/mutex => simple}/README.rst | 0 .../simple/source => simple/cpp}/nosv.cpp | 0 .../simple/source => simple/cpp}/pthreads.cpp | 0 .../simple/source => simple/cpp}/simple.hpp | 0 .../workerSpecific => simple}/meson.build | 8 +-- .../py_source => simple/python}/main.py | 0 .../py_source => simple/python}/simple.py | 0 examples/{local => }/suspend/README.rst | 0 .../suspend/source => suspend/cpp}/nosv.cpp | 0 .../source => suspend/cpp}/pthreads.cpp | 0 .../source => suspend/cpp}/suspend.hpp | 0 .../manyParallel => suspend}/meson.build | 8 +-- .../py_source => suspend/python}/main.py | 0 .../py_source => suspend/python}/suspend.py | 0 .../{local => }/workerSpecific/README.rst | 0 .../source => workerSpecific/cpp}/nosv.cpp | 0 .../cpp}/pthreads.cpp | 0 .../cpp}/workerSpecific.hpp | 0 .../meson.build | 8 +-- .../python}/main.py | 0 .../python}/workerSpecific.py | 0 extern/hicr | 2 +- extern/tracr | 2 +- include/pytaskr/{mmm.cpp => matmul.cpp} | 4 +- include/pytaskr/meson.build | 2 +- meson.build | 21 +++--- 141 files changed, 265 insertions(+), 219 deletions(-) rename examples/{local => }/abcTasks/README.rst (100%) rename examples/{local/abcTasks/source => abcTasks/cpp}/abcTasks.hpp (100%) rename examples/{local/abcTasks/source => abcTasks/cpp}/nosv.cpp (100%) rename examples/{local/abcTasks/source => abcTasks/cpp}/pthreads.cpp (100%) rename examples/{local => }/abcTasks/meson.build (73%) rename examples/{local/abcTasks/py_source => abcTasks/python}/abcTasks.py (100%) rename examples/{local/abcTasks/py_source => abcTasks/python}/main.py (100%) rename examples/{local => }/cholesky/README.md (100%) rename examples/{local => }/cholesky/meson.build (95%) rename examples/{local => }/cholesky/ompss/cholesky.hpp (100%) rename examples/{local => }/cholesky/ompss/init.hpp (100%) rename examples/{local => }/cholesky/ompss/main.cpp (100%) rename examples/{local => }/cholesky/ompss/meson.build (88%) rename examples/{local => }/cholesky/ompss/verify.hpp (100%) rename examples/{local => }/cholesky/sequential/cholesky.hpp (100%) rename examples/{local => }/cholesky/sequential/init.hpp (100%) rename examples/{local => }/cholesky/sequential/main.cpp (100%) rename examples/{local => }/cholesky/sequential/meson.build (86%) rename examples/{local => }/cholesky/sequential/verify.hpp (100%) rename examples/{local => }/cholesky/source/cholesky.hpp (100%) rename examples/{local => }/cholesky/source/init.hpp (100%) rename examples/{local => }/cholesky/source/nosv.cpp (100%) rename examples/{local => }/cholesky/source/pthreads.cpp (100%) rename examples/{local => }/cholesky/source/verify.hpp (100%) rename examples/{local => }/cholesky/utils.hpp (100%) rename examples/{local => }/conditionVariable/README.rst (100%) rename examples/{local/conditionVariable/source => conditionVariable/cpp}/conditionVariableWait.hpp (100%) rename examples/{local/conditionVariable/source => conditionVariable/cpp}/conditionVariableWaitCondition.hpp (100%) rename examples/{local/conditionVariable/source => conditionVariable/cpp}/conditionVariableWaitFor.hpp (100%) rename examples/{local/conditionVariable/source => conditionVariable/cpp}/conditionVariableWaitForCondition.hpp (100%) rename examples/{local/conditionVariable/source => conditionVariable/cpp}/nosv.cpp (100%) rename examples/{local/conditionVariable/source => conditionVariable/cpp}/pthreads.cpp (100%) rename examples/{local => }/conditionVariable/meson.build (71%) rename examples/{local/conditionVariable/py_source => conditionVariable/python}/conditionVariableWait.py (100%) rename examples/{local/conditionVariable/py_source => conditionVariable/python}/conditionVariableWaitCondition.py (100%) rename examples/{local/conditionVariable/py_source => conditionVariable/python}/conditionVariableWaitFor.py (100%) rename examples/{local/conditionVariable/py_source => conditionVariable/python}/conditionVariableWaitForCondition.py (100%) rename examples/{local/conditionVariable/py_source => conditionVariable/python}/main.py (100%) delete mode 100644 examples/distributed/meson.build delete mode 100644 examples/distributed/pingPong/meson.build rename examples/{local => }/energySaver/README.rst (100%) rename examples/{local/energySaver/source => energySaver/cpp}/nosv.cpp (100%) rename examples/{local/energySaver/source => energySaver/cpp}/pthreads.cpp (100%) rename examples/{local => }/energySaver/meson.build (74%) rename examples/{local/energySaver/py_source => energySaver/python}/energySaver.py (100%) rename examples/{local/energySaver/py_source => energySaver/python}/main.py (100%) rename examples/{local => }/fibonacci/README.md (100%) rename examples/{local/fibonacci/source => fibonacci/cpp}/fibonacci.hpp (100%) rename examples/{local/fibonacci/source => fibonacci/cpp}/nosv.cpp (100%) rename examples/{local/fibonacci/source => fibonacci/cpp}/pthreads.cpp (100%) rename examples/{local => }/fibonacci/meson.build (73%) rename examples/{local/fibonacci/py_source => fibonacci/python}/fibonacci.py (100%) rename examples/{local/fibonacci/py_source => fibonacci/python}/fibonacci_mutex.py (100%) rename examples/{local/fibonacci/py_source => fibonacci/python}/main.py (100%) rename examples/{distributed => }/jacobi3d/.gitignore (100%) rename examples/{distributed => }/jacobi3d/README.md (100%) rename examples/{distributed => }/jacobi3d/meson.build (93%) rename examples/{distributed => }/jacobi3d/mpi/Makefile (100%) rename examples/{distributed => }/jacobi3d/mpi/grid.cpp (100%) rename examples/{distributed => }/jacobi3d/mpi/grid.hpp (100%) rename examples/{distributed => }/jacobi3d/mpi/jacobi.cpp (100%) rename examples/{distributed => }/jacobi3d/source/grid.cpp (100%) rename examples/{distributed => }/jacobi3d/source/grid.hpp (100%) rename examples/{distributed => }/jacobi3d/source/nosv.cpp (100%) rename examples/{distributed => }/jacobi3d/source/pthreads.cpp (100%) rename examples/{distributed => }/jacobi3d/source/task.hpp (100%) delete mode 100644 examples/local/meson.build delete mode 100644 examples/local/mmm/py_source/mmm.py delete mode 100644 examples/local/multiJob/meson.build delete mode 100644 examples/local/simple/README.rst rename examples/{local => }/manyParallel/README.rst (100%) rename examples/{local/manyParallel/source => manyParallel/cpp}/manyParallel.hpp (100%) rename examples/{local/manyParallel/source => manyParallel/cpp}/nosv.cpp (100%) rename examples/{local/manyParallel/source => manyParallel/cpp}/pthreads.cpp (100%) rename examples/{local/suspend => manyParallel}/meson.build (74%) rename examples/{local/manyParallel/py_source => manyParallel/python}/main.py (100%) rename examples/{local/manyParallel/py_source => manyParallel/python}/manyParallel.py (100%) create mode 100644 examples/matmul/README.rst rename examples/{local/mmm => matmul}/meson.build (76%) rename examples/{local/mmm/py_source => matmul/python}/main.py (84%) create mode 100644 examples/matmul/python/matmul.cpp rename examples/{local/mmm/py_source/mmm_cpp.py => matmul/python/matmul.py} (54%) rename examples/{local/mmm => multiJob}/README.rst (100%) rename examples/{local/multiJob/source => multiJob/cpp}/job1.cpp (100%) rename examples/{local/multiJob/source => multiJob/cpp}/job2.cpp (100%) rename examples/{local/multiJob/source => multiJob/cpp}/jobs.hpp (100%) rename examples/{local/multiJob/source => multiJob/cpp}/nosv.cpp (100%) rename examples/{local/multiJob/source => multiJob/cpp}/pthreads.cpp (100%) create mode 100644 examples/multiJob/meson.build rename examples/{local/multiJob/py_source => multiJob/python}/job1.py (100%) rename examples/{local/multiJob/py_source => multiJob/python}/job2.py (100%) rename examples/{local/multiJob/py_source => multiJob/python}/main.py (100%) rename examples/{local/multiJob => mutex}/README.rst (100%) rename examples/{local/mutex/source => mutex/cpp}/mutex.hpp (100%) rename examples/{local/mutex/source => mutex/cpp}/nosv.cpp (100%) rename examples/{local/mutex/source => mutex/cpp}/pthreads.cpp (100%) rename examples/{local/simple => mutex}/meson.build (73%) rename examples/{local/mutex/py_source => mutex/python}/main.py (100%) rename examples/{local/mutex/py_source => mutex/python}/mutex.py (100%) rename examples/{local => }/pendingOperation/README.rst (100%) rename examples/{local/pendingOperation/source => pendingOperation/cpp}/nosv.cpp (100%) rename examples/{local/pendingOperation/source => pendingOperation/cpp}/pendingOperation.hpp (100%) rename examples/{local/pendingOperation/source => pendingOperation/cpp}/pthreads.cpp (100%) rename examples/{local/mutex => pendingOperation}/meson.build (73%) rename examples/{local/pendingOperation/py_source => pendingOperation/python}/main.py (100%) rename examples/{local/pendingOperation/py_source => pendingOperation/python}/pendingOperation.py (100%) rename examples/{local => }/resourceList/README.rst (100%) rename examples/{local/resourceList/source => resourceList/cpp}/nosv.cpp (99%) rename examples/{local/resourceList/source => resourceList/cpp}/pthreads.cpp (99%) rename examples/{local/resourceList/source => resourceList/cpp}/workTask.hpp (100%) rename examples/{local => }/resourceList/meson.build (74%) rename examples/{local/resourceList/py_source => resourceList/python}/main.py (100%) rename examples/{local/resourceList/py_source => resourceList/python}/workTask.py (100%) rename examples/{local/mutex => simple}/README.rst (100%) rename examples/{local/simple/source => simple/cpp}/nosv.cpp (100%) rename examples/{local/simple/source => simple/cpp}/pthreads.cpp (100%) rename examples/{local/simple/source => simple/cpp}/simple.hpp (100%) rename examples/{local/workerSpecific => simple}/meson.build (73%) rename examples/{local/simple/py_source => simple/python}/main.py (100%) rename examples/{local/simple/py_source => simple/python}/simple.py (100%) rename examples/{local => }/suspend/README.rst (100%) rename examples/{local/suspend/source => suspend/cpp}/nosv.cpp (100%) rename examples/{local/suspend/source => suspend/cpp}/pthreads.cpp (100%) rename examples/{local/suspend/source => suspend/cpp}/suspend.hpp (100%) rename examples/{local/manyParallel => suspend}/meson.build (73%) rename examples/{local/suspend/py_source => suspend/python}/main.py (100%) rename examples/{local/suspend/py_source => suspend/python}/suspend.py (100%) rename examples/{local => }/workerSpecific/README.rst (100%) rename examples/{local/workerSpecific/source => workerSpecific/cpp}/nosv.cpp (100%) rename examples/{local/workerSpecific/source => workerSpecific/cpp}/pthreads.cpp (100%) rename examples/{local/workerSpecific/source => workerSpecific/cpp}/workerSpecific.hpp (100%) rename examples/{local/pendingOperation => workerSpecific}/meson.build (72%) rename examples/{local/workerSpecific/py_source => workerSpecific/python}/main.py (100%) rename examples/{local/workerSpecific/py_source => workerSpecific/python}/workerSpecific.py (100%) rename include/pytaskr/{mmm.cpp => matmul.cpp} (95%) diff --git a/.gitmodules b/.gitmodules index 4710bc1..15a5f18 100644 --- a/.gitmodules +++ b/.gitmodules @@ -8,5 +8,5 @@ branch = master [submodule "extern/pybind11"] path = extern/pybind11 - url = ../../pybind/pybind11 + url = https://github.com/pybind/pybind11.git branch = stable diff --git a/examples/local/abcTasks/README.rst b/examples/abcTasks/README.rst similarity index 100% rename from examples/local/abcTasks/README.rst rename to examples/abcTasks/README.rst diff --git a/examples/local/abcTasks/source/abcTasks.hpp b/examples/abcTasks/cpp/abcTasks.hpp similarity index 100% rename from examples/local/abcTasks/source/abcTasks.hpp rename to examples/abcTasks/cpp/abcTasks.hpp diff --git a/examples/local/abcTasks/source/nosv.cpp b/examples/abcTasks/cpp/nosv.cpp similarity index 100% rename from examples/local/abcTasks/source/nosv.cpp rename to examples/abcTasks/cpp/nosv.cpp diff --git a/examples/local/abcTasks/source/pthreads.cpp b/examples/abcTasks/cpp/pthreads.cpp similarity index 100% rename from examples/local/abcTasks/source/pthreads.cpp rename to examples/abcTasks/cpp/pthreads.cpp diff --git a/examples/local/abcTasks/meson.build b/examples/abcTasks/meson.build similarity index 73% rename from examples/local/abcTasks/meson.build rename to examples/abcTasks/meson.build index 70d8e4f..3d8336a 100644 --- a/examples/local/abcTasks/meson.build +++ b/examples/abcTasks/meson.build @@ -1,7 +1,7 @@ -testSuite = [ 'examples', 'local', 'abcTasks' ] +testSuite = [ 'examples', 'abcTasks' ] if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('processingUnitType') - threading = executable('threading', [ 'source/pthreads.cpp'], dependencies: [ TaskRBuildDep ]) + threading = executable('threading', [ 'cpp/pthreads.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') test('threading', threading, args : [ ], suite: testSuite, workdir: threading.path() + '.p' ) @@ -9,7 +9,7 @@ if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('pro endif if 'nosv' in get_option('executionStateType') and 'nosv' in get_option('processingUnitType') - nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ]) + nosv = executable('nosv', [ 'cpp/nosv.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p') @@ -19,7 +19,7 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'python/main.py' ], is_parallel : false, env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, diff --git a/examples/local/abcTasks/py_source/abcTasks.py b/examples/abcTasks/python/abcTasks.py similarity index 100% rename from examples/local/abcTasks/py_source/abcTasks.py rename to examples/abcTasks/python/abcTasks.py diff --git a/examples/local/abcTasks/py_source/main.py b/examples/abcTasks/python/main.py similarity index 100% rename from examples/local/abcTasks/py_source/main.py rename to examples/abcTasks/python/main.py diff --git a/examples/local/cholesky/README.md b/examples/cholesky/README.md similarity index 100% rename from examples/local/cholesky/README.md rename to examples/cholesky/README.md diff --git a/examples/local/cholesky/meson.build b/examples/cholesky/meson.build similarity index 95% rename from examples/local/cholesky/meson.build rename to examples/cholesky/meson.build index bdda624..a30be1b 100644 --- a/examples/local/cholesky/meson.build +++ b/examples/cholesky/meson.build @@ -1,4 +1,4 @@ -testSuite = [ 'examples', 'local', 'cholesky' ] +testSuite = [ 'examples', 'cholesky' ] choleskyDep = declare_dependency( dependencies: [ TaskRBuildDep, dependency('openblas', required: true) ], diff --git a/examples/local/cholesky/ompss/cholesky.hpp b/examples/cholesky/ompss/cholesky.hpp similarity index 100% rename from examples/local/cholesky/ompss/cholesky.hpp rename to examples/cholesky/ompss/cholesky.hpp diff --git a/examples/local/cholesky/ompss/init.hpp b/examples/cholesky/ompss/init.hpp similarity index 100% rename from examples/local/cholesky/ompss/init.hpp rename to examples/cholesky/ompss/init.hpp diff --git a/examples/local/cholesky/ompss/main.cpp b/examples/cholesky/ompss/main.cpp similarity index 100% rename from examples/local/cholesky/ompss/main.cpp rename to examples/cholesky/ompss/main.cpp diff --git a/examples/local/cholesky/ompss/meson.build b/examples/cholesky/ompss/meson.build similarity index 88% rename from examples/local/cholesky/ompss/meson.build rename to examples/cholesky/ompss/meson.build index 00cec01..7a08c74 100644 --- a/examples/local/cholesky/ompss/meson.build +++ b/examples/cholesky/ompss/meson.build @@ -1,4 +1,4 @@ -testSuite = [ 'examples', 'local' ] +testSuite = [ 'examples' ] choleskyompssDep = declare_dependency( compile_args: ['-fompss-2'], diff --git a/examples/local/cholesky/ompss/verify.hpp b/examples/cholesky/ompss/verify.hpp similarity index 100% rename from examples/local/cholesky/ompss/verify.hpp rename to examples/cholesky/ompss/verify.hpp diff --git a/examples/local/cholesky/sequential/cholesky.hpp b/examples/cholesky/sequential/cholesky.hpp similarity index 100% rename from examples/local/cholesky/sequential/cholesky.hpp rename to examples/cholesky/sequential/cholesky.hpp diff --git a/examples/local/cholesky/sequential/init.hpp b/examples/cholesky/sequential/init.hpp similarity index 100% rename from examples/local/cholesky/sequential/init.hpp rename to examples/cholesky/sequential/init.hpp diff --git a/examples/local/cholesky/sequential/main.cpp b/examples/cholesky/sequential/main.cpp similarity index 100% rename from examples/local/cholesky/sequential/main.cpp rename to examples/cholesky/sequential/main.cpp diff --git a/examples/local/cholesky/sequential/meson.build b/examples/cholesky/sequential/meson.build similarity index 86% rename from examples/local/cholesky/sequential/meson.build rename to examples/cholesky/sequential/meson.build index 26df4aa..0f120de 100644 --- a/examples/local/cholesky/sequential/meson.build +++ b/examples/cholesky/sequential/meson.build @@ -1,4 +1,4 @@ -testSuite = [ 'examples', 'local' ] +testSuite = [ 'examples' ] choleskySequentialDep = declare_dependency( dependencies: [ choleskyDep, dependency('openmp', required: true)] diff --git a/examples/local/cholesky/sequential/verify.hpp b/examples/cholesky/sequential/verify.hpp similarity index 100% rename from examples/local/cholesky/sequential/verify.hpp rename to examples/cholesky/sequential/verify.hpp diff --git a/examples/local/cholesky/source/cholesky.hpp b/examples/cholesky/source/cholesky.hpp similarity index 100% rename from examples/local/cholesky/source/cholesky.hpp rename to examples/cholesky/source/cholesky.hpp diff --git a/examples/local/cholesky/source/init.hpp b/examples/cholesky/source/init.hpp similarity index 100% rename from examples/local/cholesky/source/init.hpp rename to examples/cholesky/source/init.hpp diff --git a/examples/local/cholesky/source/nosv.cpp b/examples/cholesky/source/nosv.cpp similarity index 100% rename from examples/local/cholesky/source/nosv.cpp rename to examples/cholesky/source/nosv.cpp diff --git a/examples/local/cholesky/source/pthreads.cpp b/examples/cholesky/source/pthreads.cpp similarity index 100% rename from examples/local/cholesky/source/pthreads.cpp rename to examples/cholesky/source/pthreads.cpp diff --git a/examples/local/cholesky/source/verify.hpp b/examples/cholesky/source/verify.hpp similarity index 100% rename from examples/local/cholesky/source/verify.hpp rename to examples/cholesky/source/verify.hpp diff --git a/examples/local/cholesky/utils.hpp b/examples/cholesky/utils.hpp similarity index 100% rename from examples/local/cholesky/utils.hpp rename to examples/cholesky/utils.hpp diff --git a/examples/local/conditionVariable/README.rst b/examples/conditionVariable/README.rst similarity index 100% rename from examples/local/conditionVariable/README.rst rename to examples/conditionVariable/README.rst diff --git a/examples/local/conditionVariable/source/conditionVariableWait.hpp b/examples/conditionVariable/cpp/conditionVariableWait.hpp similarity index 100% rename from examples/local/conditionVariable/source/conditionVariableWait.hpp rename to examples/conditionVariable/cpp/conditionVariableWait.hpp diff --git a/examples/local/conditionVariable/source/conditionVariableWaitCondition.hpp b/examples/conditionVariable/cpp/conditionVariableWaitCondition.hpp similarity index 100% rename from examples/local/conditionVariable/source/conditionVariableWaitCondition.hpp rename to examples/conditionVariable/cpp/conditionVariableWaitCondition.hpp diff --git a/examples/local/conditionVariable/source/conditionVariableWaitFor.hpp b/examples/conditionVariable/cpp/conditionVariableWaitFor.hpp similarity index 100% rename from examples/local/conditionVariable/source/conditionVariableWaitFor.hpp rename to examples/conditionVariable/cpp/conditionVariableWaitFor.hpp diff --git a/examples/local/conditionVariable/source/conditionVariableWaitForCondition.hpp b/examples/conditionVariable/cpp/conditionVariableWaitForCondition.hpp similarity index 100% rename from examples/local/conditionVariable/source/conditionVariableWaitForCondition.hpp rename to examples/conditionVariable/cpp/conditionVariableWaitForCondition.hpp diff --git a/examples/local/conditionVariable/source/nosv.cpp b/examples/conditionVariable/cpp/nosv.cpp similarity index 100% rename from examples/local/conditionVariable/source/nosv.cpp rename to examples/conditionVariable/cpp/nosv.cpp diff --git a/examples/local/conditionVariable/source/pthreads.cpp b/examples/conditionVariable/cpp/pthreads.cpp similarity index 100% rename from examples/local/conditionVariable/source/pthreads.cpp rename to examples/conditionVariable/cpp/pthreads.cpp diff --git a/examples/local/conditionVariable/meson.build b/examples/conditionVariable/meson.build similarity index 71% rename from examples/local/conditionVariable/meson.build rename to examples/conditionVariable/meson.build index b3c2479..4d7f344 100644 --- a/examples/local/conditionVariable/meson.build +++ b/examples/conditionVariable/meson.build @@ -1,10 +1,10 @@ -testSuite = [ 'examples', 'local', 'conditionVariable' ] +testSuite = [ 'examples', 'conditionVariable' ] if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('processingUnitType') - threading_conditionVariableWait = executable('threading_conditionVariableWait', [ 'source/pthreads.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ '-D__TEST_FUNCTION_=conditionVariableWait'] ) - threading_conditionVariableWaitFor = executable('threading_conditionVariableWaitFor', [ 'source/pthreads.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ '-D__TEST_FUNCTION_=conditionVariableWaitFor'] ) - threading_conditionVariableWaitCondition = executable('threading_conditionVariableWaitCondition', [ 'source/pthreads.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ '-D__TEST_FUNCTION_=conditionVariableWaitCondition'] ) - threading_conditionVariableWaitForCondition = executable('threading_conditionVariableWaitForCondition', [ 'source/pthreads.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ '-D__TEST_FUNCTION_=conditionVariableWaitForCondition'] ) + threading_conditionVariableWait = executable('threading_conditionVariableWait', [ 'cpp/pthreads.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ '-D__TEST_FUNCTION_=conditionVariableWait'] ) + threading_conditionVariableWaitFor = executable('threading_conditionVariableWaitFor', [ 'cpp/pthreads.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ '-D__TEST_FUNCTION_=conditionVariableWaitFor'] ) + threading_conditionVariableWaitCondition = executable('threading_conditionVariableWaitCondition', [ 'cpp/pthreads.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ '-D__TEST_FUNCTION_=conditionVariableWaitCondition'] ) + threading_conditionVariableWaitForCondition = executable('threading_conditionVariableWaitForCondition', [ 'cpp/pthreads.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ '-D__TEST_FUNCTION_=conditionVariableWaitForCondition'] ) if get_option('buildTests') test('threading_conditionVariableWait', threading_conditionVariableWait, args : [ ], suite: testSuite, workdir: threading_conditionVariableWait.path() + '.p' ) @@ -15,10 +15,10 @@ if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('pro endif if 'nosv' in get_option('executionStateType') and 'nosv' in get_option('processingUnitType') - nosv_conditionVariableWait = executable('nosv_conditionVariableWait', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ '-D__TEST_FUNCTION_=conditionVariableWait'] ) - nosv_conditionVariableWaitFor = executable('nosv_conditionVariableWaitFor', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ '-D__TEST_FUNCTION_=conditionVariableWaitFor'] ) - nosv_conditionVariableWaitCondition = executable('nosv_conditionVariableWaitCondition', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ '-D__TEST_FUNCTION_=conditionVariableWaitCondition'] ) - nosv_conditionVariableWaitForCondition = executable('nosv_conditionVariableWaitForCondition', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ '-D__TEST_FUNCTION_=conditionVariableWaitForCondition'] ) + nosv_conditionVariableWait = executable('nosv_conditionVariableWait', [ 'cpp/nosv.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ '-D__TEST_FUNCTION_=conditionVariableWait'] ) + nosv_conditionVariableWaitFor = executable('nosv_conditionVariableWaitFor', [ 'cpp/nosv.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ '-D__TEST_FUNCTION_=conditionVariableWaitFor'] ) + nosv_conditionVariableWaitCondition = executable('nosv_conditionVariableWaitCondition', [ 'cpp/nosv.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ '-D__TEST_FUNCTION_=conditionVariableWaitCondition'] ) + nosv_conditionVariableWaitForCondition = executable('nosv_conditionVariableWaitForCondition', [ 'cpp/nosv.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ '-D__TEST_FUNCTION_=conditionVariableWaitForCondition'] ) if get_option('buildTests') test('nosv_conditionVariableWait', nosv_conditionVariableWait, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv_conditionVariableWait.path() + '.p' ) @@ -31,7 +31,7 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR_conditionVariableWait', py, - args : [ 'py_source/main.py' ], + args : [ 'python/main.py' ], is_parallel : false, env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWait'], suite: testSuite, @@ -39,7 +39,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR_conditionVariableWaitFor', py, - args : [ 'py_source/main.py' ], + args : [ 'python/main.py' ], is_parallel : false, env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWaitFor'], suite: testSuite, @@ -47,7 +47,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR_conditionVariableWaitCondition', py, - args : [ 'py_source/main.py' ], + args : [ 'python/main.py' ], is_parallel : false, env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWaitCondition'], suite: testSuite, @@ -55,7 +55,7 @@ if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR_conditionVariableWaitForCondition', py, - args : [ 'py_source/main.py' ], + args : [ 'python/main.py' ], is_parallel : false, env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/', '__TEST_FUNCTION_=conditionVariableWaitForCondition'], suite: testSuite, diff --git a/examples/local/conditionVariable/py_source/conditionVariableWait.py b/examples/conditionVariable/python/conditionVariableWait.py similarity index 100% rename from examples/local/conditionVariable/py_source/conditionVariableWait.py rename to examples/conditionVariable/python/conditionVariableWait.py diff --git a/examples/local/conditionVariable/py_source/conditionVariableWaitCondition.py b/examples/conditionVariable/python/conditionVariableWaitCondition.py similarity index 100% rename from examples/local/conditionVariable/py_source/conditionVariableWaitCondition.py rename to examples/conditionVariable/python/conditionVariableWaitCondition.py diff --git a/examples/local/conditionVariable/py_source/conditionVariableWaitFor.py b/examples/conditionVariable/python/conditionVariableWaitFor.py similarity index 100% rename from examples/local/conditionVariable/py_source/conditionVariableWaitFor.py rename to examples/conditionVariable/python/conditionVariableWaitFor.py diff --git a/examples/local/conditionVariable/py_source/conditionVariableWaitForCondition.py b/examples/conditionVariable/python/conditionVariableWaitForCondition.py similarity index 100% rename from examples/local/conditionVariable/py_source/conditionVariableWaitForCondition.py rename to examples/conditionVariable/python/conditionVariableWaitForCondition.py diff --git a/examples/local/conditionVariable/py_source/main.py b/examples/conditionVariable/python/main.py similarity index 100% rename from examples/local/conditionVariable/py_source/main.py rename to examples/conditionVariable/python/main.py diff --git a/examples/distributed/meson.build b/examples/distributed/meson.build deleted file mode 100644 index 6c71914..0000000 --- a/examples/distributed/meson.build +++ /dev/null @@ -1,15 +0,0 @@ - -# Handling distributed engine options -if distributedEngine == 'mpi' -TaskRDistributedCppFlag = '-D_TASKR_DISTRIBUTED_ENGINE_MPI' -endif - -if distributedEngine == 'lpf' -TaskRDistributedCppFlag = '-D_TASKR_DISTRIBUTED_ENGINE_LPF' -endif - -if distributedEngine == 'none' -TaskRDistributedCppFlag = '-D_TASKR_DISTRIBUTED_ENGINE_NONE' -endif - -subdir('jacobi3d') \ No newline at end of file diff --git a/examples/distributed/pingPong/meson.build b/examples/distributed/pingPong/meson.build deleted file mode 100644 index 4726b47..0000000 --- a/examples/distributed/pingPong/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -testSuite = [ 'examples', 'distributed' ] - -if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('processingUnitType') - pingPong = executable('pingPong', [ 'source/main.cpp'], dependencies: [ TaskRBuildDep ], cpp_args: [ TaskRDistributedCppFlag ] ) - - if get_option('buildTests') - test('pingPong', pingPong, args : [ ], suite: testSuite, workdir: pingPong.path() + '.p' ) - endif -endif diff --git a/examples/local/energySaver/README.rst b/examples/energySaver/README.rst similarity index 100% rename from examples/local/energySaver/README.rst rename to examples/energySaver/README.rst diff --git a/examples/local/energySaver/source/nosv.cpp b/examples/energySaver/cpp/nosv.cpp similarity index 100% rename from examples/local/energySaver/source/nosv.cpp rename to examples/energySaver/cpp/nosv.cpp diff --git a/examples/local/energySaver/source/pthreads.cpp b/examples/energySaver/cpp/pthreads.cpp similarity index 100% rename from examples/local/energySaver/source/pthreads.cpp rename to examples/energySaver/cpp/pthreads.cpp diff --git a/examples/local/energySaver/meson.build b/examples/energySaver/meson.build similarity index 74% rename from examples/local/energySaver/meson.build rename to examples/energySaver/meson.build index fade6c8..2397f89 100644 --- a/examples/local/energySaver/meson.build +++ b/examples/energySaver/meson.build @@ -1,7 +1,7 @@ -testSuite = [ 'examples', 'local', 'energySaver' ] +testSuite = [ 'examples', 'energySaver' ] if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('processingUnitType') - threading = executable('threading', [ 'source/pthreads.cpp'], dependencies: [ TaskRBuildDep ]) + threading = executable('threading', [ 'cpp/pthreads.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') test('threading', threading, args : [ '3', '1', '100' ], suite: testSuite, workdir: threading.path() + '.p' ) @@ -9,7 +9,7 @@ if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('pro endif if 'nosv' in get_option('executionStateType') and 'nosv' in get_option('processingUnitType') - nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ]) + nosv = executable('nosv', [ 'cpp/nosv.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') test('nosv', nosv, args : [ '3', '1', '100' ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) @@ -19,7 +19,7 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py'], + args : [ 'python/main.py'], is_parallel : false, env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, diff --git a/examples/local/energySaver/py_source/energySaver.py b/examples/energySaver/python/energySaver.py similarity index 100% rename from examples/local/energySaver/py_source/energySaver.py rename to examples/energySaver/python/energySaver.py diff --git a/examples/local/energySaver/py_source/main.py b/examples/energySaver/python/main.py similarity index 100% rename from examples/local/energySaver/py_source/main.py rename to examples/energySaver/python/main.py diff --git a/examples/local/fibonacci/README.md b/examples/fibonacci/README.md similarity index 100% rename from examples/local/fibonacci/README.md rename to examples/fibonacci/README.md diff --git a/examples/local/fibonacci/source/fibonacci.hpp b/examples/fibonacci/cpp/fibonacci.hpp similarity index 100% rename from examples/local/fibonacci/source/fibonacci.hpp rename to examples/fibonacci/cpp/fibonacci.hpp diff --git a/examples/local/fibonacci/source/nosv.cpp b/examples/fibonacci/cpp/nosv.cpp similarity index 100% rename from examples/local/fibonacci/source/nosv.cpp rename to examples/fibonacci/cpp/nosv.cpp diff --git a/examples/local/fibonacci/source/pthreads.cpp b/examples/fibonacci/cpp/pthreads.cpp similarity index 100% rename from examples/local/fibonacci/source/pthreads.cpp rename to examples/fibonacci/cpp/pthreads.cpp diff --git a/examples/local/fibonacci/meson.build b/examples/fibonacci/meson.build similarity index 73% rename from examples/local/fibonacci/meson.build rename to examples/fibonacci/meson.build index f629b72..8cde6be 100644 --- a/examples/local/fibonacci/meson.build +++ b/examples/fibonacci/meson.build @@ -1,7 +1,7 @@ -testSuite = [ 'examples', 'local', 'fibonacci' ] +testSuite = [ 'examples', 'fibonacci' ] if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('processingUnitType') - threading = executable('threading', [ 'source/pthreads.cpp'], dependencies: [ TaskRBuildDep ]) + threading = executable('threading', [ 'cpp/pthreads.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') test('threading', threading, args : [ '15' ], suite: testSuite, workdir: threading.path() + '.p' ) @@ -9,7 +9,7 @@ if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('pro endif if 'nosv' in get_option('executionStateType') and 'nosv' in get_option('processingUnitType') - nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ]) + nosv = executable('nosv', [ 'cpp/nosv.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') test('nosv', nosv, args : [ '15' ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) @@ -19,7 +19,7 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py'], + args : [ 'python/main.py'], is_parallel : false, env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, diff --git a/examples/local/fibonacci/py_source/fibonacci.py b/examples/fibonacci/python/fibonacci.py similarity index 100% rename from examples/local/fibonacci/py_source/fibonacci.py rename to examples/fibonacci/python/fibonacci.py diff --git a/examples/local/fibonacci/py_source/fibonacci_mutex.py b/examples/fibonacci/python/fibonacci_mutex.py similarity index 100% rename from examples/local/fibonacci/py_source/fibonacci_mutex.py rename to examples/fibonacci/python/fibonacci_mutex.py diff --git a/examples/local/fibonacci/py_source/main.py b/examples/fibonacci/python/main.py similarity index 100% rename from examples/local/fibonacci/py_source/main.py rename to examples/fibonacci/python/main.py diff --git a/examples/distributed/jacobi3d/.gitignore b/examples/jacobi3d/.gitignore similarity index 100% rename from examples/distributed/jacobi3d/.gitignore rename to examples/jacobi3d/.gitignore diff --git a/examples/distributed/jacobi3d/README.md b/examples/jacobi3d/README.md similarity index 100% rename from examples/distributed/jacobi3d/README.md rename to examples/jacobi3d/README.md diff --git a/examples/distributed/jacobi3d/meson.build b/examples/jacobi3d/meson.build similarity index 93% rename from examples/distributed/jacobi3d/meson.build rename to examples/jacobi3d/meson.build index d6f5e28..276796d 100644 --- a/examples/distributed/jacobi3d/meson.build +++ b/examples/jacobi3d/meson.build @@ -1,4 +1,4 @@ -testSuite = [ 'examples', 'distributed', 'jacobi3d' ] +testSuite = [ 'examples', 'jacobi3d' ] if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('processingUnitType') threading = executable('threading', [ 'source/pthreads.cpp', 'source/grid.cpp' ], dependencies: [ TaskRBuildDep ], cpp_args: [ TaskRDistributedCppFlag ] ) diff --git a/examples/distributed/jacobi3d/mpi/Makefile b/examples/jacobi3d/mpi/Makefile similarity index 100% rename from examples/distributed/jacobi3d/mpi/Makefile rename to examples/jacobi3d/mpi/Makefile diff --git a/examples/distributed/jacobi3d/mpi/grid.cpp b/examples/jacobi3d/mpi/grid.cpp similarity index 100% rename from examples/distributed/jacobi3d/mpi/grid.cpp rename to examples/jacobi3d/mpi/grid.cpp diff --git a/examples/distributed/jacobi3d/mpi/grid.hpp b/examples/jacobi3d/mpi/grid.hpp similarity index 100% rename from examples/distributed/jacobi3d/mpi/grid.hpp rename to examples/jacobi3d/mpi/grid.hpp diff --git a/examples/distributed/jacobi3d/mpi/jacobi.cpp b/examples/jacobi3d/mpi/jacobi.cpp similarity index 100% rename from examples/distributed/jacobi3d/mpi/jacobi.cpp rename to examples/jacobi3d/mpi/jacobi.cpp diff --git a/examples/distributed/jacobi3d/source/grid.cpp b/examples/jacobi3d/source/grid.cpp similarity index 100% rename from examples/distributed/jacobi3d/source/grid.cpp rename to examples/jacobi3d/source/grid.cpp diff --git a/examples/distributed/jacobi3d/source/grid.hpp b/examples/jacobi3d/source/grid.hpp similarity index 100% rename from examples/distributed/jacobi3d/source/grid.hpp rename to examples/jacobi3d/source/grid.hpp diff --git a/examples/distributed/jacobi3d/source/nosv.cpp b/examples/jacobi3d/source/nosv.cpp similarity index 100% rename from examples/distributed/jacobi3d/source/nosv.cpp rename to examples/jacobi3d/source/nosv.cpp diff --git a/examples/distributed/jacobi3d/source/pthreads.cpp b/examples/jacobi3d/source/pthreads.cpp similarity index 100% rename from examples/distributed/jacobi3d/source/pthreads.cpp rename to examples/jacobi3d/source/pthreads.cpp diff --git a/examples/distributed/jacobi3d/source/task.hpp b/examples/jacobi3d/source/task.hpp similarity index 100% rename from examples/distributed/jacobi3d/source/task.hpp rename to examples/jacobi3d/source/task.hpp diff --git a/examples/local/meson.build b/examples/local/meson.build deleted file mode 100644 index ddf490b..0000000 --- a/examples/local/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -subdir('abcTasks') -subdir('conditionVariable') -subdir('cholesky') -subdir('mutex') -subdir('energySaver') -subdir('resourceList') -subdir('fibonacci') -subdir('multiJob') -subdir('pendingOperation') -subdir('workerSpecific') -subdir('manyParallel') -subdir('suspend') -subdir('simple') -subdir('mmm') \ No newline at end of file diff --git a/examples/local/mmm/py_source/mmm.py b/examples/local/mmm/py_source/mmm.py deleted file mode 100644 index 1ddc346..0000000 --- a/examples/local/mmm/py_source/mmm.py +++ /dev/null @@ -1,63 +0,0 @@ -""" - Copyright 2025 Huawei Technologies Co., Ltd. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import time -import numpy as np -import taskr - -NTASKS = 2 - -N = 1000 - -def mmm(task): - A = np.zeros((N,N)) - B = np.empty((N,N)) - C = np.empty((N,N)) - - for i in range(N): - for j in range(N): - B[i, j] = i - C[i, j] = j - - B += task.getLabel()+1 - C += task.getLabel()+1 - - A = B @ C - print(f"Hello, I am task {task.getLabel()}") - - -def mmmDriver(runtime): - # Initializing taskr - runtime.initialize() - - taskfc = taskr.Function(mmm) - - # Adding to tasks to taskr - for i in range(NTASKS): - runtime.addTask(taskr.Task(i, taskfc, i)) - - # Running taskr for the current repetition - t_start = time.time() - runtime.run() - - # Waiting current repetition to end - runtime.await_() - t_duration = time.time() - t_start - - print(f"total time: {t_duration}s") - - # Finalizing taskr - runtime.finalize() \ No newline at end of file diff --git a/examples/local/multiJob/meson.build b/examples/local/multiJob/meson.build deleted file mode 100644 index 324781f..0000000 --- a/examples/local/multiJob/meson.build +++ /dev/null @@ -1,27 +0,0 @@ -testSuite = [ 'examples', 'local', 'multiJob' ] - -if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('processingUnitType') - threading = executable('threading', [ 'source/pthreads.cpp', 'source/job1.cpp', 'source/job2.cpp' ], dependencies: [ TaskRBuildDep ] ) - - if get_option('buildTests') - test('threading', threading, args : [ ], suite: testSuite, workdir: threading.path() + '.p' ) - endif -endif - -if 'nosv' in get_option('executionStateType') and 'nosv' in get_option('processingUnitType') - nosv = executable('nosv', [ 'source/nosv.cpp', 'source/job1.cpp', 'source/job2.cpp' ], dependencies: [ TaskRBuildDep ] ) - - if get_option('buildTests') - test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) - endif -endif - -if get_option('buildPyTaskR') and get_option('buildTests') - test('pyTaskR', - py, - args : [ 'py_source/main.py' ], - is_parallel : false, - env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], - suite: testSuite, - workdir: meson.current_source_dir()) -endif \ No newline at end of file diff --git a/examples/local/simple/README.rst b/examples/local/simple/README.rst deleted file mode 100644 index 3211e05..0000000 --- a/examples/local/simple/README.rst +++ /dev/null @@ -1,7 +0,0 @@ -ABC Tasks -============ - -A simple example for creating a task dependency-based runtime system using HiCR - -It creates and adds tasks in an arbitrary order. However, given the dependencies should force the output to always be an ordered sequence of A->B->C. This example makes sure TaskR is handling these dependencies correctly. - diff --git a/examples/local/manyParallel/README.rst b/examples/manyParallel/README.rst similarity index 100% rename from examples/local/manyParallel/README.rst rename to examples/manyParallel/README.rst diff --git a/examples/local/manyParallel/source/manyParallel.hpp b/examples/manyParallel/cpp/manyParallel.hpp similarity index 100% rename from examples/local/manyParallel/source/manyParallel.hpp rename to examples/manyParallel/cpp/manyParallel.hpp diff --git a/examples/local/manyParallel/source/nosv.cpp b/examples/manyParallel/cpp/nosv.cpp similarity index 100% rename from examples/local/manyParallel/source/nosv.cpp rename to examples/manyParallel/cpp/nosv.cpp diff --git a/examples/local/manyParallel/source/pthreads.cpp b/examples/manyParallel/cpp/pthreads.cpp similarity index 100% rename from examples/local/manyParallel/source/pthreads.cpp rename to examples/manyParallel/cpp/pthreads.cpp diff --git a/examples/local/suspend/meson.build b/examples/manyParallel/meson.build similarity index 74% rename from examples/local/suspend/meson.build rename to examples/manyParallel/meson.build index 0921638..6ed7857 100644 --- a/examples/local/suspend/meson.build +++ b/examples/manyParallel/meson.build @@ -1,7 +1,7 @@ -testSuite = [ 'examples', 'local', 'suspend' ] +testSuite = [ 'examples', 'manyParallel' ] if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('processingUnitType') - threading = executable('threading', [ 'source/pthreads.cpp'], dependencies: [ TaskRBuildDep ] ) + threading = executable('threading', [ 'cpp/pthreads.cpp'], dependencies: [ TaskRBuildDep ] ) if get_option('buildTests') test('threading', threading, args : [ '2', '100' ], suite: testSuite, workdir: threading.path() + '.p' ) @@ -9,7 +9,7 @@ if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('pro endif if 'nosv' in get_option('executionStateType') and 'nosv' in get_option('processingUnitType') - nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ] ) + nosv = executable('nosv', [ 'cpp/nosv.cpp'], dependencies: [ TaskRBuildDep ] ) if get_option('buildTests') test('nosv', nosv, args : [ '2', '100' ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) @@ -19,7 +19,7 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'python/main.py' ], is_parallel : false, env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, diff --git a/examples/local/manyParallel/py_source/main.py b/examples/manyParallel/python/main.py similarity index 100% rename from examples/local/manyParallel/py_source/main.py rename to examples/manyParallel/python/main.py diff --git a/examples/local/manyParallel/py_source/manyParallel.py b/examples/manyParallel/python/manyParallel.py similarity index 100% rename from examples/local/manyParallel/py_source/manyParallel.py rename to examples/manyParallel/python/manyParallel.py diff --git a/examples/matmul/README.rst b/examples/matmul/README.rst new file mode 100644 index 0000000..ad40e64 --- /dev/null +++ b/examples/matmul/README.rst @@ -0,0 +1,8 @@ +MatMul +============ + +A simple example of pyTaskR registering a cpp-based function (in this case a Matrix-Matrix multiplication) to run in python. + +- `main.py`: The main script to initialize TaskR runtime +- `matmul.cpp`: The cpp-function to be registered and callable in python +- `matmul.py`: The Driver to load the cpp function and execute it in python. It also consists of a NumPy example for comparisons. diff --git a/examples/local/mmm/meson.build b/examples/matmul/meson.build similarity index 76% rename from examples/local/mmm/meson.build rename to examples/matmul/meson.build index 6673c02..6a11772 100644 --- a/examples/local/mmm/meson.build +++ b/examples/matmul/meson.build @@ -1,9 +1,9 @@ -testSuite = [ 'examples', 'local', 'mmmm' ] +testSuite = [ 'examples', 'matmul' ] if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'python/main.py' ], is_parallel : false, env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, diff --git a/examples/local/mmm/py_source/main.py b/examples/matmul/python/main.py similarity index 84% rename from examples/local/mmm/py_source/main.py rename to examples/matmul/python/main.py index 756f8fd..1906da7 100644 --- a/examples/local/mmm/py_source/main.py +++ b/examples/matmul/python/main.py @@ -15,8 +15,7 @@ """ import taskr -# from mmm import mmmDriver -from mmm_cpp import mmm_cpp_Driver +from matmul import matmul_cpp_Driver, matmul_numpy_Driver def main(): # Initialize taskr with the wanted compute manager backend and number of PUs @@ -25,9 +24,11 @@ def main(): # Get the runtime runtime = t.get_runtime() - # Running mmm example - # mmmDriver(runtime) - mmm_cpp_Driver(runtime) + # Running matmul example + matmul_cpp_Driver(runtime) + + matmul_numpy_Driver(runtime) + if __name__ == "__main__": main() \ No newline at end of file diff --git a/examples/matmul/python/matmul.cpp b/examples/matmul/python/matmul.cpp new file mode 100644 index 0000000..05c8f69 --- /dev/null +++ b/examples/matmul/python/matmul.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2025 Huawei Technologies Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include + +#define mytype float + +/** + * Compute mmm + */ +void matmul(taskr::Task *) +{ + const size_t N = 1000; + + // Allocate memory + volatile mytype *A = (mytype *)calloc(1, N * N * sizeof(mytype)); + volatile mytype *B = (mytype *)malloc(N * N * sizeof(mytype)); + volatile mytype *C = (mytype *)malloc(N * N * sizeof(mytype)); + + // Filling matrices B and C + for (size_t i = 0; i < N; ++i) + { + for (size_t j = 0; j < N; ++j) + { + B[i * N + j] = 1.0 / (mytype(i + 1)); + C[i * N + j] = 1.0 / (mytype(j + 1)); + } + } + + // mmm + for (size_t i = 0; i < N; ++i) + { + for (size_t j = 0; j < N; ++j) + { + for (size_t k = 0; k < N; ++k) { A[i * N + j] += B[i * N + k] * C[k * N + j]; } + } + } + + // free memory + free((mytype *)A); + free((mytype *)B); + free((mytype *)C); +} + +namespace taskr +{ + +__attribute__((constructor)) // GCC/Clang: Run before main/init +void register_my_func() +{ + register_function("cpp_matmul", matmul); +} + +} // namespace taskr \ No newline at end of file diff --git a/examples/local/mmm/py_source/mmm_cpp.py b/examples/matmul/python/matmul.py similarity index 54% rename from examples/local/mmm/py_source/mmm_cpp.py rename to examples/matmul/python/matmul.py index 7f01a02..c75248f 100644 --- a/examples/local/mmm/py_source/mmm_cpp.py +++ b/examples/matmul/python/matmul.py @@ -16,14 +16,56 @@ import time import taskr +import numpy as np NTASKS = 2 -def mmm_cpp_Driver(runtime): +def matmul_cpp_Driver(runtime): # Initializing taskr runtime.initialize() - taskfc = taskr.get_cpp_function("cpp_mmm") + taskfc = taskr.get_cpp_function("cpp_matmul") + + # Adding to tasks to taskr + for i in range(NTASKS): + runtime.addTask(taskr.Task(i, taskfc)) + + # Running taskr for the current repetition + t_start = time.time() + runtime.run() + + # Waiting current repetition to end + runtime.await_() + print(f"total time: {time.time() - t_start}") + + # Finalizing taskr + runtime.finalize() + + + + + +def matmul_numpy_Driver(runtime): + # Initializing taskr + runtime.initialize() + + def matmul_numpy(task): + N = 1000 + A = np.zeros((N,N)) + B = np.empty((N,N)) + C = np.empty((N,N)) + + for i in range(N): + for j in range(N): + B[i, j] = 1.0/(i + 1) + C[i, j] = 1.0/(j + 1) + + B += task.getLabel()+1 + C += task.getLabel()+1 + + A = B @ C + + taskfc = taskr.Function(matmul_numpy) # Adding to tasks to taskr for i in range(NTASKS): diff --git a/examples/meson.build b/examples/meson.build index 340b0c2..cc852f8 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -1,2 +1,30 @@ -subdir('local') -subdir('distributed') +# Handling distributed engine options +if distributedEngine == 'mpi' +TaskRDistributedCppFlag = '-D_TASKR_DISTRIBUTED_ENGINE_MPI' +endif + +if distributedEngine == 'lpf' +TaskRDistributedCppFlag = '-D_TASKR_DISTRIBUTED_ENGINE_LPF' +endif + +if distributedEngine == 'none' +TaskRDistributedCppFlag = '-D_TASKR_DISTRIBUTED_ENGINE_NONE' +endif + +subdir('jacobi3d') + +# local +subdir('abcTasks') +subdir('conditionVariable') +subdir('cholesky') +subdir('mutex') +subdir('energySaver') +subdir('resourceList') +subdir('fibonacci') +subdir('multiJob') +subdir('pendingOperation') +subdir('workerSpecific') +subdir('manyParallel') +subdir('suspend') +subdir('simple') +subdir('matmul') \ No newline at end of file diff --git a/examples/local/mmm/README.rst b/examples/multiJob/README.rst similarity index 100% rename from examples/local/mmm/README.rst rename to examples/multiJob/README.rst diff --git a/examples/local/multiJob/source/job1.cpp b/examples/multiJob/cpp/job1.cpp similarity index 100% rename from examples/local/multiJob/source/job1.cpp rename to examples/multiJob/cpp/job1.cpp diff --git a/examples/local/multiJob/source/job2.cpp b/examples/multiJob/cpp/job2.cpp similarity index 100% rename from examples/local/multiJob/source/job2.cpp rename to examples/multiJob/cpp/job2.cpp diff --git a/examples/local/multiJob/source/jobs.hpp b/examples/multiJob/cpp/jobs.hpp similarity index 100% rename from examples/local/multiJob/source/jobs.hpp rename to examples/multiJob/cpp/jobs.hpp diff --git a/examples/local/multiJob/source/nosv.cpp b/examples/multiJob/cpp/nosv.cpp similarity index 100% rename from examples/local/multiJob/source/nosv.cpp rename to examples/multiJob/cpp/nosv.cpp diff --git a/examples/local/multiJob/source/pthreads.cpp b/examples/multiJob/cpp/pthreads.cpp similarity index 100% rename from examples/local/multiJob/source/pthreads.cpp rename to examples/multiJob/cpp/pthreads.cpp diff --git a/examples/multiJob/meson.build b/examples/multiJob/meson.build new file mode 100644 index 0000000..99f0a8d --- /dev/null +++ b/examples/multiJob/meson.build @@ -0,0 +1,27 @@ +testSuite = [ 'examples', 'multiJob' ] + +if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('processingUnitType') + threading = executable('threading', [ 'cpp/pthreads.cpp', 'cpp/job1.cpp', 'cpp/job2.cpp' ], dependencies: [ TaskRBuildDep ] ) + + if get_option('buildTests') + test('threading', threading, args : [ ], suite: testSuite, workdir: threading.path() + '.p' ) + endif +endif + +if 'nosv' in get_option('executionStateType') and 'nosv' in get_option('processingUnitType') + nosv = executable('nosv', [ 'cpp/nosv.cpp', 'cpp/job1.cpp', 'cpp/job2.cpp' ], dependencies: [ TaskRBuildDep ] ) + + if get_option('buildTests') + test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) + endif +endif + +if get_option('buildPyTaskR') and get_option('buildTests') + test('pyTaskR', + py, + args : [ 'python/main.py' ], + is_parallel : false, + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], + suite: testSuite, + workdir: meson.current_source_dir()) +endif \ No newline at end of file diff --git a/examples/local/multiJob/py_source/job1.py b/examples/multiJob/python/job1.py similarity index 100% rename from examples/local/multiJob/py_source/job1.py rename to examples/multiJob/python/job1.py diff --git a/examples/local/multiJob/py_source/job2.py b/examples/multiJob/python/job2.py similarity index 100% rename from examples/local/multiJob/py_source/job2.py rename to examples/multiJob/python/job2.py diff --git a/examples/local/multiJob/py_source/main.py b/examples/multiJob/python/main.py similarity index 100% rename from examples/local/multiJob/py_source/main.py rename to examples/multiJob/python/main.py diff --git a/examples/local/multiJob/README.rst b/examples/mutex/README.rst similarity index 100% rename from examples/local/multiJob/README.rst rename to examples/mutex/README.rst diff --git a/examples/local/mutex/source/mutex.hpp b/examples/mutex/cpp/mutex.hpp similarity index 100% rename from examples/local/mutex/source/mutex.hpp rename to examples/mutex/cpp/mutex.hpp diff --git a/examples/local/mutex/source/nosv.cpp b/examples/mutex/cpp/nosv.cpp similarity index 100% rename from examples/local/mutex/source/nosv.cpp rename to examples/mutex/cpp/nosv.cpp diff --git a/examples/local/mutex/source/pthreads.cpp b/examples/mutex/cpp/pthreads.cpp similarity index 100% rename from examples/local/mutex/source/pthreads.cpp rename to examples/mutex/cpp/pthreads.cpp diff --git a/examples/local/simple/meson.build b/examples/mutex/meson.build similarity index 73% rename from examples/local/simple/meson.build rename to examples/mutex/meson.build index 7c82175..8ca8c9f 100644 --- a/examples/local/simple/meson.build +++ b/examples/mutex/meson.build @@ -1,7 +1,7 @@ -testSuite = [ 'examples', 'local', 'simple' ] +testSuite = [ 'examples', 'mutex' ] if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('processingUnitType') - threading = executable('threading', [ 'source/pthreads.cpp'], dependencies: [ TaskRBuildDep ]) + threading = executable('threading', [ 'cpp/pthreads.cpp'], dependencies: [ TaskRBuildDep ] ) if get_option('buildTests') test('threading', threading, args : [ ], suite: testSuite, workdir: threading.path() + '.p' ) @@ -9,7 +9,7 @@ if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('pro endif if 'nosv' in get_option('executionStateType') and 'nosv' in get_option('processingUnitType') - nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ]) + nosv = executable('nosv', [ 'cpp/nosv.cpp'], dependencies: [ TaskRBuildDep ] ) if get_option('buildTests') test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) @@ -19,7 +19,7 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'python/main.py' ], is_parallel : false, env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, diff --git a/examples/local/mutex/py_source/main.py b/examples/mutex/python/main.py similarity index 100% rename from examples/local/mutex/py_source/main.py rename to examples/mutex/python/main.py diff --git a/examples/local/mutex/py_source/mutex.py b/examples/mutex/python/mutex.py similarity index 100% rename from examples/local/mutex/py_source/mutex.py rename to examples/mutex/python/mutex.py diff --git a/examples/local/pendingOperation/README.rst b/examples/pendingOperation/README.rst similarity index 100% rename from examples/local/pendingOperation/README.rst rename to examples/pendingOperation/README.rst diff --git a/examples/local/pendingOperation/source/nosv.cpp b/examples/pendingOperation/cpp/nosv.cpp similarity index 100% rename from examples/local/pendingOperation/source/nosv.cpp rename to examples/pendingOperation/cpp/nosv.cpp diff --git a/examples/local/pendingOperation/source/pendingOperation.hpp b/examples/pendingOperation/cpp/pendingOperation.hpp similarity index 100% rename from examples/local/pendingOperation/source/pendingOperation.hpp rename to examples/pendingOperation/cpp/pendingOperation.hpp diff --git a/examples/local/pendingOperation/source/pthreads.cpp b/examples/pendingOperation/cpp/pthreads.cpp similarity index 100% rename from examples/local/pendingOperation/source/pthreads.cpp rename to examples/pendingOperation/cpp/pthreads.cpp diff --git a/examples/local/mutex/meson.build b/examples/pendingOperation/meson.build similarity index 73% rename from examples/local/mutex/meson.build rename to examples/pendingOperation/meson.build index ca07fc2..f270c81 100644 --- a/examples/local/mutex/meson.build +++ b/examples/pendingOperation/meson.build @@ -1,7 +1,7 @@ -testSuite = [ 'examples', 'local', 'mutex' ] +testSuite = [ 'examples', 'pendingOperation' ] if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('processingUnitType') - threading = executable('threading', [ 'source/pthreads.cpp'], dependencies: [ TaskRBuildDep ] ) + threading = executable('threading', [ 'cpp/pthreads.cpp'], dependencies: [ TaskRBuildDep ] ) if get_option('buildTests') test('threading', threading, args : [ ], suite: testSuite, workdir: threading.path() + '.p' ) @@ -9,7 +9,7 @@ if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('pro endif if 'nosv' in get_option('executionStateType') and 'nosv' in get_option('processingUnitType') - nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ] ) + nosv = executable('nosv', [ 'cpp/nosv.cpp'], dependencies: [ TaskRBuildDep ] ) if get_option('buildTests') test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) @@ -19,7 +19,7 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'python/main.py' ], is_parallel : false, env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, diff --git a/examples/local/pendingOperation/py_source/main.py b/examples/pendingOperation/python/main.py similarity index 100% rename from examples/local/pendingOperation/py_source/main.py rename to examples/pendingOperation/python/main.py diff --git a/examples/local/pendingOperation/py_source/pendingOperation.py b/examples/pendingOperation/python/pendingOperation.py similarity index 100% rename from examples/local/pendingOperation/py_source/pendingOperation.py rename to examples/pendingOperation/python/pendingOperation.py diff --git a/examples/local/resourceList/README.rst b/examples/resourceList/README.rst similarity index 100% rename from examples/local/resourceList/README.rst rename to examples/resourceList/README.rst diff --git a/examples/local/resourceList/source/nosv.cpp b/examples/resourceList/cpp/nosv.cpp similarity index 99% rename from examples/local/resourceList/source/nosv.cpp rename to examples/resourceList/cpp/nosv.cpp index d036699..67c32f9 100644 --- a/examples/local/resourceList/source/nosv.cpp +++ b/examples/resourceList/cpp/nosv.cpp @@ -24,7 +24,7 @@ #include #include -#include "source/workTask.hpp" +#include "cpp/workTask.hpp" int main(int argc, char **argv) { diff --git a/examples/local/resourceList/source/pthreads.cpp b/examples/resourceList/cpp/pthreads.cpp similarity index 99% rename from examples/local/resourceList/source/pthreads.cpp rename to examples/resourceList/cpp/pthreads.cpp index 43b6d0f..d85e5f0 100644 --- a/examples/local/resourceList/source/pthreads.cpp +++ b/examples/resourceList/cpp/pthreads.cpp @@ -21,7 +21,7 @@ #include #include #include -#include "source/workTask.hpp" +#include "cpp/workTask.hpp" int main(int argc, char **argv) { diff --git a/examples/local/resourceList/source/workTask.hpp b/examples/resourceList/cpp/workTask.hpp similarity index 100% rename from examples/local/resourceList/source/workTask.hpp rename to examples/resourceList/cpp/workTask.hpp diff --git a/examples/local/resourceList/meson.build b/examples/resourceList/meson.build similarity index 74% rename from examples/local/resourceList/meson.build rename to examples/resourceList/meson.build index a66bcbf..6d43937 100644 --- a/examples/local/resourceList/meson.build +++ b/examples/resourceList/meson.build @@ -1,7 +1,7 @@ -testSuite = [ 'examples', 'local', 'resourceList' ] +testSuite = [ 'examples', 'resourceList' ] if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('processingUnitType') - threading = executable('threading', [ 'source/pthreads.cpp'], dependencies: [ TaskRBuildDep ]) + threading = executable('threading', [ 'cpp/pthreads.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') test('threading', threading, args : [ '4', '100', '0', '1', '2', '3' ], suite: testSuite, workdir: threading.path() + '.p' ) @@ -9,7 +9,7 @@ if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('pro endif if 'nosv' in get_option('executionStateType') and 'nosv' in get_option('processingUnitType') - nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ]) + nosv = executable('nosv', [ 'cpp/nosv.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') test('nosv', nosv, args : [ '4', '100', '0', '1', '2', '3' ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) @@ -19,7 +19,7 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'python/main.py' ], is_parallel : false, env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, diff --git a/examples/local/resourceList/py_source/main.py b/examples/resourceList/python/main.py similarity index 100% rename from examples/local/resourceList/py_source/main.py rename to examples/resourceList/python/main.py diff --git a/examples/local/resourceList/py_source/workTask.py b/examples/resourceList/python/workTask.py similarity index 100% rename from examples/local/resourceList/py_source/workTask.py rename to examples/resourceList/python/workTask.py diff --git a/examples/local/mutex/README.rst b/examples/simple/README.rst similarity index 100% rename from examples/local/mutex/README.rst rename to examples/simple/README.rst diff --git a/examples/local/simple/source/nosv.cpp b/examples/simple/cpp/nosv.cpp similarity index 100% rename from examples/local/simple/source/nosv.cpp rename to examples/simple/cpp/nosv.cpp diff --git a/examples/local/simple/source/pthreads.cpp b/examples/simple/cpp/pthreads.cpp similarity index 100% rename from examples/local/simple/source/pthreads.cpp rename to examples/simple/cpp/pthreads.cpp diff --git a/examples/local/simple/source/simple.hpp b/examples/simple/cpp/simple.hpp similarity index 100% rename from examples/local/simple/source/simple.hpp rename to examples/simple/cpp/simple.hpp diff --git a/examples/local/workerSpecific/meson.build b/examples/simple/meson.build similarity index 73% rename from examples/local/workerSpecific/meson.build rename to examples/simple/meson.build index 04eba5a..609ffc5 100644 --- a/examples/local/workerSpecific/meson.build +++ b/examples/simple/meson.build @@ -1,7 +1,7 @@ -testSuite = [ 'examples', 'local', 'workerSpecific' ] +testSuite = [ 'examples', 'simple' ] if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('processingUnitType') - threading = executable('threading', [ 'source/pthreads.cpp'], dependencies: [ TaskRBuildDep ] ) + threading = executable('threading', [ 'cpp/pthreads.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') test('threading', threading, args : [ ], suite: testSuite, workdir: threading.path() + '.p' ) @@ -9,7 +9,7 @@ if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('pro endif if 'nosv' in get_option('executionStateType') and 'nosv' in get_option('processingUnitType') - nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ] ) + nosv = executable('nosv', [ 'cpp/nosv.cpp'], dependencies: [ TaskRBuildDep ]) if get_option('buildTests') test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) @@ -19,7 +19,7 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'python/main.py' ], is_parallel : false, env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, diff --git a/examples/local/simple/py_source/main.py b/examples/simple/python/main.py similarity index 100% rename from examples/local/simple/py_source/main.py rename to examples/simple/python/main.py diff --git a/examples/local/simple/py_source/simple.py b/examples/simple/python/simple.py similarity index 100% rename from examples/local/simple/py_source/simple.py rename to examples/simple/python/simple.py diff --git a/examples/local/suspend/README.rst b/examples/suspend/README.rst similarity index 100% rename from examples/local/suspend/README.rst rename to examples/suspend/README.rst diff --git a/examples/local/suspend/source/nosv.cpp b/examples/suspend/cpp/nosv.cpp similarity index 100% rename from examples/local/suspend/source/nosv.cpp rename to examples/suspend/cpp/nosv.cpp diff --git a/examples/local/suspend/source/pthreads.cpp b/examples/suspend/cpp/pthreads.cpp similarity index 100% rename from examples/local/suspend/source/pthreads.cpp rename to examples/suspend/cpp/pthreads.cpp diff --git a/examples/local/suspend/source/suspend.hpp b/examples/suspend/cpp/suspend.hpp similarity index 100% rename from examples/local/suspend/source/suspend.hpp rename to examples/suspend/cpp/suspend.hpp diff --git a/examples/local/manyParallel/meson.build b/examples/suspend/meson.build similarity index 73% rename from examples/local/manyParallel/meson.build rename to examples/suspend/meson.build index 8039b4c..02baefa 100644 --- a/examples/local/manyParallel/meson.build +++ b/examples/suspend/meson.build @@ -1,7 +1,7 @@ -testSuite = [ 'examples', 'local', 'manyParallel' ] +testSuite = [ 'examples', 'suspend' ] if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('processingUnitType') - threading = executable('threading', [ 'source/pthreads.cpp'], dependencies: [ TaskRBuildDep ] ) + threading = executable('threading', [ 'cpp/pthreads.cpp'], dependencies: [ TaskRBuildDep ] ) if get_option('buildTests') test('threading', threading, args : [ '2', '100' ], suite: testSuite, workdir: threading.path() + '.p' ) @@ -9,7 +9,7 @@ if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('pro endif if 'nosv' in get_option('executionStateType') and 'nosv' in get_option('processingUnitType') - nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ] ) + nosv = executable('nosv', [ 'cpp/nosv.cpp'], dependencies: [ TaskRBuildDep ] ) if get_option('buildTests') test('nosv', nosv, args : [ '2', '100' ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) @@ -19,7 +19,7 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'python/main.py' ], is_parallel : false, env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, diff --git a/examples/local/suspend/py_source/main.py b/examples/suspend/python/main.py similarity index 100% rename from examples/local/suspend/py_source/main.py rename to examples/suspend/python/main.py diff --git a/examples/local/suspend/py_source/suspend.py b/examples/suspend/python/suspend.py similarity index 100% rename from examples/local/suspend/py_source/suspend.py rename to examples/suspend/python/suspend.py diff --git a/examples/local/workerSpecific/README.rst b/examples/workerSpecific/README.rst similarity index 100% rename from examples/local/workerSpecific/README.rst rename to examples/workerSpecific/README.rst diff --git a/examples/local/workerSpecific/source/nosv.cpp b/examples/workerSpecific/cpp/nosv.cpp similarity index 100% rename from examples/local/workerSpecific/source/nosv.cpp rename to examples/workerSpecific/cpp/nosv.cpp diff --git a/examples/local/workerSpecific/source/pthreads.cpp b/examples/workerSpecific/cpp/pthreads.cpp similarity index 100% rename from examples/local/workerSpecific/source/pthreads.cpp rename to examples/workerSpecific/cpp/pthreads.cpp diff --git a/examples/local/workerSpecific/source/workerSpecific.hpp b/examples/workerSpecific/cpp/workerSpecific.hpp similarity index 100% rename from examples/local/workerSpecific/source/workerSpecific.hpp rename to examples/workerSpecific/cpp/workerSpecific.hpp diff --git a/examples/local/pendingOperation/meson.build b/examples/workerSpecific/meson.build similarity index 72% rename from examples/local/pendingOperation/meson.build rename to examples/workerSpecific/meson.build index 5d4bc27..f890e61 100644 --- a/examples/local/pendingOperation/meson.build +++ b/examples/workerSpecific/meson.build @@ -1,7 +1,7 @@ -testSuite = [ 'examples', 'local', 'pendingOperation' ] +testSuite = [ 'examples', 'workerSpecific' ] if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('processingUnitType') - threading = executable('threading', [ 'source/pthreads.cpp'], dependencies: [ TaskRBuildDep ] ) + threading = executable('threading', [ 'cpp/pthreads.cpp'], dependencies: [ TaskRBuildDep ] ) if get_option('buildTests') test('threading', threading, args : [ ], suite: testSuite, workdir: threading.path() + '.p' ) @@ -9,7 +9,7 @@ if 'boost' in get_option('executionStateType') and 'pthreads' in get_option('pro endif if 'nosv' in get_option('executionStateType') and 'nosv' in get_option('processingUnitType') - nosv = executable('nosv', [ 'source/nosv.cpp'], dependencies: [ TaskRBuildDep ] ) + nosv = executable('nosv', [ 'cpp/nosv.cpp'], dependencies: [ TaskRBuildDep ] ) if get_option('buildTests') test('nosv', nosv, args : [ ], is_parallel : false, suite: testSuite, workdir: nosv.path() + '.p' ) @@ -19,7 +19,7 @@ endif if get_option('buildPyTaskR') and get_option('buildTests') test('pyTaskR', py, - args : [ 'py_source/main.py' ], + args : [ 'python/main.py' ], is_parallel : false, env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], suite: testSuite, diff --git a/examples/local/workerSpecific/py_source/main.py b/examples/workerSpecific/python/main.py similarity index 100% rename from examples/local/workerSpecific/py_source/main.py rename to examples/workerSpecific/python/main.py diff --git a/examples/local/workerSpecific/py_source/workerSpecific.py b/examples/workerSpecific/python/workerSpecific.py similarity index 100% rename from examples/local/workerSpecific/py_source/workerSpecific.py rename to examples/workerSpecific/python/workerSpecific.py diff --git a/extern/hicr b/extern/hicr index de89eec..a3408df 160000 --- a/extern/hicr +++ b/extern/hicr @@ -1 +1 @@ -Subproject commit de89eec1c608feda79d6139511612437e64eece7 +Subproject commit a3408df876e3f41fc72cf5bed24c587c7c4e3788 diff --git a/extern/tracr b/extern/tracr index 5f46dca..54387c3 160000 --- a/extern/tracr +++ b/extern/tracr @@ -1 +1 @@ -Subproject commit 5f46dca3692c210516d7b8415cb6aa172e8e13ba +Subproject commit 54387c3c786095780c7a325162c5ebab3accbed4 diff --git a/include/pytaskr/mmm.cpp b/include/pytaskr/matmul.cpp similarity index 95% rename from include/pytaskr/mmm.cpp rename to include/pytaskr/matmul.cpp index 3f0730b..3167ff3 100644 --- a/include/pytaskr/mmm.cpp +++ b/include/pytaskr/matmul.cpp @@ -26,7 +26,7 @@ /** * Compute mmm locally */ -void mmm(taskr::Task *) +void matmul(taskr::Task *) { const size_t N = 1000; @@ -66,7 +66,7 @@ namespace taskr __attribute__((constructor)) // GCC/Clang: Run before main/init void register_my_func() { - register_function("cpp_mmm", mmm); + register_function("cpp_matmul", matmul); } } // namespace taskr \ No newline at end of file diff --git a/include/pytaskr/meson.build b/include/pytaskr/meson.build index 7328282..81e92ff 100644 --- a/include/pytaskr/meson.build +++ b/include/pytaskr/meson.build @@ -6,7 +6,7 @@ py = import('python').find_installation(pure: false) pybind11_dep = dependency('pybind11', required: true) py.extension_module('taskr', - ['pytaskr.cpp', 'mmm.cpp'], + ['pytaskr.cpp', 'matmul.cpp'], install: true, dependencies : [TaskRBuildDep, pybind11_dep], ) \ No newline at end of file diff --git a/meson.build b/meson.build index e88ec4b..bfd5495 100644 --- a/meson.build +++ b/meson.build @@ -20,26 +20,24 @@ if meson.is_subproject() == false # Selecting default HiCR Backends HiCRBackends = ['hwloc'] - HiCR_ES_PU_Backends = [] if 'boost' in get_option('executionStateType') - HiCR_ES_PU_Backends += ['boost'] + HiCRBackends += ['boost'] endif if 'nosv' in get_option('executionStateType') - HiCR_ES_PU_Backends += ['nosv'] + HiCRBackends += ['nosv'] endif if 'pthreads' in get_option('processingUnitType') - HiCR_ES_PU_Backends += ['pthreads'] + HiCRBackends += ['pthreads'] endif if 'nosv' in get_option('processingUnitType') - if 'nosv' not in HiCR_ES_PU_Backends - HiCR_ES_PU_Backends += ['nosv'] + if 'nosv' not in HiCRBackends + HiCRBackends += ['nosv'] endif endif endif - HiCRBackends += HiCR_ES_PU_Backends # Getting selected distributed engine distributedEngine = get_option('distributedEngine') @@ -96,7 +94,14 @@ TaskRBuildDep = declare_dependency( ####### Build PyTaskR if get_option('buildPyTaskR') - assert(HiCR_ES_PU_Backends.length() == 3, 'To use pyTaskr, one has to enable all 4 backends: -DexecutionStateType=nosv,boost -DprocessingUnitType=nosv,pthreads') + missing = [] + foreach r : ['boost', 'pthreads', 'nosv'] + if not (r in HiCRBackends) + missing += r + endif + endforeach + + assert(missing.length() == 0, 'Missing required backends for pyTaskr: ' + ', '.join(missing)) subdir('include/pytaskr') endif From f1f7a2503d90bfd1b45fb693c06dff85b62fa5d5 Mon Sep 17 00:00:00 2001 From: noabauma Date: Wed, 2 Jul 2025 14:56:00 +0200 Subject: [PATCH 26/27] old approach of adding a cpp function --- examples/matmul/python/matmul.cpp | 12 +++--- include/pytaskr/matmul.cpp | 72 ------------------------------- include/pytaskr/meson.build | 6 ++- 3 files changed, 12 insertions(+), 78 deletions(-) delete mode 100644 include/pytaskr/matmul.cpp diff --git a/examples/matmul/python/matmul.cpp b/examples/matmul/python/matmul.cpp index 05c8f69..3129388 100644 --- a/examples/matmul/python/matmul.cpp +++ b/examples/matmul/python/matmul.cpp @@ -61,10 +61,12 @@ void matmul(taskr::Task *) namespace taskr { -__attribute__((constructor)) // GCC/Clang: Run before main/init -void register_my_func() -{ - register_function("cpp_matmul", matmul); -} +struct AutoRegister { + AutoRegister() { + register_function("cpp_matmul", matmul); + } +}; + +static AutoRegister reg{}; } // namespace taskr \ No newline at end of file diff --git a/include/pytaskr/matmul.cpp b/include/pytaskr/matmul.cpp deleted file mode 100644 index 3167ff3..0000000 --- a/include/pytaskr/matmul.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2025 Huawei Technologies Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include -#include - -#define mytype float - -#define NTASKS 2 - -/** - * Compute mmm locally - */ -void matmul(taskr::Task *) -{ - const size_t N = 1000; - - // Allocate memory - volatile mytype *A = (mytype *)calloc(1, N * N * sizeof(mytype)); - volatile mytype *B = (mytype *)malloc(N * N * sizeof(mytype)); - volatile mytype *C = (mytype *)malloc(N * N * sizeof(mytype)); - - // Filling matrices B and C - for (size_t i = 0; i < N; ++i) - { - for (size_t j = 0; j < N; ++j) - { - B[i * N + j] = 1.0 / (mytype(i + 1)); - C[i * N + j] = 1.0 / (mytype(j + 1)); - } - } - - // mmm - for (size_t i = 0; i < N; ++i) - { - for (size_t j = 0; j < N; ++j) - { - for (size_t k = 0; k < N; ++k) { A[i * N + j] += B[i * N + k] * C[k * N + j]; } - } - } - - // free memory - free((mytype *)A); - free((mytype *)B); - free((mytype *)C); -} - -namespace taskr -{ - -__attribute__((constructor)) // GCC/Clang: Run before main/init -void register_my_func() -{ - register_function("cpp_matmul", matmul); -} - -} // namespace taskr \ No newline at end of file diff --git a/include/pytaskr/meson.build b/include/pytaskr/meson.build index 81e92ff..990891c 100644 --- a/include/pytaskr/meson.build +++ b/include/pytaskr/meson.build @@ -5,8 +5,12 @@ py = import('python').find_installation(pure: false) pybind11_dep = dependency('pybind11', required: true) +pysources = ['pytaskr.cpp'] + +pysources += ['../../examples/matmul/python/matmul.cpp'] + py.extension_module('taskr', - ['pytaskr.cpp', 'matmul.cpp'], + pysources, install: true, dependencies : [TaskRBuildDep, pybind11_dep], ) \ No newline at end of file From a6af87308800b4cf0a39fbdc7575fa7f170aabba Mon Sep 17 00:00:00 2001 From: noabauma Date: Wed, 2 Jul 2025 15:34:49 +0200 Subject: [PATCH 27/27] remaking the binding now. Now, the user has to create his own pybind --- examples/matmul/meson.build | 8 +++++- examples/matmul/python/matmul.cpp | 16 ++++------- examples/matmul/python/matmul.py | 6 +++-- include/pytaskr/meson.build | 6 +---- include/pytaskr/pytaskr.cpp | 28 -------------------- include/pytaskr/pytaskr.hpp | 44 ------------------------------- 6 files changed, 17 insertions(+), 91 deletions(-) delete mode 100644 include/pytaskr/pytaskr.hpp diff --git a/examples/matmul/meson.build b/examples/matmul/meson.build index 6a11772..94ec388 100644 --- a/examples/matmul/meson.build +++ b/examples/matmul/meson.build @@ -1,11 +1,17 @@ testSuite = [ 'examples', 'matmul' ] if get_option('buildPyTaskR') and get_option('buildTests') + py.extension_module('cpp_matmul', + ['python/matmul.cpp'], + install: true, + dependencies : [TaskRBuildDep, pybind11_dep], + ) + test('pyTaskR', py, args : [ 'python/main.py' ], is_parallel : false, - env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/'], + env: ['PYTHONPATH=' + meson.project_build_root() + '/include/pytaskr/:' + meson.project_build_root() + '/examples/matmul/'], suite: testSuite, workdir: meson.current_source_dir()) endif \ No newline at end of file diff --git a/examples/matmul/python/matmul.cpp b/examples/matmul/python/matmul.cpp index 3129388..ccc17c6 100644 --- a/examples/matmul/python/matmul.cpp +++ b/examples/matmul/python/matmul.cpp @@ -15,9 +15,9 @@ */ #include +#include #include -#include #define mytype float @@ -58,15 +58,9 @@ void matmul(taskr::Task *) free((mytype *)C); } -namespace taskr +PYBIND11_MODULE(cpp_matmul, m) { + m.doc() = "pybind11 plugin for matmul example"; -struct AutoRegister { - AutoRegister() { - register_function("cpp_matmul", matmul); - } -}; - -static AutoRegister reg{}; - -} // namespace taskr \ No newline at end of file + m.def("cpp_matmul", &matmul, "cpp function to do matrix-matrix multiplication."); +} \ No newline at end of file diff --git a/examples/matmul/python/matmul.py b/examples/matmul/python/matmul.py index c75248f..daf8ebb 100644 --- a/examples/matmul/python/matmul.py +++ b/examples/matmul/python/matmul.py @@ -15,16 +15,18 @@ """ import time -import taskr import numpy as np +import taskr +import cpp_matmul + NTASKS = 2 def matmul_cpp_Driver(runtime): # Initializing taskr runtime.initialize() - taskfc = taskr.get_cpp_function("cpp_matmul") + taskfc = taskr.Function(cpp_matmul.cpp_matmul) # Adding to tasks to taskr for i in range(NTASKS): diff --git a/include/pytaskr/meson.build b/include/pytaskr/meson.build index 990891c..905bc9e 100644 --- a/include/pytaskr/meson.build +++ b/include/pytaskr/meson.build @@ -5,12 +5,8 @@ py = import('python').find_installation(pure: false) pybind11_dep = dependency('pybind11', required: true) -pysources = ['pytaskr.cpp'] - -pysources += ['../../examples/matmul/python/matmul.cpp'] - py.extension_module('taskr', - pysources, + ['pytaskr.cpp'], install: true, dependencies : [TaskRBuildDep, pybind11_dep], ) \ No newline at end of file diff --git a/include/pytaskr/pytaskr.cpp b/include/pytaskr/pytaskr.cpp index 02d241e..122e72a 100644 --- a/include/pytaskr/pytaskr.cpp +++ b/include/pytaskr/pytaskr.cpp @@ -21,27 +21,11 @@ #include #include -#include "pytaskr.hpp" - namespace py = pybind11; namespace taskr { -/** - * Vector to keep track which cpp functions to register - */ -std::vector &get_registry() -{ - static std::vector reg; - return reg; -} - -/** - * Function to store the cpp function with a given naming - */ -void register_function(const std::string &name, function_t fc) { get_registry().push_back({name, fc}); } - /** * Pybind11 module for binding taskr stuff */ @@ -49,18 +33,6 @@ PYBIND11_MODULE(taskr, m) { m.doc() = "pybind11 plugin for TaskR"; - // Register any other user defined functions - m.def("get_cpp_function", [](const std::string &name) { - auto ® = taskr::get_registry(); - - // check if this function even exists - auto it = std::find_if(reg.begin(), reg.end(), [&](const auto &e) { return e.name == name; }); - - if (it == reg.end()) HICR_THROW_RUNTIME("Function not found: %s\n", name); - - return std::make_unique(it->fc); - }); - py::enum_(m, "HiCRBackend").value("nosv", backend_t::nosv).value("threading", backend_t::threading).export_values(); // pyTaskR's PyRuntime class diff --git a/include/pytaskr/pytaskr.hpp b/include/pytaskr/pytaskr.hpp deleted file mode 100644 index 981f07d..0000000 --- a/include/pytaskr/pytaskr.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2025 Huawei Technologies Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -namespace taskr -{ - -/** - * Struct with the cpp funcion and the given name - */ -struct FunctionRegistration -{ - std::string name; - function_t fc; -}; - -/** - * Vector to keep track which cpp functions to register - */ -std::vector &get_registry(); - -/** - * Function to store the cpp function with a given naming - */ -void register_function(const std::string &name, function_t fc); - -} // namespace taskr \ No newline at end of file