diff options
Diffstat (limited to 'src/silx/opencl/utils.py')
-rw-r--r-- | src/silx/opencl/utils.py | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/src/silx/opencl/utils.py b/src/silx/opencl/utils.py new file mode 100644 index 0000000..575e018 --- /dev/null +++ b/src/silx/opencl/utils.py @@ -0,0 +1,214 @@ +# -*- coding: utf-8 -*- +# /*########################################################################## +# Copyright (C) 2017 European Synchrotron Radiation Facility +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# +# ############################################################################*/ +""" +Project: Sift implementation in Python + OpenCL + https://github.com/silx-kit/silx +""" + +from __future__ import division + +__authors__ = ["Jérôme Kieffer", "Pierre Paleo"] +__contact__ = "jerome.kieffer@esrf.eu" +__license__ = "MIT" +__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France" +__date__ = "06/09/2017" +__status__ = "Production" + +import os +import numpy +from .. import resources +from math import log, ceil + + +def calc_size(shape, blocksize): + """ + Calculate the optimal size for a kernel according to the workgroup size + """ + if "__len__" in dir(blocksize): + return tuple((int(i) + int(j) - 1) & ~(int(j) - 1) for i, j in zip(shape, blocksize)) + else: + return tuple((int(i) + int(blocksize) - 1) & ~(int(blocksize) - 1) for i in shape) + + +def nextpower(n): + """Calculate the power of two + + :param n: an integer, for example 100 + :return: another integer, 100-> 128 + """ + return 1 << int(ceil(log(n, 2))) + + +def sizeof(shape, dtype="uint8"): + """ + Calculate the number of bytes needed to allocate for a given structure + + :param shape: size or tuple of sizes + :param dtype: data type + """ + itemsize = numpy.dtype(dtype).itemsize + cnt = 1 + if "__len__" in dir(shape): + for dim in shape: + cnt *= dim + else: + cnt = int(shape) + return cnt * itemsize + + +def get_cl_file(resource): + """get the full path of a openCL resource file + + The resource name can be prefixed by the name of a resource directory. For + example "silx:foo.png" identify the resource "foo.png" from the resource + directory "silx". + See also :func:`silx.resources.register_resource_directory`. + + :param str resource: Resource name. File name contained if the `opencl` + directory of the resources. + :return: the full path of the openCL source file + """ + if not resource.endswith(".cl"): + resource += ".cl" + return resources._resource_filename(resource, + default_directory="opencl") + + +def read_cl_file(filename): + """ + :param filename: read an OpenCL file and apply a preprocessor + :return: preprocessed source code + """ + with open(get_cl_file(filename), "r") as f: + # Dummy preprocessor which removes the #include + lines = [i for i in f.readlines() if not i.startswith("#include ")] + return "".join(lines) + + +get_opencl_code = read_cl_file + + +def concatenate_cl_kernel(filenames): + """Concatenates all the kernel from the list of files + + :param filenames: filenames containing the kernels + :type filenames: list of str which can be filename of kernel as a string. + :return: a string with all kernels concatenated + + this method concatenates all the kernel from the list + """ + return os.linesep.join(read_cl_file(fn) for fn in filenames) + + + + +class ConvolutionInfos(object): + allowed_axes = { + "1D": [None], + "separable_2D_1D_2D": [None, (0, 1), (1, 0)], + "batched_1D_2D": [(0,), (1,)], + "separable_3D_1D_3D": [ + None, + (0, 1, 2), + (1, 2, 0), + (2, 0, 1), + (2, 1, 0), + (1, 0, 2), + (0, 2, 1) + ], + "batched_1D_3D": [(0,), (1,), (2,)], + "batched_separable_2D_1D_3D": [(0,), (1,), (2,)], # unsupported (?) + "2D": [None], + "batched_2D_3D": [(0,), (1,), (2,)], + "separable_3D_2D_3D": [ + (1, 0), + (0, 1), + (2, 0), + (0, 2), + (1, 2), + (2, 1), + ], + "3D": [None], + } + use_cases = { + (1, 1): { + "1D": { + "name": "1D convolution on 1D data", + "kernels": ["convol_1D_X"], + }, + }, + (2, 2): { + "2D": { + "name": "2D convolution on 2D data", + "kernels": ["convol_2D_XY"], + }, + }, + (3, 3): { + "3D": { + "name": "3D convolution on 3D data", + "kernels": ["convol_3D_XYZ"], + }, + }, + (2, 1): { + "separable_2D_1D_2D": { + "name": "Separable (2D->1D) convolution on 2D data", + "kernels": ["convol_1D_X", "convol_1D_Y"], + }, + "batched_1D_2D": { + "name": "Batched 1D convolution on 2D data", + "kernels": ["convol_1D_X", "convol_1D_Y"], + }, + }, + (3, 1): { + "separable_3D_1D_3D": { + "name": "Separable (3D->1D) convolution on 3D data", + "kernels": ["convol_1D_X", "convol_1D_Y", "convol_1D_Z"], + }, + "batched_1D_3D": { + "name": "Batched 1D convolution on 3D data", + "kernels": ["convol_1D_X", "convol_1D_Y", "convol_1D_Z"], + }, + "batched_separable_2D_1D_3D": { + "name": "Batched separable (2D->1D) convolution on 3D data", + "kernels": ["convol_1D_X", "convol_1D_Y", "convol_1D_Z"], + }, + }, + (3, 2): { + "separable_3D_2D_3D": { + "name": "Separable (3D->2D) convolution on 3D data", + "kernels": ["convol_2D_XY", "convol_2D_XZ", "convol_2D_YZ"], + }, + "batched_2D_3D": { + "name": "Batched 2D convolution on 3D data", + "kernels": ["convol_2D_XY", "convol_2D_XZ", "convol_2D_YZ"], + }, + }, + } + + + + + + + |