diff --git a/pyopencl/c_wrapper/wrap_cl_core.h b/pyopencl/c_wrapper/wrap_cl_core.h index a3b6f54e5a4c434d907fec472f5c2b1b2fe62529..2e3132b9073c890d693ae7d7a70c4d91684398c4 100644 --- a/pyopencl/c_wrapper/wrap_cl_core.h +++ b/pyopencl/c_wrapper/wrap_cl_core.h @@ -85,3 +85,5 @@ void pyopencl_free_pointer(void*); void pyopencl_free_pointer_array(void**, uint32_t size); int pyopencl_have_gl(); + +unsigned pyopencl_bitlog2(unsigned long v); diff --git a/pyopencl/tools.py b/pyopencl/tools.py index 635dfb6327047c40309bd6fc59810315a9514ab5..b335dee32821819df35be0f6cf2f275d3896466f 100644 --- a/pyopencl/tools.py +++ b/pyopencl/tools.py @@ -32,6 +32,7 @@ import pyopencl.np as np from decorator import decorator import pyopencl as cl from pytools import memoize, memoize_method +from pyopencl._cffi import _lib import re @@ -61,6 +62,7 @@ _register_types() # {{{ imported names +bitlog2 = _lib.pyopencl_bitlog2 from pyopencl.mempool import ( # noqa PooledBuffer, DeferredAllocator, ImmediateAllocator, MemoryPool) diff --git a/setup.py b/setup.py index 23f14b1fe4e2596fa4c4b04d0059f419a46aee85..a6a220a656e56adc394c643778dfc579e5223af4 100644 --- a/setup.py +++ b/setup.py @@ -231,6 +231,7 @@ def main(): Extension("_wrapcl", ["src/c_wrapper/wrap_cl.cpp", "src/c_wrapper/wrap_constants.cpp", + "src/c_wrapper/bitlog.cpp", #"src/c_wrapper/wrap_mempool.cpp", ], include_dirs=( diff --git a/src/c_wrapper/bitlog.cpp b/src/c_wrapper/bitlog.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f795172979b24d07b2bed99e344f536549f46a00 --- /dev/null +++ b/src/c_wrapper/bitlog.cpp @@ -0,0 +1,28 @@ +#include "bitlog.h" +#include "wrap_cl.h" + +/* from http://graphics.stanford.edu/~seander/bithacks.html */ +const char pyopencl::log_table_8[] = +{ + 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 +}; + +unsigned pyopencl_bitlog2(unsigned long v) +{ + return pyopencl::bitlog2(v); +} diff --git a/src/c_wrapper/bitlog.h b/src/c_wrapper/bitlog.h new file mode 100644 index 0000000000000000000000000000000000000000..fde67e8d8569970ec8c888c02ed91ec598f940b1 --- /dev/null +++ b/src/c_wrapper/bitlog.h @@ -0,0 +1,40 @@ +// Base-2 logarithm bithack. + +#ifndef _AFJDFJSDFSD_PYOPENCL_HEADER_SEEN_BITLOG_HPP +#define _AFJDFJSDFSD_PYOPENCL_HEADER_SEEN_BITLOG_HPP + +#include <climits> +#include <stdint.h> + +namespace pyopencl +{ + extern const char log_table_8[]; + + static inline unsigned bitlog2_16(uint16_t v) + { + if (unsigned long t = v >> 8) + return 8 + log_table_8[t]; + else + return log_table_8[v]; + } + + static inline unsigned bitlog2_32(uint32_t v) + { + if (uint16_t t = v >> 16) + return 16 + bitlog2_16(t); + else + return bitlog2_16(v); + } + + static inline unsigned bitlog2(unsigned long v) + { +#if (ULONG_MAX != 4294967295) + if (uint32_t t = v >> 32) + return 32 + bitlog2_32(t); + else +#endif + return bitlog2_32(v); + } +} + +#endif diff --git a/src/c_wrapper/wrap_cl.h b/src/c_wrapper/wrap_cl.h index f15e3deb3e829ddeb63a0ca0eb0d97f2ab2e4ea8..ee029fbf87679ab64bac267c64827f08fefdf005 100644 --- a/src/c_wrapper/wrap_cl.h +++ b/src/c_wrapper/wrap_cl.h @@ -74,5 +74,3 @@ extern "C" { #endif #endif - -