Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
tomotools
Nabu
Commits
811c42d3
Commit
811c42d3
authored
Jan 06, 2022
by
Pierre Paleo
Browse files
Add array normalization in CudaSinoNormalization
parent
c1e9b385
Changes
1
Hide whitespace changes
Inline
Side-by-side
nabu/reconstruction/sinogram_cuda.py
View file @
811c42d3
...
...
@@ -155,9 +155,9 @@ CudaSinoProcessing = deprecated_class(
class
CudaSinoNormalization
(
SinoNormalization
):
def
__init__
(
self
,
kind
=
"chebyshev"
,
sinos_shape
=
None
,
radios_shape
=
None
,
cuda_options
=
None
):
def
__init__
(
self
,
kind
=
"chebyshev"
,
sinos_shape
=
None
,
radios_shape
=
None
,
normalization_array
=
None
,
cuda_options
=
None
):
super
().
__init__
(
kind
=
kind
,
sinos_shape
=
sinos_shape
,
radios_shape
=
radios_shape
,
kind
=
kind
,
sinos_shape
=
sinos_shape
,
radios_shape
=
radios_shape
,
normalization_array
=
normalization_array
)
self
.
_get_shapes
(
sinos_shape
,
radios_shape
)
self
.
cuda_processing
=
CudaProcessing
(
**
(
cuda_options
or
{}))
...
...
@@ -166,41 +166,89 @@ class CudaSinoNormalization(SinoNormalization):
_get_shapes
=
SinoBuilder
.
_get_shapes
#
# Chebyshev normalization
#
def
_init_cuda_normalization
(
self
):
self
.
_cuda_kernel
=
CudaKernel
(
self
.
_get_norm_func_name
(),
filename
=
get_cuda_srcfile
(
"normalization.cu"
),
signature
=
"Piii"
,
)
self
.
_cuda_kernel_args
=
[
np
.
int32
(
self
.
n_x
),
np
.
int32
(
self
.
n_angles
),
np
.
int32
(
self
.
n_z
)
]
blk
=
(
1
,
64
,
16
)
# TODO tune ?
self
.
_cuda_kernel_kwargs
=
{
"block"
:
blk
,
"grid"
:
(
1
,
int
(
updiv
(
self
.
n_angles
,
blk
[
1
])),
int
(
updiv
(
self
.
n_z
,
blk
[
2
]))),
}
self
.
_d_tmp
=
garray
.
zeros
(
self
.
sinos_shape
[
-
2
:],
"f"
)
if
self
.
normalization_kind
==
"chebyshev"
:
self
.
_chebyshev_kernel
=
CudaKernel
(
self
.
_get_norm_func_name
(),
filename
=
get_cuda_srcfile
(
"normalization.cu"
),
signature
=
"Piii"
,
)
self
.
_chebyshev_kernel_args
=
[
np
.
int32
(
self
.
n_x
),
np
.
int32
(
self
.
n_angles
),
np
.
int32
(
self
.
n_z
)
]
blk
=
(
1
,
64
,
16
)
# TODO tune ?
self
.
_chebyshev_kernel_kwargs
=
{
"block"
:
blk
,
"grid"
:
(
1
,
int
(
updiv
(
self
.
n_angles
,
blk
[
1
])),
int
(
updiv
(
self
.
n_z
,
blk
[
2
]))),
}
return
elif
self
.
normalization_array
is
not
None
:
normalization_array
=
self
.
normalization_array
n_angles
,
n_x
=
self
.
sinos_shape
[
-
2
:]
# If normalization_array is 1D, make a 2D array by repeating the line
if
normalization_array
.
ndim
==
1
:
normalization_array
=
np
.
tile
(
normalization_array
,
(
n_angles
,
1
))
if
normalization_array
.
shape
!=
(
n_angles
,
n_x
):
raise
ValueError
(
"Expected normalization array to be of shape (n_angles, n_x) = (%d, %d)"
%
(
n_angles
,
n_x
)
)
self
.
_d_normalization_array
=
garray
.
to_gpu
(
normalization_array
.
astype
(
"f"
))
def
normalize
(
self
,
sinos
):
def
_
normalize
_chebyshev
(
self
,
sinos
):
if
sinos
.
flags
.
c_contiguous
:
self
.
_c
uda
_kernel
(
sinos
,
*
self
.
_c
uda
_kernel_args
,
**
self
.
_c
uda
_kernel_kwargs
self
.
_c
hebyshev
_kernel
(
sinos
,
*
self
.
_c
hebyshev
_kernel_args
,
**
self
.
_c
hebyshev
_kernel_kwargs
)
else
:
d_tmp
=
garray
.
zeros
(
sinos
.
shape
[
1
:],
"f"
)
# This kernel seems to have an issue on arrays that are not C-contiguous.
# We have to process image per image.
nz
=
np
.
int32
(
1
)
nthreadsperblock
=
(
1
,
32
,
1
)
# TODO tune
nblocks
=
(
1
,
int
(
updiv
(
self
.
n_angles
,
nthreadsperblock
[
1
])),
1
)
for
i
in
range
(
sinos
.
shape
[
0
]):
d_tmp
[:]
=
sinos
[
i
][:]
self
.
_c
uda
_kernel
(
d_tmp
,
self
.
_
d_tmp
[:]
=
sinos
[
i
][:]
self
.
_c
hebyshev
_kernel
(
self
.
_
d_tmp
,
np
.
int32
(
self
.
n_x
),
np
.
int32
(
self
.
n_angles
),
np
.
int32
(
1
),
grid
=
nblocks
,
block
=
nthreadsperblock
)
sinos
[
i
][:]
=
d_tmp
[:]
sinos
[
i
][:]
=
self
.
_
d_tmp
[:]
return
sinos
#
# Array subtraction
#
def
_normalize_subtract_array
(
self
,
sino
):
if
sino
.
ndim
==
2
:
# Things can go wrong if "sino" is a non-contiguous 2D array
# But this should be handled outside this function, as the processing is in-place
print
(
type
(
sino
))
print
(
sino
.
shape
)
print
(
sino
.
dtype
)
print
(
type
(
self
.
normalization_array
))
print
(
self
.
normalization_array
.
shape
)
print
(
self
.
normalization_array
.
dtype
)
sino
-=
self
.
_d_normalization_array
else
:
if
sino
.
flags
.
forc
:
# Contiguous 3D array. But pycuda wants the same shape for both operands.
for
i
in
range
(
sino
.
shape
[
0
]):
sino
[
i
]
-=
self
.
_d_normalization_array
else
:
# Non-contiguous 2D array. Make a temp. copy
for
i
in
range
(
sino
.
shape
[
0
]):
self
.
_d_tmp
[:]
=
sino
[
i
][:]
self
.
_d_tmp
-=
self
.
_d_normalization_array
sino
[
i
][:]
=
self
.
_d_tmp
[:]
return
sino
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment