Dnia 2010-10-21, czw o godzinie 20:07 +0100, Adam D. Barratt pisze: > On Thu, 2010-10-21 at 19:36 +0200, Tomasz Rybak wrote: > > Dnia 2010-10-18, pon o godzinie 21:13 +0100, Adam D. Barratt pisze: > > > On Tue, 2010-10-12 at 11:23 +0200, Tomasz Rybak wrote: > [...] > > > > There has been 24 changes in upstream between version in Debian > > > > and final 0.92. From those maybe 6 are not needed - documentation > > > > and example fixes, fixing Python setup (which is disabled in package), > > > > fixing Windows bug. If I would to backport fixes for errors, I would > > > > need to include more than half of changes made by upstream. > > > > > > It's a little difficult to tell from that description whether the > > > changes would be acceptable. Please could you provide a debdiff for the > > > proposed upload? > > > > Attached. > > I can also attach full diff of source between version in Squeeze > > and proposed version, if needed. > > Thanks. A debdiff between the source packages was what I intended so > yes, please. :-) > > Regards, > > Adam > Sorry. pyopencl.debdiff contains debbiff pyopencl.gitdiff contains diff from upstream git respository between version in Squeeze and proposed one. Regards. -- Tomasz Rybak <bogomips@post.pl> GPG/PGP key ID: 2AD5 9860 Fingerprint A481 824E 7DD3 9C0E C40A 488E C654 FB33 2AD5 9860 http://member.acm.org/~tomaszrybak
diff -Nru pyopencl-0.92~beta+git20100709/aksetup_helper.py pyopencl-0.92/aksetup_helper.py
--- pyopencl-0.92~beta+git20100709/aksetup_helper.py 2010-07-10 18:03:27.000000000 +0200
+++ pyopencl-0.92/aksetup_helper.py 2010-10-21 19:10:19.000000000 +0200
@@ -2,8 +2,34 @@
import distribute_setup
distribute_setup.use_setuptools()
+import setuptools
from setuptools import Extension
+if not hasattr(setuptools, "_distribute"):
+ print("-------------------------------------------------------------------------")
+ print("Setuptools conflict detected.")
+ print("-------------------------------------------------------------------------")
+ print("When I imported setuptools, I did not get the distribute version of")
+ print("setuptools, which is troubling--this package really wants to be used")
+ print("with distribute rather than the old setuptools package. More than likely,")
+ print("you have both distribute and setuptools installed, which is bad.")
+ print("")
+ print("See this page for more information:")
+ print("http://wiki.tiker.net/DistributeVsSetuptools")
+ print("-------------------------------------------------------------------------")
+ print("I will continue after a short while, fingers crossed.")
+ print("-------------------------------------------------------------------------")
+
+ delay = 10
+
+ from time import sleep
+ import sys
+ while delay:
+ sys.stdout.write("Continuing in %d seconds... \r" % delay)
+ sys.stdout.flush()
+ delay -= 1
+ sleep(1)
+
def setup(*args, **kwargs):
from setuptools import setup
import traceback
@@ -14,16 +40,16 @@
except SystemExit:
raise
except:
- print "----------------------------------------------------------------------------"
- print "Sorry, your build failed. Try rerunning configure.py with different options."
- print "----------------------------------------------------------------------------"
+ print ("----------------------------------------------------------------------------")
+ print ("Sorry, your build failed. Try rerunning configure.py with different options.")
+ print ("----------------------------------------------------------------------------")
raise
class NumpyExtension(Extension):
- # nicked from
+ # nicked from
# http://mail.python.org/pipermail/distutils-sig/2007-September/008253.html
# solution by Michael Hoffmann
def __init__(self, *args, **kwargs):
@@ -83,7 +109,7 @@
# tools -----------------------------------------------------------------------
def flatten(list):
- """For an iterable of sub-iterables, generate each member of each
+ """For an iterable of sub-iterables, generate each member of each
sub-iterable in turn, i.e. a flattened version of that super-iterable.
Example: Turn [[a,b,c],[d,e,f]] into [a,b,c,d,e,f].
@@ -110,20 +136,20 @@
if (not schema.have_config() and not schema.have_global_config()
and warn_about_no_config):
- print "*************************************************************"
- print "*** I have detected that you have not run configure.py."
- print "*************************************************************"
- print "*** Additionally, no global config files were found."
- print "*** I will go ahead with the default configuration."
- print "*** In all likelihood, this will not work out."
- print "*** "
- print "*** See README_SETUP.txt for more information."
- print "*** "
- print "*** If the build does fail, just re-run configure.py with the"
- print "*** correct arguments, and then retry. Good luck!"
- print "*************************************************************"
- print "*** HIT Ctrl-C NOW IF THIS IS NOT WHAT YOU WANT"
- print "*************************************************************"
+ print("*************************************************************")
+ print("*** I have detected that you have not run configure.py.")
+ print("*************************************************************")
+ print("*** Additionally, no global config files were found.")
+ print("*** I will go ahead with the default configuration.")
+ print("*** In all likelihood, this will not work out.")
+ print("*** ")
+ print("*** See README_SETUP.txt for more information.")
+ print("*** ")
+ print("*** If the build does fail, just re-run configure.py with the")
+ print("*** correct arguments, and then retry. Good luck!")
+ print("*************************************************************")
+ print("*** HIT Ctrl-C NOW IF THIS IS NOT WHAT YOU WANT")
+ print("*************************************************************")
delay = 10
@@ -204,7 +230,7 @@
return re.subn(r"\$\{([a-zA-Z0-9_]+)\}", my_repl, s)[0]
def expand_value(v, options):
- if isinstance(v, (str, unicode)):
+ if isinstance(v, str):
return expand_str(v, options)
elif isinstance(v, list):
return [expand_value(i, options) for i in v]
@@ -246,15 +272,15 @@
self.conf_dir = conf_dir
def get_default_config(self):
- return dict((opt.name, opt.default)
+ return dict((opt.name, opt.default)
for opt in self.options)
-
+
def read_config_from_pyfile(self, filename):
result = {}
filevars = {}
- execfile(filename, filevars)
+ exec(compile(open(filename, "r").read(), filename, "exec"), filevars)
- for key, value in filevars.iteritems():
+ for key, value in filevars.items():
if key in self.optdict:
result[key] = value
@@ -265,13 +291,13 @@
filevars = {}
try:
- execfile(filename, filevars)
+ exec(compile(open(filename, "r").read(), filename, "exec"), filevars)
except IOError:
pass
del filevars["__builtins__"]
- for key, value in config.iteritems():
+ for key, value in config.items():
if value is not None:
filevars[key] = value
@@ -296,7 +322,7 @@
result = self.get_default_config()
import os
-
+
confignames = []
if self.global_conf_file is not None:
confignames.append(self.global_conf_file)
@@ -328,16 +354,16 @@
result = self.get_default_config_with_files()
if os.access(cfile, os.R_OK):
filevars = {}
- execfile(cfile, filevars)
+ exec(compile(open(cfile, "r").read(), cfile, "exec"), filevars)
- for key, value in filevars.iteritems():
+ for key, value in filevars.items():
if key in self.optdict:
result[key] = value
elif key == "__builtins__":
pass
else:
- raise KeyError, "invalid config key in %s: %s" % (
- cfile, key)
+ raise KeyError("invalid config key in %s: %s" % (
+ cfile, key))
expand_options(result)
@@ -399,13 +425,13 @@
return result
def value_to_str(self, default):
- return default
+ return default
def add_to_configparser(self, parser, default=None):
default = default_or(default, self.default)
default_str = self.value_to_str(default)
parser.add_option(
- "--" + self.as_option(), dest=self.name,
+ "--" + self.as_option(), dest=self.name,
default=default_str,
metavar=self.metavar(), help=self.get_help(default))
@@ -417,7 +443,7 @@
option = self.as_option()
if not isinstance(self.default, bool):
- raise ValueError, "Switch options must have a default"
+ raise ValueError("Switch options must have a default")
if default is None:
default = self.default
@@ -426,11 +452,11 @@
action = "store_false"
else:
action = "store_true"
-
+
parser.add_option(
- "--" + self.as_option(),
- dest=self.name,
- help=self.get_help(default),
+ "--" + self.as_option(),
+ dest=self.name,
+ help=self.get_help(default),
default=default,
action=action)
@@ -458,7 +484,7 @@
class IncludeDir(StringListOption):
def __init__(self, lib_name, default=None, human_name=None, help=None):
StringListOption.__init__(self, "%s_INC_DIR" % lib_name, default,
- help=help or ("Include directories for %s"
+ help=help or ("Include directories for %s"
% (human_name or humanize(lib_name))))
class LibraryDir(StringListOption):
@@ -470,14 +496,14 @@
class Libraries(StringListOption):
def __init__(self, lib_name, default=None, human_name=None, help=None):
StringListOption.__init__(self, "%s_LIBNAME" % lib_name, default,
- help=help or ("Library names for %s (without lib or .so)"
+ help=help or ("Library names for %s (without lib or .so)"
% (human_name or humanize(lib_name))))
class BoostLibraries(Libraries):
def __init__(self, lib_base_name):
- Libraries.__init__(self, "BOOST_%s" % lib_base_name.upper(),
+ Libraries.__init__(self, "BOOST_%s" % lib_base_name.upper(),
["boost_%s-${BOOST_COMPILER}-mt" % lib_base_name],
- help="Library names for Boost C++ %s library (without lib or .so)"
+ help="Library names for Boost C++ %s library (without lib or .so)"
% humanize(lib_base_name))
def set_up_shipped_boost_if_requested(conf):
@@ -491,22 +517,22 @@
if conf["USE_SHIPPED_BOOST"]:
if not exists("bpl-subset/bpl_subset/boost/version.hpp"):
- print >>sys.stderr, "------------------------------------------------------------------------"
- print >>sys.stderr, "The shipped Boost library was not found, but USE_SHIPPED_BOOST is True."
- print >>sys.stderr, "(The files should be under bpl-subset/.)"
- print >>sys.stderr, "------------------------------------------------------------------------"
- print >>sys.stderr, "If you got this package from git, you probably want to do"
- print >>sys.stderr, ""
- print >>sys.stderr, " $ git submodule init"
- print >>sys.stderr, " $ git submodule update"
- print >>sys.stderr, ""
- print >>sys.stderr, "to fetch what you are presently missing. If you got this from"
- print >>sys.stderr, "a distributed package on the net, that package is broken and"
- print >>sys.stderr, "should be fixed. For now, I will turn off 'USE_SHIPPED_BOOST'"
- print >>sys.stderr, "to try and see if the build succeeds that way, but in the long"
- print >>sys.stderr, "run you might want to either get the missing bits or turn"
- print >>sys.stderr, "'USE_SHIPPED_BOOST' off."
- print >>sys.stderr, "------------------------------------------------------------------------"
+ print("------------------------------------------------------------------------")
+ print("The shipped Boost library was not found, but USE_SHIPPED_BOOST is True.")
+ print("(The files should be under bpl-subset/.)")
+ print("------------------------------------------------------------------------")
+ print("If you got this package from git, you probably want to do")
+ print("")
+ print(" $ git submodule init")
+ print(" $ git submodule update")
+ print("")
+ print("to fetch what you are presently missing. If you got this from")
+ print("a distributed package on the net, that package is broken and")
+ print("should be fixed. For now, I will turn off 'USE_SHIPPED_BOOST'")
+ print("to try and see if the build succeeds that way, but in the long")
+ print("run you might want to either get the missing bits or turn")
+ print("'USE_SHIPPED_BOOST' off.")
+ print("------------------------------------------------------------------------")
conf["USE_SHIPPED_BOOST"] = False
delay = 10
@@ -541,7 +567,7 @@
source_files += glob(
"bpl-subset/bpl_subset/libs/thread/src/pthread/*.cpp")
- return (source_files,
+ return (source_files,
{"BOOST_MULTI_INDEX_DISABLE_SERIALIZATION": 1}
)
else:
@@ -552,7 +578,7 @@
return [
IncludeDir("BOOST", []),
LibraryDir("BOOST", []),
- Option("BOOST_COMPILER", default="gcc43",
+ Option("BOOST_COMPILER", default="gcc43",
help="The compiler with which Boost C++ was compiled, e.g. gcc43"),
]
@@ -568,29 +594,29 @@
from setup import get_config_schema
schema = get_config_schema()
if schema.have_config():
- print "************************************************************"
- print "*** I have detected that you have already run configure."
- print "*** I'm taking the configured values as defaults for this"
- print "*** configure run. If you don't want this, delete the file"
- print "*** %s." % schema.get_conf_file()
- print "************************************************************"
+ print("************************************************************")
+ print("*** I have detected that you have already run configure.")
+ print("*** I'm taking the configured values as defaults for this")
+ print("*** configure run. If you don't want this, delete the file")
+ print("*** %s." % schema.get_conf_file())
+ print("************************************************************")
import sys
description = "generate a configuration file for this software package"
parser = OptionParser(description=description)
parser.add_option(
- "--python-exe", dest="python_exe", default=sys.executable,
- help="Which Python interpreter to use", metavar="PATH")
+ "--python-exe", dest="python_exe", default=sys.executable,
+ help="Which Python interpreter to use", metavar="PATH")
parser.add_option("--prefix", default=None,
- help="Ignored")
+ help="Ignored")
parser.add_option("--enable-shared", help="Ignored", action="store_false")
parser.add_option("--disable-static", help="Ignored", action="store_false")
- parser.add_option("--update-user", help="Update user config file (%s)" % schema.user_conf_file,
+ parser.add_option("--update-user", help="Update user config file (%s)" % schema.user_conf_file,
action="store_true")
- parser.add_option("--update-global",
- help="Update global config file (%s)" % schema.global_conf_file,
+ parser.add_option("--update-global",
+ help="Update global config file (%s)" % schema.global_conf_file,
action="store_true")
schema.add_to_configparser(parser, schema.read_config())
diff -Nru pyopencl-0.92~beta+git20100709/debian/changelog pyopencl-0.92/debian/changelog
--- pyopencl-0.92~beta+git20100709/debian/changelog 2010-07-12 22:52:35.000000000 +0200
+++ pyopencl-0.92/debian/changelog 2010-10-21 19:26:59.000000000 +0200
@@ -1,3 +1,23 @@
+pyopencl (0.92-1) UNRELEASED; urgency=low
+
+ * New upstream release
+ * Fixed Vcs-* URLs in debian/control; now they point to Alioth
+ instead of upstream git repository (Closes: #599875)
+ * Fixed Maintainer field in debian/copyrigth (Closes: #588873)
+ * Added missing licence for pyopencl/clrandom.py file (Closes: #599874)
+ * Fixed FTBFS on i386 (Closes: #599782)
+ * Forced build scripts not to use boost libraries included in the source
+ * Removed messages about missing Boost libraries; they are superfluous
+ as package is using Debian ones
+ * Update Standards-Version to 3.9.1; no changes necessary.
+ * Switch to debhelper compat level 8; no changes necessary.
+ * Changed dependencies:
+ * Depend on libnvidia-compiler instead of transitional libnvidia-compiler1
+ * Build-depend on nvidia-libopencl1 and khronos-opencl-headers
+ instead of nvidia-libopencl1-dev
+
+ -- Tomasz Rybak <bogomips@post.pl> Mon, 18 Oct 2010 21:13:06 +0200
+
pyopencl (0.92~beta+git20100709-1) unstable; urgency=low
* Initial release
diff -Nru pyopencl-0.92~beta+git20100709/debian/compat pyopencl-0.92/debian/compat
--- pyopencl-0.92~beta+git20100709/debian/compat 2010-07-10 18:32:03.000000000 +0200
+++ pyopencl-0.92/debian/compat 2010-10-21 19:26:59.000000000 +0200
@@ -1 +1 @@
-7
+8
diff -Nru pyopencl-0.92~beta+git20100709/debian/control pyopencl-0.92/debian/control
--- pyopencl-0.92~beta+git20100709/debian/control 2010-07-10 18:32:03.000000000 +0200
+++ pyopencl-0.92/debian/control 2010-10-21 19:26:59.000000000 +0200
@@ -2,27 +2,29 @@
Section: contrib/python
Priority: optional
Maintainer: Tomasz Rybak <bogomips@post.pl>
-Build-Depends: debhelper (>= 7.0.50~),
+Build-Depends: debhelper (>= 8),
python-support,
python-all-dev,
python-setuptools,
- nvidia-libopencl1-dev | libopencl1-dev,
+ nvidia-libopencl1-dev | khronos-opencl-headers | libopencl1-dev | nvidia-current-dev,
+ nvidia-libopencl1,
libboost-python-dev,
mesa-common-dev,
python-numpy,
python-matplotlib,
python-sphinx,
python-pytools (>= 7)
-Standards-Version: 3.8.4
+Standards-Version: 3.9.1
XS-Python-Version: >= 2.5
Homepage: http://mathema.tician.de/software/pyopencl
-Vcs-Git: http://git.tiker.net/trees/pyopencl.git
-Vcs-Browser: http://git.tiker.net/?p=pyopencl.git;a=summary
+Vcs-Git: git://git.debian.org/git/collab-maint/python-pyopencl.git
+Vcs-Browser: http://git.debian.org/?p=collab-maint/python-pyopencl.git
Package: python-pyopencl
Architecture: amd64 i386
Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends},
- libnvidia-compiler1,
+ libnvidia-compiler1 | libnvidia-compiler,
+ nvidia-libopencl1,
nvidia-opencl-common,
python-numpy,
python-matplotlib,
diff -Nru pyopencl-0.92~beta+git20100709/debian/copyright pyopencl-0.92/debian/copyright
--- pyopencl-0.92~beta+git20100709/debian/copyright 2010-07-10 18:32:03.000000000 +0200
+++ pyopencl-0.92/debian/copyright 2010-10-21 19:26:59.000000000 +0200
@@ -1,6 +1,6 @@
Format-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=135
Name: PyOpenCL
-Maintainer: Tomasz Rybak <bogomips@post.pl>
+Maintainer: Andreas Klöckner <lists@informa.tiker.net>
Source: http://git.tiker.net/trees/pyopencl.git
http://pypi.python.org/pypi/pyopencl/
http://pypi.python.org/packages/source/p/pyopencl/
@@ -29,3 +29,26 @@
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
+Files: pyopencl/clrandom.py
+Copyright: Copyright (C) 1990, RSA Data Security, Inc.
+Licence:
+ Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.
+
+ License to copy and use this software is granted provided that
+ it is identified as the "RSA Data Security, Inc. MD5 Message
+ Digest Algorithm" in all material mentioning or referencing this
+ software or this function.
+
+ License is also granted to make and use derivative works
+ provided that such works are identified as "derived from the RSA
+ Data Security, Inc. MD5 Message Digest Algorithm" in all
+ material mentioning or referencing the derived work.
+
+ RSA Data Security, Inc. makes no representations concerning
+ either the merchantability of this software or the suitability
+ of this software for any particular purpose. It is provided "as
+ is" without express or implied warranty of any kind.
+
+ These notices must be retained in any copies of any part of this
+ documentation and/or software.
+
diff -Nru pyopencl-0.92~beta+git20100709/debian/patches/replace-setuptools.patch pyopencl-0.92/debian/patches/replace-setuptools.patch
--- pyopencl-0.92~beta+git20100709/debian/patches/replace-setuptools.patch 2010-07-10 18:32:03.000000000 +0200
+++ pyopencl-0.92/debian/patches/replace-setuptools.patch 2010-10-21 19:26:59.000000000 +0200
@@ -4,10 +4,10 @@
Forwarded: not-needed
Author: Tomasz Rybak <bogomips@post.pl>
Last-Update: 2010-06-02
-Index: pyopencl-0,91.5+git20100531/MANIFEST.in
+Index: pyopencl-0.92~beta+git20100806/MANIFEST.in
===================================================================
---- pyopencl-0,91.5+git20100531.orig/MANIFEST.in 2010-06-02 17:30:59.000000000 +0200
-+++ pyopencl-0,91.5+git20100531/MANIFEST.in 2010-06-02 17:31:14.000000000 +0200
+--- pyopencl-0.92~beta+git20100806.orig/MANIFEST.in 2010-08-07 13:49:58.000000000 +0200
++++ pyopencl-0.92~beta+git20100806/MANIFEST.in 2010-08-07 15:13:27.000000000 +0200
@@ -7,7 +7,6 @@
include doc/*.py
include doc/source/conf.py
@@ -16,15 +16,112 @@
include configure.py
include Makefile.in
include aksetup_helper.py
-Index: pyopencl-0,91.5+git20100531/aksetup_helper.py
+Index: pyopencl-0.92~beta+git20100806/aksetup_helper.py
===================================================================
---- pyopencl-0,91.5+git20100531.orig/aksetup_helper.py 2010-06-02 17:30:55.000000000 +0200
-+++ pyopencl-0,91.5+git20100531/aksetup_helper.py 2010-06-02 17:31:06.000000000 +0200
-@@ -1,7 +1,3 @@
+--- pyopencl-0.92~beta+git20100806.orig/aksetup_helper.py 2010-08-07 13:49:58.000000000 +0200
++++ pyopencl-0.92~beta+git20100806/aksetup_helper.py 2010-08-07 15:13:52.000000000 +0200
+@@ -1,35 +1,6 @@
-# dealings with ez_setup ------------------------------------------------------
-import distribute_setup
-distribute_setup.use_setuptools()
-
+ import setuptools
from setuptools import Extension
+-if not hasattr(setuptools, "_distribute"):
+- print("-------------------------------------------------------------------------")
+- print("Setuptools conflict detected.")
+- print("-------------------------------------------------------------------------")
+- print("When I imported setuptools, I did not get the distribute version of")
+- print("setuptools, which is troubling--this package really wants to be used")
+- print("with distribute rather than the old setuptools package. More than likely,")
+- print("you have both distribute and setuptools installed, which is bad.")
+- print("")
+- print("See this page for more information:")
+- print("http://wiki.tiker.net/DistributeVsSetuptools")
+- print("-------------------------------------------------------------------------")
+- print("I will continue after a short while, fingers crossed.")
+- print("-------------------------------------------------------------------------")
+-
+- delay = 10
+-
+- from time import sleep
+- import sys
+- while delay:
+- sys.stdout.write("Continuing in %d seconds... \r" % delay)
+- sys.stdout.flush()
+- delay -= 1
+- sleep(1)
+-
def setup(*args, **kwargs):
+ from setuptools import setup
+ import traceback
+@@ -134,33 +105,6 @@
+ from setup import get_config_schema
+ schema = get_config_schema()
+
+- if (not schema.have_config() and not schema.have_global_config()
+- and warn_about_no_config):
+- print("*************************************************************")
+- print("*** I have detected that you have not run configure.py.")
+- print("*************************************************************")
+- print("*** Additionally, no global config files were found.")
+- print("*** I will go ahead with the default configuration.")
+- print("*** In all likelihood, this will not work out.")
+- print("*** ")
+- print("*** See README_SETUP.txt for more information.")
+- print("*** ")
+- print("*** If the build does fail, just re-run configure.py with the")
+- print("*** correct arguments, and then retry. Good luck!")
+- print("*************************************************************")
+- print("*** HIT Ctrl-C NOW IF THIS IS NOT WHAT YOU WANT")
+- print("*************************************************************")
+-
+- delay = 10
+-
+- from time import sleep
+- import sys
+- while delay:
+- sys.stdout.write("Continuing in %d seconds... \r" % delay)
+- sys.stdout.flush()
+- delay -= 1
+- sleep(1)
+-
+ return schema.read_config()
+
+
+@@ -517,34 +461,8 @@
+
+ if conf["USE_SHIPPED_BOOST"]:
+ if not exists("bpl-subset/bpl_subset/boost/version.hpp"):
+- print("------------------------------------------------------------------------")
+- print("The shipped Boost library was not found, but USE_SHIPPED_BOOST is True.")
+- print("(The files should be under bpl-subset/.)")
+- print("------------------------------------------------------------------------")
+- print("If you got this package from git, you probably want to do")
+- print("")
+- print(" $ git submodule init")
+- print(" $ git submodule update")
+- print("")
+- print("to fetch what you are presently missing. If you got this from")
+- print("a distributed package on the net, that package is broken and")
+- print("should be fixed. For now, I will turn off 'USE_SHIPPED_BOOST'")
+- print("to try and see if the build succeeds that way, but in the long")
+- print("run you might want to either get the missing bits or turn")
+- print("'USE_SHIPPED_BOOST' off.")
+- print("------------------------------------------------------------------------")
+ conf["USE_SHIPPED_BOOST"] = False
+
+- delay = 10
+-
+- from time import sleep
+- import sys
+- while delay:
+- sys.stdout.write("Continuing in %d seconds... \r" % delay)
+- sys.stdout.flush()
+- delay -= 1
+- sleep(1)
+-
+ if conf["USE_SHIPPED_BOOST"]:
+ conf["BOOST_INC_DIR"] = ["bpl-subset/bpl_subset"]
+ conf["BOOST_LIB_DIR"] = []
diff -Nru pyopencl-0.92~beta+git20100709/debian/rules pyopencl-0.92/debian/rules
--- pyopencl-0.92~beta+git20100709/debian/rules 2010-07-10 18:32:03.000000000 +0200
+++ pyopencl-0.92/debian/rules 2010-10-21 19:26:59.000000000 +0200
@@ -8,11 +8,11 @@
override_dh_auto_configure:
./configure.py --boost-python-libname=boost_python-py \
- --cl-enable-gl
+ --cl-enable-gl --cl-inc-dir=/usr/include/nvidia-current
override_dh_auto_build:
dh_auto_build --buildsystem=python_distutils
- PYTHONPATH=../build/lib.$(DEB_BUILD_ARCH_OS)-$(DEB_BUILD_GNU_CPU)-$(firstword $(PYVERS))/ $(MAKE) -C doc html
+ PYTHONPATH=../$$(ls -d build/lib.*-*-$(firstword $(PYVERS)))/ $(MAKE) -C doc html
override_dh_auto_install:
dh_auto_install --buildsystem=python_distutils --destdir=debian/$(PACKAGE_NAME)
@@ -28,14 +28,14 @@
MODULE_NAME=pyopencl
DEB_UPSTREAM_VERSION=$(shell dpkg-parsechangelog \
| sed -rne 's/^Version: ([^-]+).*/\1/p')
-GIT_REVISION=6fee76173b147a6c84364f8248649d52a9d6557f
+GIT_REVISION=dcd70ebc88337cc6474452b83ac02d4ae0c411a9
GIT_URL=http://git.tiker.net/trees/pyopencl.git
get-orig-source:
rm -rf $(MODULE_NAME)-$(DEB_UPSTREAM_VERSION) $(MODULE_NAME)_$(DEB_UPSTREAM_VERSION).orig.tar.gz
git clone $(GIT_URL) $(MODULE_NAME)-$(DEB_UPSTREAM_VERSION)
cd $(MODULE_NAME)-$(DEB_UPSTREAM_VERSION) && git checkout $(GIT_REVISION)
- rm -rf $(MODULE_NAME)-$(DEB_UPSTREAM_VERSION)/.git $(MODULE_NAME)-$(DEB_UPSTREAM_VERSION)/.gitignore
+ rm -rf $(MODULE_NAME)-$(DEB_UPSTREAM_VERSION)/.git $(MODULE_NAME)-$(DEB_UPSTREAM_VERSION)/.gitignore $(MODULE_NAME)-$(DEB_UPSTREAM_VERSION)/.gitmodules
tar czf $(MODULE_NAME)_$(DEB_UPSTREAM_VERSION).orig.tar.gz $(MODULE_NAME)-$(DEB_UPSTREAM_VERSION)
rm -rf $(MODULE_NAME)-$(DEB_UPSTREAM_VERSION)
diff -Nru pyopencl-0.92~beta+git20100709/distribute_setup.py pyopencl-0.92/distribute_setup.py
--- pyopencl-0.92~beta+git20100709/distribute_setup.py 2010-07-10 18:03:27.000000000 +0200
+++ pyopencl-0.92/distribute_setup.py 2010-10-21 19:10:19.000000000 +0200
@@ -46,19 +46,21 @@
args = [quote(arg) for arg in args]
return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
-DEFAULT_VERSION = "0.6.4"
+DEFAULT_VERSION = "0.6.14"
DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
+SETUPTOOLS_FAKED_VERSION = "0.6c11"
+
SETUPTOOLS_PKG_INFO = """\
Metadata-Version: 1.0
Name: setuptools
-Version: 0.6c9
+Version: %s
Summary: xxxx
Home-page: xxx
Author: xxx
Author-email: xxx
License: xxx
Description: xxx
-"""
+""" % SETUPTOOLS_FAKED_VERSION
def _install(tarball):
@@ -79,12 +81,14 @@
# installing
log.warn('Installing Distribute')
- assert _python_cmd('setup.py', 'install')
+ if not _python_cmd('setup.py', 'install'):
+ log.warn('Something went wrong during the installation.')
+ log.warn('See the error message above.')
finally:
os.chdir(old_wd)
-def _build_egg(tarball, to_dir):
+def _build_egg(egg, tarball, to_dir):
# extracting the tarball
tmpdir = tempfile.mkdtemp()
log.warn('Extracting in %s', tmpdir)
@@ -104,27 +108,28 @@
log.warn('Building a Distribute egg in %s', to_dir)
_python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
- # returning the result
- for file in os.listdir(to_dir):
- if fnmatch.fnmatch(file, 'distribute-%s*.egg' % DEFAULT_VERSION):
- return os.path.join(to_dir, file)
-
- raise IOError('Could not build the egg.')
finally:
os.chdir(old_wd)
+ # returning the result
+ log.warn(egg)
+ if not os.path.exists(egg):
+ raise IOError('Could not build the egg.')
def _do_download(version, download_base, to_dir, download_delay):
- tarball = download_setuptools(version, download_base,
- to_dir, download_delay)
- egg = _build_egg(tarball, to_dir)
+ egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg'
+ % (version, sys.version_info[0], sys.version_info[1]))
+ if not os.path.exists(egg):
+ tarball = download_setuptools(version, download_base,
+ to_dir, download_delay)
+ _build_egg(egg, tarball, to_dir)
sys.path.insert(0, egg)
import setuptools
setuptools.bootstrap_install_from = egg
def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
- to_dir=os.curdir, download_delay=15):
+ to_dir=os.curdir, download_delay=15, no_fake=True):
# making sure we use the absolute path
to_dir = os.path.abspath(to_dir)
was_imported = 'pkg_resources' in sys.modules or \
@@ -133,21 +138,23 @@
try:
import pkg_resources
if not hasattr(pkg_resources, '_distribute'):
- fake_setuptools()
+ if not no_fake:
+ _fake_setuptools()
raise ImportError
except ImportError:
return _do_download(version, download_base, to_dir, download_delay)
try:
pkg_resources.require("distribute>="+version)
return
- except pkg_resources.VersionConflict, e:
+ except pkg_resources.VersionConflict:
+ e = sys.exc_info()[1]
if was_imported:
- print >>sys.stderr, (
+ sys.stderr.write(
"The required version of distribute (>=%s) is not available,\n"
"and can't be installed while this script is running. Please\n"
"install a more recent version first, using\n"
"'easy_install -U distribute'."
- "\n\n(Currently using %r)") % (version, e.args[0])
+ "\n\n(Currently using %r)\n" % (version, e.args[0]))
sys.exit(2)
else:
del pkg_resources, sys.modules['pkg_resources'] # reload ok
@@ -157,7 +164,8 @@
return _do_download(version, download_base, to_dir,
download_delay)
finally:
- _create_fake_setuptools_pkg_info(to_dir)
+ if not no_fake:
+ _create_fake_setuptools_pkg_info(to_dir)
def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
to_dir=os.curdir, delay=15):
@@ -171,7 +179,10 @@
"""
# making sure we use the absolute path
to_dir = os.path.abspath(to_dir)
- import urllib2
+ try:
+ from urllib.request import urlopen
+ except ImportError:
+ from urllib2 import urlopen
tgz_name = "distribute-%s.tar.gz" % version
url = download_base + tgz_name
saveto = os.path.join(to_dir, tgz_name)
@@ -179,7 +190,7 @@
if not os.path.exists(saveto): # Avoid repeated downloads
try:
log.warn("Downloading %s", url)
- src = urllib2.urlopen(url)
+ src = urlopen(url)
# Read/write all in one block, so we don't create a corrupt file
# if the download is interrupted.
data = src.read()
@@ -192,6 +203,29 @@
dst.close()
return os.path.realpath(saveto)
+def _no_sandbox(function):
+ def __no_sandbox(*args, **kw):
+ try:
+ from setuptools.sandbox import DirectorySandbox
+ if not hasattr(DirectorySandbox, '_old'):
+ def violation(*args):
+ pass
+ DirectorySandbox._old = DirectorySandbox._violation
+ DirectorySandbox._violation = violation
+ patched = True
+ else:
+ patched = False
+ except ImportError:
+ patched = False
+
+ try:
+ return function(*args, **kw)
+ finally:
+ if patched:
+ DirectorySandbox._violation = DirectorySandbox._old
+ del DirectorySandbox._old
+
+ return __no_sandbox
def _patch_file(path, content):
"""Will backup the file then patch it"""
@@ -209,26 +243,17 @@
f.close()
return True
+_patch_file = _no_sandbox(_patch_file)
def _same_content(path, content):
return open(path).read() == content
-
def _rename_path(path):
new_name = path + '.OLD.%s' % time.time()
log.warn('Renaming %s into %s', path, new_name)
- try:
- from setuptools.sandbox import DirectorySandbox
- def _violation(*args):
- pass
- DirectorySandbox._violation = _violation
- except ImportError:
- pass
-
os.rename(path, new_name)
return new_name
-
def _remove_flat_installation(placeholder):
if not os.path.isdir(placeholder):
log.warn('Unkown installation at %s', placeholder)
@@ -262,6 +287,7 @@
'Setuptools distribution', element)
return True
+_remove_flat_installation = _no_sandbox(_remove_flat_installation)
def _after_install(dist):
log.warn('After install bootstrap.')
@@ -273,17 +299,20 @@
log.warn('Could not find the install location')
return
pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1])
- setuptools_file = 'setuptools-0.6c9-py%s.egg-info' % pyver
+ setuptools_file = 'setuptools-%s-py%s.egg-info' % \
+ (SETUPTOOLS_FAKED_VERSION, pyver)
pkg_info = os.path.join(placeholder, setuptools_file)
if os.path.exists(pkg_info):
log.warn('%s already exists', pkg_info)
return
+
log.warn('Creating %s', pkg_info)
f = open(pkg_info, 'w')
try:
f.write(SETUPTOOLS_PKG_INFO)
finally:
f.close()
+
pth_file = os.path.join(placeholder, 'setuptools.pth')
log.warn('Creating %s', pth_file)
f = open(pth_file, 'w')
@@ -292,6 +321,7 @@
finally:
f.close()
+_create_fake_setuptools_pkg_info = _no_sandbox(_create_fake_setuptools_pkg_info)
def _patch_egg_dir(path):
# let's check if it's already patched
@@ -311,10 +341,11 @@
f.close()
return True
+_patch_egg_dir = _no_sandbox(_patch_egg_dir)
def _before_install():
log.warn('Before install bootstrap.')
- fake_setuptools()
+ _fake_setuptools()
def _under_prefix(location):
@@ -330,12 +361,12 @@
if len(args) > index:
top_dir = args[index+1]
return location.startswith(top_dir)
- elif option == '--user' and USER_SITE is not None:
- return location.startswith(USER_SITE)
+ if arg == '--user' and USER_SITE is not None:
+ return location.startswith(USER_SITE)
return True
-def fake_setuptools():
+def _fake_setuptools():
log.warn('Scanning installed packages')
try:
import pkg_resources
@@ -344,7 +375,13 @@
log.warn('Setuptools or Distribute does not seem to be installed.')
return
ws = pkg_resources.working_set
- setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools'))
+ try:
+ setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools',
+ replacement=False))
+ except TypeError:
+ # old distribute API
+ setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools'))
+
if setuptools_dist is None:
log.warn('No setuptools distribution found')
return
@@ -384,6 +421,9 @@
def _relaunch():
log.warn('Relaunching...')
# we have to relaunch the process
+ # pip marker to avoid a relaunch bug
+ if sys.argv[:3] == ['-c', 'install', '--single-version-externally-managed']:
+ sys.argv[0] = 'setup.py'
args = [sys.executable] + sys.argv
sys.exit(subprocess.call(args))
@@ -408,7 +448,7 @@
# Extract directories with a safe mode.
directories.append(tarinfo)
tarinfo = copy.copy(tarinfo)
- tarinfo.mode = 0700
+ tarinfo.mode = 448 # decimal for oct 0700
self.extract(tarinfo, path)
# Reverse sort directories.
@@ -427,7 +467,8 @@
self.chown(tarinfo, dirpath)
self.utime(tarinfo, dirpath)
self.chmod(tarinfo, dirpath)
- except ExtractError, e:
+ except ExtractError:
+ e = sys.exc_info()[1]
if self.errorlevel > 1:
raise
else:
diff -Nru pyopencl-0.92~beta+git20100709/doc/source/array.rst pyopencl-0.92/doc/source/array.rst
--- pyopencl-0.92~beta+git20100709/doc/source/array.rst 1970-01-01 01:00:00.000000000 +0100
+++ pyopencl-0.92/doc/source/array.rst 2010-10-21 19:10:19.000000000 +0200
@@ -0,0 +1,356 @@
+The :class:`Array` Class
+========================
+
+.. module:: pyopencl.array
+
+.. class:: DefaultAllocator(context, flags=pyopencl.mem_flags.READ_WRITE)
+
+ An Allocator that uses :class:`pyopencl.Buffer` with the given *flags*.
+
+ .. method:: __call__(self, size)
+
+.. class:: Array(context, shape, dtype, order="C", allocator=None, base=None, data=None, queue=None)
+
+ A :class:`numpy.ndarray` work-alike that stores its data and performs its
+ computations on the compute device. *shape* and *dtype* work exactly as in
+ :mod:`numpy`. Arithmetic methods in :class:`Array` support the
+ broadcasting of scalars. (e.g. `array+5`) If the
+
+ *allocator* is a callable that, upon being called with an argument of the number
+ of bytes to be allocated, returns an object that can be cast to an
+ :class:`int` representing the address of the newly allocated memory.
+ (See :class:`DefaultAllocator`.)
+
+ .. attribute :: data
+
+ The :class:`pyopencl.MemoryObject` instance created for the memory that backs
+ this :class:`Array`.
+
+ .. attribute :: shape
+
+ The tuple of lengths of each dimension in the array.
+
+ .. attribute :: dtype
+
+ The :class:`numpy.dtype` of the items in the GPU array.
+
+ .. attribute :: size
+
+ The number of meaningful entries in the array. Can also be computed by
+ multiplying up the numbers in :attr:`shape`.
+
+ .. attribute :: mem_size
+
+ The total number of entries, including padding, that are present in
+ the array.
+
+ .. attribute :: nbytes
+
+ The size of the entire array in bytes. Computed as :attr:`size` times
+ ``dtype.itemsize``.
+
+ .. method :: __len__()
+
+ Returns the size of the leading dimension of *self*.
+
+ .. method :: set(ary, queue=None, async=False)
+
+ Transfer the contents the :class:`numpy.ndarray` object *ary*
+ onto the device.
+
+ *ary* must have the same dtype and size (not necessarily shape) as *self*.
+
+
+ .. method :: get(queue=None, ary=None, async=False)
+
+ Transfer the contents of *self* into *ary* or a newly allocated
+ :mod:`numpy.ndarray`. If *ary* is given, it must have the right
+ size (not necessarily shape) and dtype.
+
+ .. method :: __str__()
+ .. method :: __repr__()
+
+ .. method :: mul_add(self, selffac, other, otherfac, queue=None):
+
+ Return `selffac*self + otherfac*other`.
+
+ .. method :: __add__(other)
+ .. method :: __sub__(other)
+ .. method :: __iadd__(other)
+ .. method :: __isub__(other)
+ .. method :: __neg__(other)
+ .. method :: __mul__(other)
+ .. method :: __div__(other)
+ .. method :: __rdiv__(other)
+ .. method :: __pow__(other)
+
+ .. method :: __abs__()
+
+ Return a :class:`Array` containing the absolute value of each
+ element of *self*.
+
+ .. UNDOC reverse()
+
+ .. method :: fill(scalar, queue=None)
+
+ Fill the array with *scalar*.
+
+ .. method :: astype(dtype, queue=None)
+
+ Return *self*, cast to *dtype*.
+
+Constructing :class:`Array` Instances
+----------------------------------------
+
+.. function:: to_device(context, queue, ary, allocator=None, async=False)
+
+ Return a :class:`Array` that is an exact copy of the :class:`numpy.ndarray`
+ instance *ary*.
+
+ See :class:`Array` for the meaning of *allocator*.
+
+.. function:: empty(context, shape, dtype, order="C", allocator=None, base=None, data=None, queue=None)
+
+ A synonym for the :class:`Array` constructor.
+
+.. function:: zeros(context, queue, shape, dtype, order="C", allocator=None)
+
+ Same as :func:`empty`, but the :class:`Array` is zero-initialized before
+ being returned.
+
+.. function:: empty_like(other_ary)
+
+ Make a new, uninitialized :class:`Array` having the same properties
+ as *other_ary*.
+
+.. function:: zeros_like(other_ary)
+
+ Make a new, zero-initialized :class:`Array` having the same properties
+ as *other_ary*.
+
+.. function:: arange(context, queue, start, stop, step, dtype=None)
+
+ Create a :class:`Array` filled with numbers spaced `step` apart,
+ starting from `start` and ending at `stop`.
+
+ For floating point arguments, the length of the result is
+ `ceil((stop - start)/step)`. This rule may result in the last
+ element of the result being greater than `stop`.
+
+ *dtype*, if not specified, is taken as the largest common type
+ of *start*, *stop* and *step*.
+
+.. function:: take(a, indices, out=None, queue=None)
+
+ Return the :class:`Array` ``[a[indices[0]], ..., a[indices[n]]]``.
+ For the moment, *a* must be a type that can be bound to a texture.
+
+Conditionals
+^^^^^^^^^^^^
+
+.. function:: if_positive(criterion, then_, else_, out=None, queue=None)
+
+ Return an array like *then_*, which, for the element at index *i*,
+ contains *then_[i]* if *criterion[i]>0*, else *else_[i]*. (added in 0.94)
+
+.. function:: maximum(a, b, out=None, queue=None)
+
+ Return the elementwise maximum of *a* and *b*. (added in 0.94)
+
+.. function:: minimum(a, b, out=None, queue=None)
+
+ Return the elementwise minimum of *a* and *b*. (added in 0.94)
+
+Elementwise Functions on :class:`Arrray` Instances
+-----------------------------------------------------
+
+.. module:: pyopencl.clmath
+
+The :mod:`pyopencl.clmath` module contains exposes array versions of the C
+functions available in the OpenCL standard. (See table 6.8 in the spec.)
+
+.. function:: acos(array, queue=None)
+.. function:: acosh(array, queue=None)
+.. function:: acospi(array, queue=None)
+
+.. function:: asin(array, queue=None)
+.. function:: asinh(array, queue=None)
+.. function:: asinpi(array, queue=None)
+
+.. function:: atan(array, queue=None)
+.. TODO: atan2
+.. function:: atanh(array, queue=None)
+.. function:: atanpi(array, queue=None)
+.. TODO: atan2pi
+
+.. function:: cbrt(array, queue=None)
+.. function:: ceil(array, queue=None)
+.. TODO: copysign
+
+.. function:: cos(array, queue=None)
+.. function:: cosh(array, queue=None)
+.. function:: cospi(array, queue=None)
+
+.. function:: erfc(array, queue=None)
+.. function:: erf(array, queue=None)
+.. function:: exp(array, queue=None)
+.. function:: exp2(array, queue=None)
+.. function:: exp10(array, queue=None)
+.. function:: expm1(array, queue=None)
+
+.. function:: fabs(array, queue=None)
+.. TODO: fdim
+.. function:: floor(array, queue=None)
+.. TODO: fma
+.. TODO: fmax
+.. TODO: fmin
+
+.. function:: fmod(arg, mod, queue=None)
+
+ Return the floating point remainder of the division `arg/mod`,
+ for each element in `arg` and `mod`.
+
+.. TODO: fract
+
+
+.. function:: frexp(arg, queue=None)
+
+ Return a tuple `(significands, exponents)` such that
+ `arg == significand * 2**exponent`.
+
+.. TODO: hypot
+
+.. function:: ilogb(array, queue=None)
+.. function:: ldexp(significand, exponent, queue=None)
+
+ Return a new array of floating point values composed from the
+ entries of `significand` and `exponent`, paired together as
+ `result = significand * 2**exponent`.
+
+
+.. function:: lgamma(array, queue=None)
+.. TODO: lgamma_r
+
+.. function:: log(array, queue=None)
+.. function:: log2(array, queue=None)
+.. function:: log10(array, queue=None)
+.. function:: log1p(array, queue=None)
+.. function:: logb(array, queue=None)
+
+.. TODO: mad
+.. TODO: maxmag
+.. TODO: minmag
+
+
+.. function:: modf(arg, queue=None)
+
+ Return a tuple `(fracpart, intpart)` of arrays containing the
+ integer and fractional parts of `arg`.
+
+.. function:: nan(array, queue=None)
+
+.. TODO: nextafter
+.. TODO: remainder
+.. TODO: remquo
+
+.. function:: rint(array, queue=None)
+.. TODO: rootn
+.. function:: round(array, queue=None)
+
+.. function:: sin(array, queue=None)
+.. TODO: sincos
+.. function:: sinh(array, queue=None)
+.. function:: sinpi(array, queue=None)
+
+.. function:: sqrt(array, queue=None)
+
+.. function:: tan(array, queue=None)
+.. function:: tanh(array, queue=None)
+.. function:: tanpi(array, queue=None)
+.. function:: tgamma(array, queue=None)
+.. function:: trunc(array, queue=None)
+
+
+Generating Arrays of Random Numbers
+-----------------------------------
+
+.. module:: pyopencl.clrandom
+
+.. function:: rand(context, queue, shape, dtype)
+
+ Return an array of `shape` filled with random values of `dtype`
+ in the range [0,1).
+
+Single-pass Custom Expression Evaluation
+----------------------------------------
+
+.. warning::
+
+ The following functionality is included in this documentation in the
+ hope that it may be useful, but its interface may change in future
+ revisions. Feedback is welcome.
+
+.. module:: pyopencl.elementwise
+
+Evaluating involved expressions on :class:`pyopencl.array.Array` instances can be
+somewhat inefficient, because a new temporary is created for each
+intermediate result. The functionality in the module :mod:`pyopencl.elementwise`
+contains tools to help generate kernels that evaluate multi-stage expressions
+on one or several operands in a single pass.
+
+.. class:: ElementwiseKernel(context, arguments, operation, name="kernel", options=[])
+
+ Generate a kernel that takes a number of scalar or vector *arguments*
+ and performs the scalar *operation* on each entry of its arguments, if that
+ argument is a vector.
+
+ *arguments* is specified as a string formatted as a C argument list.
+ *operation* is specified as a C assignment statement, without a semicolon.
+ Vectors in *operation* should be indexed by the variable *i*.
+
+ *name* specifies the name as which the kernel is compiled,
+ and *options* are passed unmodified to :meth:`pyopencl.Program.build`.
+
+ .. method:: __call__(*args)
+
+ Invoke the generated scalar kernel. The arguments may either be scalars or
+ :class:`GPUArray` instances.
+
+Here's a usage example::
+
+ import pyopencl as cl
+ import pyopencl.array as cl_array
+ import numpy
+
+ ctx = cl.create_some_context()
+ queue = cl.CommandQueue(ctx)
+
+ n = 10
+ a_gpu = cl_array.to_device(
+ ctx, queue, numpy.random.randn(n).astype(numpy.float32))
+ b_gpu = cl_array.to_device(
+ ctx, queue, numpy.random.randn(n).astype(numpy.float32))
+
+ from pyopencl.elementwise import ElementwiseKernel
+ lin_comb = ElementwiseKernel(ctx,
+ "float a, float *x, "
+ "float b, float *y, "
+ "float *z",
+ "z[i] = a*x[i] + b*y[i]",
+ "linear_combination")
+
+ c_gpu = cl_array.empty_like(a_gpu)
+ lin_comb(5, a_gpu, 6, b_gpu, c_gpu)
+
+ import numpy.linalg as la
+ assert la.norm((c_gpu - (5*a_gpu+6*b_gpu)).get()) < 1e-5
+
+(You can find this example as :file:`examples/demo_elementwise.py` in the PyOpenCL
+distribution.)
+
+Fast Fourier Transforms
+-----------------------
+
+Bogdan Opanchuk's `pyfft <http://pypi.python.org/pypi/pyfft>`_ package offers a
+variety of GPU-based FFT implementations.
+
diff -Nru pyopencl-0.92~beta+git20100709/doc/source/index.rst pyopencl-0.92/doc/source/index.rst
--- pyopencl-0.92~beta+git20100709/doc/source/index.rst 2010-07-10 18:03:27.000000000 +0200
+++ pyopencl-0.92/doc/source/index.rst 2010-10-21 19:10:19.000000000 +0200
@@ -70,6 +70,7 @@
:maxdepth: 2
runtime
+ array
misc
Note that this guide does not explain OpenCL programming and technology. Please
diff -Nru pyopencl-0.92~beta+git20100709/doc/source/misc.rst pyopencl-0.92/doc/source/misc.rst
--- pyopencl-0.92~beta+git20100709/doc/source/misc.rst 2010-07-10 18:03:27.000000000 +0200
+++ pyopencl-0.92/doc/source/misc.rst 2010-10-21 19:10:19.000000000 +0200
@@ -82,9 +82,10 @@
emphasize the importance of *loccal_size*.
* Add :meth:`pyopencl.Kernel.set_scalar_arg_dtypes`.
* Add support for the
- `cl_nv_device_attribute_query <ghttp://www.khronos.org/registry/cl/extensions/khr/cl_nv_device_attribute_query.txt>`_
+ `cl_nv_device_attribute_query <http://www.khronos.org/registry/cl/extensions/khr/cl_nv_device_attribute_query.txt>`_
extension.
-
+* Add :meth:`pyopencl.array.Array` and related functionality.
+* Make build not depend on Boost C++.
Version 0.91.5
--------------
diff -Nru pyopencl-0.92~beta+git20100709/doc/source/runtime.rst pyopencl-0.92/doc/source/runtime.rst
--- pyopencl-0.92~beta+git20100709/doc/source/runtime.rst 2010-07-10 18:03:27.000000000 +0200
+++ pyopencl-0.92/doc/source/runtime.rst 2010-10-21 19:10:19.000000000 +0200
@@ -565,7 +565,7 @@
See :class:`kernel_work_group_info` for values of *param*.
- .. method:: set_arg(self, arg)
+ .. method:: set_arg(self, index, arg)
*arg* may be
@@ -594,6 +594,8 @@
Invoke :meth:`set_arg` on each element of *args* in turn.
+ ..versionadded:: 0.92
+
.. method:: set_scalar_arg_dtypes(arg_dtypes)
Inform the wrapper about the sized types of scalar
diff -Nru pyopencl-0.92~beta+git20100709/examples/demo_mandelbrot.py pyopencl-0.92/examples/demo_mandelbrot.py
--- pyopencl-0.92~beta+git20100709/examples/demo_mandelbrot.py 2010-07-10 18:03:27.000000000 +0200
+++ pyopencl-0.92/examples/demo_mandelbrot.py 2010-10-21 19:10:19.000000000 +0200
@@ -27,41 +27,43 @@
# Speed notes are listed in the same place
# set width and height of window, more pixels take longer to calculate
-w = 400
-h = 400
+w = 256
+h = 256
def calc_fractal_opencl(q, maxiter):
ctx = cl.Context(cl.get_platforms()[0].get_devices())
queue = cl.CommandQueue(ctx)
- output = np.empty(q.shape, dtype=np.uint64)# resize(np.array(0,), q.shape)
+ output = np.empty(q.shape, dtype=np.uint16)
mf = cl.mem_flags
q_opencl = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=q)
output_opencl = cl.Buffer(ctx, mf.WRITE_ONLY, output.nbytes)
prg = cl.Program(ctx, """
+ #pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable
__kernel void mandelbrot(__global float2 *q,
- __global long *output, long const maxiter)
+ __global ushort *output, ushort const maxiter)
{
int gid = get_global_id(0);
float nreal, real = 0;
float imag = 0;
+
+ output[gid] = 0;
+
for(int curiter = 0; curiter < maxiter; curiter++) {
- nreal = real*real - imag*imag + q[gid][0];
- imag = 2* real*imag + q[gid][1];
+ nreal = real*real - imag*imag + q[gid].x;
+ imag = 2* real*imag + q[gid].y;
real = nreal;
- if (real*real + imag*imag > 4.) {
+ if (real*real + imag*imag > 4.0f)
output[gid] = curiter;
- break;
- }
}
}
""").build()
- prg.mandelbrot(queue, output.shape, None, q_opencl,
- output_opencl, np.int32(maxiter))
+ prg.mandelbrot(queue, output.shape, (64,), q_opencl,
+ output_opencl, np.uint16(maxiter))
cl.enqueue_read_buffer(queue, output_opencl, output).wait()
@@ -121,10 +123,10 @@
self.root.mainloop()
- def draw(self, x1, x2, y1, y2, maxiter=300):
+ def draw(self, x1, x2, y1, y2, maxiter=30):
# draw the Mandelbrot set, from numpy example
- xx = np.arange(x1, x2, (x2-x1)/w*2)
- yy = np.arange(y2, y1, (y1-y2)/h*2) * 1j
+ xx = np.arange(x1, x2, (x2-x1)/w)
+ yy = np.arange(y2, y1, (y1-y2)/h) * 1j
q = np.ravel(xx+yy[:, np.newaxis]).astype(np.complex64)
start_main = time.time()
@@ -134,18 +136,20 @@
secs = end_main - start_main
print "Main took", secs
- output = (output + (256*output) + (256**2)*output) * 8
- # convert output to a string
- self.mandel = output.tostring()
+ self.mandel = (output.reshape((h,w)) /
+ float(output.max()) * 255.).astype(np.uint8)
def create_image(self):
""""
create the image from the draw() string
"""
- self.im = Image.new("RGB", (w/2, h/2))
# you can experiment with these x and y ranges
self.draw(-2.13, 0.77, -1.3, 1.3)
- self.im.fromstring(self.mandel, "raw", "RGBX", 0, -1)
+ self.im = Image.fromarray(self.mandel)
+ self.im.putpalette(reduce(
+ lambda a,b: a+b, ((i,0,0) for i in range(255))
+ ))
+
def create_label(self):
# put the image on a label widget
diff -Nru pyopencl-0.92~beta+git20100709/examples/gl_interop_demo.py pyopencl-0.92/examples/gl_interop_demo.py
--- pyopencl-0.92~beta+git20100709/examples/gl_interop_demo.py 2010-07-10 18:03:27.000000000 +0200
+++ pyopencl-0.92/examples/gl_interop_demo.py 2010-10-21 19:10:19.000000000 +0200
@@ -1,75 +1,80 @@
-from OpenGL.GL import *
-from OpenGL.GLUT import *
-from OpenGL.raw.GL.VERSION.GL_1_5 import glBufferData as rawGlBufferData
-try:
- from OpenGL.WGL import wglGetCurrentDisplay as GetCurrentDisplay, wglGetCurrentContext as GetCurrentContext
-except:
- pass
-try:
- from OpenGL.GLX import glXGetCurrentDisplay as GetCurrentDisplay, glXGetCurrentContext as GetCurrentContext
-except:
- pass
-import pyopencl as cl
-
-
-n_vertices = 10000
-
-src = """
-
-__kernel void generate_sin(__global float2* a)
-{
- int id = get_global_id(0);
- int n = get_global_size(0);
- float r = (float)id / (float)n;
- float x = r * 16.0f * 3.1415f;
- a[id].x = r * 2.0f - 1.0f;
- a[id].y = native_sin(x);
-}
-
-"""
-
-def initialize():
- plats = cl.get_platforms()
- ctx_props = cl.context_properties
- props = [(ctx_props.PLATFORM, plats[0]), (ctx_props.GL_CONTEXT_KHR,
- GetCurrentContext()), (ctx_props.GLX_DISPLAY_KHR, GetCurrentDisplay())]
- ctx = cl.Context(properties=props)
- glClearColor(1, 1, 1, 1)
- glColor(0, 0, 1)
- vbo = glGenBuffers(1)
- glBindBuffer(GL_ARRAY_BUFFER, vbo)
- rawGlBufferData(GL_ARRAY_BUFFER, n_vertices * 2 * 4, None, GL_STATIC_DRAW)
- glEnableClientState(GL_VERTEX_ARRAY)
- glVertexPointer(2, GL_FLOAT, 0, None)
- coords_dev = cl.GLBuffer(ctx, cl.mem_flags.READ_WRITE, int(vbo))
- prog = cl.Program(ctx, src).build()
- queue = cl.CommandQueue(ctx)
- cl.enqueue_acquire_gl_objects(queue, [coords_dev])
- prog.generate_sin(queue, (n_vertices,), None, coords_dev)
- cl.enqueue_release_gl_objects(queue, [coords_dev])
- queue.finish()
- glFlush()
-
-def display():
- glClear(GL_COLOR_BUFFER_BIT)
- glDrawArrays(GL_LINE_STRIP, 0, n_vertices)
- glFlush()
-
-def reshape(w, h):
- glViewport(0, 0, w, h)
- glMatrixMode(GL_PROJECTION)
- glLoadIdentity()
- glMatrixMode(GL_MODELVIEW)
-
-if __name__ == '__main__':
- import sys
- glutInit(sys.argv)
- if len(sys.argv) > 1:
- n_vertices = int(sys.argv[1])
- glutInitWindowSize(800, 160)
- glutInitWindowPosition(0, 0)
- glutCreateWindow('OpenCL/OpenGL Interop Tutorial: Sin Generator')
- glutDisplayFunc(display)
- glutReshapeFunc(reshape)
- initialize()
- glutMainLoop()
+from OpenGL.GL import *
+from OpenGL.GLUT import *
+from OpenGL.raw.GL.VERSION.GL_1_5 import glBufferData as rawGlBufferData
+from OpenGL import platform, GLX, WGL
+import pyopencl as cl
+
+
+n_vertices = 10000
+
+src = """
+
+__kernel void generate_sin(__global float2* a)
+{
+ int id = get_global_id(0);
+ int n = get_global_size(0);
+ float r = (float)id / (float)n;
+ float x = r * 16.0f * 3.1415f;
+ a[id].x = r * 2.0f - 1.0f;
+ a[id].y = native_sin(x);
+}
+
+"""
+
+def initialize():
+ plats = cl.get_platforms()
+ ctx_props = cl.context_properties
+
+ props = [(ctx_props.PLATFORM, plats[0]),
+ (ctx_props.GL_CONTEXT_KHR, platform.GetCurrentContext())]
+
+ import sys
+ if sys.platform == "linux2":
+ props.append(
+ (ctx_props.GLX_DISPLAY_KHR,
+ GLX.glXGetCurrentDisplay()))
+ elif sys.platform == "win32":
+ props.append(
+ (ctx_props.WGL_HDC_KHR,
+ WGL.wglGetCurrentDC()))
+ ctx = cl.Context(properties=props)
+
+ glClearColor(1, 1, 1, 1)
+ glColor(0, 0, 1)
+ vbo = glGenBuffers(1)
+ glBindBuffer(GL_ARRAY_BUFFER, vbo)
+ rawGlBufferData(GL_ARRAY_BUFFER, n_vertices * 2 * 4, None, GL_STATIC_DRAW)
+ glEnableClientState(GL_VERTEX_ARRAY)
+ glVertexPointer(2, GL_FLOAT, 0, None)
+ coords_dev = cl.GLBuffer(ctx, cl.mem_flags.READ_WRITE, int(vbo))
+ prog = cl.Program(ctx, src).build()
+ queue = cl.CommandQueue(ctx)
+ cl.enqueue_acquire_gl_objects(queue, [coords_dev])
+ prog.generate_sin(queue, (n_vertices,), None, coords_dev)
+ cl.enqueue_release_gl_objects(queue, [coords_dev])
+ queue.finish()
+ glFlush()
+
+def display():
+ glClear(GL_COLOR_BUFFER_BIT)
+ glDrawArrays(GL_LINE_STRIP, 0, n_vertices)
+ glFlush()
+
+def reshape(w, h):
+ glViewport(0, 0, w, h)
+ glMatrixMode(GL_PROJECTION)
+ glLoadIdentity()
+ glMatrixMode(GL_MODELVIEW)
+
+if __name__ == '__main__':
+ import sys
+ glutInit(sys.argv)
+ if len(sys.argv) > 1:
+ n_vertices = int(sys.argv[1])
+ glutInitWindowSize(800, 160)
+ glutInitWindowPosition(0, 0)
+ glutCreateWindow('OpenCL/OpenGL Interop Tutorial: Sin Generator')
+ glutDisplayFunc(display)
+ glutReshapeFunc(reshape)
+ initialize()
+ glutMainLoop()
diff -Nru pyopencl-0.92~beta+git20100709/.gitmodules pyopencl-0.92/.gitmodules
--- pyopencl-0.92~beta+git20100709/.gitmodules 2010-07-10 18:03:27.000000000 +0200
+++ pyopencl-0.92/.gitmodules 1970-01-01 01:00:00.000000000 +0100
@@ -1,3 +0,0 @@
-[submodule "bpl-subset"]
- path = bpl-subset
- url = http://git.tiker.net/trees/bpl-subset.git
diff -Nru pyopencl-0.92~beta+git20100709/MANIFEST.in pyopencl-0.92/MANIFEST.in
--- pyopencl-0.92~beta+git20100709/MANIFEST.in 2010-07-10 18:03:27.000000000 +0200
+++ pyopencl-0.92/MANIFEST.in 2010-10-21 19:10:19.000000000 +0200
@@ -13,4 +13,4 @@
include aksetup_helper.py
include README_SETUP.txt
-recursive-include bpl-subset
+recursive-include bpl-subset *.h *.hpp *.cpp *.html *.inl *.ipp *.pl *.txt
diff -Nru pyopencl-0.92~beta+git20100709/pyopencl/array.py pyopencl-0.92/pyopencl/array.py
--- pyopencl-0.92~beta+git20100709/pyopencl/array.py 2010-07-10 18:03:27.000000000 +0200
+++ pyopencl-0.92/pyopencl/array.py 2010-10-21 19:10:19.000000000 +0200
@@ -126,7 +126,7 @@
work on an element-by-element basis, just like :class:`numpy.ndarray`.
"""
- def __init__(self, context, shape, dtype, allocator=None,
+ def __init__(self, context, shape, dtype, order="C", allocator=None,
base=None, data=None, queue=None):
if allocator is None:
allocator = DefaultAllocator(context)
@@ -147,6 +147,9 @@
self.shape = shape
self.dtype = numpy.dtype(dtype)
+ if order not in ["C", "F"]:
+ raise ValueError("order must be either 'C' or 'F'")
+ self.order = order
self.mem_size = self.size = s
self.nbytes = self.dtype.itemsize * self.size
@@ -180,7 +183,7 @@
def get(self, queue=None, ary=None, async=False):
if ary is None:
- ary = numpy.empty(self.shape, self.dtype)
+ ary = numpy.empty(self.shape, self.dtype, order=self.order)
else:
if ary.size != self.size:
raise TypeError("'ary' has non-matching type")
@@ -344,12 +347,20 @@
return result
def __iadd__(self, other):
- self._axpbyz(self, 1, self, 1, other)
- return self
+ if isinstance(other, Array):
+ self._axpbyz(self, 1, self, 1, other)
+ return self
+ else:
+ self._axpbz(self, 1, self, other)
+ return self
def __isub__(self, other):
- self._axpbyz(self, 1, self, -1, other)
- return self
+ if isinstance(other, Array):
+ self._axpbyz(self, 1, self, -1, other)
+ return self
+ else:
+ self._axpbz(self, 1, self, -other)
+ return self
def __neg__(self):
result = self._new_like_me()
@@ -470,30 +481,6 @@
self._copy(result, self, queue=queue)
return result
- # slicing -----------------------------------------------------------------
- def __getitem__(self, idx):
- if idx == ():
- return self
-
- if len(self.shape) > 1:
- raise NotImplementedError("multi-d slicing is not yet implemented")
-
- if not isinstance(idx, slice):
- raise ValueError("non-slice indexing not supported: %s" % (idx,))
-
- l, = self.shape
- start, stop, stride = idx.indices(l)
-
- if stride != 1:
- raise NotImplementedError("strided slicing is not yet implemented")
-
- return Array(
- shape=((stop-start)//stride,),
- dtype=self.dtype,
- allocator=self.allocator,
- base=self,
- data=int(self.data) + start*self.dtype.itemsize)
-
# rich comparisons (or rather, lack thereof) ------------------------------
def __eq__(self, other):
raise NotImplementedError
@@ -517,7 +504,15 @@
def to_device(context, queue, ary, allocator=None, async=False):
"""Converts a numpy array to a :class:`Array`."""
- result = Array(context, ary.shape, ary.dtype, allocator,
+ if ary.flags.f_contiguous:
+ order = "F"
+ elif ary.flags.c_contiguous:
+ order = "C"
+ else:
+ raise ValueError("to_device only works on C- or Fortran-"
+ "contiguous arrays")
+
+ result = Array(context, ary.shape, ary.dtype, order, allocator,
queue=queue)
result.set(ary, async=async)
return result
@@ -525,21 +520,22 @@
empty = Array
-def zeros(context, queue, shape, dtype, allocator=None):
+def zeros(context, queue, shape, dtype, order="C", allocator=None):
"""Returns an array of the given shape and dtype filled with 0's."""
- result = Array(context, shape, dtype, allocator, queue=queue)
+ result = Array(context, shape, dtype,
+ order=order, allocator=allocator, queue=queue)
result.fill(0)
return result
def empty_like(ary):
result = Array(ary.context,
- ary.shape, ary.dtype, ary.allocator, queue=ary.queue)
+ ary.shape, ary.dtype, allocator=ary.allocator, queue=ary.queue)
return result
def zeros_like(ary):
result = Array(ary.context,
- ary.shape, ary.dtype, ary.allocator, queue=ary.queue)
+ ary.shape, ary.dtype, allocator=ary.allocator, queue=ary.queue)
result.fill(0)
return result
@@ -641,7 +637,8 @@
def take(a, indices, out=None, queue=None):
if out is None:
- out = Array(a.context, indices.shape, a.dtype, a.allocator,
+ out = Array(a.context, indices.shape, a.dtype,
+ allocator=a.allocator,
queue=queue or a.queue)
assert len(indices.shape) == 1
@@ -666,7 +663,8 @@
vec_count = len(arrays)
if out is None:
- out = [Array(context, queue, indices.shape, a_dtype, a_allocator)
+ out = [Array(context, queue, indices.shape, a_dtype,
+ allocator=a_allocator)
for i in range(vec_count)]
else:
if len(out) != len(arrays):
@@ -715,7 +713,8 @@
vec_count = len(arrays)
if out is None:
- out = [Array(context, dest_shape, a_dtype, a_allocator, queue=queue)
+ out = [Array(context, dest_shape, a_dtype,
+ allocator=a_allocator, queue=queue)
for i in range(vec_count)]
else:
if a_dtype != single_valued(o.dtype for o in out):
@@ -783,7 +782,7 @@
vec_count = len(arrays)
if out is None:
- out = [Array(context, dest_shape, a_dtype, a_allocator, queue=queue)
+ out = [Array(context, dest_shape, a_dtype, allocator=a_allocator, queue=queue)
for i in range(vec_count)]
else:
if a_dtype != single_valued(o.dtype for o in out):
diff -Nru pyopencl-0.92~beta+git20100709/pyopencl/__init__.py pyopencl-0.92/pyopencl/__init__.py
--- pyopencl-0.92~beta+git20100709/pyopencl/__init__.py 2010-07-10 18:03:27.000000000 +0200
+++ pyopencl-0.92/pyopencl/__init__.py 2010-10-21 19:10:19.000000000 +0200
@@ -224,6 +224,10 @@
self.set_arg(i, arg)
else:
from struct import pack
+
+ if len(args) != len(arg_type_chars):
+ raise ValueError("length of argument type array and "
+ "length of argument list do not agree")
for i, (arg, arg_type_char) in enumerate(
zip(args, arg_type_chars)):
if arg_type_char:
diff -Nru pyopencl-0.92~beta+git20100709/pyopencl/version.py pyopencl-0.92/pyopencl/version.py
--- pyopencl-0.92~beta+git20100709/pyopencl/version.py 2010-07-10 18:03:27.000000000 +0200
+++ pyopencl-0.92/pyopencl/version.py 2010-10-21 19:10:19.000000000 +0200
@@ -1,5 +1,5 @@
VERSION = (0, 92)
-VERSION_STATUS = "beta"
+VERSION_STATUS = ""
VERSION_TEXT = ".".join(str(x) for x in VERSION) + VERSION_STATUS
diff -Nru pyopencl-0.92~beta+git20100709/src/wrapper/wrap_cl.hpp pyopencl-0.92/src/wrapper/wrap_cl.hpp
--- pyopencl-0.92~beta+git20100709/src/wrapper/wrap_cl.hpp 2010-07-10 18:03:27.000000000 +0200
+++ pyopencl-0.92/src/wrapper/wrap_cl.hpp 2010-10-21 19:10:19.000000000 +0200
@@ -20,6 +20,12 @@
#include <CL/cl.h>
// FIXME: Nvidia doesn't install cl_ext.h by default. Grr.
// #include <CL/cl_ext.h>
+
+#ifdef _WIN32
+#define NOMINMAX
+#include <windows.h>
+#endif
+
#ifdef HAVE_GL
#include <GL/gl.h>
#include <CL/cl_gl.h>
@@ -2575,7 +2581,8 @@
std::vector<size_t> result;
PYOPENCL_GET_VEC_INFO(KernelWorkGroup,
PYOPENCL_FIRST_ARG, param_name, result);
- return py::list(result);
+
+ PYOPENCL_RETURN_VECTOR(size_t, result);
}
case CL_KERNEL_LOCAL_MEM_SIZE:
#ifdef CL_VERSION_1_1
@@ -2875,8 +2882,8 @@
std::vector<cl_context_properties> props
= parse_context_properties(py_properties);
- typedef CL_API_ENTRY cl_int CL_API_CALL
- (*func_ptr_type)(const cl_context_properties * /* properties */,
+ typedef CL_API_ENTRY cl_int (CL_API_CALL
+ *func_ptr_type)(const cl_context_properties * /* properties */,
cl_gl_context_info /* param_name */,
size_t /* param_value_size */,
void * /* param_value */,
diff -Nru pyopencl-0.92~beta+git20100709/src/wrapper/wrap_constants.cpp pyopencl-0.92/src/wrapper/wrap_constants.cpp
--- pyopencl-0.92~beta+git20100709/src/wrapper/wrap_constants.cpp 2010-07-10 18:03:27.000000000 +0200
+++ pyopencl-0.92/src/wrapper/wrap_constants.cpp 2010-10-21 19:10:19.000000000 +0200
@@ -167,6 +167,7 @@
ADD_ATTR(DEVICE_, QUEUE_PROPERTIES);
ADD_ATTR(DEVICE_, NAME);
ADD_ATTR(DEVICE_, VENDOR);
+ ADD_ATTR(, DRIVER_VERSION);
ADD_ATTR(DEVICE_, VERSION);
ADD_ATTR(DEVICE_, PROFILE);
ADD_ATTR(DEVICE_, VERSION);
diff -Nru pyopencl-0.92~beta+git20100709/test/test_clmath.py pyopencl-0.92/test/test_clmath.py
--- pyopencl-0.92~beta+git20100709/test/test_clmath.py 1970-01-01 01:00:00.000000000 +0100
+++ pyopencl-0.92/test/test_clmath.py 2010-10-21 19:10:19.000000000 +0200
@@ -0,0 +1,182 @@
+from __future__ import division
+import math
+import numpy
+import pytools.test
+
+def have_cl():
+ try:
+ import pyopencl
+ return True
+ except:
+ return False
+
+if have_cl():
+ import pyopencl.array as cl_array
+ import pyopencl as cl
+ import pyopencl.clmath as clmath
+ from pyopencl.tools import pytest_generate_tests_for_pyopencl \
+ as pytest_generate_tests
+
+
+
+
+
+sizes = [10, 128, 1024, 1<<10, 1<<13]
+
+
+
+
+def has_double_support(dev):
+ for ext in dev.extensions.split(" "):
+ if ext == "cl_khr_fp64":
+ return True
+ return False
+
+
+
+
+numpy_func_names = {
+ "asin": "arcsin",
+ "acos": "arccos",
+ "atan": "arctan",
+ }
+
+
+
+
+def make_unary_function_test(name, (a, b)=(0, 1), threshold=0):
+ def test(ctx_getter):
+ context = ctx_getter()
+ queue = cl.CommandQueue(context)
+
+ gpu_func = getattr(clmath, name)
+ cpu_func = getattr(numpy, numpy_func_names.get(name, name))
+
+ if has_double_support(context.devices[0]):
+ dtypes = [numpy.float32, numpy.float64]
+ else:
+ dtypes = [numpy.float32]
+
+ for s in sizes:
+ for dtype in dtypes:
+ args = cl_array.arange(context, queue, a, b, (b-a)/s,
+ dtype=numpy.float32)
+ gpu_results = gpu_func(args).get()
+ cpu_results = cpu_func(args.get())
+
+ max_err = numpy.max(numpy.abs(cpu_results - gpu_results))
+ assert (max_err <= threshold).all(), \
+ (max_err, name, dtype)
+
+ return pytools.test.mark_test.opencl(test)
+
+
+
+
+if have_cl():
+ test_ceil = make_unary_function_test("ceil", (-10, 10))
+ test_floor = make_unary_function_test("ceil", (-10, 10))
+ test_fabs = make_unary_function_test("fabs", (-10, 10))
+ test_exp = make_unary_function_test("exp", (-3, 3), 1e-5)
+ test_log = make_unary_function_test("log", (1e-5, 1), 1e-6)
+ test_log10 = make_unary_function_test("log10", (1e-5, 1), 5e-7)
+ test_sqrt = make_unary_function_test("sqrt", (1e-5, 1), 2e-7)
+
+ test_sin = make_unary_function_test("sin", (-10, 10), 1e-7)
+ test_cos = make_unary_function_test("cos", (-10, 10), 1e-7)
+ test_asin = make_unary_function_test("asin", (-0.9, 0.9), 5e-7)
+ test_acos = make_unary_function_test("acos", (-0.9, 0.9), 5e-7)
+ test_tan = make_unary_function_test("tan",
+ (-math.pi/2 + 0.1, math.pi/2 - 0.1), 1e-5)
+ test_atan = make_unary_function_test("atan", (-10, 10), 2e-7)
+
+ test_sinh = make_unary_function_test("sinh", (-3, 3), 1e-6)
+ test_cosh = make_unary_function_test("cosh", (-3, 3), 1e-6)
+ test_tanh = make_unary_function_test("tanh", (-3, 3), 2e-6)
+
+
+
+
+@pytools.test.mark_test.opencl
+def test_fmod(ctx_getter):
+ context = ctx_getter()
+ queue = cl.CommandQueue(context)
+
+ for s in sizes:
+ a = cl_array.arange(context, queue, s, dtype=numpy.float32)/10
+ a2 = cl_array.arange(context, queue, s, dtype=numpy.float32)/45.2 + 0.1
+ b = clmath.fmod(a, a2)
+
+ a = a.get()
+ a2 = a2.get()
+ b = b.get()
+
+ for i in range(s):
+ assert math.fmod(a[i], a2[i]) == b[i]
+
+@pytools.test.mark_test.opencl
+def test_ldexp(ctx_getter):
+ context = ctx_getter()
+ queue = cl.CommandQueue(context)
+
+ for s in sizes:
+ a = cl_array.arange(context, queue, s, dtype=numpy.float32)
+ a2 = cl_array.arange(context, queue, s, dtype=numpy.float32)*1e-3
+ b = clmath.ldexp(a,a2)
+
+ a = a.get()
+ a2 = a2.get()
+ b = b.get()
+
+ for i in range(s):
+ assert math.ldexp(a[i], int(a2[i])) == b[i]
+
+@pytools.test.mark_test.opencl
+def test_modf(ctx_getter):
+ context = ctx_getter()
+ queue = cl.CommandQueue(context)
+
+ for s in sizes:
+ a = cl_array.arange(context, queue, s, dtype=numpy.float32)/10
+ fracpart, intpart = clmath.modf(a)
+
+ a = a.get()
+ intpart = intpart.get()
+ fracpart = fracpart.get()
+
+ for i in range(s):
+ fracpart_true, intpart_true = math.modf(a[i])
+
+ assert intpart_true == intpart[i]
+ assert abs(fracpart_true - fracpart[i]) < 1e-4
+
+@pytools.test.mark_test.opencl
+def test_frexp(ctx_getter):
+ context = ctx_getter()
+ queue = cl.CommandQueue(context)
+
+ for s in sizes:
+ a = cl_array.arange(context, queue, s, dtype=numpy.float32)/10
+ significands, exponents = clmath.frexp(a)
+
+ a = a.get()
+ significands = significands.get()
+ exponents = exponents.get()
+
+ for i in range(s):
+ sig_true, ex_true = math.frexp(a[i])
+
+ assert sig_true == significands[i]
+ assert ex_true == exponents[i]
+
+
+
+
+if __name__ == "__main__":
+ # make sure that import failures get reported, instead of skipping the tests.
+ import sys
+ if len(sys.argv) > 1:
+ exec sys.argv[1]
+ else:
+ from py.test.cmdline import main
+ main([__file__])
diff -Nru pyopencl-0.92~beta+git20100709/test/test_math.py pyopencl-0.92/test/test_math.py
--- pyopencl-0.92~beta+git20100709/test/test_math.py 2010-07-10 18:03:27.000000000 +0200
+++ pyopencl-0.92/test/test_math.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,182 +0,0 @@
-from __future__ import division
-import math
-import numpy
-import pytools.test
-
-def have_cl():
- try:
- import pyopencl
- return True
- except:
- return False
-
-if have_cl():
- import pyopencl.array as cl_array
- import pyopencl as cl
- import pyopencl.clmath as clmath
- from pyopencl.tools import pytest_generate_tests_for_pyopencl \
- as pytest_generate_tests
-
-
-
-
-
-sizes = [10, 128, 1024, 1<<10, 1<<13]
-
-
-
-
-def has_double_support(dev):
- for ext in dev.extensions.split(" "):
- if ext == "cl_khr_fp64":
- return True
- return False
-
-
-
-
-numpy_func_names = {
- "asin": "arcsin",
- "acos": "arccos",
- "atan": "arctan",
- }
-
-
-
-
-def make_unary_function_test(name, (a, b)=(0, 1), threshold=0):
- def test(ctx_getter):
- context = ctx_getter()
- queue = cl.CommandQueue(context)
-
- gpu_func = getattr(clmath, name)
- cpu_func = getattr(numpy, numpy_func_names.get(name, name))
-
- if has_double_support(context.devices[0]):
- dtypes = [numpy.float32, numpy.float64]
- else:
- dtypes = [numpy.float32]
-
- for s in sizes:
- for dtype in dtypes:
- args = cl_array.arange(context, queue, a, b, (b-a)/s,
- dtype=numpy.float32)
- gpu_results = gpu_func(args).get()
- cpu_results = cpu_func(args.get())
-
- max_err = numpy.max(numpy.abs(cpu_results - gpu_results))
- assert (max_err <= threshold).all(), \
- (max_err, name, dtype)
-
- return pytools.test.mark_test.opencl(test)
-
-
-
-
-if have_cl():
- test_ceil = make_unary_function_test("ceil", (-10, 10))
- test_floor = make_unary_function_test("ceil", (-10, 10))
- test_fabs = make_unary_function_test("fabs", (-10, 10))
- test_exp = make_unary_function_test("exp", (-3, 3), 1e-5)
- test_log = make_unary_function_test("log", (1e-5, 1), 5e-7)
- test_log10 = make_unary_function_test("log10", (1e-5, 1), 3e-7)
- test_sqrt = make_unary_function_test("sqrt", (1e-5, 1), 2e-7)
-
- test_sin = make_unary_function_test("sin", (-10, 10), 1e-7)
- test_cos = make_unary_function_test("cos", (-10, 10), 1e-7)
- test_asin = make_unary_function_test("asin", (-0.9, 0.9), 5e-7)
- test_acos = make_unary_function_test("acos", (-0.9, 0.9), 5e-7)
- test_tan = make_unary_function_test("tan",
- (-math.pi/2 + 0.1, math.pi/2 - 0.1), 1e-5)
- test_atan = make_unary_function_test("atan", (-10, 10), 2e-7)
-
- test_sinh = make_unary_function_test("sinh", (-3, 3), 1e-6)
- test_cosh = make_unary_function_test("cosh", (-3, 3), 1e-6)
- test_tanh = make_unary_function_test("tanh", (-3, 3), 2e-6)
-
-
-
-
-@pytools.test.mark_test.opencl
-def test_fmod(ctx_getter):
- context = ctx_getter()
- queue = cl.CommandQueue(context)
-
- for s in sizes:
- a = cl_array.arange(context, queue, s, dtype=numpy.float32)/10
- a2 = cl_array.arange(context, queue, s, dtype=numpy.float32)/45.2 + 0.1
- b = clmath.fmod(a, a2)
-
- a = a.get()
- a2 = a2.get()
- b = b.get()
-
- for i in range(s):
- assert math.fmod(a[i], a2[i]) == b[i]
-
-@pytools.test.mark_test.opencl
-def test_ldexp(ctx_getter):
- context = ctx_getter()
- queue = cl.CommandQueue(context)
-
- for s in sizes:
- a = cl_array.arange(context, queue, s, dtype=numpy.float32)
- a2 = cl_array.arange(context, queue, s, dtype=numpy.float32)*1e-3
- b = clmath.ldexp(a,a2)
-
- a = a.get()
- a2 = a2.get()
- b = b.get()
-
- for i in range(s):
- assert math.ldexp(a[i], int(a2[i])) == b[i]
-
-@pytools.test.mark_test.opencl
-def test_modf(ctx_getter):
- context = ctx_getter()
- queue = cl.CommandQueue(context)
-
- for s in sizes:
- a = cl_array.arange(context, queue, s, dtype=numpy.float32)/10
- fracpart, intpart = clmath.modf(a)
-
- a = a.get()
- intpart = intpart.get()
- fracpart = fracpart.get()
-
- for i in range(s):
- fracpart_true, intpart_true = math.modf(a[i])
-
- assert intpart_true == intpart[i]
- assert abs(fracpart_true - fracpart[i]) < 1e-4
-
-@pytools.test.mark_test.opencl
-def test_frexp(ctx_getter):
- context = ctx_getter()
- queue = cl.CommandQueue(context)
-
- for s in sizes:
- a = cl_array.arange(context, queue, s, dtype=numpy.float32)/10
- significands, exponents = clmath.frexp(a)
-
- a = a.get()
- significands = significands.get()
- exponents = exponents.get()
-
- for i in range(s):
- sig_true, ex_true = math.frexp(a[i])
-
- assert sig_true == significands[i]
- assert ex_true == exponents[i]
-
-
-
-
-if __name__ == "__main__":
- # make sure that import failures get reported, instead of skipping the tests.
- import sys
- if len(sys.argv) > 1:
- exec sys.argv[1]
- else:
- from py.test.cmdline import main
- main([__file__])
diff --git a/.gitignore b/.gitignore
index 8a52c24..2ed0d45 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,3 +44,4 @@ MANIFEST
tmp
temp*
setuptools.pth
+distribute-*.tar.gz
diff --git a/MANIFEST.in b/MANIFEST.in
index fdfc08c..1426ac2 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -13,4 +13,4 @@ include Makefile.in
include aksetup_helper.py
include README_SETUP.txt
-recursive-include bpl-subset
+recursive-include bpl-subset *.h *.hpp *.cpp *.html *.inl *.ipp *.pl *.txt
diff --git a/aksetup_helper.py b/aksetup_helper.py
index 5637d68..252fd3f 100644
--- a/aksetup_helper.py
+++ b/aksetup_helper.py
@@ -2,8 +2,34 @@
import distribute_setup
distribute_setup.use_setuptools()
+import setuptools
from setuptools import Extension
+if not hasattr(setuptools, "_distribute"):
+ print("-------------------------------------------------------------------------")
+ print("Setuptools conflict detected.")
+ print("-------------------------------------------------------------------------")
+ print("When I imported setuptools, I did not get the distribute version of")
+ print("setuptools, which is troubling--this package really wants to be used")
+ print("with distribute rather than the old setuptools package. More than likely,")
+ print("you have both distribute and setuptools installed, which is bad.")
+ print("")
+ print("See this page for more information:")
+ print("http://wiki.tiker.net/DistributeVsSetuptools")
+ print("-------------------------------------------------------------------------")
+ print("I will continue after a short while, fingers crossed.")
+ print("-------------------------------------------------------------------------")
+
+ delay = 10
+
+ from time import sleep
+ import sys
+ while delay:
+ sys.stdout.write("Continuing in %d seconds... \r" % delay)
+ sys.stdout.flush()
+ delay -= 1
+ sleep(1)
+
def setup(*args, **kwargs):
from setuptools import setup
import traceback
@@ -14,16 +40,16 @@ def setup(*args, **kwargs):
except SystemExit:
raise
except:
- print "----------------------------------------------------------------------------"
- print "Sorry, your build failed. Try rerunning configure.py with different options."
- print "----------------------------------------------------------------------------"
+ print ("----------------------------------------------------------------------------")
+ print ("Sorry, your build failed. Try rerunning configure.py with different options.")
+ print ("----------------------------------------------------------------------------")
raise
class NumpyExtension(Extension):
- # nicked from
+ # nicked from
# http://mail.python.org/pipermail/distutils-sig/2007-September/008253.html
# solution by Michael Hoffmann
def __init__(self, *args, **kwargs):
@@ -83,7 +109,7 @@ class HedgeExtension(PyUblasExtension):
# tools -----------------------------------------------------------------------
def flatten(list):
- """For an iterable of sub-iterables, generate each member of each
+ """For an iterable of sub-iterables, generate each member of each
sub-iterable in turn, i.e. a flattened version of that super-iterable.
Example: Turn [[a,b,c],[d,e,f]] into [a,b,c,d,e,f].
@@ -110,20 +136,20 @@ def get_config(schema=None, warn_about_no_config=True):
if (not schema.have_config() and not schema.have_global_config()
and warn_about_no_config):
- print "*************************************************************"
- print "*** I have detected that you have not run configure.py."
- print "*************************************************************"
- print "*** Additionally, no global config files were found."
- print "*** I will go ahead with the default configuration."
- print "*** In all likelihood, this will not work out."
- print "*** "
- print "*** See README_SETUP.txt for more information."
- print "*** "
- print "*** If the build does fail, just re-run configure.py with the"
- print "*** correct arguments, and then retry. Good luck!"
- print "*************************************************************"
- print "*** HIT Ctrl-C NOW IF THIS IS NOT WHAT YOU WANT"
- print "*************************************************************"
+ print("*************************************************************")
+ print("*** I have detected that you have not run configure.py.")
+ print("*************************************************************")
+ print("*** Additionally, no global config files were found.")
+ print("*** I will go ahead with the default configuration.")
+ print("*** In all likelihood, this will not work out.")
+ print("*** ")
+ print("*** See README_SETUP.txt for more information.")
+ print("*** ")
+ print("*** If the build does fail, just re-run configure.py with the")
+ print("*** correct arguments, and then retry. Good luck!")
+ print("*************************************************************")
+ print("*** HIT Ctrl-C NOW IF THIS IS NOT WHAT YOU WANT")
+ print("*************************************************************")
delay = 10
@@ -204,7 +230,7 @@ def expand_str(s, options):
return re.subn(r"\$\{([a-zA-Z0-9_]+)\}", my_repl, s)[0]
def expand_value(v, options):
- if isinstance(v, (str, unicode)):
+ if isinstance(v, str):
return expand_str(v, options)
elif isinstance(v, list):
return [expand_value(i, options) for i in v]
@@ -246,15 +272,15 @@ class ConfigSchema:
self.conf_dir = conf_dir
def get_default_config(self):
- return dict((opt.name, opt.default)
+ return dict((opt.name, opt.default)
for opt in self.options)
-
+
def read_config_from_pyfile(self, filename):
result = {}
filevars = {}
- execfile(filename, filevars)
+ exec(compile(open(filename, "r").read(), filename, "exec"), filevars)
- for key, value in filevars.iteritems():
+ for key, value in filevars.items():
if key in self.optdict:
result[key] = value
@@ -265,13 +291,13 @@ class ConfigSchema:
filevars = {}
try:
- execfile(filename, filevars)
+ exec(compile(open(filename, "r").read(), filename, "exec"), filevars)
except IOError:
pass
del filevars["__builtins__"]
- for key, value in config.iteritems():
+ for key, value in config.items():
if value is not None:
filevars[key] = value
@@ -296,7 +322,7 @@ class ConfigSchema:
result = self.get_default_config()
import os
-
+
confignames = []
if self.global_conf_file is not None:
confignames.append(self.global_conf_file)
@@ -328,16 +354,16 @@ class ConfigSchema:
result = self.get_default_config_with_files()
if os.access(cfile, os.R_OK):
filevars = {}
- execfile(cfile, filevars)
+ exec(compile(open(cfile, "r").read(), cfile, "exec"), filevars)
- for key, value in filevars.iteritems():
+ for key, value in filevars.items():
if key in self.optdict:
result[key] = value
elif key == "__builtins__":
pass
else:
- raise KeyError, "invalid config key in %s: %s" % (
- cfile, key)
+ raise KeyError("invalid config key in %s: %s" % (
+ cfile, key))
expand_options(result)
@@ -399,13 +425,13 @@ class Option(object):
return result
def value_to_str(self, default):
- return default
+ return default
def add_to_configparser(self, parser, default=None):
default = default_or(default, self.default)
default_str = self.value_to_str(default)
parser.add_option(
- "--" + self.as_option(), dest=self.name,
+ "--" + self.as_option(), dest=self.name,
default=default_str,
metavar=self.metavar(), help=self.get_help(default))
@@ -417,7 +443,7 @@ class Switch(Option):
option = self.as_option()
if not isinstance(self.default, bool):
- raise ValueError, "Switch options must have a default"
+ raise ValueError("Switch options must have a default")
if default is None:
default = self.default
@@ -426,11 +452,11 @@ class Switch(Option):
action = "store_false"
else:
action = "store_true"
-
+
parser.add_option(
- "--" + self.as_option(),
- dest=self.name,
- help=self.get_help(default),
+ "--" + self.as_option(),
+ dest=self.name,
+ help=self.get_help(default),
default=default,
action=action)
@@ -458,7 +484,7 @@ class StringListOption(Option):
class IncludeDir(StringListOption):
def __init__(self, lib_name, default=None, human_name=None, help=None):
StringListOption.__init__(self, "%s_INC_DIR" % lib_name, default,
- help=help or ("Include directories for %s"
+ help=help or ("Include directories for %s"
% (human_name or humanize(lib_name))))
class LibraryDir(StringListOption):
@@ -470,14 +496,14 @@ class LibraryDir(StringListOption):
class Libraries(StringListOption):
def __init__(self, lib_name, default=None, human_name=None, help=None):
StringListOption.__init__(self, "%s_LIBNAME" % lib_name, default,
- help=help or ("Library names for %s (without lib or .so)"
+ help=help or ("Library names for %s (without lib or .so)"
% (human_name or humanize(lib_name))))
class BoostLibraries(Libraries):
def __init__(self, lib_base_name):
- Libraries.__init__(self, "BOOST_%s" % lib_base_name.upper(),
+ Libraries.__init__(self, "BOOST_%s" % lib_base_name.upper(),
["boost_%s-${BOOST_COMPILER}-mt" % lib_base_name],
- help="Library names for Boost C++ %s library (without lib or .so)"
+ help="Library names for Boost C++ %s library (without lib or .so)"
% humanize(lib_base_name))
def set_up_shipped_boost_if_requested(conf):
@@ -491,22 +517,22 @@ def set_up_shipped_boost_if_requested(conf):
if conf["USE_SHIPPED_BOOST"]:
if not exists("bpl-subset/bpl_subset/boost/version.hpp"):
- print >>sys.stderr, "------------------------------------------------------------------------"
- print >>sys.stderr, "The shipped Boost library was not found, but USE_SHIPPED_BOOST is True."
- print >>sys.stderr, "(The files should be under bpl-subset/.)"
- print >>sys.stderr, "------------------------------------------------------------------------"
- print >>sys.stderr, "If you got this package from git, you probably want to do"
- print >>sys.stderr, ""
- print >>sys.stderr, " $ git submodule init"
- print >>sys.stderr, " $ git submodule update"
- print >>sys.stderr, ""
- print >>sys.stderr, "to fetch what you are presently missing. If you got this from"
- print >>sys.stderr, "a distributed package on the net, that package is broken and"
- print >>sys.stderr, "should be fixed. For now, I will turn off 'USE_SHIPPED_BOOST'"
- print >>sys.stderr, "to try and see if the build succeeds that way, but in the long"
- print >>sys.stderr, "run you might want to either get the missing bits or turn"
- print >>sys.stderr, "'USE_SHIPPED_BOOST' off."
- print >>sys.stderr, "------------------------------------------------------------------------"
+ print("------------------------------------------------------------------------")
+ print("The shipped Boost library was not found, but USE_SHIPPED_BOOST is True.")
+ print("(The files should be under bpl-subset/.)")
+ print("------------------------------------------------------------------------")
+ print("If you got this package from git, you probably want to do")
+ print("")
+ print(" $ git submodule init")
+ print(" $ git submodule update")
+ print("")
+ print("to fetch what you are presently missing. If you got this from")
+ print("a distributed package on the net, that package is broken and")
+ print("should be fixed. For now, I will turn off 'USE_SHIPPED_BOOST'")
+ print("to try and see if the build succeeds that way, but in the long")
+ print("run you might want to either get the missing bits or turn")
+ print("'USE_SHIPPED_BOOST' off.")
+ print("------------------------------------------------------------------------")
conf["USE_SHIPPED_BOOST"] = False
delay = 10
@@ -541,7 +567,7 @@ def set_up_shipped_boost_if_requested(conf):
source_files += glob(
"bpl-subset/bpl_subset/libs/thread/src/pthread/*.cpp")
- return (source_files,
+ return (source_files,
{"BOOST_MULTI_INDEX_DISABLE_SERIALIZATION": 1}
)
else:
@@ -552,7 +578,7 @@ def make_boost_base_options():
return [
IncludeDir("BOOST", []),
LibraryDir("BOOST", []),
- Option("BOOST_COMPILER", default="gcc43",
+ Option("BOOST_COMPILER", default="gcc43",
help="The compiler with which Boost C++ was compiled, e.g. gcc43"),
]
@@ -568,29 +594,29 @@ def configure_frontend():
from setup import get_config_schema
schema = get_config_schema()
if schema.have_config():
- print "************************************************************"
- print "*** I have detected that you have already run configure."
- print "*** I'm taking the configured values as defaults for this"
- print "*** configure run. If you don't want this, delete the file"
- print "*** %s." % schema.get_conf_file()
- print "************************************************************"
+ print("************************************************************")
+ print("*** I have detected that you have already run configure.")
+ print("*** I'm taking the configured values as defaults for this")
+ print("*** configure run. If you don't want this, delete the file")
+ print("*** %s." % schema.get_conf_file())
+ print("************************************************************")
import sys
description = "generate a configuration file for this software package"
parser = OptionParser(description=description)
parser.add_option(
- "--python-exe", dest="python_exe", default=sys.executable,
- help="Which Python interpreter to use", metavar="PATH")
+ "--python-exe", dest="python_exe", default=sys.executable,
+ help="Which Python interpreter to use", metavar="PATH")
parser.add_option("--prefix", default=None,
- help="Ignored")
+ help="Ignored")
parser.add_option("--enable-shared", help="Ignored", action="store_false")
parser.add_option("--disable-static", help="Ignored", action="store_false")
- parser.add_option("--update-user", help="Update user config file (%s)" % schema.user_conf_file,
+ parser.add_option("--update-user", help="Update user config file (%s)" % schema.user_conf_file,
action="store_true")
- parser.add_option("--update-global",
- help="Update global config file (%s)" % schema.global_conf_file,
+ parser.add_option("--update-global",
+ help="Update global config file (%s)" % schema.global_conf_file,
action="store_true")
schema.add_to_configparser(parser, schema.read_config())
diff --git a/distribute_setup.py b/distribute_setup.py
index 59424cc..3ea2e66 100644
--- a/distribute_setup.py
+++ b/distribute_setup.py
@@ -46,19 +46,21 @@ except ImportError:
args = [quote(arg) for arg in args]
return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
-DEFAULT_VERSION = "0.6.4"
+DEFAULT_VERSION = "0.6.14"
DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
+SETUPTOOLS_FAKED_VERSION = "0.6c11"
+
SETUPTOOLS_PKG_INFO = """\
Metadata-Version: 1.0
Name: setuptools
-Version: 0.6c9
+Version: %s
Summary: xxxx
Home-page: xxx
Author: xxx
Author-email: xxx
License: xxx
Description: xxx
-"""
+""" % SETUPTOOLS_FAKED_VERSION
def _install(tarball):
@@ -79,12 +81,14 @@ def _install(tarball):
# installing
log.warn('Installing Distribute')
- assert _python_cmd('setup.py', 'install')
+ if not _python_cmd('setup.py', 'install'):
+ log.warn('Something went wrong during the installation.')
+ log.warn('See the error message above.')
finally:
os.chdir(old_wd)
-def _build_egg(tarball, to_dir):
+def _build_egg(egg, tarball, to_dir):
# extracting the tarball
tmpdir = tempfile.mkdtemp()
log.warn('Extracting in %s', tmpdir)
@@ -104,27 +108,28 @@ def _build_egg(tarball, to_dir):
log.warn('Building a Distribute egg in %s', to_dir)
_python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
- # returning the result
- for file in os.listdir(to_dir):
- if fnmatch.fnmatch(file, 'distribute-%s*.egg' % DEFAULT_VERSION):
- return os.path.join(to_dir, file)
-
- raise IOError('Could not build the egg.')
finally:
os.chdir(old_wd)
+ # returning the result
+ log.warn(egg)
+ if not os.path.exists(egg):
+ raise IOError('Could not build the egg.')
def _do_download(version, download_base, to_dir, download_delay):
- tarball = download_setuptools(version, download_base,
- to_dir, download_delay)
- egg = _build_egg(tarball, to_dir)
+ egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg'
+ % (version, sys.version_info[0], sys.version_info[1]))
+ if not os.path.exists(egg):
+ tarball = download_setuptools(version, download_base,
+ to_dir, download_delay)
+ _build_egg(egg, tarball, to_dir)
sys.path.insert(0, egg)
import setuptools
setuptools.bootstrap_install_from = egg
def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
- to_dir=os.curdir, download_delay=15):
+ to_dir=os.curdir, download_delay=15, no_fake=True):
# making sure we use the absolute path
to_dir = os.path.abspath(to_dir)
was_imported = 'pkg_resources' in sys.modules or \
@@ -133,21 +138,23 @@ def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
try:
import pkg_resources
if not hasattr(pkg_resources, '_distribute'):
- fake_setuptools()
+ if not no_fake:
+ _fake_setuptools()
raise ImportError
except ImportError:
return _do_download(version, download_base, to_dir, download_delay)
try:
pkg_resources.require("distribute>="+version)
return
- except pkg_resources.VersionConflict, e:
+ except pkg_resources.VersionConflict:
+ e = sys.exc_info()[1]
if was_imported:
- print >>sys.stderr, (
+ sys.stderr.write(
"The required version of distribute (>=%s) is not available,\n"
"and can't be installed while this script is running. Please\n"
"install a more recent version first, using\n"
"'easy_install -U distribute'."
- "\n\n(Currently using %r)") % (version, e.args[0])
+ "\n\n(Currently using %r)\n" % (version, e.args[0]))
sys.exit(2)
else:
del pkg_resources, sys.modules['pkg_resources'] # reload ok
@@ -157,7 +164,8 @@ def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
return _do_download(version, download_base, to_dir,
download_delay)
finally:
- _create_fake_setuptools_pkg_info(to_dir)
+ if not no_fake:
+ _create_fake_setuptools_pkg_info(to_dir)
def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
to_dir=os.curdir, delay=15):
@@ -171,7 +179,10 @@ def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
"""
# making sure we use the absolute path
to_dir = os.path.abspath(to_dir)
- import urllib2
+ try:
+ from urllib.request import urlopen
+ except ImportError:
+ from urllib2 import urlopen
tgz_name = "distribute-%s.tar.gz" % version
url = download_base + tgz_name
saveto = os.path.join(to_dir, tgz_name)
@@ -179,7 +190,7 @@ def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
if not os.path.exists(saveto): # Avoid repeated downloads
try:
log.warn("Downloading %s", url)
- src = urllib2.urlopen(url)
+ src = urlopen(url)
# Read/write all in one block, so we don't create a corrupt file
# if the download is interrupted.
data = src.read()
@@ -192,6 +203,29 @@ def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
dst.close()
return os.path.realpath(saveto)
+def _no_sandbox(function):
+ def __no_sandbox(*args, **kw):
+ try:
+ from setuptools.sandbox import DirectorySandbox
+ if not hasattr(DirectorySandbox, '_old'):
+ def violation(*args):
+ pass
+ DirectorySandbox._old = DirectorySandbox._violation
+ DirectorySandbox._violation = violation
+ patched = True
+ else:
+ patched = False
+ except ImportError:
+ patched = False
+
+ try:
+ return function(*args, **kw)
+ finally:
+ if patched:
+ DirectorySandbox._violation = DirectorySandbox._old
+ del DirectorySandbox._old
+
+ return __no_sandbox
def _patch_file(path, content):
"""Will backup the file then patch it"""
@@ -209,26 +243,17 @@ def _patch_file(path, content):
f.close()
return True
+_patch_file = _no_sandbox(_patch_file)
def _same_content(path, content):
return open(path).read() == content
-
def _rename_path(path):
new_name = path + '.OLD.%s' % time.time()
log.warn('Renaming %s into %s', path, new_name)
- try:
- from setuptools.sandbox import DirectorySandbox
- def _violation(*args):
- pass
- DirectorySandbox._violation = _violation
- except ImportError:
- pass
-
os.rename(path, new_name)
return new_name
-
def _remove_flat_installation(placeholder):
if not os.path.isdir(placeholder):
log.warn('Unkown installation at %s', placeholder)
@@ -262,6 +287,7 @@ def _remove_flat_installation(placeholder):
'Setuptools distribution', element)
return True
+_remove_flat_installation = _no_sandbox(_remove_flat_installation)
def _after_install(dist):
log.warn('After install bootstrap.')
@@ -273,17 +299,20 @@ def _create_fake_setuptools_pkg_info(placeholder):
log.warn('Could not find the install location')
return
pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1])
- setuptools_file = 'setuptools-0.6c9-py%s.egg-info' % pyver
+ setuptools_file = 'setuptools-%s-py%s.egg-info' % \
+ (SETUPTOOLS_FAKED_VERSION, pyver)
pkg_info = os.path.join(placeholder, setuptools_file)
if os.path.exists(pkg_info):
log.warn('%s already exists', pkg_info)
return
+
log.warn('Creating %s', pkg_info)
f = open(pkg_info, 'w')
try:
f.write(SETUPTOOLS_PKG_INFO)
finally:
f.close()
+
pth_file = os.path.join(placeholder, 'setuptools.pth')
log.warn('Creating %s', pth_file)
f = open(pth_file, 'w')
@@ -292,6 +321,7 @@ def _create_fake_setuptools_pkg_info(placeholder):
finally:
f.close()
+_create_fake_setuptools_pkg_info = _no_sandbox(_create_fake_setuptools_pkg_info)
def _patch_egg_dir(path):
# let's check if it's already patched
@@ -311,10 +341,11 @@ def _patch_egg_dir(path):
f.close()
return True
+_patch_egg_dir = _no_sandbox(_patch_egg_dir)
def _before_install():
log.warn('Before install bootstrap.')
- fake_setuptools()
+ _fake_setuptools()
def _under_prefix(location):
@@ -330,12 +361,12 @@ def _under_prefix(location):
if len(args) > index:
top_dir = args[index+1]
return location.startswith(top_dir)
- elif option == '--user' and USER_SITE is not None:
- return location.startswith(USER_SITE)
+ if arg == '--user' and USER_SITE is not None:
+ return location.startswith(USER_SITE)
return True
-def fake_setuptools():
+def _fake_setuptools():
log.warn('Scanning installed packages')
try:
import pkg_resources
@@ -344,7 +375,13 @@ def fake_setuptools():
log.warn('Setuptools or Distribute does not seem to be installed.')
return
ws = pkg_resources.working_set
- setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools'))
+ try:
+ setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools',
+ replacement=False))
+ except TypeError:
+ # old distribute API
+ setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools'))
+
if setuptools_dist is None:
log.warn('No setuptools distribution found')
return
@@ -384,6 +421,9 @@ def fake_setuptools():
def _relaunch():
log.warn('Relaunching...')
# we have to relaunch the process
+ # pip marker to avoid a relaunch bug
+ if sys.argv[:3] == ['-c', 'install', '--single-version-externally-managed']:
+ sys.argv[0] = 'setup.py'
args = [sys.executable] + sys.argv
sys.exit(subprocess.call(args))
@@ -408,7 +448,7 @@ def _extractall(self, path=".", members=None):
# Extract directories with a safe mode.
directories.append(tarinfo)
tarinfo = copy.copy(tarinfo)
- tarinfo.mode = 0700
+ tarinfo.mode = 448 # decimal for oct 0700
self.extract(tarinfo, path)
# Reverse sort directories.
@@ -427,7 +467,8 @@ def _extractall(self, path=".", members=None):
self.chown(tarinfo, dirpath)
self.utime(tarinfo, dirpath)
self.chmod(tarinfo, dirpath)
- except ExtractError, e:
+ except ExtractError:
+ e = sys.exc_info()[1]
if self.errorlevel > 1:
raise
else:
diff --git a/doc/source/array.rst b/doc/source/array.rst
new file mode 100644
index 0000000..93e5587
--- /dev/null
+++ b/doc/source/array.rst
@@ -0,0 +1,356 @@
+The :class:`Array` Class
+========================
+
+.. module:: pyopencl.array
+
+.. class:: DefaultAllocator(context, flags=pyopencl.mem_flags.READ_WRITE)
+
+ An Allocator that uses :class:`pyopencl.Buffer` with the given *flags*.
+
+ .. method:: __call__(self, size)
+
+.. class:: Array(context, shape, dtype, order="C", allocator=None, base=None, data=None, queue=None)
+
+ A :class:`numpy.ndarray` work-alike that stores its data and performs its
+ computations on the compute device. *shape* and *dtype* work exactly as in
+ :mod:`numpy`. Arithmetic methods in :class:`Array` support the
+ broadcasting of scalars. (e.g. `array+5`) If the
+
+ *allocator* is a callable that, upon being called with an argument of the number
+ of bytes to be allocated, returns an object that can be cast to an
+ :class:`int` representing the address of the newly allocated memory.
+ (See :class:`DefaultAllocator`.)
+
+ .. attribute :: data
+
+ The :class:`pyopencl.MemoryObject` instance created for the memory that backs
+ this :class:`Array`.
+
+ .. attribute :: shape
+
+ The tuple of lengths of each dimension in the array.
+
+ .. attribute :: dtype
+
+ The :class:`numpy.dtype` of the items in the GPU array.
+
+ .. attribute :: size
+
+ The number of meaningful entries in the array. Can also be computed by
+ multiplying up the numbers in :attr:`shape`.
+
+ .. attribute :: mem_size
+
+ The total number of entries, including padding, that are present in
+ the array.
+
+ .. attribute :: nbytes
+
+ The size of the entire array in bytes. Computed as :attr:`size` times
+ ``dtype.itemsize``.
+
+ .. method :: __len__()
+
+ Returns the size of the leading dimension of *self*.
+
+ .. method :: set(ary, queue=None, async=False)
+
+ Transfer the contents the :class:`numpy.ndarray` object *ary*
+ onto the device.
+
+ *ary* must have the same dtype and size (not necessarily shape) as *self*.
+
+
+ .. method :: get(queue=None, ary=None, async=False)
+
+ Transfer the contents of *self* into *ary* or a newly allocated
+ :mod:`numpy.ndarray`. If *ary* is given, it must have the right
+ size (not necessarily shape) and dtype.
+
+ .. method :: __str__()
+ .. method :: __repr__()
+
+ .. method :: mul_add(self, selffac, other, otherfac, queue=None):
+
+ Return `selffac*self + otherfac*other`.
+
+ .. method :: __add__(other)
+ .. method :: __sub__(other)
+ .. method :: __iadd__(other)
+ .. method :: __isub__(other)
+ .. method :: __neg__(other)
+ .. method :: __mul__(other)
+ .. method :: __div__(other)
+ .. method :: __rdiv__(other)
+ .. method :: __pow__(other)
+
+ .. method :: __abs__()
+
+ Return a :class:`Array` containing the absolute value of each
+ element of *self*.
+
+ .. UNDOC reverse()
+
+ .. method :: fill(scalar, queue=None)
+
+ Fill the array with *scalar*.
+
+ .. method :: astype(dtype, queue=None)
+
+ Return *self*, cast to *dtype*.
+
+Constructing :class:`Array` Instances
+----------------------------------------
+
+.. function:: to_device(context, queue, ary, allocator=None, async=False)
+
+ Return a :class:`Array` that is an exact copy of the :class:`numpy.ndarray`
+ instance *ary*.
+
+ See :class:`Array` for the meaning of *allocator*.
+
+.. function:: empty(context, shape, dtype, order="C", allocator=None, base=None, data=None, queue=None)
+
+ A synonym for the :class:`Array` constructor.
+
+.. function:: zeros(context, queue, shape, dtype, order="C", allocator=None)
+
+ Same as :func:`empty`, but the :class:`Array` is zero-initialized before
+ being returned.
+
+.. function:: empty_like(other_ary)
+
+ Make a new, uninitialized :class:`Array` having the same properties
+ as *other_ary*.
+
+.. function:: zeros_like(other_ary)
+
+ Make a new, zero-initialized :class:`Array` having the same properties
+ as *other_ary*.
+
+.. function:: arange(context, queue, start, stop, step, dtype=None)
+
+ Create a :class:`Array` filled with numbers spaced `step` apart,
+ starting from `start` and ending at `stop`.
+
+ For floating point arguments, the length of the result is
+ `ceil((stop - start)/step)`. This rule may result in the last
+ element of the result being greater than `stop`.
+
+ *dtype*, if not specified, is taken as the largest common type
+ of *start*, *stop* and *step*.
+
+.. function:: take(a, indices, out=None, queue=None)
+
+ Return the :class:`Array` ``[a[indices[0]], ..., a[indices[n]]]``.
+ For the moment, *a* must be a type that can be bound to a texture.
+
+Conditionals
+^^^^^^^^^^^^
+
+.. function:: if_positive(criterion, then_, else_, out=None, queue=None)
+
+ Return an array like *then_*, which, for the element at index *i*,
+ contains *then_[i]* if *criterion[i]>0*, else *else_[i]*. (added in 0.94)
+
+.. function:: maximum(a, b, out=None, queue=None)
+
+ Return the elementwise maximum of *a* and *b*. (added in 0.94)
+
+.. function:: minimum(a, b, out=None, queue=None)
+
+ Return the elementwise minimum of *a* and *b*. (added in 0.94)
+
+Elementwise Functions on :class:`Arrray` Instances
+-----------------------------------------------------
+
+.. module:: pyopencl.clmath
+
+The :mod:`pyopencl.clmath` module contains exposes array versions of the C
+functions available in the OpenCL standard. (See table 6.8 in the spec.)
+
+.. function:: acos(array, queue=None)
+.. function:: acosh(array, queue=None)
+.. function:: acospi(array, queue=None)
+
+.. function:: asin(array, queue=None)
+.. function:: asinh(array, queue=None)
+.. function:: asinpi(array, queue=None)
+
+.. function:: atan(array, queue=None)
+.. TODO: atan2
+.. function:: atanh(array, queue=None)
+.. function:: atanpi(array, queue=None)
+.. TODO: atan2pi
+
+.. function:: cbrt(array, queue=None)
+.. function:: ceil(array, queue=None)
+.. TODO: copysign
+
+.. function:: cos(array, queue=None)
+.. function:: cosh(array, queue=None)
+.. function:: cospi(array, queue=None)
+
+.. function:: erfc(array, queue=None)
+.. function:: erf(array, queue=None)
+.. function:: exp(array, queue=None)
+.. function:: exp2(array, queue=None)
+.. function:: exp10(array, queue=None)
+.. function:: expm1(array, queue=None)
+
+.. function:: fabs(array, queue=None)
+.. TODO: fdim
+.. function:: floor(array, queue=None)
+.. TODO: fma
+.. TODO: fmax
+.. TODO: fmin
+
+.. function:: fmod(arg, mod, queue=None)
+
+ Return the floating point remainder of the division `arg/mod`,
+ for each element in `arg` and `mod`.
+
+.. TODO: fract
+
+
+.. function:: frexp(arg, queue=None)
+
+ Return a tuple `(significands, exponents)` such that
+ `arg == significand * 2**exponent`.
+
+.. TODO: hypot
+
+.. function:: ilogb(array, queue=None)
+.. function:: ldexp(significand, exponent, queue=None)
+
+ Return a new array of floating point values composed from the
+ entries of `significand` and `exponent`, paired together as
+ `result = significand * 2**exponent`.
+
+
+.. function:: lgamma(array, queue=None)
+.. TODO: lgamma_r
+
+.. function:: log(array, queue=None)
+.. function:: log2(array, queue=None)
+.. function:: log10(array, queue=None)
+.. function:: log1p(array, queue=None)
+.. function:: logb(array, queue=None)
+
+.. TODO: mad
+.. TODO: maxmag
+.. TODO: minmag
+
+
+.. function:: modf(arg, queue=None)
+
+ Return a tuple `(fracpart, intpart)` of arrays containing the
+ integer and fractional parts of `arg`.
+
+.. function:: nan(array, queue=None)
+
+.. TODO: nextafter
+.. TODO: remainder
+.. TODO: remquo
+
+.. function:: rint(array, queue=None)
+.. TODO: rootn
+.. function:: round(array, queue=None)
+
+.. function:: sin(array, queue=None)
+.. TODO: sincos
+.. function:: sinh(array, queue=None)
+.. function:: sinpi(array, queue=None)
+
+.. function:: sqrt(array, queue=None)
+
+.. function:: tan(array, queue=None)
+.. function:: tanh(array, queue=None)
+.. function:: tanpi(array, queue=None)
+.. function:: tgamma(array, queue=None)
+.. function:: trunc(array, queue=None)
+
+
+Generating Arrays of Random Numbers
+-----------------------------------
+
+.. module:: pyopencl.clrandom
+
+.. function:: rand(context, queue, shape, dtype)
+
+ Return an array of `shape` filled with random values of `dtype`
+ in the range [0,1).
+
+Single-pass Custom Expression Evaluation
+----------------------------------------
+
+.. warning::
+
+ The following functionality is included in this documentation in the
+ hope that it may be useful, but its interface may change in future
+ revisions. Feedback is welcome.
+
+.. module:: pyopencl.elementwise
+
+Evaluating involved expressions on :class:`pyopencl.array.Array` instances can be
+somewhat inefficient, because a new temporary is created for each
+intermediate result. The functionality in the module :mod:`pyopencl.elementwise`
+contains tools to help generate kernels that evaluate multi-stage expressions
+on one or several operands in a single pass.
+
+.. class:: ElementwiseKernel(context, arguments, operation, name="kernel", options=[])
+
+ Generate a kernel that takes a number of scalar or vector *arguments*
+ and performs the scalar *operation* on each entry of its arguments, if that
+ argument is a vector.
+
+ *arguments* is specified as a string formatted as a C argument list.
+ *operation* is specified as a C assignment statement, without a semicolon.
+ Vectors in *operation* should be indexed by the variable *i*.
+
+ *name* specifies the name as which the kernel is compiled,
+ and *options* are passed unmodified to :meth:`pyopencl.Program.build`.
+
+ .. method:: __call__(*args)
+
+ Invoke the generated scalar kernel. The arguments may either be scalars or
+ :class:`GPUArray` instances.
+
+Here's a usage example::
+
+ import pyopencl as cl
+ import pyopencl.array as cl_array
+ import numpy
+
+ ctx = cl.create_some_context()
+ queue = cl.CommandQueue(ctx)
+
+ n = 10
+ a_gpu = cl_array.to_device(
+ ctx, queue, numpy.random.randn(n).astype(numpy.float32))
+ b_gpu = cl_array.to_device(
+ ctx, queue, numpy.random.randn(n).astype(numpy.float32))
+
+ from pyopencl.elementwise import ElementwiseKernel
+ lin_comb = ElementwiseKernel(ctx,
+ "float a, float *x, "
+ "float b, float *y, "
+ "float *z",
+ "z[i] = a*x[i] + b*y[i]",
+ "linear_combination")
+
+ c_gpu = cl_array.empty_like(a_gpu)
+ lin_comb(5, a_gpu, 6, b_gpu, c_gpu)
+
+ import numpy.linalg as la
+ assert la.norm((c_gpu - (5*a_gpu+6*b_gpu)).get()) < 1e-5
+
+(You can find this example as :file:`examples/demo_elementwise.py` in the PyOpenCL
+distribution.)
+
+Fast Fourier Transforms
+-----------------------
+
+Bogdan Opanchuk's `pyfft <http://pypi.python.org/pypi/pyfft>`_ package offers a
+variety of GPU-based FFT implementations.
+
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 38456e9..c3bca32 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -70,6 +70,7 @@ Contents
:maxdepth: 2
runtime
+ array
misc
Note that this guide does not explain OpenCL programming and technology. Please
diff --git a/doc/source/misc.rst b/doc/source/misc.rst
index 56ce060..bd92d09 100644
--- a/doc/source/misc.rst
+++ b/doc/source/misc.rst
@@ -82,9 +82,10 @@ Version 0.92
emphasize the importance of *loccal_size*.
* Add :meth:`pyopencl.Kernel.set_scalar_arg_dtypes`.
* Add support for the
- `cl_nv_device_attribute_query <ghttp://www.khronos.org/registry/cl/extensions/khr/cl_nv_device_attribute_query.txt>`_
+ `cl_nv_device_attribute_query <http://www.khronos.org/registry/cl/extensions/khr/cl_nv_device_attribute_query.txt>`_
extension.
-
+* Add :meth:`pyopencl.array.Array` and related functionality.
+* Make build not depend on Boost C++.
Version 0.91.5
--------------
diff --git a/doc/source/runtime.rst b/doc/source/runtime.rst
index c1c83d8..00c3ef2 100644
--- a/doc/source/runtime.rst
+++ b/doc/source/runtime.rst
@@ -565,7 +565,7 @@ Programs and Kernels
See :class:`kernel_work_group_info` for values of *param*.
- .. method:: set_arg(self, arg)
+ .. method:: set_arg(self, index, arg)
*arg* may be
@@ -594,6 +594,8 @@ Programs and Kernels
Invoke :meth:`set_arg` on each element of *args* in turn.
+ ..versionadded:: 0.92
+
.. method:: set_scalar_arg_dtypes(arg_dtypes)
Inform the wrapper about the sized types of scalar
diff --git a/examples/demo_mandelbrot.py b/examples/demo_mandelbrot.py
index ddcf1b2..4919dbb 100644
--- a/examples/demo_mandelbrot.py
+++ b/examples/demo_mandelbrot.py
@@ -27,41 +27,43 @@ import pyopencl as cl
# Speed notes are listed in the same place
# set width and height of window, more pixels take longer to calculate
-w = 400
-h = 400
+w = 256
+h = 256
def calc_fractal_opencl(q, maxiter):
ctx = cl.Context(cl.get_platforms()[0].get_devices())
queue = cl.CommandQueue(ctx)
- output = np.empty(q.shape, dtype=np.uint64)# resize(np.array(0,), q.shape)
+ output = np.empty(q.shape, dtype=np.uint16)
mf = cl.mem_flags
q_opencl = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=q)
output_opencl = cl.Buffer(ctx, mf.WRITE_ONLY, output.nbytes)
prg = cl.Program(ctx, """
+ #pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable
__kernel void mandelbrot(__global float2 *q,
- __global long *output, long const maxiter)
+ __global ushort *output, ushort const maxiter)
{
int gid = get_global_id(0);
float nreal, real = 0;
float imag = 0;
+
+ output[gid] = 0;
+
for(int curiter = 0; curiter < maxiter; curiter++) {
- nreal = real*real - imag*imag + q[gid][0];
- imag = 2* real*imag + q[gid][1];
+ nreal = real*real - imag*imag + q[gid].x;
+ imag = 2* real*imag + q[gid].y;
real = nreal;
- if (real*real + imag*imag > 4.) {
+ if (real*real + imag*imag > 4.0f)
output[gid] = curiter;
- break;
- }
}
}
""").build()
- prg.mandelbrot(queue, output.shape, None, q_opencl,
- output_opencl, np.int32(maxiter))
+ prg.mandelbrot(queue, output.shape, (64,), q_opencl,
+ output_opencl, np.uint16(maxiter))
cl.enqueue_read_buffer(queue, output_opencl, output).wait()
@@ -121,10 +123,10 @@ if __name__ == '__main__':
self.root.mainloop()
- def draw(self, x1, x2, y1, y2, maxiter=300):
+ def draw(self, x1, x2, y1, y2, maxiter=30):
# draw the Mandelbrot set, from numpy example
- xx = np.arange(x1, x2, (x2-x1)/w*2)
- yy = np.arange(y2, y1, (y1-y2)/h*2) * 1j
+ xx = np.arange(x1, x2, (x2-x1)/w)
+ yy = np.arange(y2, y1, (y1-y2)/h) * 1j
q = np.ravel(xx+yy[:, np.newaxis]).astype(np.complex64)
start_main = time.time()
@@ -134,18 +136,20 @@ if __name__ == '__main__':
secs = end_main - start_main
print "Main took", secs
- output = (output + (256*output) + (256**2)*output) * 8
- # convert output to a string
- self.mandel = output.tostring()
+ self.mandel = (output.reshape((h,w)) /
+ float(output.max()) * 255.).astype(np.uint8)
def create_image(self):
""""
create the image from the draw() string
"""
- self.im = Image.new("RGB", (w/2, h/2))
# you can experiment with these x and y ranges
self.draw(-2.13, 0.77, -1.3, 1.3)
- self.im.fromstring(self.mandel, "raw", "RGBX", 0, -1)
+ self.im = Image.fromarray(self.mandel)
+ self.im.putpalette(reduce(
+ lambda a,b: a+b, ((i,0,0) for i in range(255))
+ ))
+
def create_label(self):
# put the image on a label widget
diff --git a/examples/gl_interop_demo.py b/examples/gl_interop_demo.py
index dd4bf3e..0246976 100644
--- a/examples/gl_interop_demo.py
+++ b/examples/gl_interop_demo.py
@@ -1,75 +1,80 @@
-from OpenGL.GL import *
-from OpenGL.GLUT import *
-from OpenGL.raw.GL.VERSION.GL_1_5 import glBufferData as rawGlBufferData
-try:
- from OpenGL.WGL import wglGetCurrentDisplay as GetCurrentDisplay, wglGetCurrentContext as GetCurrentContext
-except:
- pass
-try:
- from OpenGL.GLX import glXGetCurrentDisplay as GetCurrentDisplay, glXGetCurrentContext as GetCurrentContext
-except:
- pass
-import pyopencl as cl
-
-
-n_vertices = 10000
-
-src = """
-
-__kernel void generate_sin(__global float2* a)
-{
- int id = get_global_id(0);
- int n = get_global_size(0);
- float r = (float)id / (float)n;
- float x = r * 16.0f * 3.1415f;
- a[id].x = r * 2.0f - 1.0f;
- a[id].y = native_sin(x);
-}
-
-"""
-
-def initialize():
- plats = cl.get_platforms()
- ctx_props = cl.context_properties
- props = [(ctx_props.PLATFORM, plats[0]), (ctx_props.GL_CONTEXT_KHR,
- GetCurrentContext()), (ctx_props.GLX_DISPLAY_KHR, GetCurrentDisplay())]
- ctx = cl.Context(properties=props)
- glClearColor(1, 1, 1, 1)
- glColor(0, 0, 1)
- vbo = glGenBuffers(1)
- glBindBuffer(GL_ARRAY_BUFFER, vbo)
- rawGlBufferData(GL_ARRAY_BUFFER, n_vertices * 2 * 4, None, GL_STATIC_DRAW)
- glEnableClientState(GL_VERTEX_ARRAY)
- glVertexPointer(2, GL_FLOAT, 0, None)
- coords_dev = cl.GLBuffer(ctx, cl.mem_flags.READ_WRITE, int(vbo))
- prog = cl.Program(ctx, src).build()
- queue = cl.CommandQueue(ctx)
- cl.enqueue_acquire_gl_objects(queue, [coords_dev])
- prog.generate_sin(queue, (n_vertices,), None, coords_dev)
- cl.enqueue_release_gl_objects(queue, [coords_dev])
- queue.finish()
- glFlush()
-
-def display():
- glClear(GL_COLOR_BUFFER_BIT)
- glDrawArrays(GL_LINE_STRIP, 0, n_vertices)
- glFlush()
-
-def reshape(w, h):
- glViewport(0, 0, w, h)
- glMatrixMode(GL_PROJECTION)
- glLoadIdentity()
- glMatrixMode(GL_MODELVIEW)
-
-if __name__ == '__main__':
- import sys
- glutInit(sys.argv)
- if len(sys.argv) > 1:
- n_vertices = int(sys.argv[1])
- glutInitWindowSize(800, 160)
- glutInitWindowPosition(0, 0)
- glutCreateWindow('OpenCL/OpenGL Interop Tutorial: Sin Generator')
- glutDisplayFunc(display)
- glutReshapeFunc(reshape)
- initialize()
- glutMainLoop()
+from OpenGL.GL import *
+from OpenGL.GLUT import *
+from OpenGL.raw.GL.VERSION.GL_1_5 import glBufferData as rawGlBufferData
+from OpenGL import platform, GLX, WGL
+import pyopencl as cl
+
+
+n_vertices = 10000
+
+src = """
+
+__kernel void generate_sin(__global float2* a)
+{
+ int id = get_global_id(0);
+ int n = get_global_size(0);
+ float r = (float)id / (float)n;
+ float x = r * 16.0f * 3.1415f;
+ a[id].x = r * 2.0f - 1.0f;
+ a[id].y = native_sin(x);
+}
+
+"""
+
+def initialize():
+ plats = cl.get_platforms()
+ ctx_props = cl.context_properties
+
+ props = [(ctx_props.PLATFORM, plats[0]),
+ (ctx_props.GL_CONTEXT_KHR, platform.GetCurrentContext())]
+
+ import sys
+ if sys.platform == "linux2":
+ props.append(
+ (ctx_props.GLX_DISPLAY_KHR,
+ GLX.glXGetCurrentDisplay()))
+ elif sys.platform == "win32":
+ props.append(
+ (ctx_props.WGL_HDC_KHR,
+ WGL.wglGetCurrentDC()))
+ ctx = cl.Context(properties=props)
+
+ glClearColor(1, 1, 1, 1)
+ glColor(0, 0, 1)
+ vbo = glGenBuffers(1)
+ glBindBuffer(GL_ARRAY_BUFFER, vbo)
+ rawGlBufferData(GL_ARRAY_BUFFER, n_vertices * 2 * 4, None, GL_STATIC_DRAW)
+ glEnableClientState(GL_VERTEX_ARRAY)
+ glVertexPointer(2, GL_FLOAT, 0, None)
+ coords_dev = cl.GLBuffer(ctx, cl.mem_flags.READ_WRITE, int(vbo))
+ prog = cl.Program(ctx, src).build()
+ queue = cl.CommandQueue(ctx)
+ cl.enqueue_acquire_gl_objects(queue, [coords_dev])
+ prog.generate_sin(queue, (n_vertices,), None, coords_dev)
+ cl.enqueue_release_gl_objects(queue, [coords_dev])
+ queue.finish()
+ glFlush()
+
+def display():
+ glClear(GL_COLOR_BUFFER_BIT)
+ glDrawArrays(GL_LINE_STRIP, 0, n_vertices)
+ glFlush()
+
+def reshape(w, h):
+ glViewport(0, 0, w, h)
+ glMatrixMode(GL_PROJECTION)
+ glLoadIdentity()
+ glMatrixMode(GL_MODELVIEW)
+
+if __name__ == '__main__':
+ import sys
+ glutInit(sys.argv)
+ if len(sys.argv) > 1:
+ n_vertices = int(sys.argv[1])
+ glutInitWindowSize(800, 160)
+ glutInitWindowPosition(0, 0)
+ glutCreateWindow('OpenCL/OpenGL Interop Tutorial: Sin Generator')
+ glutDisplayFunc(display)
+ glutReshapeFunc(reshape)
+ initialize()
+ glutMainLoop()
diff --git a/pyopencl/__init__.py b/pyopencl/__init__.py
index e9c4474..0108257 100644
--- a/pyopencl/__init__.py
+++ b/pyopencl/__init__.py
@@ -224,6 +224,10 @@ def _add_functionality():
self.set_arg(i, arg)
else:
from struct import pack
+
+ if len(args) != len(arg_type_chars):
+ raise ValueError("length of argument type array and "
+ "length of argument list do not agree")
for i, (arg, arg_type_char) in enumerate(
zip(args, arg_type_chars)):
if arg_type_char:
diff --git a/pyopencl/array.py b/pyopencl/array.py
index a84a8eb..a754305 100644
--- a/pyopencl/array.py
+++ b/pyopencl/array.py
@@ -126,7 +126,7 @@ class Array(object):
work on an element-by-element basis, just like :class:`numpy.ndarray`.
"""
- def __init__(self, context, shape, dtype, allocator=None,
+ def __init__(self, context, shape, dtype, order="C", allocator=None,
base=None, data=None, queue=None):
if allocator is None:
allocator = DefaultAllocator(context)
@@ -147,6 +147,9 @@ class Array(object):
self.shape = shape
self.dtype = numpy.dtype(dtype)
+ if order not in ["C", "F"]:
+ raise ValueError("order must be either 'C' or 'F'")
+ self.order = order
self.mem_size = self.size = s
self.nbytes = self.dtype.itemsize * self.size
@@ -180,7 +183,7 @@ class Array(object):
def get(self, queue=None, ary=None, async=False):
if ary is None:
- ary = numpy.empty(self.shape, self.dtype)
+ ary = numpy.empty(self.shape, self.dtype, order=self.order)
else:
if ary.size != self.size:
raise TypeError("'ary' has non-matching type")
@@ -344,12 +347,20 @@ class Array(object):
return result
def __iadd__(self, other):
- self._axpbyz(self, 1, self, 1, other)
- return self
+ if isinstance(other, Array):
+ self._axpbyz(self, 1, self, 1, other)
+ return self
+ else:
+ self._axpbz(self, 1, self, other)
+ return self
def __isub__(self, other):
- self._axpbyz(self, 1, self, -1, other)
- return self
+ if isinstance(other, Array):
+ self._axpbyz(self, 1, self, -1, other)
+ return self
+ else:
+ self._axpbz(self, 1, self, -other)
+ return self
def __neg__(self):
result = self._new_like_me()
@@ -470,30 +481,6 @@ class Array(object):
self._copy(result, self, queue=queue)
return result
- # slicing -----------------------------------------------------------------
- def __getitem__(self, idx):
- if idx == ():
- return self
-
- if len(self.shape) > 1:
- raise NotImplementedError("multi-d slicing is not yet implemented")
-
- if not isinstance(idx, slice):
- raise ValueError("non-slice indexing not supported: %s" % (idx,))
-
- l, = self.shape
- start, stop, stride = idx.indices(l)
-
- if stride != 1:
- raise NotImplementedError("strided slicing is not yet implemented")
-
- return Array(
- shape=((stop-start)//stride,),
- dtype=self.dtype,
- allocator=self.allocator,
- base=self,
- data=int(self.data) + start*self.dtype.itemsize)
-
# rich comparisons (or rather, lack thereof) ------------------------------
def __eq__(self, other):
raise NotImplementedError
@@ -517,7 +504,15 @@ class Array(object):
def to_device(context, queue, ary, allocator=None, async=False):
"""Converts a numpy array to a :class:`Array`."""
- result = Array(context, ary.shape, ary.dtype, allocator,
+ if ary.flags.f_contiguous:
+ order = "F"
+ elif ary.flags.c_contiguous:
+ order = "C"
+ else:
+ raise ValueError("to_device only works on C- or Fortran-"
+ "contiguous arrays")
+
+ result = Array(context, ary.shape, ary.dtype, order, allocator,
queue=queue)
result.set(ary, async=async)
return result
@@ -525,21 +520,22 @@ def to_device(context, queue, ary, allocator=None, async=False):
empty = Array
-def zeros(context, queue, shape, dtype, allocator=None):
+def zeros(context, queue, shape, dtype, order="C", allocator=None):
"""Returns an array of the given shape and dtype filled with 0's."""
- result = Array(context, shape, dtype, allocator, queue=queue)
+ result = Array(context, shape, dtype,
+ order=order, allocator=allocator, queue=queue)
result.fill(0)
return result
def empty_like(ary):
result = Array(ary.context,
- ary.shape, ary.dtype, ary.allocator, queue=ary.queue)
+ ary.shape, ary.dtype, allocator=ary.allocator, queue=ary.queue)
return result
def zeros_like(ary):
result = Array(ary.context,
- ary.shape, ary.dtype, ary.allocator, queue=ary.queue)
+ ary.shape, ary.dtype, allocator=ary.allocator, queue=ary.queue)
result.fill(0)
return result
@@ -641,7 +637,8 @@ def _take(result, ary, indices):
def take(a, indices, out=None, queue=None):
if out is None:
- out = Array(a.context, indices.shape, a.dtype, a.allocator,
+ out = Array(a.context, indices.shape, a.dtype,
+ allocator=a.allocator,
queue=queue or a.queue)
assert len(indices.shape) == 1
@@ -666,7 +663,8 @@ def multi_take(arrays, indices, out=None, queue=None):
vec_count = len(arrays)
if out is None:
- out = [Array(context, queue, indices.shape, a_dtype, a_allocator)
+ out = [Array(context, queue, indices.shape, a_dtype,
+ allocator=a_allocator)
for i in range(vec_count)]
else:
if len(out) != len(arrays):
@@ -715,7 +713,8 @@ def multi_take_put(arrays, dest_indices, src_indices, dest_shape=None,
vec_count = len(arrays)
if out is None:
- out = [Array(context, dest_shape, a_dtype, a_allocator, queue=queue)
+ out = [Array(context, dest_shape, a_dtype,
+ allocator=a_allocator, queue=queue)
for i in range(vec_count)]
else:
if a_dtype != single_valued(o.dtype for o in out):
@@ -783,7 +782,7 @@ def multi_put(arrays, dest_indices, dest_shape=None, out=None, queue=None):
vec_count = len(arrays)
if out is None:
- out = [Array(context, dest_shape, a_dtype, a_allocator, queue=queue)
+ out = [Array(context, dest_shape, a_dtype, allocator=a_allocator, queue=queue)
for i in range(vec_count)]
else:
if a_dtype != single_valued(o.dtype for o in out):
diff --git a/pyopencl/version.py b/pyopencl/version.py
index 107a527..359274f 100644
--- a/pyopencl/version.py
+++ b/pyopencl/version.py
@@ -1,5 +1,5 @@
VERSION = (0, 92)
-VERSION_STATUS = "beta"
+VERSION_STATUS = ""
VERSION_TEXT = ".".join(str(x) for x in VERSION) + VERSION_STATUS
diff --git a/src/wrapper/wrap_cl.hpp b/src/wrapper/wrap_cl.hpp
index e001d90..233ea32 100644
--- a/src/wrapper/wrap_cl.hpp
+++ b/src/wrapper/wrap_cl.hpp
@@ -20,6 +20,12 @@
#include <CL/cl.h>
// FIXME: Nvidia doesn't install cl_ext.h by default. Grr.
// #include <CL/cl_ext.h>
+
+#ifdef _WIN32
+#define NOMINMAX
+#include <windows.h>
+#endif
+
#ifdef HAVE_GL
#include <GL/gl.h>
#include <CL/cl_gl.h>
@@ -2575,7 +2581,8 @@ namespace pyopencl
std::vector<size_t> result;
PYOPENCL_GET_VEC_INFO(KernelWorkGroup,
PYOPENCL_FIRST_ARG, param_name, result);
- return py::list(result);
+
+ PYOPENCL_RETURN_VECTOR(size_t, result);
}
case CL_KERNEL_LOCAL_MEM_SIZE:
#ifdef CL_VERSION_1_1
@@ -2875,8 +2882,8 @@ namespace pyopencl
std::vector<cl_context_properties> props
= parse_context_properties(py_properties);
- typedef CL_API_ENTRY cl_int CL_API_CALL
- (*func_ptr_type)(const cl_context_properties * /* properties */,
+ typedef CL_API_ENTRY cl_int (CL_API_CALL
+ *func_ptr_type)(const cl_context_properties * /* properties */,
cl_gl_context_info /* param_name */,
size_t /* param_value_size */,
void * /* param_value */,
diff --git a/src/wrapper/wrap_constants.cpp b/src/wrapper/wrap_constants.cpp
index 4f2548b..a81adc9 100644
--- a/src/wrapper/wrap_constants.cpp
+++ b/src/wrapper/wrap_constants.cpp
@@ -167,6 +167,7 @@ void pyopencl_expose_constants()
ADD_ATTR(DEVICE_, QUEUE_PROPERTIES);
ADD_ATTR(DEVICE_, NAME);
ADD_ATTR(DEVICE_, VENDOR);
+ ADD_ATTR(, DRIVER_VERSION);
ADD_ATTR(DEVICE_, VERSION);
ADD_ATTR(DEVICE_, PROFILE);
ADD_ATTR(DEVICE_, VERSION);
diff --git a/test/test_clmath.py b/test/test_clmath.py
new file mode 100644
index 0000000..58b6a09
--- /dev/null
+++ b/test/test_clmath.py
@@ -0,0 +1,182 @@
+from __future__ import division
+import math
+import numpy
+import pytools.test
+
+def have_cl():
+ try:
+ import pyopencl
+ return True
+ except:
+ return False
+
+if have_cl():
+ import pyopencl.array as cl_array
+ import pyopencl as cl
+ import pyopencl.clmath as clmath
+ from pyopencl.tools import pytest_generate_tests_for_pyopencl \
+ as pytest_generate_tests
+
+
+
+
+
+sizes = [10, 128, 1024, 1<<10, 1<<13]
+
+
+
+
+def has_double_support(dev):
+ for ext in dev.extensions.split(" "):
+ if ext == "cl_khr_fp64":
+ return True
+ return False
+
+
+
+
+numpy_func_names = {
+ "asin": "arcsin",
+ "acos": "arccos",
+ "atan": "arctan",
+ }
+
+
+
+
+def make_unary_function_test(name, (a, b)=(0, 1), threshold=0):
+ def test(ctx_getter):
+ context = ctx_getter()
+ queue = cl.CommandQueue(context)
+
+ gpu_func = getattr(clmath, name)
+ cpu_func = getattr(numpy, numpy_func_names.get(name, name))
+
+ if has_double_support(context.devices[0]):
+ dtypes = [numpy.float32, numpy.float64]
+ else:
+ dtypes = [numpy.float32]
+
+ for s in sizes:
+ for dtype in dtypes:
+ args = cl_array.arange(context, queue, a, b, (b-a)/s,
+ dtype=numpy.float32)
+ gpu_results = gpu_func(args).get()
+ cpu_results = cpu_func(args.get())
+
+ max_err = numpy.max(numpy.abs(cpu_results - gpu_results))
+ assert (max_err <= threshold).all(), \
+ (max_err, name, dtype)
+
+ return pytools.test.mark_test.opencl(test)
+
+
+
+
+if have_cl():
+ test_ceil = make_unary_function_test("ceil", (-10, 10))
+ test_floor = make_unary_function_test("ceil", (-10, 10))
+ test_fabs = make_unary_function_test("fabs", (-10, 10))
+ test_exp = make_unary_function_test("exp", (-3, 3), 1e-5)
+ test_log = make_unary_function_test("log", (1e-5, 1), 1e-6)
+ test_log10 = make_unary_function_test("log10", (1e-5, 1), 5e-7)
+ test_sqrt = make_unary_function_test("sqrt", (1e-5, 1), 2e-7)
+
+ test_sin = make_unary_function_test("sin", (-10, 10), 1e-7)
+ test_cos = make_unary_function_test("cos", (-10, 10), 1e-7)
+ test_asin = make_unary_function_test("asin", (-0.9, 0.9), 5e-7)
+ test_acos = make_unary_function_test("acos", (-0.9, 0.9), 5e-7)
+ test_tan = make_unary_function_test("tan",
+ (-math.pi/2 + 0.1, math.pi/2 - 0.1), 1e-5)
+ test_atan = make_unary_function_test("atan", (-10, 10), 2e-7)
+
+ test_sinh = make_unary_function_test("sinh", (-3, 3), 1e-6)
+ test_cosh = make_unary_function_test("cosh", (-3, 3), 1e-6)
+ test_tanh = make_unary_function_test("tanh", (-3, 3), 2e-6)
+
+
+
+
+@pytools.test.mark_test.opencl
+def test_fmod(ctx_getter):
+ context = ctx_getter()
+ queue = cl.CommandQueue(context)
+
+ for s in sizes:
+ a = cl_array.arange(context, queue, s, dtype=numpy.float32)/10
+ a2 = cl_array.arange(context, queue, s, dtype=numpy.float32)/45.2 + 0.1
+ b = clmath.fmod(a, a2)
+
+ a = a.get()
+ a2 = a2.get()
+ b = b.get()
+
+ for i in range(s):
+ assert math.fmod(a[i], a2[i]) == b[i]
+
+@pytools.test.mark_test.opencl
+def test_ldexp(ctx_getter):
+ context = ctx_getter()
+ queue = cl.CommandQueue(context)
+
+ for s in sizes:
+ a = cl_array.arange(context, queue, s, dtype=numpy.float32)
+ a2 = cl_array.arange(context, queue, s, dtype=numpy.float32)*1e-3
+ b = clmath.ldexp(a,a2)
+
+ a = a.get()
+ a2 = a2.get()
+ b = b.get()
+
+ for i in range(s):
+ assert math.ldexp(a[i], int(a2[i])) == b[i]
+
+@pytools.test.mark_test.opencl
+def test_modf(ctx_getter):
+ context = ctx_getter()
+ queue = cl.CommandQueue(context)
+
+ for s in sizes:
+ a = cl_array.arange(context, queue, s, dtype=numpy.float32)/10
+ fracpart, intpart = clmath.modf(a)
+
+ a = a.get()
+ intpart = intpart.get()
+ fracpart = fracpart.get()
+
+ for i in range(s):
+ fracpart_true, intpart_true = math.modf(a[i])
+
+ assert intpart_true == intpart[i]
+ assert abs(fracpart_true - fracpart[i]) < 1e-4
+
+@pytools.test.mark_test.opencl
+def test_frexp(ctx_getter):
+ context = ctx_getter()
+ queue = cl.CommandQueue(context)
+
+ for s in sizes:
+ a = cl_array.arange(context, queue, s, dtype=numpy.float32)/10
+ significands, exponents = clmath.frexp(a)
+
+ a = a.get()
+ significands = significands.get()
+ exponents = exponents.get()
+
+ for i in range(s):
+ sig_true, ex_true = math.frexp(a[i])
+
+ assert sig_true == significands[i]
+ assert ex_true == exponents[i]
+
+
+
+
+if __name__ == "__main__":
+ # make sure that import failures get reported, instead of skipping the tests.
+ import sys
+ if len(sys.argv) > 1:
+ exec sys.argv[1]
+ else:
+ from py.test.cmdline import main
+ main([__file__])
diff --git a/test/test_math.py b/test/test_math.py
deleted file mode 100644
index c7aabf4..0000000
--- a/test/test_math.py
+++ /dev/null
@@ -1,182 +0,0 @@
-from __future__ import division
-import math
-import numpy
-import pytools.test
-
-def have_cl():
- try:
- import pyopencl
- return True
- except:
- return False
-
-if have_cl():
- import pyopencl.array as cl_array
- import pyopencl as cl
- import pyopencl.clmath as clmath
- from pyopencl.tools import pytest_generate_tests_for_pyopencl \
- as pytest_generate_tests
-
-
-
-
-
-sizes = [10, 128, 1024, 1<<10, 1<<13]
-
-
-
-
-def has_double_support(dev):
- for ext in dev.extensions.split(" "):
- if ext == "cl_khr_fp64":
- return True
- return False
-
-
-
-
-numpy_func_names = {
- "asin": "arcsin",
- "acos": "arccos",
- "atan": "arctan",
- }
-
-
-
-
-def make_unary_function_test(name, (a, b)=(0, 1), threshold=0):
- def test(ctx_getter):
- context = ctx_getter()
- queue = cl.CommandQueue(context)
-
- gpu_func = getattr(clmath, name)
- cpu_func = getattr(numpy, numpy_func_names.get(name, name))
-
- if has_double_support(context.devices[0]):
- dtypes = [numpy.float32, numpy.float64]
- else:
- dtypes = [numpy.float32]
-
- for s in sizes:
- for dtype in dtypes:
- args = cl_array.arange(context, queue, a, b, (b-a)/s,
- dtype=numpy.float32)
- gpu_results = gpu_func(args).get()
- cpu_results = cpu_func(args.get())
-
- max_err = numpy.max(numpy.abs(cpu_results - gpu_results))
- assert (max_err <= threshold).all(), \
- (max_err, name, dtype)
-
- return pytools.test.mark_test.opencl(test)
-
-
-
-
-if have_cl():
- test_ceil = make_unary_function_test("ceil", (-10, 10))
- test_floor = make_unary_function_test("ceil", (-10, 10))
- test_fabs = make_unary_function_test("fabs", (-10, 10))
- test_exp = make_unary_function_test("exp", (-3, 3), 1e-5)
- test_log = make_unary_function_test("log", (1e-5, 1), 5e-7)
- test_log10 = make_unary_function_test("log10", (1e-5, 1), 3e-7)
- test_sqrt = make_unary_function_test("sqrt", (1e-5, 1), 2e-7)
-
- test_sin = make_unary_function_test("sin", (-10, 10), 1e-7)
- test_cos = make_unary_function_test("cos", (-10, 10), 1e-7)
- test_asin = make_unary_function_test("asin", (-0.9, 0.9), 5e-7)
- test_acos = make_unary_function_test("acos", (-0.9, 0.9), 5e-7)
- test_tan = make_unary_function_test("tan",
- (-math.pi/2 + 0.1, math.pi/2 - 0.1), 1e-5)
- test_atan = make_unary_function_test("atan", (-10, 10), 2e-7)
-
- test_sinh = make_unary_function_test("sinh", (-3, 3), 1e-6)
- test_cosh = make_unary_function_test("cosh", (-3, 3), 1e-6)
- test_tanh = make_unary_function_test("tanh", (-3, 3), 2e-6)
-
-
-
-
-@pytools.test.mark_test.opencl
-def test_fmod(ctx_getter):
- context = ctx_getter()
- queue = cl.CommandQueue(context)
-
- for s in sizes:
- a = cl_array.arange(context, queue, s, dtype=numpy.float32)/10
- a2 = cl_array.arange(context, queue, s, dtype=numpy.float32)/45.2 + 0.1
- b = clmath.fmod(a, a2)
-
- a = a.get()
- a2 = a2.get()
- b = b.get()
-
- for i in range(s):
- assert math.fmod(a[i], a2[i]) == b[i]
-
-@pytools.test.mark_test.opencl
-def test_ldexp(ctx_getter):
- context = ctx_getter()
- queue = cl.CommandQueue(context)
-
- for s in sizes:
- a = cl_array.arange(context, queue, s, dtype=numpy.float32)
- a2 = cl_array.arange(context, queue, s, dtype=numpy.float32)*1e-3
- b = clmath.ldexp(a,a2)
-
- a = a.get()
- a2 = a2.get()
- b = b.get()
-
- for i in range(s):
- assert math.ldexp(a[i], int(a2[i])) == b[i]
-
-@pytools.test.mark_test.opencl
-def test_modf(ctx_getter):
- context = ctx_getter()
- queue = cl.CommandQueue(context)
-
- for s in sizes:
- a = cl_array.arange(context, queue, s, dtype=numpy.float32)/10
- fracpart, intpart = clmath.modf(a)
-
- a = a.get()
- intpart = intpart.get()
- fracpart = fracpart.get()
-
- for i in range(s):
- fracpart_true, intpart_true = math.modf(a[i])
-
- assert intpart_true == intpart[i]
- assert abs(fracpart_true - fracpart[i]) < 1e-4
-
-@pytools.test.mark_test.opencl
-def test_frexp(ctx_getter):
- context = ctx_getter()
- queue = cl.CommandQueue(context)
-
- for s in sizes:
- a = cl_array.arange(context, queue, s, dtype=numpy.float32)/10
- significands, exponents = clmath.frexp(a)
-
- a = a.get()
- significands = significands.get()
- exponents = exponents.get()
-
- for i in range(s):
- sig_true, ex_true = math.frexp(a[i])
-
- assert sig_true == significands[i]
- assert ex_true == exponents[i]
-
-
-
-
-if __name__ == "__main__":
- # make sure that import failures get reported, instead of skipping the tests.
- import sys
- if len(sys.argv) > 1:
- exec sys.argv[1]
- else:
- from py.test.cmdline import main
- main([__file__])
Attachment:
signature.asc
Description: This is a digitally signed message part