Skip to content

Commit

Permalink
Merge pull request #177 from clEsperanto/release-0.10.0
Browse files Browse the repository at this point in the history
Release 0.10.0
  • Loading branch information
StRigaud authored Apr 17, 2024
2 parents cbd08a1 + 7e2e493 commit 5353db1
Show file tree
Hide file tree
Showing 64 changed files with 2,229 additions and 229 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ option(BUILD_SHARED_LIBS OFF)


## CLIc dependency
set(CLIC_REPO_TAG 0.9.1) # branch name for dev
set(CLIC_REPO_TAG 0.10.0) # branch name for dev
set(CLIC_REPO_URL https://github.com/clEsperanto/CLIc.git)
set(BUILD_OPENCL_BACKEND ON CACHE BOOL "Build with OCL if FOUND" FORCE)
set(BUILD_CUDA_BACKEND ON CACHE BOOL "Build with CUDA if FOUND" FORCE)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/clic EXCLUDE_FROM_ALL)


Expand Down
59 changes: 56 additions & 3 deletions docs/source/contribute.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,63 @@ Contributing
This section of the documentation in under construction.


py-clesperanto is a Python API layer for the `CLIc library <https://github.com/clEsperanto/CLIc>`__.
Several operation and functionality are directly inherited from the CLIc library, compiled and imported in the package as ``_clesperanto``.
Arround this C++ core, the package as several Python code to ensure proper integration with the Python ecosystem (numpy, etc.).

Therefore, it is possible to contribute to the development of py-clesperanto either on the C++ side or on the Python side depending on what you are trying to achieve.

Environment setup
------------------

Like for any other python development we encourage you to use a virtual environment to develop py-clesperanto.
Here we will describe how to setup a development environment for py-clesperanto with `conda/mamba`.

1. Create a new environment with `conda/mamba`:

.. code-block:: bash
mamba create -n pycle-dev python=3.9 -c conda-forge
conda activate pycle-dev
2. Install the dependencies:

.. code-block:: bash
mamba install -c conda-forge numpy pytest jupyter scikit-image black flake8 pre-commit
3. Setup pre-commit:

.. code-block:: bash
pre-commit install
4. Install py-clesperanto in development mode:

.. code-block:: bash
pip install . -v
5. Run the tests:

.. code-block:: bash
pytest
All tests should pass.
The ``pip install`` command will compile and install the package in the environment.
You will now be able to modify the ``pyclesperanto`` package and see the changes directly in the environment.
The ``pre-commit`` tool will ensure that the code is properly formatted and linted before any commit.

.. warning::

``-e`` flag of the ``pip install`` command is not available for the moment.


Versioning
----------

pyClesperanto version folows the `CLIc <https://github.com/clEsperanto/CLIc>`__ versioning.
pyClesperanto version folows the `CLIc <https://github.com/clEsperanto/CLIc>`__ versioning.
Although they are not necessarily made to be identically, the versioning is kept in sync as much as possible.

In order to update the version of pyClesperanto, you will need to follow the following steps:
Expand All @@ -19,6 +72,6 @@ In order to update the version of pyClesperanto, you will need to follow the fol
3. Update the version in the `pyclesperanto/_version.py <https://github.com/clEsperanto/pyclesperanto/blob/main/pyclesperanto/_version.py>`__ file.
Both ``VERSION`` and ``CLIC_VERSION`` should be updated accordingly.

.. note::
.. note::

The version tag in the ``pyproject.toml`` file should be made automatic in the near future.
The version tag in the ``pyproject.toml`` file should be made automatic in the near future.
3 changes: 1 addition & 2 deletions pyclesperanto/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from ._core import (
gpu_info,
execute,
select_backend,
select_device,
get_device,
Expand All @@ -12,7 +11,7 @@
)
from ._array import Array, Image, is_image
from ._memory import create, create_like, push, pull
from ._functionalities import imshow, list_operations
from ._functionalities import imshow, list_operations, execute, native_execute

from ._tier1 import *
from ._tier2 import *
Expand Down
65 changes: 3 additions & 62 deletions pyclesperanto/_core.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from typing import Optional, Union
from pathlib import Path
import numpy as np
import warnings

from ._pyclesperanto import _Device as Device
from ._pyclesperanto import _BackendManager as BackendManager
from ._pyclesperanto import _execute


class _current_device:
Expand All @@ -27,7 +25,7 @@ def select_device(device_id: Union[str, int] = "", device_type: str = "all") ->
If selecting the device by string, the function compares the device name and substring.
(e.g. "NVIDIA", "RTX", "Iris", etc. will match the device name "NVIDIA RTX 2080" or "Intel Iris Pro")
If selecting the device by index, the function will select the device at the given index in the list
If selecting the device by index, the function will select the device at the given index in the list
of available devices. (e.g. 0, 1, 2, etc. will select the first, second, third, etc. device in the list)
If device_id is an empty string, the function will select the first available device.
The device_type enables selecting the type of device to be selected (e.g. "all", "cpu", "gpu")
Expand Down Expand Up @@ -62,7 +60,7 @@ def list_available_devices(device_type: str = "all") -> list:
"""Retrieve a list of names of available devices
Will search the system for backend compatible device available and return a list of their names.
This will NOT set the device!
This will NOT set the device!
Use 'select_device' to select devices.
Use 'get_device' to retrieve the current device.
Expand Down Expand Up @@ -130,7 +128,7 @@ def select_backend(backend: str = "opencl") -> str:
def wait_for_kernel_to_finish(flag: bool = True, device: Device = None):
"""Wait for kernel to finish
Enforce the system to wait for the kernel to finish before continuing. Introducing a
Enforce the system to wait for the kernel to finish before continuing. Introducing a
slowdown in the workflow. This is useful for debugging purposes, benchmarking and
profiling, as well as for complex workflows where the order of operations is important.
Expand Down Expand Up @@ -159,63 +157,6 @@ def default_initialisation():
)


def execute(anchor = '__file__', kernel_source: str = '', kernel_name: str = '', global_size: tuple = (1, 1, 1), parameters: dict = {}, constants: dict = {}, device: Device = None):
"""Execute a kernel from a file or a string
Call, build, and execute a kernel compatible with CLIj framework.
The kernel can be called from a file or a string.
Parameters
----------
anchor : str, default = '__file__'
Enter __file__ when calling this method and the corresponding open.cl
file lies in the same folder as the python file calling it.
Ignored if kernel_source is a string.
kernel_source : str
Filename of the open.cl file to be called or string containing the open.cl source code
kernel_name : str
Kernel method inside the open.cl file to be called
most clij/clesperanto kernel functions have the same name as the file they are in
global_size : tuple (z,y,x), default = (1, 1, 1)
Global_size according to OpenCL definition (usually shape of the destination image).
parameters : dict(str, [Array, float, int])
Dictionary containing parameters. Take care: They must be of the
right type and in the right order as specified in the open.cl file.
constants: dict(str, int), optional
Dictionary with names/values which will be added to the define
statements. They are necessary, e.g. to create arrays of a given
maximum size in OpenCL as variable array lengths are not supported.
device : Device, default = None
The device to execute the kernel on. If None, use the current device
"""

# load the kernel file
def load_file(anchor, filename):
"""Load the opencl kernel file as a string"""
if anchor is None:
kernel = Path(filename).read_text()
else:
kernel = (Path(anchor).parent / filename).read_text()
return kernel

# test if kernel_source ends with .cl or .cu
if kernel_source.endswith('.cl') or kernel_source.endswith('.cu'):
kernel_source = load_file(anchor, kernel_source)

# manage the device if not given
if not device:
device = get_device()

# manage global range
if not isinstance(global_size, tuple):
if isinstance(global_size, list) or isinstance(global_size, np.ndarray):
global_size = tuple(global_size)
else:
global_size = (global_size,)

_execute(device, kernel_name, kernel_source, parameters, global_size, constants)


def gpu_info():
device_list = list_available_devices()
info = []
Expand Down
Loading

0 comments on commit 5353db1

Please sign in to comment.