summaryrefslogtreecommitdiff
path: root/src/silx/opencl/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/silx/opencl/utils.py')
-rw-r--r--src/silx/opencl/utils.py214
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"],
+ },
+ },
+ }
+
+
+
+
+
+
+