initial commit

This commit is contained in:
2026-08-07 15:56:42 +09:00
commit 91ad25aca9
1012 changed files with 159314 additions and 0 deletions
+103
View File
@@ -0,0 +1,103 @@
% function f = local_TV3D_chambolle(f, lambda, niter)
% apply local total variation usiniter matlab functions, it uses chambolle
% solver -> faster but more memory demanding
% Inputs: f - 3D array to be regularized
% lambda - constant to be tuned
% niter - number of iterations
%*-----------------------------------------------------------------------*
%|                                                                       |
%|  Except where otherwise noted, this work is licensed under a          |
%|  Creative Commons Attribution-NonCommercial-ShareAlike 4.0            |
%|  International (CC BY-NC-SA 4.0) license.                             |
%|                                                                       |
%|  Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch)    |
%|                                                                       |
%|      Author: CXS group, PSI  |
%*-----------------------------------------------------------------------*
% You may use this code with the followiniter provisions:
%
% If the code is fully or partially redistributed, or rewritten in another
% computiniter laniteruage this notice should be included in the redistribution.
%
% If this code, or subfunctions or parts of it, is used for research in a
% publication or if it is fully or partially rewritten for another
% computiniter laniteruage the authors and institution should be acknowledged
% in written form in the publication: Data processiniter was carried out
% usiniter the cSAXS matlab package developed by the CXS group,
% Paul Scherrer Institut, Switzerland.
% Variations on the latter text can be incorporated upon discussion with
% the CXS group if needed to more specifically reflect the use of the package
% for the published work.
%
% A publication that focuses on describiniter features, or parameters, that
% are already existiniter in the code should be first discussed with the
% authors.
%
% This code and subroutines are part of a continuous development, they
% are provided as they are without guarantees or liability on part
% of PSI or the authors. It is the user responsibility to ensure its
% proper use and the correctness of the results.
function x = local_TV3D_chambolle(x,lambda, niter)
[M,N,O] = size(x);
if lambda == 0
return
end
x0 = x;
xi = zeros(M,N,O,3, class(x));
tau=2/8;
%%% INNER LOOP
for iinner = 1:niter
% chambolle step
gdv = grad( div(xi) - x/lambda );
%% isotropic
% d = sqrt(sum(gdv.^2,3));
%% anisotropic
d = sum( abs(gdv), 4);
xi = bsxfun(@times, xi + tau*gdv, 1 ./ ( 1+tau*d ));
% reconstruct
x = x - lambda*div( xi );
end
% prevent pushing values to zero by the TV regularization
x = sum(x0(:).* x(:)) / sum(x(:).^2) * x;
end
function fd = div(P)
% div - divergence (backward difference)
%
% fd = div(P);
Px = P(:,:,:,1);
Py = P(:,:,:,2);
Pz = P(:,:,:,3);
fx = Px-Px([1 1:end-1],:,:);
fy = Py-Py(:,[1 1:end-1],:);
fz = Pz-Pz(:,:,[1 1:end-1]);
fd = fx+fy+fz;
end
function f = grad(M)
% grad - gradient, forward differences
% g = grad(M);
fx = M([2:end end],:,:)-M;
fy = M(:,[2:end end],:)-M;
fz = M(:,:,[2:end end])-M;
f = cat(4,fx,fy,fz);
end
+72
View File
@@ -0,0 +1,72 @@
% function f = local_TV3D_grad(f, dtvg, niter)
% apply local total variation usiniter matlab functions, it uses basic
% steepest descent solver.
% Inputs: f - 3D array to be regularized
% dtvg - gradient descent step (constant to be tuned)
% niter - number of iterations
%*-----------------------------------------------------------------------*
%|                                                                       |
%|  Except where otherwise noted, this work is licensed under a          |
%|  Creative Commons Attribution-NonCommercial-ShareAlike 4.0            |
%|  International (CC BY-NC-SA 4.0) license.                             |
%|                                                                       |
%|  Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch)    |
%|                                                                       |
%|      Author: CXS group, PSI  |
%*-----------------------------------------------------------------------*
% You may use this code with the followiniter provisions:
%
% If the code is fully or partially redistributed, or rewritten in another
% computiniter laniteruage this notice should be included in the redistribution.
%
% If this code, or subfunctions or parts of it, is used for research in a
% publication or if it is fully or partially rewritten for another
% computiniter laniteruage the authors and institution should be acknowledged
% in written form in the publication: Data processiniter was carried out
% usiniter the cSAXS matlab package developed by the CXS group,
% Paul Scherrer Institut, Switzerland.
% Variations on the latter text can be incorporated upon discussion with
% the CXS group if needed to more specifically reflect the use of the package
% for the published work.
%
% A publication that focuses on describiniter features, or parameters, that
% are already existiniter in the code should be first discussed with the
% authors.
%
% This code and subroutines are part of a continuous development, they
% are provided as they are without guarantees or liability on part
% of PSI or the authors. It is the user responsibility to ensure its
% proper use and the correctness of the results.
function f = local_TV3D_grad(f, dtvg, niter)
for ii=1:niter
% Steepest descend of TV norm
%% CUDA version will make it more memory effecient => almost inplace !!
df=gradientTVnormForward(f);
df=df./sqrt(mean(df(:).^2)); % it will be close to 1 anyway
f=f-dtvg.*df;
end
end
%% Forward differences
function tvg=gradientTVnormForward(f)
% gradient
Gx=diff(f,1,1);
Gy=diff(f,1,2);
Gz=diff(f,1,3);
Gx=cat(1,Gx,zeros(size(Gx(end,:,:)), class(f)));
Gy=cat(2,Gy,zeros(size(Gy(:,end,:)), class(f)));
Gz=cat(3,Gz,zeros(size(Gz(:,:,end)), class(f)));
nrm=sqrt(Gx.^2+Gy.^2+Gz.^2)+1e-7;
% divergence
tvg=Gx([1,1:end-1],:,:)-Gx + Gy(:,[1,1:end-1],:)-Gy+Gz(:,:,[1,1:end-1])-Gz;
tvg=tvg ./ nrm;
end
+75
View File
@@ -0,0 +1,75 @@
% Vol = local_TV_zsplit(Vol, lambda, eps, Niter, use_chambolle)
% FUNCTION
% - split volume on smaller blocks for processing by local total variation
% - splitting is done automatically in order to fit to GPU memory
% Inputs:
% Vol - refined volume
% lambda - refinement step (tunning constant)
% eps - regularization term (tunning constant)
% Niter - number of iterations
% use_chambolle - if true use Chambolle method, if false use simple gradient descent solver
% Recompile:
% mexcuda -output +regularization/private/local_TV_mex +regularization/private/TV_cuda_texture.cu +regularization/private/local_TV_mex.cpp
%*-----------------------------------------------------------------------*
%|                                                                       |
%|  Except where otherwise noted, this work is licensed under a          |
%|  Creative Commons Attribution-NonCommercial-ShareAlike 4.0            |
%|  International (CC BY-NC-SA 4.0) license.                             |
%|                                                                       |
%|  Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch)    |
%|                                                                       |
%|      Author: CXS group, PSI  |
%*-----------------------------------------------------------------------*
% You may use this code with the following provisions:
%
% If the code is fully or partially redistributed, or rewritten in another
% computing language this notice should be included in the redistribution.
%
% If this code, or subfunctions or parts of it, is used for research in a
% publication or if it is fully or partially rewritten for another
% computing language the authors and institution should be acknowledged
% in written form in the publication: Data processing was carried out
% using the cSAXS matlab package developed by the CXS group,
% Paul Scherrer Institut, Switzerland.
% Variations on the latter text can be incorporated upon discussion with
% the CXS group if needed to more specifically reflect the use of the package
% for the published work.
%
% A publication that focuses on describing features, or parameters, that
% are already existing in the code should be first discussed with the
% authors.
%
% This code and subroutines are part of a continuous development, they
% are provided as they are without guarantees or liability on part
% of PSI or the authors. It is the user responsibility to ensure its
% proper use and the correctness of the results.
function Vol = local_TV_zsplit(Vol, lambda, eps, Niter, use_chambolle)
keep_on_gpu = isa(Vol, 'gpuArray');
gpu = gpuDevice;
Nlayers = size(Vol,3);
Nblocks = ceil(numel(Vol)*4 / 1024e6);
% empirically tested condition
Nblocks = max(Nblocks, ceil((numel(Vol)*4*14) / gpu.AvailableMemory));
Nlayers_on_GPU = ceil(Nlayers/Nblocks);
Nblocks = ceil(Nlayers/Nlayers_on_GPU);
if Nblocks > 1
for i = 1:Nblocks
utils.progressbar(i, ceil(Nlayers/Nlayers_on_GPU))
ind = (1+(i-1)*Nlayers_on_GPU):min(i*Nlayers_on_GPU, Nlayers);
Vol_tmp = gpuArray(Vol(:,:,ind));
Vol_tmp = local_TV_mex(Vol_tmp,lambda,eps, Niter, use_chambolle);
if ~keep_on_gpu; Vol_tmp = gather(Vol_tmp);end
Vol(:,:,ind) = Vol_tmp;
end
else
Vol = local_TV_mex(Vol,lambda,eps, Niter, use_chambolle);
if ~keep_on_gpu; Vol = gather(Vol);end
end
end
+100
View File
@@ -0,0 +1,100 @@
% [Im] = nonlocalTV_GPU(Im0,CloseInd, Neighbours, Rwin,Niter,lambda, dt, eps)
% FUNCTION
% nonlocal total variation solved by a simple steepest descent solver
% Inputs:
% Im0 - regularized array (3D volume)
% CloseInd - close indices generated by nonlocalTV_weight code
% Neighbours - number of neighbors used for calculation
% Rwin - radius of the window used to find similar regions
% Niter - number of reconstruction iterations
% lambda - step size (tunning value), usually < 1, if zero ->
% completelly ignore data and just find the solution that most fits to
% nonlocal TV constraint
% dt - also kind of step size (tunning value), usually << 1
% eps - regularization constant (tunning value), usually << 1
% RECOMPILE COMMAND
% mexcuda -output +regularization/private/nonlocalTV_tex +regularization/private/TV_cuda_texture.cu +regularization/private/nonlocalTV_mex.cpp
%*-----------------------------------------------------------------------*
%|                                                                       |
%|  Except where otherwise noted, this work is licensed under a          |
%|  Creative Commons Attribution-NonCommercial-ShareAlike 4.0            |
%|  International (CC BY-NC-SA 4.0) license.                             |
%|                                                                       |
%|  Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch)    |
%|                                                                       |
%|      Author: CXS group, PSI  |
%*-----------------------------------------------------------------------*
% You may use this code with the following provisions:
%
% If the code is fully or partially redistributed, or rewritten in another
% computing language this notice should be included in the redistribution.
%
% If this code, or subfunctions or parts of it, is used for research in a
% publication or if it is fully or partially rewritten for another
% computing language the authors and institution should be acknowledged
% in written form in the publication: Data processing was carried out
% using the cSAXS matlab package developed by the CXS group,
% Paul Scherrer Institut, Switzerland.
% Variations on the latter text can be incorporated upon discussion with
% the CXS group if needed to more specifically reflect the use of the package
% for the published work.
%
% A publication that focuses on describing features, or parameters, that
% are already existing in the code should be first discussed with the
% authors.
%
% This code and subroutines are part of a continuous development, they
% are provided as they are without guarantees or liability on part
% of PSI or the authors. It is the user responsibility to ensure its
% proper use and the correctness of the results.
function [Im] = nonlocalTV_GPU(Im0,CloseInd, Neighbours, Rwin,Niter,lambda, dt, eps)
keep_on_gpu = isa(Im0, 'gpuArray');
CloseInd = gpuArray(uint8(CloseInd));
Im0 = gpuArray(single(Im0));
try
%Input should be between 0 and 1 to make the regularizations constants selection
%kind of repeatable for similar samples
minIm=min(Im0(:));
Im0=Im0-minIm;
maxIm=prctile(Im0(1:10:end), 99);
Im0=Im0/maxIm;
catch err
error(err.message)
end
Nclose = size(CloseInd,ndims(CloseInd));
%% primitive replacement of the real weights based on assumption that CloseInd is sorted by importance !!!
Nnbrs = size(CloseInd,ndims(CloseInd));
% Nbrs_weights = single(exp(-linspace(0,1,Nnbrs)));
Nbrs_weights = single(1./(1:Nnbrs));
% Nbrs_weights = ones(Nnbrs,1, 'single');
% keyboard
% tic
Im = nonlocalTV_tex(Im0,CloseInd,uint8(Neighbours), Nbrs_weights, dt, eps, lambda, Nclose, Rwin,Niter);
% wait(gpu)
% toc
%Back to original pixel range
Im=Im*maxIm;
Im=Im+minIm;
if ~keep_on_gpu
Im = gather(Im);
end
end
@@ -0,0 +1,157 @@
% [CloseInd,Neighbours] = nonlocalTV_weight_GPU(Im0, Rpatch, Rwin, Nclose, sigma)
% FUNCTION
% find close indices for the nonlocalTV_GPU method , similar to the nonlocal means method
% Inputs:
% Im0 - volume to be regularized
% Rpatch - radius of the patch used to ocompare similarities
% Rwin - radius of the window used to find similar regions
% Nclose - number of most similar regions searched
% sigma - similarity threshold, (tunning constant, value < 1)
% Outputs:
% CloseInd - close indices generated by nonlocalTV_weight code
% Neighbours - list of neighboring pixels used for calculation and excluded from CloseInd
% RECOMPILE COMMAND
% mexcuda -output +regularization/private/nonlocalTV_weight_tex +regularization/private/TV_cuda_texture.cu +regularization/private/nonlocalTV_mex_weight.cpp
%*-----------------------------------------------------------------------*
%|                                                                       |
%|  Except where otherwise noted, this work is licensed under a          |
%|  Creative Commons Attribution-NonCommercial-ShareAlike 4.0            |
%|  International (CC BY-NC-SA 4.0) license.                             |
%|                                                                       |
%|  Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch)    |
%|                                                                       |
%|      Author: CXS group, PSI  |
%*-----------------------------------------------------------------------*
% You may use this code with the following provisions:
%
% If the code is fully or partially redistributed, or rewritten in another
% computing language this notice should be included in the redistribution.
%
% If this code, or subfunctions or parts of it, is used for research in a
% publication or if it is fully or partially rewritten for another
% computing language the authors and institution should be acknowledged
% in written form in the publication: Data processing was carried out
% using the cSAXS matlab package developed by the CXS group,
% Paul Scherrer Institut, Switzerland.
% Variations on the latter text can be incorporated upon discussion with
% the CXS group if needed to more specifically reflect the use of the package
% for the published work.
%
% A publication that focuses on describing features, or parameters, that
% are already existing in the code should be first discussed with the
% authors.
%
% This code and subroutines are part of a continuous development, they
% are provided as they are without guarantees or liability on part
% of PSI or the authors. It is the user responsibility to ensure its
% proper use and the correctness of the results.
function [CloseInd,Neighbours] = nonlocalTV_weight_GPU(Im0, Rpatch, Rwin, Nclose, sigma)
%% nonlocal TV
% mexcuda -output nonlocalTV_weight_tex TV_cuda_texture.cu nonlocalTV_mex_weight.cpp
Nwin= 2*Rwin+1;
Nclose_min=2;
Nclose_max = 256;
if Nclose > Nclose_max
error('Nclose is more than Nclose_max')
end
if ismatrix(Im0)
assert(Nwin^2 < Nclose_max, 'Too large Nwin')
% Neighbours=uint8(sub2ind([Nwin,Nwin],...
% Rwin+1+[0,-1,1,0,0],Rwin+1+[0,0,0,-1,1]));
Neighbours=uint8(sub2ind([Nwin,Nwin],...
Rwin+1,Rwin+1));
else
assert(Nwin^3 < Nclose_max, 'Too large Nwin')
% include all neighbors
% Neighbours=uint8(sub2ind([Nwin,Nwin,Nwin],...
% Rwin+1+[0,-1,1,0,0,0,0], ...
% Rwin+1+[0,0,0,-1,1,0,0], ...
% Rwin+1+[0,0,0,0,0,-1,1]));
% only the central point !!
Neighbours=uint8(sub2ind([Nwin,Nwin,Nwin],...
Rwin+1, Rwin+1,Rwin+1));
end
% keyboard
[Nx, Ny, Nz] = size(Im0);
MAX_SIZE = 512; %% TESTED FOR TITAN X 12GB !!!
% MAX_SIZE = 320; %% roughly for Quadro K4200
split = ceil([Nx, Ny, Nz]/MAX_SIZE);
if prod(split) == 1
CloseInd = nonlocalTV_weight_GPU_partial(Im0, Rpatch, Rwin, Nclose,Nclose_min,sigma, Neighbours);
else %% in case of too large datasets
warning('Volume is too large, it will be sliced')
CloseInd = zeros(Nx, Ny,Nz,Nclose, 'uint8');
ind = {':',':',':'};
for i = 1:split(1)
ind{1} = (1+(i-1)*ceil(Nx/split(1))):min(Nx,i*ceil(Nx/split(1)));
for j = 1:split(2)
ind{2} = (1+(j-1)*ceil(Ny/split(2))):min(Ny,j*ceil(Ny/split(2)));
for k = 1:split(3)
ind{3} = (1+(k-1)*ceil(Nz/split(3))):min(Nz,j*ceil(Nz/split(3)));
CloseInd(ind{:},:) = gather(nonlocalTV_weight_GPU_partial(Im0(ind{:}), Rpatch, Rwin, Nclose,Nclose_min, sigma, Neighbours));
utils.progressbar(k + (j-1)*split(2)+(i-1)*split(1)*split(2), prod(split))
end
end
end
end
end
function CloseInd = nonlocalTV_weight_GPU_partial(Im0, Rpatch, Rwin, Nclose, Nclose_min, sigma, Neighbours)
Im0_gpu = gpuArray(single(Im0));
Npatch= 2*Rpatch+1;
%% get simple estimate of the average gradients
if ismatrix(Im0_gpu)
dx = diff(Im0_gpu,1,1);
dx = dx(:,2:end).^2;
dy = diff(Im0_gpu,1,2);
dy = dy(2:end,:).^2;
ker = ones(Npatch, 'single');
threshold = mean2(sqrt(conv2( (dx + dy)/2,ker, 'same')));
elseif ndims(Im0_gpu) == 3
dx = diff(Im0_gpu,1,1);
dx = dx(:,2:end,2:end).^2;
dy = diff(Im0_gpu,1,2);
dy = dy(2:end,:,2:end).^2;
dz = diff(Im0_gpu,1,3);
dz = dz(2:end,2:end,:).^2;
ker = ones([Npatch,Npatch,Npatch], 'single');
threshold = mean2(sqrt(convn( (dx + dy + dz)/3,ker, 'same')));
end
% sigma is changing the threshold level
%% patched more different than threshold will be rejected !!!
threshold = gather(threshold ) * sigma;
clear dx dy dz
% tic
CloseInd = nonlocalTV_weight_tex(Im0_gpu,Neighbours,Nclose,Nclose_min,Rwin,Rpatch,threshold);
% toc
end
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,23 @@
#ifndef TV_GPU_tex_HPP
#define TV_GPU_tex_HPP
#include "tmwtypes.h"
int checkLastError(char * msg);
void nonlocal_TV_init( float * Img, const float * Img0, const uint8_T *CloseInd,
const uint8_T * neighbours, const float * p_Nbrs_weights, const float dt, const float eps, const float lambda,const unsigned int Nclose, const unsigned int Nbrs, const int Rwin,
const unsigned int N, const unsigned int M, const unsigned int O, const unsigned int Niter);
void nonlocal_weight_TV_init( uint8_T *c, const float * p,
const uint8_T * neighbours, const unsigned int Nclose, const unsigned int Nclose_min, const unsigned int Nbrs, const int Rwin, const int Rpatch,
const unsigned int N, const unsigned int M, const unsigned int O, const float threshold);
void local_TV_init( float * Img, const float dt, const float eps, const unsigned int M, const unsigned int N, const unsigned int O, const unsigned int Niter);
void local_TV_chambolle_init( float * Img, float ** Xi, const float dt, const float tau,
const unsigned int M, const unsigned int N, const unsigned int O, const unsigned int Niter);
#endif
@@ -0,0 +1,124 @@
#include "mex.h"
#include "gpu/mxGPUArray.h"
#include "TV_texture.hpp"
//mexcuda -output private/local_TV_mex private/TV_cuda_texture.cu private/local_TV_mex.cpp
/**
*
*-----------------------------------------------------------------------*
|                                                                       |
|  Except where otherwise noted, this work is licensed under a          |
|  Creative Commons Attribution-NonCommercial-ShareAlike 4.0            |
|  International (CC BY-NC-SA 4.0) license.                             |
|                                                                       |
|  Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch)    |
|                                                                       |
|      Author: CXS group, PSI  |
*-----------------------------------------------------------------------*
You may use this code with the following provisions:
If the code is fully or partially redistributed, or rewritten in another
computing language this notice should be included in the redistribution.
If this code, or subfunctions or parts of it, is used for research in a
publication or if it is fully or partially rewritten for another
computing language the authors and institution should be acknowledged
in written form in the publication: “Data processing was carried out
using the “cSAXS matlab package” developed by the CXS group,
Paul Scherrer Institut, Switzerland.”
Variations on the latter text can be incorporated upon discussion with
the CXS group if needed to more specifically reflect the use of the package
for the published work.
A publication that focuses on describing features, or parameters, that
are already existing in the code should be first discussed with the
authors.
This code and subroutines are part of a continuous development, they
are provided “as they are” without guarantees or liability on part
of PSI or the authors. It is the user responsibility to ensure its
*
* MEX gateway
*/
void mexFunction(int nlhs , mxArray *plhs[],
int nrhs, mxArray const *prhs[])
{
char const * const errId = "parallel:gpu:mexGPUExample:InvalidInput";
char const * const errMsg = "Invalid input to MEX file.";
// Initialize the MathWorks GPU API.
mxInitGPU();
if (nrhs!=5) {
mexPrintf("Wrong number of inputs\n");
mexErrMsgIdAndTxt(errId, errMsg);
}
const float dt = (float)mxGetScalar(prhs[1]);
const float tau = (float)mxGetScalar(prhs[2]);
const int Niter = (int)mxGetScalar(prhs[3]);
const int UseChambolle = (int)mxGetScalar(prhs[4]);
/* allocate output image field */
mxGPUArray * m_Img_new = mxGPUCopyFromMxArray(prhs[0]);
if ((mxGPUGetClassID(m_Img_new) != mxSINGLE_CLASS)) {
mexPrintf("m_Img_new\n");
mexErrMsgIdAndTxt(errId, errMsg);
}
float * p_Img_new = (float *)mxGPUGetData(m_Img_new);
mwSize const * dimensions = mxGPUGetDimensions(m_Img_new);
mwSize Ndim = mxGPUGetNumberOfDimensions(m_Img_new);
int M = (int)dimensions[0];
int N = (int)dimensions[1];
int O = Ndim > 2 ? (int)dimensions[2] : 1;
mxGPUArray * mXi[3] ;
if (UseChambolle ) {
/* allocate Xi field */
float * Xi[3] ;
mwSize xiSize[3] = {M,N,O};
for( int i = 0; i < 3; i++) {
mXi[i] = mxGPUCreateGPUArray(3,
xiSize,
mxSINGLE_CLASS,
mxREAL,
MX_GPU_INITIALIZE_VALUES);
Xi[i] = (float *)mxGPUGetData(mXi[i]);
}
//mexPrintf("local_TV_chambolle_init\n");
local_TV_chambolle_init( p_Img_new, Xi, dt, tau, M, N, O, Niter);
} else {
// mexPrintf("local_TV_init\n");
local_TV_init( p_Img_new, dt, tau, N, M, O, Niter);
}
checkLastError("After iteration");
//mexcuda -output utils3D\local_TV_mex utils3D\TV_cuda_texture.cu utils3D\local_TV_mex.cpp
plhs[0] = mxGPUCreateMxArrayOnGPU(m_Img_new);
mxGPUDestroyGPUArray(m_Img_new);
if (UseChambolle )
for( int i = 0; i < 3; i++)
mxGPUDestroyGPUArray( mXi[i]);
}
@@ -0,0 +1,141 @@
#include "mex.h"
#include "gpu/mxGPUArray.h"
#include "TV_texture.hpp"
/**
*
**-----------------------------------------------------------------------*
|                                                                       |
|  Except where otherwise noted, this work is licensed under a          |
|  Creative Commons Attribution-NonCommercial-ShareAlike 4.0            |
|  International (CC BY-NC-SA 4.0) license.                             |
|                                                                       |
|  Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch)    |
|                                                                       |
|      Author: CXS group, PSI  |
*-----------------------------------------------------------------------*
You may use this code with the following provisions:
If the code is fully or partially redistributed, or rewritten in another
computing language this notice should be included in the redistribution.
If this code, or subfunctions or parts of it, is used for research in a
publication or if it is fully or partially rewritten for another
computing language the authors and institution should be acknowledged
in written form in the publication: “Data processing was carried out
using the “cSAXS matlab package” developed by the CXS group,
Paul Scherrer Institut, Switzerland.”
Variations on the latter text can be incorporated upon discussion with
the CXS group if needed to more specifically reflect the use of the package
for the published work.
A publication that focuses on describing features, or parameters, that
are already existing in the code should be first discussed with the
authors.
This code and subroutines are part of a continuous development, they
are provided “as they are” without guarantees or liability on part
of PSI or the authors. It is the user responsibility to ensure its
*
*
* MEX gateway
*/
void mexFunction(int nlhs , mxArray *plhs[],
int nrhs, mxArray const *prhs[])
{
char const * const errId = "parallel:gpu:mexGPUExample:InvalidInput";
char const * const errMsg = "Invalid input to MEX file.";
// Initialize the MathWorks GPU API.
mxInitGPU();
if (nrhs!=10) {
mexPrintf("nargin\n");
mexErrMsgIdAndTxt(errId, errMsg);
}
// Im0,CloseInd,neighbours, dt, eps, lambda, Nclose, Rwin, Niter, Nx, Ny
mxGPUArray const * m_Img = mxGPUCreateFromMxArray(prhs[0]);
if ((mxGPUGetClassID(m_Img) != mxSINGLE_CLASS)) {
mexPrintf("m_Img\n");
mexErrMsgIdAndTxt(errId, errMsg);
}
const float * p_Img = (float *)mxGPUGetDataReadOnly(m_Img);
mxGPUArray const * m_CloseInd = mxGPUCreateFromMxArray(prhs[1]);
if ((mxGPUGetClassID(m_CloseInd) != mxUINT8_CLASS)) {
mexPrintf("m_CloseInd\n");
mexErrMsgIdAndTxt(errId, errMsg);
}
const uint8_T * p_CloseInd = (uint8_T *)mxGPUGetDataReadOnly(m_CloseInd);
mxGPUArray const * m_Nbrs = mxGPUCreateFromMxArray(prhs[2]);
if ((mxGPUGetClassID(m_Nbrs) != mxUINT8_CLASS)) {
mexPrintf("m_Nbrs\n");
mexErrMsgIdAndTxt(errId, errMsg);
}
const uint8_T * p_Nbrs = (uint8_T *)mxGPUGetDataReadOnly(m_Nbrs);
mxGPUArray const * mNbrs_weights = mxGPUCreateFromMxArray(prhs[3]);
if ((mxGPUGetClassID(mNbrs_weights) != mxSINGLE_CLASS)) {
mexPrintf("mNbrs_weights\n");
mexErrMsgIdAndTxt(errId, errMsg);
}
const float * p_Nbrs_weights = (float *)mxGPUGetDataReadOnly(mNbrs_weights);
const float dt = (float)mxGetScalar(prhs[4]);
const float eps = (float)mxGetScalar(prhs[5]);
const float lambda = (float)mxGetScalar(prhs[6]);
const int Nclose = (int)mxGetScalar(prhs[7]);
const int Rwin = (int)mxGetScalar(prhs[8]);
const int Niter = (int)mxGetScalar(prhs[9]);
const int Nnbrs = mxGetNumberOfElements(prhs[2]);
mwSize const * dimensions = mxGPUGetDimensions(m_Img);
mwSize Ndim = mxGPUGetNumberOfDimensions(m_Img);
int M = (int)dimensions[0];
int N = (int)dimensions[1];
int O = Ndim > 2 ? (int)dimensions[2] : 1;
/* allocate output image field */
mxGPUArray * m_Img_new = mxGPUCopyFromMxArray(prhs[0]);
float * p_Img_new = (float *)mxGPUGetData(m_Img_new);
// for(int i = 0; i < Nnbrs; i++)
// mexPrintf("neighbours %i\n", p_Nbrs[i]);
// for(int i = 0; i < Nnbrs; i++)
// mexPrintf("Nbrs_weights %g\n", p_Nbrs_weights[i]);
nonlocal_TV_init( p_Img_new, p_Img, p_CloseInd, p_Nbrs, p_Nbrs_weights, dt, eps,
lambda, Nclose, Nnbrs, Rwin, N, M, O, Niter);
checkLastError("After iteration");
plhs[0] = mxGPUCreateMxArrayOnGPU(m_Img_new);
mxGPUDestroyGPUArray(m_CloseInd);
mxGPUDestroyGPUArray(m_Img);
mxGPUDestroyGPUArray(m_Nbrs);
mxGPUDestroyGPUArray(m_Img_new);
mxGPUDestroyGPUArray(mNbrs_weights);
}
@@ -0,0 +1,131 @@
#include "mex.h"
#include "gpu/mxGPUArray.h"
#include "TV_texture.hpp"
/**
*
**-----------------------------------------------------------------------*
|                                                                       |
|  Except where otherwise noted, this work is licensed under a          |
|  Creative Commons Attribution-NonCommercial-ShareAlike 4.0            |
|  International (CC BY-NC-SA 4.0) license.                             |
|                                                                       |
|  Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch)    |
|                                                                       |
|      Author: CXS group, PSI  |
*-----------------------------------------------------------------------*
You may use this code with the following provisions:
If the code is fully or partially redistributed, or rewritten in another
computing language this notice should be included in the redistribution.
If this code, or subfunctions or parts of it, is used for research in a
publication or if it is fully or partially rewritten for another
computing language the authors and institution should be acknowledged
in written form in the publication: “Data processing was carried out
using the “cSAXS matlab package” developed by the CXS group,
Paul Scherrer Institut, Switzerland.”
Variations on the latter text can be incorporated upon discussion with
the CXS group if needed to more specifically reflect the use of the package
for the published work.
A publication that focuses on describing features, or parameters, that
are already existing in the code should be first discussed with the
authors.
This code and subroutines are part of a continuous development, they
are provided “as they are” without guarantees or liability on part
of PSI or the authors. It is the user responsibility to ensure its
*
*
* MEX gateway
*/
void mexFunction(int nlhs , mxArray *plhs[],
int nrhs, mxArray const *prhs[])
{
char const * const errId = "parallel:gpu:mexGPUExample:InvalidInput";
char const * const errMsg = "Invalid input to MEX file.";
// Initialize the MathWorks GPU API.
mxInitGPU();
if (nrhs!=7) {
mexPrintf("nargin\n");
mexErrMsgIdAndTxt(errId, errMsg);
}
mxGPUArray const * m_Img = mxGPUCreateFromMxArray(prhs[0]);
if ((mxGPUGetClassID(m_Img) != mxSINGLE_CLASS)) {
mexPrintf("m_Img\n");
mexErrMsgIdAndTxt(errId, errMsg);
}
const float * p_Img = (float *)mxGPUGetDataReadOnly(m_Img);
mxGPUArray const * m_Nbrs = mxGPUCreateFromMxArray(prhs[1]);
if ((mxGPUGetClassID(m_Nbrs) != mxUINT8_CLASS)) {
mexPrintf("m_Nbrs\n");
mexErrMsgIdAndTxt(errId, errMsg);
}
const uint8_T * p_Nbrs = (uint8_T *)mxGPUGetDataReadOnly(m_Nbrs);
const int Nclose = (int)mxGetScalar(prhs[2]);
const int Nclose_min = (int)mxGetScalar(prhs[3]);
const int Rwin = (int)mxGetScalar(prhs[4]);
const int Rpatch = (int)mxGetScalar(prhs[5]);
const float threshold = (float)mxGetScalar(prhs[6]);
//mexPrintf("thresh %3.5g \n ", threshold);
mwSize const * dimensions = mxGPUGetDimensions(m_Img);
mwSize const Ndim = mxGPUGetNumberOfDimensions(m_Img);
const int M = (int)dimensions[0];
const int N = (int)dimensions[1];
const int O = Ndim > 2 ? (int)dimensions[2] : 1;
// mexPrintf("%i %i %i \n ", M,N,O);
// mexPrintf("Nc %i Rw %i Rp%i \n ", Nclose, Rwin, Rpatch);
const int Nnbrs = mxGetNumberOfElements(prhs[1]);
/* allocate index of closest patches field */
mwSize matSize[4];
matSize[0] = M;
matSize[1] = N;
matSize[2] = O;
matSize[3] = Nclose;
mxGPUArray* m_CloseInd = mxGPUCreateGPUArray(4,
matSize,
mxUINT8_CLASS,
mxREAL,
MX_GPU_INITIALIZE_VALUES);
uint8_T * p_CloseInd = (uint8_T *)mxGPUGetData(m_CloseInd);
// mexPrintf("%i %i %i \n ", matSize[0], matSize[1], matSize[2]);
nonlocal_weight_TV_init( p_CloseInd, p_Img, p_Nbrs, Nclose,Nclose_min, Nnbrs, Rwin, Rpatch, N, M, O, threshold);
plhs[0] = mxGPUCreateMxArrayOnGPU(m_CloseInd);
mxGPUDestroyGPUArray(m_CloseInd);
mxGPUDestroyGPUArray(m_Img);
mxGPUDestroyGPUArray(m_Nbrs);
}