diff --git a/src/pyronn_torch/codegen.py b/src/pyronn_torch/codegen.py index 4e17c7690ed6203f348e477f14d9ab6a4c2679be..755ac01bf2204fa1c35e68d83b919671977a27c6 100644 --- a/src/pyronn_torch/codegen.py +++ b/src/pyronn_torch/codegen.py @@ -99,7 +99,8 @@ void Cone_Projection_Kernel_Tex_Interp_Launcher( const int volume_height, const int volume_depth, const float volume_spacing_x, const float volume_spacing_y, const float volume_spacing_z, const int detector_width, - const int detector_height, const float step_size);"""), # noqa + const int detector_height, const float step_size); +"""), # noqa 'Parallel_Projection2D_Kernel_Launcher': CustomFunctionCall('Parallel_Projection2D_Kernel_Launcher', FieldPointerSymbol(volume_slice.name, volume_slice.dtype, const=True), FieldPointerSymbol(projections_1d.name, projections_1d.dtype, const=False), @@ -183,6 +184,7 @@ def generate_shared_object(output_folder=None, source_files=None, show_code=Fals shared_object_file = module.compiled_file.replace('.cpp', '.so') copyfile(shared_object_file, join(output_folder, 'pyronn_torch.so')) + copyfile(module.compiled_file, join(output_folder, 'pyronn_torch.cpp')) def main(): diff --git a/src/pyronn_torch/pyronn_torch.cpp b/src/pyronn_torch/pyronn_torch.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ecad67e8dd2aad521726c36ef04c52fea7f46a7e --- /dev/null +++ b/src/pyronn_torch/pyronn_torch.cpp @@ -0,0 +1,208 @@ +#define RESTRICT __restrict__ + +//#if GOOGLE_CUDA +//#define EIGEN_USE_GPU +//#include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor" +//#endif + +#include <ATen/ATen.h> +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> +#include <torch/extension.h> + + +void Cone_Backprojection3D_Kernel_Launcher(const float *sinogram_ptr, float *out, const float *projection_matrices, const int number_of_projections, + const int volume_width, const int volume_height, const int volume_depth, + const float volume_spacing_x, const float volume_spacing_y, const float volume_spacing_z, + const float volume_origin_x, const float volume_origin_y, const float volume_origin_z, + const int detector_width, const int detector_height, const float projection_multiplier); + + +void Cone_Projection_Kernel_Launcher(const float* volume_ptr, float *out, const float *inv_AR_matrix, const float *src_points, + const int number_of_projections, const int volume_width, const int volume_height, const int volume_depth, + const float volume_spacing_x, const float volume_spacing_y, const float volume_spacing_z, + const int detector_width, const int detector_height, const float step_size); + + +void Cone_Projection_Kernel_Tex_Interp_Launcher( + const float *__restrict__ volume_ptr, float *out, + const float *inv_AR_matrix, const float *src_points, + const int number_of_projections, const int volume_width, + const int volume_height, const int volume_depth, + const float volume_spacing_x, const float volume_spacing_y, + const float volume_spacing_z, const int detector_width, + const int detector_height, const float step_size); + + +void Parallel_Backprojection2D_Kernel_Launcher(const float *sinogram_ptr, float *out, const float *ray_vectors, const int number_of_projections, + const int volume_width, const int volume_height, const float volume_spacing_x, const float volume_spacing_y, + const float volume_origin_x, const float volume_origin_y, + const int detector_size, const float detector_spacing, const float detector_origin); + + +void Parallel_Projection2D_Kernel_Launcher( + const float *volume_ptr, float *out, const float *ray_vectors, + const int number_of_projections, const int volume_width, + const int volume_height, const float volume_spacing_x, + const float volume_spacing_y, const float volume_origin_x, + const float volume_origin_y, const int detector_size, + const float detector_spacing, const float detector_origin); + +using namespace pybind11::literals; + + + + + +void call_Cone_Backprojection3D_Kernel_Launcher(at::Tensor& matrices, at::Tensor& projection, float projection_multiplier, at::Tensor& volume, float volume_origin_x, float volume_origin_y, float volume_origin_z, float volume_spacing_x, float volume_spacing_y, float volume_spacing_z) +{ + float * RESTRICT _data_volume = volume.data_ptr<float>(); + float * RESTRICT const _data_matrices = matrices.data_ptr<float>(); + float * RESTRICT const _data_projection = projection.data_ptr<float>(); + int64_t const _size_matrices_0 = matrices.size(0); + int64_t const _size_projection_1 = projection.size(1); + int64_t const _size_projection_2 = projection.size(2); + int64_t const _size_volume_0 = volume.size(0); + int64_t const _size_volume_1 = volume.size(1); + int64_t const _size_volume_2 = volume.size(2); + { + Cone_Backprojection3D_Kernel_Launcher(_data_matrices, + _data_projection, + _data_volume, + _size_matrices_0, + _size_projection_1, + _size_projection_2, + _size_volume_0, + _size_volume_1, + _size_volume_2, + projection_multiplier, + volume_origin_x, + volume_origin_y, + volume_origin_z, + volume_spacing_x, + volume_spacing_y, + volume_spacing_z); + } +} + +void call_Cone_Projection_Kernel_Launcher(at::Tensor& inv_matrices, at::Tensor& projection, at::Tensor& source_points, float step_size, at::Tensor& volume, float volume_spacing_x, float volume_spacing_y, float volume_spacing_z) +{ + float * RESTRICT _data_projection = projection.data_ptr<float>(); + float * RESTRICT const _data_inv_matrices = inv_matrices.data_ptr<float>(); + float * RESTRICT const _data_source_points = source_points.data_ptr<float>(); + float * RESTRICT const _data_volume = volume.data_ptr<float>(); + int64_t const _size_projection_1 = projection.size(1); + int64_t const _size_projection_2 = projection.size(2); + int64_t const _size_source_points_0 = source_points.size(0); + int64_t const _size_volume_0 = volume.size(0); + int64_t const _size_volume_1 = volume.size(1); + int64_t const _size_volume_2 = volume.size(2); + { + Cone_Projection_Kernel_Launcher(_data_inv_matrices, + _data_projection, + _data_source_points, + _data_volume, + _size_projection_1, + _size_projection_2, + _size_source_points_0, + _size_volume_0, + _size_volume_1, + _size_volume_2, + step_size, + volume_spacing_x, + volume_spacing_y, + volume_spacing_z); + } +} + +void call_Cone_Projection_Kernel_Tex_Interp_Launcher(at::Tensor& inv_matrices, at::Tensor& projection, at::Tensor& source_points, float step_size, at::Tensor& volume, float volume_spacing_x, float volume_spacing_y, float volume_spacing_z) +{ + float * RESTRICT _data_projection = projection.data_ptr<float>(); + float * RESTRICT const _data_inv_matrices = inv_matrices.data_ptr<float>(); + float * RESTRICT const _data_source_points = source_points.data_ptr<float>(); + float * RESTRICT const _data_volume = volume.data_ptr<float>(); + int64_t const _size_projection_1 = projection.size(1); + int64_t const _size_projection_2 = projection.size(2); + int64_t const _size_source_points_0 = source_points.size(0); + int64_t const _size_volume_0 = volume.size(0); + int64_t const _size_volume_1 = volume.size(1); + int64_t const _size_volume_2 = volume.size(2); + { + Cone_Projection_Kernel_Tex_Interp_Launcher(_data_inv_matrices, + _data_projection, + _data_source_points, + _data_volume, + _size_projection_1, + _size_projection_2, + _size_source_points_0, + _size_volume_0, + _size_volume_1, + _size_volume_2, + step_size, + volume_spacing_x, + volume_spacing_y, + volume_spacing_z); + } +} + +void call_Parallel_Projection2D_Kernel_Launcher(float detector_origin, float detector_spacing, at::Tensor& projections_1d, at::Tensor& ray_vectors, float volume_origin_x, float volume_origin_y, at::Tensor& volume_slice, float volume_spacing_x, float volume_spacing_y) +{ + float * RESTRICT _data_projections_1d = projections_1d.data_ptr<float>(); + float * RESTRICT const _data_ray_vectors = ray_vectors.data_ptr<float>(); + float * RESTRICT const _data_volume_slice = volume_slice.data_ptr<float>(); + int64_t const _size_projections_1d_1 = projections_1d.size(1); + int64_t const _size_ray_vectors_0 = ray_vectors.size(0); + int64_t const _size_volume_slice_0 = volume_slice.size(0); + int64_t const _size_volume_slice_1 = volume_slice.size(1); + { + Parallel_Projection2D_Kernel_Launcher(_data_projections_1d, + _data_ray_vectors, + _data_volume_slice, + _size_projections_1d_1, + _size_ray_vectors_0, + _size_volume_slice_0, + _size_volume_slice_1, + detector_origin, + detector_spacing, + volume_origin_x, + volume_origin_y, + volume_spacing_x, + volume_spacing_y); + } +} + +void call_Parallel_Backprojection2D_Kernel_Launcher(float detector_origin, float detector_spacing, at::Tensor& projections_1d, at::Tensor& ray_vectors, float volume_origin_x, float volume_origin_y, at::Tensor& volume_slice, float volume_spacing_x, float volume_spacing_y) +{ + float * RESTRICT _data_volume_slice = volume_slice.data_ptr<float>(); + float * RESTRICT const _data_projections_1d = projections_1d.data_ptr<float>(); + float * RESTRICT const _data_ray_vectors = ray_vectors.data_ptr<float>(); + int64_t const _size_projections_1d_1 = projections_1d.size(1); + int64_t const _size_ray_vectors_0 = ray_vectors.size(0); + int64_t const _size_volume_slice_0 = volume_slice.size(0); + int64_t const _size_volume_slice_1 = volume_slice.size(1); + { + Parallel_Backprojection2D_Kernel_Launcher(_data_projections_1d, + _data_ray_vectors, + _data_volume_slice, + _size_projections_1d_1, + _size_ray_vectors_0, + _size_volume_slice_0, + _size_volume_slice_1, + detector_origin, + detector_spacing, + volume_origin_x, + volume_origin_y, + volume_spacing_x, + volume_spacing_y); + } +} + + +PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) +{ + m.def("call_Cone_Backprojection3D_Kernel_Launcher", &call_Cone_Backprojection3D_Kernel_Launcher, "matrices"_a, "projection"_a, "projection_multiplier"_a, "volume"_a, "volume_origin_x"_a, "volume_origin_y"_a, "volume_origin_z"_a, "volume_spacing_x"_a, "volume_spacing_y"_a, "volume_spacing_z"_a); + m.def("call_Cone_Projection_Kernel_Launcher", &call_Cone_Projection_Kernel_Launcher, "inv_matrices"_a, "projection"_a, "source_points"_a, "step_size"_a, "volume"_a, "volume_spacing_x"_a, "volume_spacing_y"_a, "volume_spacing_z"_a); + m.def("call_Cone_Projection_Kernel_Tex_Interp_Launcher", &call_Cone_Projection_Kernel_Tex_Interp_Launcher, "inv_matrices"_a, "projection"_a, "source_points"_a, "step_size"_a, "volume"_a, "volume_spacing_x"_a, "volume_spacing_y"_a, "volume_spacing_z"_a); + m.def("call_Parallel_Projection2D_Kernel_Launcher", &call_Parallel_Projection2D_Kernel_Launcher, "detector_origin"_a, "detector_spacing"_a, "projections_1d"_a, "ray_vectors"_a, "volume_origin_x"_a, "volume_origin_y"_a, "volume_slice"_a, "volume_spacing_x"_a, "volume_spacing_y"_a); + m.def("call_Parallel_Backprojection2D_Kernel_Launcher", &call_Parallel_Backprojection2D_Kernel_Launcher, "detector_origin"_a, "detector_spacing"_a, "projections_1d"_a, "ray_vectors"_a, "volume_origin_x"_a, "volume_origin_y"_a, "volume_slice"_a, "volume_spacing_x"_a, "volume_spacing_y"_a); +} \ No newline at end of file