Skip to content

Commit 2403627

Browse files
authored
Merge pull request #183 from vais-ral/use_ctypes
2 parents 71f8d30 + 1002eea commit 2403627

19 files changed

+2178
-1636
lines changed

.gitignore

+8-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
1-
.idea/
1+
/build_proj/
2+
/install/
3+
__pycache__/
4+
/src/Python/build/
5+
/src/Python/*.egg*/
6+
*.so
7+
*.dll
8+
*.dylib

CMakeLists.txt

+8-27
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,13 @@
1-
# Copyright 2017 Edoardo Pasca
2-
#
3-
# Licensed under the Apache License, Version 2.0 (the "License");
4-
# you may not use this file except in compliance with the License.
5-
# You may obtain a copy of the License at
6-
#
7-
# http://www.apache.org/licenses/LICENSE-2.0
8-
#
9-
# Unless required by applicable law or agreed to in writing, software
10-
# distributed under the License is distributed on an "AS IS" BASIS,
11-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12-
# See the License for the specific language governing permissions and
13-
# limitations under the License.
14-
15-
cmake_minimum_required (VERSION 3.0)
1+
cmake_minimum_required(VERSION 3.5)
162

173
project(RGL)
184
#https://stackoverflow.com/questions/13298504/using-cmake-with-setup-py
195

6+
if(NOT CMAKE_BUILD_TYPE)
7+
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Options: Debug Release RelWithDebInfo MinSizeRel" FORCE)
8+
endif()
9+
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
10+
2011
# The version number.
2112
set (RGL_VERSION_MAJOR 1)
2213
set (RGL_VERSION_MINOR 0)
@@ -28,32 +19,22 @@ set (CIL_VERSION_PATCH 2)
2819
# set (CIL_VERSION '${CIL_VERSION_MAJOR}.${CIL_VERSION_MINOR}.${CIL_VERSION_PATCH}' CACHE INTERNAL "Core Imaging Library version" FORCE)
2920
# get CIL_VERSION from environment variable and set it in cmake
3021
set (CIL_VERSION $ENV{CIL_VERSION} CACHE INTERNAL "Core Imaging Library version" FORCE)
31-
message(STATUS "CIL_VERSION set to " ${CIL_VERSION})
22+
message(STATUS "CIL_VERSION: ${CIL_VERSION}")
3223

3324
# set the Python variables for the Conda environment
3425
#include(${CMAKE_SOURCE_DIR}/CMake/FindAnacondaEnvironment.cmake)
3526

3627
option (BUILD_MATLAB_WRAPPER "Build Matlab Wrappers" OFF)
3728
option (BUILD_PYTHON_WRAPPER "Build Python Wrappers" ON)
38-
option (CONDA_BUILD "Conda Build" OFF)
3929
option (BUILD_CUDA "Build the CUDA modules" ON)
4030

4131
set(MATLAB_DEST_DIR "" CACHE PATH "Directory of the Matlab wrappers")
4232
if (MATLAB_DEST_DIR)
4333
set(MATLAB_DEST "${MATLAB_DEST_DIR}")
44-
else()
34+
else()
4535
set(MATLAB_DEST "${CMAKE_INSTALL_PREFIX}/matlab")
4636
endif()
4737
message(STATUS "Matlab wrappers will be installed in " ${MATLAB_DEST})
4838

49-
set(PYTHON_DEST_DIR "" CACHE PATH "Directory of the Python wrappers")
50-
if (PYTHON_DEST_DIR)
51-
set(PYTHON_DEST "${PYTHON_DEST_DIR}")
52-
else()
53-
set(PYTHON_DEST "${CMAKE_INSTALL_PREFIX}/python")
54-
endif()
55-
message(STATUS "Python wrappers will be installed in " ${PYTHON_DEST})
56-
57-
5839
#add_subdirectory(src/Core)
5940
add_subdirectory(src)

Installation.md

+53-30
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
1-
## Installation:
1+
# CCPi Regularisation Toolkit
2+
3+
## Installation
24

35
In order to compile C/C++ sources and additional wrappers from source code for numpy 1.24 and python 3.10, the recommended way is:
4-
```
6+
7+
```sh
58
git clone https://github.com/vais-ral/CCPi-Regularisation-Toolkit
69
cd CCPi-Regularisation-Toolkit
710
export CCPI_BUILD_ARGS="--numpy 1.24 --python 3.10"
811
build/jenkins-build.sh
912
```
13+
1014
this will install `conda build` environment and compiles C/C++ and Python wrappers and performs basic tests for environment with python 3.10 and numpy 1.24.
1115

1216
### CMake
17+
1318
If you want to build directly using cmake, install CMake (v.>=3) to configure it. Additionally you will need a C compiler, `make` (on linux) and CUDA SDK where available. The toolkit may be used directly from C/C++ as it is compiled as a shared library (check-out the include files in `Core` for this)
19+
1420
1. Clone this repository to a directory, i.e. `CCPi-Regularisation-Toolkit`,
1521
2. create a build directory.
1622
3. Issue `cmake` to configure (or `cmake-gui`, or `ccmake`, or `cmake3`). Use additional flags to fine tune the configuration.
@@ -22,35 +28,35 @@ Flags used during configuration
2228
| `BUILD_PYTHON_WRAPPER` | bool | `ON\|OFF` whether to build the Python wrapper |
2329
| `BUILD_MATLAB_WRAPPER` | bool | `ON\|OFF` whether to build the Matlab wrapper |
2430
| `CMAKE_INSTALL_PREFIX` | path | your favourite install directory |
25-
| `PYTHON_DEST_DIR` | path | python modules install directory (default `${CMAKE_INSTALL_PREFIX}/python`) |
2631
| `MATLAB_DEST_DIR` | path | Matlab modules install directory (default `${CMAKE_INSTALL_PREFIX}/matlab`)|
2732
| `BUILD_CUDA` | bool | `ON\|OFF` whether to build the CUDA regularisers |
28-
| `CONDA_BUILD`| bool | `ON\|OFF` whether it is installed with `setup.py install`|
2933
| `Matlab_ROOT_DIR` | path | Matlab directory|
30-
|`PYTHON_EXECUTABLE` | path | /path/to/python/executable|
34+
| `PYTHON_EXECUTABLE` | path | /path/to/python/executable|
3135

3236
Here an example of build on Linux (see also `run.sh` for additional info):
3337

34-
```bash
35-
git clone https://github.com/vais-ral/CCPi-Regularisation-Toolkit.git
36-
cd build
37-
cmake .. -DCONDA_BUILD=OFF -DBUILD_MATLAB_WRAPPER=ON -DBUILD_PYTHON_WRAPPER=ON -DBUILD_CUDA=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=./install
38-
make install
39-
cd install/python
40-
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:../lib
38+
```sh
39+
git clone https://github.com/vais-ral/CCPi-Regularisation-Toolkit
40+
cd CCPi-Regularisation-Toolkit
41+
cmake -S . -B ./build_proj -DBUILD_MATLAB_WRAPPER=ON -DBUILD_PYTHON_WRAPPER=ON -DBUILD_CUDA=ON -DCMAKE_INSTALL_PREFIX=./install
42+
cmake --build ./build_proj --target install
4143
```
4244

4345
### Python
46+
4447
#### Python binaries
48+
4549
Python binaries are distributed via the [ccpi](https://anaconda.org/ccpi/ccpi-regulariser) conda channel.
4650

47-
```
51+
```sh
4852
conda install ccpi-regulariser -c ccpi -c conda-forge
4953
```
5054

5155
#### Python (conda-build)
52-
```
53-
export CIL_VERSION=$(date +%Y.%m) (Unix) / set CIL_VERSION=19.10 (Windows)
56+
57+
```sh
58+
export CIL_VERSION=$(date +%Y.%m.%d) # UNIX
59+
# set CIL_VERSION=24.3.0 # Windows
5460
conda build recipe/ --numpy 1.23 --python 3.10
5561
conda install ccpi-regulariser=${CIL_VERSION} --use-local --force-reinstall # doesn't work?
5662
conda install -c file://${CONDA_PREFIX}/conda-bld/ ccpi-regulariser=${CIL_VERSION} --force-reinstall # try this one
@@ -60,25 +66,38 @@ python demo_gpu_regularisers.py # to run GPU demo
6066
```
6167

6268
### Python (GPU-CuPy)
63-
One can also use some of the GPU modules directly (i.e. without the need of building the package) by using [CuPy](https://docs.cupy.dev/en/stable/index.html) implementations.
69+
70+
One can also use some of the GPU modules directly (i.e. without the need of building the package) by using [CuPy](https://docs.cupy.dev) implementations.
71+
72+
```sh
73+
pip install git+https://github.com/vais-ral/CCPi-Regularisation-Toolkit
6474
```
65-
git clone git@github.com:vais-ral/CCPi-Regularisation-Toolkit.git
66-
cd CCPi-Regularisation-Toolkit
67-
pip install .
68-
```
75+
76+
> [!WARNING]
77+
> The above currently doesn't work; see **Python build** below instead:
6978
7079
#### Python build
71-
If passed `CONDA_BUILD=ON` the software will be installed by issuing `python setup.py install` which will install in the system python (or whichever other python it's been picked up by CMake at configuration time.)
72-
If passed `CONDA_BUILD=OFF` the software will be installed in the directory pointed by `${PYTHON_DEST_DIR}` which defaults to `${CMAKE_INSTALL_PREFIX}/python`. Therefore this directory should be added to the `PYTHONPATH`.
7380

74-
If Python is not picked by CMake you can provide the additional flag to CMake `-DPYTHON_EXECUTABLE=/path/to/python/executable`.
81+
If passed `BUILD_PYTHON_WRAPPER=ON`, CMake will install libraries in-place under `./src/Python`, followed by running `python -m pip install ./src/Python`.
82+
(Note that libraries are also installed under the user-specified `${CMAKE_INSTALL_PREFIX}`, which could be set to a throwaway directory, e.g. `-DCMAKE_INSTALL_PREFIX=./install`).
83+
84+
If Python is not picked by CMake you can provide the additional flag to CMake `-DPYTHON_EXECUTABLE=/path/to/executable/python`.
85+
86+
Tests can also be run in-place after the build:
87+
88+
```sh
89+
PYTHONPATH=./src/Python python -m unittest discover ./test
90+
```
7591

7692
### MultiGPU capability (to use in Python with mpi4py)
93+
7794
The toolkit can be used by running in parallel across multiple GPU devices on a PC or a compute node of a cluster. In order to initiate a parallel run on your GPUs you will need an MPI library, such as, [mpi4py](https://mpi4py.readthedocs.io/en/stable/). See multi_gpu demo script in demos folder, it can be run as
78-
```
95+
96+
```sh
7997
mpirun -np 2 python multi_gpu.py -g -s -gpus 2
8098
```
81-
where `-np` parameter defines the total number of processes and `-gpus` defines the number of available GPUs.
99+
100+
where `-np` parameter defines the total number of processes and `-gpus` defines the number of available GPUs.
82101

83102
### Matlab
84103

@@ -87,23 +106,27 @@ Matlab wrapper will install in the `${MATLAB_DEST_DIR}` directory, which default
87106
If Matlab is not picked by CMake, you could add `-DMatlab_ROOT_DIR=<Matlab directory>`.
88107

89108
#### Linux
109+
90110
Because you've installed the modules in `<your favourite install directory>` you need to instruct Matlab to look in those directories:
91111

92112
```bash
93-
94113
PATH="/path/to/mex/:$PATH" LD_LIBRARY_PATH="/path/to/library:$LD_LIBRARY_PATH" matlab
95114
```
115+
96116
By default `/path/to/mex` is `${CMAKE_INSTALL_PREFIX}/bin` and `/path/to/library/` is `${CMAKE_INSTALL_PREFIX}/lib`
97117

98118
#### Windows
119+
99120
On Windows the `dll` and the mex modules must reside in the same directory. It is sufficient to add the directory at the beginning of the m-file.
121+
100122
```matlab
101123
addpath(/path/to/library);
102124
```
103125

104126
#### Legacy Matlab installation (partly supported, please use Cmake)
127+
128+
```sh
129+
cd src/Matlab/mex_compile
130+
compileCPU_mex.m % to compile CPU modules
131+
compileGPU_mex.m % to compile GPU modules (see instructions in the file)
105132
```
106-
cd src/Matlab/mex_compile
107-
compileCPU_mex.m % to compile CPU modules
108-
compileGPU_mex.m % to compile GPU modules (see instructions in the file)
109-
```

demos/demo_cpu_regularisers3D.py

+23-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
3+
#%%
34
"""
45
Created on Thu Feb 22 11:39:43 2018
56
@@ -30,6 +31,7 @@ def printParametersToString(pars):
3031
return txt
3132
###############################################################################
3233

34+
os.chdir(os.path.join("..", "demos"))
3335
filename = os.path.join( "data" ,"lena_gray_512.tif")
3436

3537
# read image
@@ -101,11 +103,12 @@ def printParametersToString(pars):
101103

102104
print ("#############ROF TV CPU####################")
103105
start_time = timeit.default_timer()
104-
(rof_cpu3D, info_vec_cpu) = ROF_TV(pars['input'],
106+
info_vec_cpu = np.zeros(2, dtype = np.float32)
107+
rof_cpu3D = ROF_TV(pars['input'],
105108
pars['regularisation_parameter'],
106109
pars['number_of_iterations'],
107110
pars['time_marching_parameter'],
108-
pars['tolerance_constant'], 'cpu')
111+
pars['tolerance_constant'], device='cpu', infovector=info_vec_cpu)
109112

110113
Qtools = QualityTools(idealVol, rof_cpu3D)
111114
pars['rmse'] = Qtools.rmse()
@@ -146,12 +149,12 @@ def printParametersToString(pars):
146149

147150
print ("#############FGP TV GPU####################")
148151
start_time = timeit.default_timer()
149-
(fgp_cpu3D, info_vec_cpu) = FGP_TV(pars['input'],
152+
fgp_cpu3D = FGP_TV(pars['input'],
150153
pars['regularisation_parameter'],
151154
pars['number_of_iterations'],
152155
pars['tolerance_constant'],
153156
pars['methodTV'],
154-
pars['nonneg'], 'cpu')
157+
pars['nonneg'], device='cpu', infovector=info_vec_cpu)
155158

156159
Qtools = QualityTools(idealVol, fgp_cpu3D)
157160
pars['rmse'] = Qtools.rmse()
@@ -190,15 +193,16 @@ def printParametersToString(pars):
190193
'nonneg': 0,
191194
'lipschitz_const' : 8}
192195

193-
print ("#############FGP TV GPU####################")
196+
print ("#############PD-TV (3D) CPU####################")
194197
start_time = timeit.default_timer()
195-
(pd_cpu3D,info_vec_cpu) = PD_TV(pars['input'],
198+
pd_cpu3D = PD_TV(pars['input'],
196199
pars['regularisation_parameter'],
197200
pars['number_of_iterations'],
198201
pars['tolerance_constant'],
202+
pars['lipschitz_const'],
199203
pars['methodTV'],
200204
pars['nonneg'],
201-
pars['lipschitz_const'],'cpu')
205+
device='cpu', infovector=info_vec_cpu)
202206

203207
Qtools = QualityTools(idealVol, pd_cpu3D)
204208
pars['rmse'] = Qtools.rmse()
@@ -237,11 +241,11 @@ def printParametersToString(pars):
237241

238242
print ("#############SB TV CPU####################")
239243
start_time = timeit.default_timer()
240-
(sb_cpu3D, info_vec_cpu) = SB_TV(pars['input'],
244+
sb_cpu3D = SB_TV(pars['input'],
241245
pars['regularisation_parameter'],
242246
pars['number_of_iterations'],
243247
pars['tolerance_constant'],
244-
pars['methodTV'],'cpu')
248+
pars['methodTV'], device='cpu', infovector=info_vec_cpu)
245249

246250
Qtools = QualityTools(idealVol, sb_cpu3D)
247251
pars['rmse'] = Qtools.rmse()
@@ -283,12 +287,12 @@ def printParametersToString(pars):
283287

284288
print ("#############LLT ROF CPU####################")
285289
start_time = timeit.default_timer()
286-
(lltrof_cpu3D,info_vec_cpu) = LLT_ROF(pars['input'],
290+
lltrof_cpu3D = LLT_ROF(pars['input'],
287291
pars['regularisation_parameterROF'],
288292
pars['regularisation_parameterLLT'],
289293
pars['number_of_iterations'],
290294
pars['time_marching_parameter'],
291-
pars['tolerance_constant'], 'cpu')
295+
pars['tolerance_constant'], device='cpu', infovector=info_vec_cpu)
292296

293297

294298
Qtools = QualityTools(idealVol, lltrof_cpu3D)
@@ -331,13 +335,13 @@ def printParametersToString(pars):
331335

332336
print ("#############TGV CPU####################")
333337
start_time = timeit.default_timer()
334-
(tgv_cpu3D,info_vec_cpu) = TGV(pars['input'],
338+
tgv_cpu3D = TGV(pars['input'],
335339
pars['regularisation_parameter'],
336340
pars['alpha1'],
337341
pars['alpha0'],
338342
pars['number_of_iterations'],
339343
pars['LipshitzConstant'],
340-
pars['tolerance_constant'],'cpu')
344+
pars['tolerance_constant'], device='cpu', infovector=info_vec_cpu)
341345

342346

343347
Qtools = QualityTools(idealVol, tgv_cpu3D)
@@ -380,13 +384,13 @@ def printParametersToString(pars):
380384

381385
print ("#############NDF CPU################")
382386
start_time = timeit.default_timer()
383-
(ndf_cpu3D,info_vec_cpu) = NDF(pars['input'],
387+
ndf_cpu3D = NDF(pars['input'],
384388
pars['regularisation_parameter'],
385389
pars['edge_parameter'],
386390
pars['number_of_iterations'],
387391
pars['time_marching_parameter'],
388392
pars['penalty_type'],
389-
pars['tolerance_constant'], 'cpu')
393+
pars['tolerance_constant'], device='cpu', infovector=info_vec_cpu)
390394

391395

392396
Qtools = QualityTools(idealVol, ndf_cpu3D)
@@ -428,12 +432,12 @@ def printParametersToString(pars):
428432

429433
print ("#############Diff4th CPU################")
430434
start_time = timeit.default_timer()
431-
(diff4th_cpu3D,info_vec_cpu) = Diff4th(pars['input'],
435+
diff4th_cpu3D = Diff4th(pars['input'],
432436
pars['regularisation_parameter'],
433437
pars['edge_parameter'],
434438
pars['number_of_iterations'],
435439
pars['time_marching_parameter'],
436-
pars['tolerance_constant'],'cpu')
440+
pars['tolerance_constant'], device='cpu', infovector=info_vec_cpu)
437441

438442

439443
Qtools = QualityTools(idealVol, diff4th_cpu3D)
@@ -477,14 +481,14 @@ def printParametersToString(pars):
477481

478482
print ("#############FGP dTV CPU####################")
479483
start_time = timeit.default_timer()
480-
(fgp_dTV_cpu3D,info_vec_cpu) = FGP_dTV(pars['input'],
484+
fgp_dTV_cpu3D = FGP_dTV(pars['input'],
481485
pars['refdata'],
482486
pars['regularisation_parameter'],
483487
pars['number_of_iterations'],
484488
pars['tolerance_constant'],
485489
pars['eta_const'],
486490
pars['methodTV'],
487-
pars['nonneg'],'cpu')
491+
pars['nonneg'], device='cpu', infovector=info_vec_cpu)
488492

489493

490494
Qtools = QualityTools(idealVol, fgp_dTV_cpu3D)

0 commit comments

Comments
 (0)