Skip to content
Snippets Groups Projects
Commit 221d211f authored by Andreas Klöckner's avatar Andreas Klöckner
Browse files

Merge branch 'master' into cffi

Conflicts:
	pyopencl/__init__.py
parents b0139dff 9b407a5b
No related branches found
No related tags found
No related merge requests found
...@@ -285,17 +285,17 @@ def link_program(context, programs, options=[], devices=None): ...@@ -285,17 +285,17 @@ def link_program(context, programs, options=[], devices=None):
def _add_functionality(): def _add_functionality():
cls_to_info_cls = { cls_to_info_cls = {
_cl.Platform: (_cl.Platform.get_info, _cl.platform_info), _cl.Platform: (_cl.Platform.get_info, _cl.platform_info),
_cl.Device: (_cl.Device.get_info, _cl.device_info), _cl.Device: (_cl.Device.get_info, _cl.device_info),
_cl.Context: (_cl.Context.get_info, _cl.context_info), _cl.Context: (_cl.Context.get_info, _cl.context_info),
_cl.CommandQueue: (_cl.CommandQueue.get_info, _cl.command_queue_info), _cl.CommandQueue: (_cl.CommandQueue.get_info, _cl.command_queue_info),
_cl.Event: (_cl.Event.get_info, _cl.event_info), _cl.Event: (_cl.Event.get_info, _cl.event_info),
_cl.MemoryObjectHolder: (MemoryObjectHolder.get_info, _cl.mem_info), _cl.MemoryObjectHolder: (MemoryObjectHolder.get_info, _cl.mem_info),
Image: (_cl.Image.get_image_info, _cl.image_info), Image: (_cl.Image.get_image_info, _cl.image_info),
Program: (Program.get_info, _cl.program_info), Program: (Program.get_info, _cl.program_info),
Kernel: (Kernel.get_info, _cl.kernel_info), Kernel: (Kernel.get_info, _cl.kernel_info),
_cl.Sampler: (Sampler.get_info, _cl.sampler_info), _cl.Sampler: (Sampler.get_info, _cl.sampler_info),
} }
def to_string(cls, value, default_format=None): def to_string(cls, value, default_format=None):
for name in dir(cls): for name in dir(cls):
...@@ -802,8 +802,6 @@ def create_some_context(interactive=None, answers=None): ...@@ -802,8 +802,6 @@ def create_some_context(interactive=None, answers=None):
if not platforms: if not platforms:
raise Error("no platforms found") raise Error("no platforms found")
elif len(platforms) == 1:
platform, = platforms
else: else:
if not answers: if not answers:
cc_print("Choose platform:") cc_print("Choose platform:")
......
...@@ -1288,20 +1288,118 @@ class Array(object): ...@@ -1288,20 +1288,118 @@ class Array(object):
raise TypeError("unexpected keyword arguments: %s" raise TypeError("unexpected keyword arguments: %s"
% kwargs.keys()) % kwargs.keys())
if order not in "CF":
raise ValueError("order must be either 'C' or 'F'")
# TODO: add more error-checking, perhaps # TODO: add more error-checking, perhaps
if isinstance(shape[0], tuple) or isinstance(shape[0], list): if isinstance(shape[0], tuple) or isinstance(shape[0], list):
shape = tuple(shape[0]) shape = tuple(shape[0])
if -1 in shape:
shape = list(shape)
idx = shape.index(-1)
size = -reduce(lambda x, y: x * y, shape, 1)
shape[idx] = self.size // size
if any(s < 0 for s in shape):
raise ValueError("can only specify one unknown dimension")
shape = tuple(shape)
if shape == self.shape: if shape == self.shape:
return self return self._new_with_changes(
data=self.base_data, offset=self.offset, shape=shape,
strides=self.strides)
size = reduce(lambda x, y: x * y, shape, 1) import operator
size = reduce(operator.mul, shape, 1)
if size != self.size: if size != self.size:
raise ValueError("total size of new array must be unchanged") raise ValueError("total size of new array must be unchanged")
# {{{ determine reshaped strides
# copied and translated from
# https://github.com/numpy/numpy/blob/4083883228d61a3b571dec640185b5a5d983bf59/numpy/core/src/multiarray/shape.c # noqa
newdims = shape
newnd = len(newdims)
# Remove axes with dimension 1 from the old array. They have no effect
# but would need special cases since their strides do not matter.
olddims = []
oldstrides = []
for oi in range(len(self.shape)):
s = self.shape[oi]
if s != 1:
olddims.append(s)
oldstrides.append(self.strides[oi])
oldnd = len(olddims)
newstrides = [-1]*len(newdims)
# oi to oj and ni to nj give the axis ranges currently worked with
oi = 0
oj = 1
ni = 0
nj = 1
while ni < newnd and oi < oldnd:
np = newdims[ni]
op = olddims[oi]
while np != op:
if np < op:
# Misses trailing 1s, these are handled later
np *= newdims[nj]
nj += 1
else:
op *= olddims[oj]
oj += 1
# Check whether the original axes can be combined
for ok in range(oi, oj-1):
if order == "F":
if oldstrides[ok+1] != olddims[ok]*oldstrides[ok]:
raise ValueError("cannot reshape without copy")
else:
# C order
if (oldstrides[ok] != olddims[ok+1]*oldstrides[ok+1]):
raise ValueError("cannot reshape without copy")
# Calculate new strides for all axes currently worked with
if order == "F":
newstrides[ni] = oldstrides[oi]
for nk in xrange(ni+1, nj):
newstrides[nk] = newstrides[nk - 1]*newdims[nk - 1]
else:
# C order
newstrides[nj - 1] = oldstrides[oj - 1]
for nk in range(nj-1, ni, -1):
newstrides[nk - 1] = newstrides[nk]*newdims[nk]
ni = nj
nj += 1
oi = oj
oj += 1
# Set strides corresponding to trailing 1s of the new shape.
if ni >= 1:
last_stride = newstrides[ni - 1]
else:
last_stride = self.dtype.itemsize
if order == "F":
last_stride *= newdims[ni - 1]
for nk in range(ni, len(shape)):
newstrides[nk] = last_stride
# }}}
return self._new_with_changes( return self._new_with_changes(
data=self.base_data, offset=self.offset, shape=shape, data=self.base_data, offset=self.offset, shape=shape,
strides=_make_strides(self.dtype.itemsize, shape, order)) strides=tuple(newstrides))
def ravel(self): def ravel(self):
"""Returns flattened array containing the same data.""" """Returns flattened array containing the same data."""
......
...@@ -3,6 +3,7 @@ from __future__ import division ...@@ -3,6 +3,7 @@ from __future__ import division
from IPython.core.magic import (magics_class, Magics, cell_magic, line_magic) from IPython.core.magic import (magics_class, Magics, cell_magic, line_magic)
import pyopencl as cl import pyopencl as cl
import sys
def _try_to_utf8(text): def _try_to_utf8(text):
...@@ -14,8 +15,10 @@ def _try_to_utf8(text): ...@@ -14,8 +15,10 @@ def _try_to_utf8(text):
@magics_class @magics_class
class PyOpenCLMagics(Magics): class PyOpenCLMagics(Magics):
def _run_kernel(self, kernel, options): def _run_kernel(self, kernel, options):
kernel = _try_to_utf8(kernel) if sys.version_info < (3,):
options = _try_to_utf8(options).strip() kernel = _try_to_utf8(kernel)
options = _try_to_utf8(options).strip()
try: try:
ctx = self.shell.user_ns["cl_ctx"] ctx = self.shell.user_ns["cl_ctx"]
except KeyError: except KeyError:
...@@ -34,37 +37,33 @@ class PyOpenCLMagics(Magics): ...@@ -34,37 +37,33 @@ class PyOpenCLMagics(Magics):
raise RuntimeError("unable to locate cl context, which must be " raise RuntimeError("unable to locate cl context, which must be "
"present in namespace as 'cl_ctx' or 'ctx'") "present in namespace as 'cl_ctx' or 'ctx'")
prg = cl.Program(ctx, kernel).build(options=options) prg = cl.Program(ctx, kernel).build(options=options.split())
for knl in prg.all_kernels(): for knl in prg.all_kernels():
self.shell.user_ns[knl.function_name] = knl self.shell.user_ns[knl.function_name] = knl
@cell_magic @cell_magic
def cl_kernel(self, line, cell): def cl_kernel(self, line, cell):
kernel = cell kernel = cell
opts, args = self.parse_options(line,'o:') opts, args = self.parse_options(line, 'o:')
build_options = opts.get('o', '') build_options = opts.get('o', '')
self._run_kernel(kernel, build_options) self._run_kernel(kernel, build_options)
def _load_kernel_and_options(self, line): def _load_kernel_and_options(self, line):
opts, args = self.parse_options(line,'o:f:') opts, args = self.parse_options(line, 'o:f:')
build_options = opts.get('o') build_options = opts.get('o')
kernel = self.shell.find_user_code(opts.get('f') or args) kernel = self.shell.find_user_code(opts.get('f') or args)
return kernel, build_options return kernel, build_options
@line_magic @line_magic
def cl_kernel_from_file(self, line): def cl_kernel_from_file(self, line):
kernel, build_options = self._load_kernel_and_options(line) kernel, build_options = self._load_kernel_and_options(line)
self._run_kernel(kernel, build_options) self._run_kernel(kernel, build_options)
@line_magic @line_magic
def cl_load_edit_kernel(self, line): def cl_load_edit_kernel(self, line):
kernel, build_options = self._load_kernel_and_options(line) kernel, build_options = self._load_kernel_and_options(line)
......
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: latin-1 -*- # -*- coding: latin-1 -*-
from setuptools.command.build_ext import build_ext as _build_ext
class build_ext(_build_ext):
def finalize_options(self):
_build_ext.finalize_options(self)
# Prevent numpy from thinking it is still in its setup process:
__builtins__.__NUMPY_SETUP__ = False
import numpy
self.include_dirs.append(numpy.get_include())
__copyright__ = """ __copyright__ = """
Copyright (C) 2009-14 Andreas Kloeckner Copyright (C) 2009-14 Andreas Kloeckner
...@@ -222,6 +231,7 @@ def main(): ...@@ -222,6 +231,7 @@ def main():
], ],
install_requires=[ install_requires=[
"numpy",
"pytools>=2014.2", "pytools>=2014.2",
"pytest>=2", "pytest>=2",
"decorator>=3.2.0", "decorator>=3.2.0",
......
...@@ -148,7 +148,7 @@ def test_mix_complex(ctx_factory): ...@@ -148,7 +148,7 @@ def test_mix_complex(ctx_factory):
err = la.norm(host_result-dev_result)/la.norm(host_result) err = la.norm(host_result-dev_result)/la.norm(host_result)
print(err) print(err)
correct = err < 1e-5 correct = err < 1e-4
if not correct: if not correct:
print(host_result) print(host_result)
print(dev_result) print(dev_result)
...@@ -719,6 +719,24 @@ def test_view_and_strides(ctx_factory): ...@@ -719,6 +719,24 @@ def test_view_and_strides(ctx_factory):
assert (y.get() == X.get()[:3, :5]).all() assert (y.get() == X.get()[:3, :5]).all()
def test_meshmode_view(ctx_factory):
context = ctx_factory()
queue = cl.CommandQueue(context)
n = 2
result = cl.array.empty(queue, (2, n*6), np.float32)
def view(z):
return z[..., n*3:n*6].reshape(z.shape[:-1] + (n, 3))
result = result.with_queue(queue)
result.fill(0)
view(result)[0].fill(1)
view(result)[1].fill(1)
x = result.get()
assert (view(x) == 1).all()
def test_event_management(ctx_factory): def test_event_management(ctx_factory):
context = ctx_factory() context = ctx_factory()
queue = cl.CommandQueue(context) queue = cl.CommandQueue(context)
...@@ -758,6 +776,28 @@ def test_event_management(ctx_factory): ...@@ -758,6 +776,28 @@ def test_event_management(ctx_factory):
assert len(x.events) < 100 assert len(x.events) < 100
def test_reshape(ctx_factory):
context = ctx_factory()
queue = cl.CommandQueue(context)
a = np.arange(128).reshape(8, 16).astype(np.float32)
a_dev = cl_array.to_device(queue, a)
# different ways to specify the shape
a_dev.reshape(4, 32)
a_dev.reshape((4, 32))
a_dev.reshape([4, 32])
# using -1 as unknown dimension
assert a_dev.reshape(-1, 32).shape == (4, 32)
assert a_dev.reshape((32, -1)).shape == (32, 4)
assert a_dev.reshape(((8, -1, 4))).shape == (8, 4, 4)
import pytest
with pytest.raises(ValueError):
a_dev.reshape(-1, -1, 4)
if __name__ == "__main__": if __name__ == "__main__":
# make sure that import failures get reported, instead of skipping the # make sure that import failures get reported, instead of skipping the
# tests. # tests.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment