From a2c6f4d49049f86c0cc867368194d2e08812379a Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Fri, 1 Feb 2013 20:20:54 +0100 Subject: pmt: added python converters --- gruel/src/python/CMakeLists.txt | 5 +- gruel/src/python/pmt/__init__.py | 2 + gruel/src/python/pmt/pmt_to_python.py | 97 +++++++++++++++++++++++++++++++++++ gruel/src/python/qa_pmt_to_python.py | 34 ++++++++++++ 4 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 gruel/src/python/pmt/pmt_to_python.py create mode 100755 gruel/src/python/qa_pmt_to_python.py (limited to 'gruel/src') diff --git a/gruel/src/python/CMakeLists.txt b/gruel/src/python/CMakeLists.txt index 13f2111ba..f5c4ac47a 100644 --- a/gruel/src/python/CMakeLists.txt +++ b/gruel/src/python/CMakeLists.txt @@ -28,8 +28,9 @@ GR_PYTHON_INSTALL( COMPONENT "gruel_python" ) -GR_PYTHON_INSTALL( - FILES pmt/__init__.py +GR_PYTHON_INSTALL(FILES + pmt/__init__.py + pmt/pmt_to_python.py DESTINATION ${GR_PYTHON_DIR}/gruel/pmt COMPONENT "gruel_python" ) diff --git a/gruel/src/python/pmt/__init__.py b/gruel/src/python/pmt/__init__.py index 0862af0eb..bc933e80a 100644 --- a/gruel/src/python/pmt/__init__.py +++ b/gruel/src/python/pmt/__init__.py @@ -26,4 +26,6 @@ The GNU Radio Utility Etcetera Library's Polymorphic Types for Python. ''' from pmt_swig import * +from pmt_to_python import pmt_to_python as to_python +from pmt_to_python import python_to_pmt as to_pmt diff --git a/gruel/src/python/pmt/pmt_to_python.py b/gruel/src/python/pmt/pmt_to_python.py new file mode 100644 index 000000000..030c1c11d --- /dev/null +++ b/gruel/src/python/pmt/pmt_to_python.py @@ -0,0 +1,97 @@ +# Copyright 2012,2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +try: import pmt_swig as pmt +except: import pmt +import numpy + +#define missing +def pmt_to_tuple(p): + elems = list() + for i in range(pmt.pmt_length(p)): + elem = pmt.pmt_tuple_ref(p, i) + elems.append(pmt_to_python(elem)) + return tuple(elems) + +def pmt_from_tuple(p): + args = map(python_to_pmt, p) + return pmt.pmt_make_tuple(*args) + +def pmt_to_vector(p): + v = list() + for i in range(pmt.pmt_length(p)): + elem = pmt.pmt_vector_ref(p, i) + v.append(pmt_to_python(elem)) + return v + +def pmt_from_vector(p): + v = pmt.pmt_make_vector(len(p), pmt.PMT_NIL) + for i, elem in enumerate(p): + pmt.pmt_vector_set(v, i, python_to_pmt(elem)) + return v + +def pmt_to_dict(p): + d = dict() + items = pmt.pmt_dict_items(p) + for i in range(pmt.pmt_length(items)): + pair = pmt.pmt_nth(i, items) + k = pmt.pmt_car(pair) + v = pmt.pmt_cdr(pair) + d[pmt_to_python(k)] = pmt_to_python(v) + return d + +def pmt_from_dict(p): + d = pmt.pmt_make_dict() + for k, v in p.iteritems(): + #dict is immutable -> therefore pmt_dict_add returns the new dict + d = pmt.pmt_dict_add(d, python_to_pmt(k), python_to_pmt(v)) + return d + +def numpy_to_blob(p): + p = p.view(numpy.uint8) + b = pmt.pmt_make_blob(len(p)) + pmt.pmt_blob_data(b)[:] = p + return b + +THE_TABLE = ( #python type, check pmt type, to python, from python + (None, pmt.pmt_is_null, lambda x: None, lambda x: pmt.PMT_NIL), + (bool, pmt.pmt_is_bool, pmt.pmt_to_bool, pmt.pmt_from_bool), + (str, pmt.pmt_is_symbol, pmt.pmt_symbol_to_string, pmt.pmt_string_to_symbol), + (int, pmt.pmt_is_integer, pmt.pmt_to_long, pmt.pmt_from_long), + (long, pmt.pmt_is_uint64, lambda x: long(pmt.pmt_to_uint64(x)), pmt.pmt_from_uint64), + (float, pmt.pmt_is_real, pmt.pmt_to_double, pmt.pmt_from_double), + (complex, pmt.pmt_is_complex, pmt.pmt_to_complex, pmt.pmt_from_complex), + (tuple, pmt.pmt_is_tuple, pmt_to_tuple, pmt_from_tuple), + (list, pmt.pmt_is_vector, pmt_to_vector, pmt_from_vector), + (dict, pmt.pmt_is_dict, pmt_to_dict, pmt_from_dict), + (numpy.ndarray, pmt.pmt_is_blob, pmt.pmt_blob_data, numpy_to_blob), +) + +def pmt_to_python(p): + for python_type, pmt_check, to_python, from_python in THE_TABLE: + if pmt_check(p): return to_python(p) + return p #give up, we return the same + +def python_to_pmt(p): + for python_type, pmt_check, to_python, from_python in THE_TABLE: + if python_type is None: + if p == None: return from_python(p) + elif isinstance(p, python_type): return from_python(p) + return p #give up, we return the same + diff --git a/gruel/src/python/qa_pmt_to_python.py b/gruel/src/python/qa_pmt_to_python.py new file mode 100755 index 000000000..c63403a52 --- /dev/null +++ b/gruel/src/python/qa_pmt_to_python.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# +# Copyright 2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import unittest +import pmt + +class test_gruel_pmt_to_python(unittest.TestCase): + + def test01 (self): + b = pmt.pmt_from_double(123765) + self.assertEqual(pmt.to_python(b), 123765) + t = pmt.to_pmt(range(5)) + +if __name__ == '__main__': + unittest.main() -- cgit From 7bc415bd2875132ce321c5913950d23e7c9ad8b1 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Wed, 19 Dec 2012 13:37:39 -0500 Subject: gruel: adding wrapper layer for gruel threads to enable setting thread affinity. Working in Linux; programmed for Windows (but untested); nops for OSX. --- gruel/src/include/gruel/thread.h | 19 +++- gruel/src/lib/CMakeLists.txt | 1 + gruel/src/lib/thread.cc | 223 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 gruel/src/lib/thread.cc (limited to 'gruel/src') diff --git a/gruel/src/include/gruel/thread.h b/gruel/src/include/gruel/thread.h index 63143c8b4..72499808c 100644 --- a/gruel/src/include/gruel/thread.h +++ b/gruel/src/include/gruel/thread.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2009,2010,2011 Free Software Foundation, Inc. + * Copyright 2009-2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -26,6 +26,7 @@ #include #include #include +#include namespace gruel { @@ -34,6 +35,22 @@ namespace gruel { typedef boost::mutex::scoped_lock scoped_lock; typedef boost::condition_variable condition_variable; +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + typedef HANDLE gr_thread_t; +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) + typedef pthread_t gr_thread_t; +#else + typedef pthread_t gr_thread_t; +#endif + + GRUEL_API gr_thread_t get_current_thread_id(); + GRUEL_API void thread_bind_to_processor(const std::vector &mask); + GRUEL_API void thread_bind_to_processor(unsigned int n); + GRUEL_API void thread_bind_to_processor(gr_thread_t thread, const std::vector &mask); + GRUEL_API void thread_bind_to_processor(gr_thread_t thread, unsigned int n); + GRUEL_API void thread_unbind(); + GRUEL_API void thread_unbind(gr_thread_t thread); + } /* namespace gruel */ #endif /* INCLUDED_THREAD_H */ diff --git a/gruel/src/lib/CMakeLists.txt b/gruel/src/lib/CMakeLists.txt index e33b80d64..717d56660 100644 --- a/gruel/src/lib/CMakeLists.txt +++ b/gruel/src/lib/CMakeLists.txt @@ -76,6 +76,7 @@ link_directories(${Boost_LIBRARY_DIRS}) list(APPEND gruel_sources realtime.cc sys_pri.cc + thread.cc thread_body_wrapper.cc thread_group.cc ) diff --git a/gruel/src/lib/thread.cc b/gruel/src/lib/thread.cc new file mode 100644 index 000000000..46ba1745a --- /dev/null +++ b/gruel/src/lib/thread.cc @@ -0,0 +1,223 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + +#include + +namespace gruel { + + gr_thread_t + get_current_thread_id() + { + return GetCurrentThread(); + } + + void + thread_bind_to_processor(unsigned int n) + { + std::vector mask(1, n); + thread_bind_to_processor(get_current_thread_id(), mask); + } + + void + thread_bind_to_processor(const std::vector &mask) + { + thread_bind_to_processor(get_current_thread_id(), mask); + } + + void + thread_bind_to_processor(gr_thread_t thread, unsigned int n) + { + std::vector mask(1, n); + thread_bind_to_processor(thread, mask); + } + + void + thread_bind_to_processor(gr_thread_t thread, const std::vector &mask) + { + //DWORD_PTR mask = (1 << n); + DWORD_PTR mask = 0; + + std::vector _mask = mask; + std::vector::iterator itr; + for(itr = _mask.begin(); itr != _mask.end(); itr++) + mask |= (1 << (*itr)); + + DWORD_PTR ret = SetThreadAffinityMask(thread, mask); + if(ret == 0) { + std::stringstream s; + s << "thread_bind_to_processor failed with error: " << GetLastError() << std::endl; + throw std::runtime_error(s.str()); + } + } + + void + thread_unbind() + { + thread_bind_unbind(get_current_thread_id()); + } + + void + thread_unbind(gr_thread_t thread) + { + DWORD_PTR mask = sizeof(DWORD_PTR) - 1; + DWORD_PTR ret = SetThreadAffinityMask(thread, mask); + if(ret == 0) { + std::stringstream s; + s << "thread_unbind failed with error: " << GetLastError() << std::endl; + throw std::runtime_error(s.str()); + } + } +} /* namespace gruel */ + +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) + +namespace gruel { + + gr_thread_t + get_current_thread_id() + { + // Not implemented on OSX + } + + void + thread_bind_to_processor(unsigned int n) + { + // Not implemented on OSX + } + + void + thread_bind_to_processor(gr_thread_t thread, unsigned int n) + { + // Not implemented on OSX + } + + void + thread_bind_to_processor(gr_thread_t thread, const std::vector &mask) + { + // Not implemented on OSX + } + + void + thread_bind_to_processor(gr_thread_t thread, const std::vector &mask) + + void + thread_unbind() + { + // Not implemented on OSX + } + + void + thread_unbind(gr_thread_t thread) + { + // Not implemented on OSX + } +} /* namespace gruel */ + +#else + +#include +#include +#include + +namespace gruel { + + gr_thread_t + get_current_thread_id() + { + return pthread_self(); + } + + void + thread_bind_to_processor(unsigned int n) + { + std::vector mask(1, n); + thread_bind_to_processor(get_current_thread_id(), mask); + } + + void + thread_bind_to_processor(const std::vector &mask) + { + thread_bind_to_processor(get_current_thread_id(), mask); + } + + void + thread_bind_to_processor(gr_thread_t thread, unsigned int n) + { + std::vector mask(1, n); + thread_bind_to_processor(thread, mask); + } + + void + thread_bind_to_processor(gr_thread_t thread, const std::vector &mask) + { + cpu_set_t set; + size_t len = sizeof(cpu_set_t); + std::vector _mask = mask; + std::vector::iterator itr; + + CPU_ZERO(&set); + for(itr = _mask.begin(); itr != _mask.end(); itr++) + CPU_SET(*itr, &set); + + int ret = pthread_setaffinity_np(thread, len, &set); + if(ret != 0) { + std::stringstream s; + s << "thread_bind_to_processor failed with error: " << ret << std::endl; + throw std::runtime_error(s.str()); + } + } + + void + thread_unbind() + { + thread_unbind(get_current_thread_id()); + } + + void + thread_unbind(gr_thread_t thread) + { + cpu_set_t set; + size_t len = sizeof(cpu_set_t); + + CPU_ZERO(&set); + long ncpus = sysconf(_SC_NPROCESSORS_ONLN); + for(long n = 0; n < ncpus; n++) { + CPU_SET(n, &set); + } + + int ret = pthread_setaffinity_np(thread, len, &set); + if(ret != 0) { + std::stringstream s; + s << "thread_unbind failed with error: " << ret << std::endl; + throw std::runtime_error(s.str()); + } + } +} /* namespace gruel */ + +#endif -- cgit From 01eab0c7e283db9c1cfff0a26296a49128062cca Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Wed, 19 Dec 2012 13:38:24 -0500 Subject: core: working thread affinity concept into gr_blocks. Example in gnuradio-core/src/examples/mp-sched/affinity_set.py Documentation describing API in docs/doxygen/other/thread_affinity.dox --- gruel/src/lib/thread.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'gruel/src') diff --git a/gruel/src/lib/thread.cc b/gruel/src/lib/thread.cc index 46ba1745a..ab022c0bd 100644 --- a/gruel/src/lib/thread.cc +++ b/gruel/src/lib/thread.cc @@ -118,13 +118,16 @@ namespace gruel { } void - thread_bind_to_processor(gr_thread_t thread, const std::vector &mask) + thread_bind_to_processor(const std::vector &mask) { // Not implemented on OSX } void thread_bind_to_processor(gr_thread_t thread, const std::vector &mask) + { + // Not implemented on OSX + } void thread_unbind() -- cgit From 8bf083a99c8a0d43d365bdd9ad90e3d840c582e7 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Thu, 24 Jan 2013 09:26:19 -0500 Subject: gruel: need to include windows.h to know about HANDLE. --- gruel/src/include/gruel/thread.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gruel/src') diff --git a/gruel/src/include/gruel/thread.h b/gruel/src/include/gruel/thread.h index 72499808c..0427a8efc 100644 --- a/gruel/src/include/gruel/thread.h +++ b/gruel/src/include/gruel/thread.h @@ -28,6 +28,10 @@ #include #include +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +#include +#endif + namespace gruel { typedef boost::thread thread; -- cgit From 8511ee7f22f197526e0345554842a9ac422974ae Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sun, 27 Jan 2013 13:32:20 -0500 Subject: sched: added documentation for affinity setting functions. --- gruel/src/include/gruel/thread.h | 73 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'gruel/src') diff --git a/gruel/src/include/gruel/thread.h b/gruel/src/include/gruel/thread.h index 0427a8efc..595b7b1ac 100644 --- a/gruel/src/include/gruel/thread.h +++ b/gruel/src/include/gruel/thread.h @@ -39,6 +39,8 @@ namespace gruel { typedef boost::mutex::scoped_lock scoped_lock; typedef boost::condition_variable condition_variable; + /*! \brief a system-dependent typedef for the underlying thread type. + */ #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) typedef HANDLE gr_thread_t; #elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) @@ -47,12 +49,83 @@ namespace gruel { typedef pthread_t gr_thread_t; #endif + /*! \brief Get the current thread's ID as a gr_thread_t + * + * We use this when setting the thread affinity or any other + * low-level thread settings. Can be called withing a GNU Radio + * block to get a reference to its current thread ID. + */ GRUEL_API gr_thread_t get_current_thread_id(); + + /*! \brief Bind the current thread to a set of cores. + * + * Wrapper for system-dependent calls to set the affinity of the + * current thread to the processor mask. The mask is simply a + * 1-demensional vector containing the processor or core number from + * 0 to N-1 for N cores. + * + * Note: this does not work on OSX; it is a nop call since OSX does + * not support the concept of thread affinity (and what they do + * support in this way since 10.5 is not what we want or can use in + * this fashion). + */ GRUEL_API void thread_bind_to_processor(const std::vector &mask); + + /*! \brief Convineince function to bind the current thread to a single core. + * + * Wrapper for system-dependent calls to set the affinity of the + * current thread to a given core from 0 to N-1 for N cores. + * + * Note: this does not work on OSX; it is a nop call since OSX does + * not support the concept of thread affinity (and what they do + * support in this way since 10.5 is not what we want or can use in + * this fashion). + */ GRUEL_API void thread_bind_to_processor(unsigned int n); + + /*! \brief Bind a thread to a set of cores. + * + * Wrapper for system-dependent calls to set the affinity of the + * given thread ID to the processor mask. The mask is simply a + * 1-demensional vector containing the processor or core number from + * 0 to N-1 for N cores. + * + * Note: this does not work on OSX; it is a nop call since OSX does + * not support the concept of thread affinity (and what they do + * support in this way since 10.5 is not what we want or can use in + * this fashion). + */ GRUEL_API void thread_bind_to_processor(gr_thread_t thread, const std::vector &mask); + + + /*! \brief Convineince function to bind the a thread to a single core. + * + * Wrapper for system-dependent calls to set the affinity of the + * given thread ID to a given core from 0 to N-1 for N cores. + * + * Note: this does not work on OSX; it is a nop call since OSX does + * not support the concept of thread affinity (and what they do + * support in this way since 10.5 is not what we want or can use in + * this fashion). + */ GRUEL_API void thread_bind_to_processor(gr_thread_t thread, unsigned int n); + + /*! \brief Remove any thread-processor affinity for the current thread. + * + * Note: this does not work on OSX; it is a nop call since OSX does + * not support the concept of thread affinity (and what they do + * support in this way since 10.5 is not what we want or can use in + * this fashion). + */ GRUEL_API void thread_unbind(); + + /*! \brief Remove any thread-processor affinity for a given thread ID. + * + * Note: this does not work on OSX; it is a nop call since OSX does + * not support the concept of thread affinity (and what they do + * support in this way since 10.5 is not what we want or can use in + * this fashion). + */ GRUEL_API void thread_unbind(gr_thread_t thread); } /* namespace gruel */ -- cgit From 0c46b36ed5c52f0003f0cd45195bdee1193a2a33 Mon Sep 17 00:00:00 2001 From: Nicholas Corgan Date: Wed, 6 Feb 2013 12:36:13 -0800 Subject: gruel: renamed mask to dword_mask --- gruel/src/lib/thread.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'gruel/src') diff --git a/gruel/src/lib/thread.cc b/gruel/src/lib/thread.cc index ab022c0bd..8ebe822fb 100644 --- a/gruel/src/lib/thread.cc +++ b/gruel/src/lib/thread.cc @@ -61,14 +61,14 @@ namespace gruel { thread_bind_to_processor(gr_thread_t thread, const std::vector &mask) { //DWORD_PTR mask = (1 << n); - DWORD_PTR mask = 0; + DWORD_PTR dword_mask = 0; std::vector _mask = mask; std::vector::iterator itr; for(itr = _mask.begin(); itr != _mask.end(); itr++) - mask |= (1 << (*itr)); + dword_mask |= (1 << (*itr)); - DWORD_PTR ret = SetThreadAffinityMask(thread, mask); + DWORD_PTR ret = SetThreadAffinityMask(thread, dword_mask); if(ret == 0) { std::stringstream s; s << "thread_bind_to_processor failed with error: " << GetLastError() << std::endl; @@ -79,14 +79,14 @@ namespace gruel { void thread_unbind() { - thread_bind_unbind(get_current_thread_id()); + thread_unbind(get_current_thread_id()); } void thread_unbind(gr_thread_t thread) { - DWORD_PTR mask = sizeof(DWORD_PTR) - 1; - DWORD_PTR ret = SetThreadAffinityMask(thread, mask); + DWORD_PTR dword_mask = sizeof(DWORD_PTR) - 1; + DWORD_PTR ret = SetThreadAffinityMask(thread, dword_mask); if(ret == 0) { std::stringstream s; s << "thread_unbind failed with error: " << GetLastError() << std::endl; -- cgit From e05c3cd81e2b3e60a6d09ebd1afbb641c33c8ea9 Mon Sep 17 00:00:00 2001 From: Nicholas Corgan Date: Wed, 6 Feb 2013 14:21:11 -0800 Subject: gruel: Added WIN32_LEAN_AND_MEAN definition before windows.h include --- gruel/src/include/gruel/thread.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'gruel/src') diff --git a/gruel/src/include/gruel/thread.h b/gruel/src/include/gruel/thread.h index 595b7b1ac..2172e90d3 100644 --- a/gruel/src/include/gruel/thread.h +++ b/gruel/src/include/gruel/thread.h @@ -29,7 +29,13 @@ #include #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + #include + #endif namespace gruel { -- cgit