summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWillem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>2017-01-26 14:57:57 +0100
committerWillem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>2017-02-08 14:39:01 +0100
commitd85a660f064e8130b27e11c7fd762221c754c315 (patch)
tree72382e8414c8dc51a7a7ef45845b4c61b25dfed9
parentebd5fe932fd2d6c4a516bc1cdc69e37aa4f5cf55 (diff)
downloadastra-d85a660f064e8130b27e11c7fd762221c754c315.tar.gz
astra-d85a660f064e8130b27e11c7fd762221c754c315.tar.bz2
astra-d85a660f064e8130b27e11c7fd762221c754c315.tar.xz
astra-d85a660f064e8130b27e11c7fd762221c754c315.zip
Start work on CFloat32Data3DGPU to allow persistent/external GPU memory
-rw-r--r--astra_vc14.vcxproj6
-rw-r--r--astra_vc14.vcxproj.filters18
-rw-r--r--build/linux/Makefile.in5
-rw-r--r--build/msvc/gen.py7
-rw-r--r--cuda/3d/mem3d.cu24
-rw-r--r--cuda/3d/mem3d.h5
-rw-r--r--include/astra/CompositeGeometryManager.h43
-rw-r--r--include/astra/CudaBackProjectionAlgorithm3D.h8
-rw-r--r--include/astra/CudaFDKAlgorithm3D.h8
-rw-r--r--include/astra/CudaForwardProjectionAlgorithm3D.h8
-rw-r--r--include/astra/Float32Data3D.h2
-rw-r--r--include/astra/Float32Data3DGPU.h108
-rw-r--r--include/astra/Float32ProjectionData3DGPU.h92
-rw-r--r--include/astra/Float32VolumeData3DGPU.h92
-rw-r--r--python/astra/PyIncludes.pxd48
-rw-r--r--python/astra/data3d.py8
-rw-r--r--python/astra/data3d_c.pyx53
-rw-r--r--python/astra/experimental.pyx24
-rw-r--r--python/astra/pythonutils.py18
-rw-r--r--src/CompositeGeometryManager.cpp260
-rw-r--r--src/CudaBackProjectionAlgorithm3D.cpp20
-rw-r--r--src/CudaFDKAlgorithm3D.cpp12
-rw-r--r--src/CudaForwardProjectionAlgorithm3D.cpp8
-rw-r--r--src/Float32Data3D.cpp6
-rw-r--r--src/Float32Data3DGPU.cpp98
-rw-r--r--src/Float32Data3DMemory.cpp2
-rw-r--r--src/Float32ProjectionData3DGPU.cpp71
-rw-r--r--src/Float32ProjectionData3DMemory.cpp2
-rw-r--r--src/Float32VolumeData3DGPU.cpp71
-rw-r--r--src/Float32VolumeData3DMemory.cpp2
30 files changed, 990 insertions, 139 deletions
diff --git a/astra_vc14.vcxproj b/astra_vc14.vcxproj
index a28bbfa..36d37ec 100644
--- a/astra_vc14.vcxproj
+++ b/astra_vc14.vcxproj
@@ -512,12 +512,15 @@
<ClCompile Include="src\Float32Data.cpp" />
<ClCompile Include="src\Float32Data2D.cpp" />
<ClCompile Include="src\Float32Data3D.cpp" />
+ <ClCompile Include="src\Float32Data3DGPU.cpp" />
<ClCompile Include="src\Float32Data3DMemory.cpp" />
<ClCompile Include="src\Float32ProjectionData2D.cpp" />
<ClCompile Include="src\Float32ProjectionData3D.cpp" />
+ <ClCompile Include="src\Float32ProjectionData3DGPU.cpp" />
<ClCompile Include="src\Float32ProjectionData3DMemory.cpp" />
<ClCompile Include="src\Float32VolumeData2D.cpp" />
<ClCompile Include="src\Float32VolumeData3D.cpp" />
+ <ClCompile Include="src\Float32VolumeData3DGPU.cpp" />
<ClCompile Include="src\Float32VolumeData3DMemory.cpp" />
<ClCompile Include="src\ForwardProjectionAlgorithm.cpp" />
<ClCompile Include="src\Fourier.cpp" />
@@ -624,12 +627,15 @@
<ClInclude Include="include\astra\Float32Data.h" />
<ClInclude Include="include\astra\Float32Data2D.h" />
<ClInclude Include="include\astra\Float32Data3D.h" />
+ <ClInclude Include="include\astra\Float32Data3DGPU.h" />
<ClInclude Include="include\astra\Float32Data3DMemory.h" />
<ClInclude Include="include\astra\Float32ProjectionData2D.h" />
<ClInclude Include="include\astra\Float32ProjectionData3D.h" />
+ <ClInclude Include="include\astra\Float32ProjectionData3DGPU.h" />
<ClInclude Include="include\astra\Float32ProjectionData3DMemory.h" />
<ClInclude Include="include\astra\Float32VolumeData2D.h" />
<ClInclude Include="include\astra\Float32VolumeData3D.h" />
+ <ClInclude Include="include\astra\Float32VolumeData3DGPU.h" />
<ClInclude Include="include\astra\Float32VolumeData3DMemory.h" />
<ClInclude Include="include\astra\ForwardProjectionAlgorithm.h" />
<ClInclude Include="include\astra\Fourier.h" />
diff --git a/astra_vc14.vcxproj.filters b/astra_vc14.vcxproj.filters
index dd7f574..591a4c7 100644
--- a/astra_vc14.vcxproj.filters
+++ b/astra_vc14.vcxproj.filters
@@ -321,6 +321,15 @@
<ClCompile Include="src\CudaSirtAlgorithm3D.cpp">
<Filter>CUDA\astra source</Filter>
</ClCompile>
+ <ClCompile Include="src\Float32Data3DGPU.cpp">
+ <Filter>CUDA\astra source</Filter>
+ </ClCompile>
+ <ClCompile Include="src\Float32ProjectionData3DGPU.cpp">
+ <Filter>CUDA\astra source</Filter>
+ </ClCompile>
+ <ClCompile Include="src\Float32VolumeData3DGPU.cpp">
+ <Filter>CUDA\astra source</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\astra\Algorithm.h">
@@ -581,6 +590,15 @@
<ClInclude Include="include\astra\CudaSirtAlgorithm3D.h">
<Filter>CUDA\astra headers</Filter>
</ClInclude>
+ <ClInclude Include="include\astra\Float32Data3DGPU.h">
+ <Filter>CUDA\astra headers</Filter>
+ </ClInclude>
+ <ClInclude Include="include\astra\Float32ProjectionData3DGPU.h">
+ <Filter>CUDA\astra headers</Filter>
+ </ClInclude>
+ <ClInclude Include="include\astra\Float32VolumeData3DGPU.h">
+ <Filter>CUDA\astra headers</Filter>
+ </ClInclude>
<ClInclude Include="cuda\2d\algo.h">
<Filter>CUDA\cuda headers</Filter>
</ClInclude>
diff --git a/build/linux/Makefile.in b/build/linux/Makefile.in
index 371b656..9066f0a 100644
--- a/build/linux/Makefile.in
+++ b/build/linux/Makefile.in
@@ -199,7 +199,10 @@ CUDA_CXX_OBJECTS=\
src/CudaFDKAlgorithm3D.lo \
src/CudaSirtAlgorithm3D.lo \
src/CudaBackProjectionAlgorithm3D.lo \
- src/CudaForwardProjectionAlgorithm3D.lo
+ src/CudaForwardProjectionAlgorithm3D.lo \
+ src/Float32Data3DGPU.lo \
+ src/Float32ProjectionData3DGPU.lo \
+ src/Float32VolumeData3DGPU.lo
CUDA_OBJECTS=\
cuda/2d/algo.lo \
diff --git a/build/msvc/gen.py b/build/msvc/gen.py
index 8a40c45..9c14ffe 100644
--- a/build/msvc/gen.py
+++ b/build/msvc/gen.py
@@ -274,6 +274,9 @@ P_astra["filters"]["CUDA\\astra source"] = [
"src\\CudaSartAlgorithm.cpp",
"src\\CudaSirtAlgorithm.cpp",
"src\\CudaSirtAlgorithm3D.cpp",
+"src\\Float32Data3DGPU.cpp",
+"src\\Float32ProjectionData3DGPU.cpp",
+"src\\Float32VolumeData3DGPU.cpp",
]
P_astra["filters"]["CUDA\\cuda headers"] = [
"4e17872e-db7d-41bc-9760-fad1c253b583",
@@ -411,7 +414,9 @@ P_astra["filters"]["CUDA\\astra headers"] = [
"include\\astra\\CudaSartAlgorithm.h",
"include\\astra\\CudaSirtAlgorithm.h",
"include\\astra\\CudaSirtAlgorithm3D.h",
-
+"include\\astra\\Float32Data3DGPU.h",
+"include\\astra\\Float32ProjectionData3DGPU.h",
+"include\\astra\\Float32VolumeData3DGPU.h",
]
P_astra["filters"]["Projectors\\inline"] = [
"0daffd63-ba49-4a5f-8d7a-5322e0e74f22",
diff --git a/cuda/3d/mem3d.cu b/cuda/3d/mem3d.cu
index 2b26fe1..97be8a4 100644
--- a/cuda/3d/mem3d.cu
+++ b/cuda/3d/mem3d.cu
@@ -118,6 +118,13 @@ MemHandle3D allocateGPUMemory(unsigned int x, unsigned int y, unsigned int z, Me
return ret;
}
+bool zeroGPUMemory(MemHandle3D handle, unsigned int x, unsigned int y, unsigned int z)
+{
+ SMemHandle3D_internal& hnd = *handle.d.get();
+ cudaError_t err = cudaMemset3D(hnd.ptr, 0, make_cudaExtent(sizeof(float)*x, y, z));
+ return err == cudaSuccess;
+}
+
bool freeGPUMemory(MemHandle3D handle)
{
size_t free = availableGPUMemory();
@@ -307,6 +314,23 @@ bool FDK(const astra::CProjectionGeometry3D* pProjGeom, MemHandle3D projData, co
}
+MemHandle3D wrapHandle(float *D_ptr, unsigned int x, unsigned int y, unsigned int z, unsigned int pitch)
+{
+ cudaPitchedPtr ptr;
+ ptr.ptr = D_ptr;
+ ptr.xsize = sizeof(float) * x;
+ ptr.pitch = sizeof(float) * pitch;
+ ptr.ysize = y;
+
+ SMemHandle3D_internal h;
+ h.ptr = ptr;
+
+ MemHandle3D hnd;
+ hnd.d = boost::shared_ptr<SMemHandle3D_internal>(new SMemHandle3D_internal);
+ *hnd.d = h;
+
+ return hnd;
+}
diff --git a/cuda/3d/mem3d.h b/cuda/3d/mem3d.h
index a0829e2..7a87ae6 100644
--- a/cuda/3d/mem3d.h
+++ b/cuda/3d/mem3d.h
@@ -80,6 +80,8 @@ enum Mem3DZeroMode {
size_t availableGPUMemory();
int maxBlockDimension();
+MemHandle3D wrapHandle(float *D_ptr, unsigned int x, unsigned int y, unsigned int z, unsigned int pitch);
+
MemHandle3D allocateGPUMemory(unsigned int x, unsigned int y, unsigned int z, Mem3DZeroMode zero);
bool copyToGPUMemory(const float *src, MemHandle3D dst, const SSubDimensions3D &pos);
@@ -88,6 +90,8 @@ bool copyFromGPUMemory(float *dst, MemHandle3D src, const SSubDimensions3D &pos)
bool freeGPUMemory(MemHandle3D handle);
+bool zeroGPUMemory(MemHandle3D handle, unsigned int x, unsigned int y, unsigned int z);
+
bool setGPUIndex(int index);
@@ -97,7 +101,6 @@ bool BP(const astra::CProjectionGeometry3D* pProjGeom, MemHandle3D projData, con
bool FDK(const astra::CProjectionGeometry3D* pProjGeom, MemHandle3D projData, const astra::CVolumeGeometry3D* pVolGeom, MemHandle3D volData, bool bShortScan, const float *pfFilter = 0);
-
}
#endif
diff --git a/include/astra/CompositeGeometryManager.h b/include/astra/CompositeGeometryManager.h
index c0acf4f..08eb7af 100644
--- a/include/astra/CompositeGeometryManager.h
+++ b/include/astra/CompositeGeometryManager.h
@@ -42,9 +42,9 @@ namespace astra {
class CCompositeVolume;
class CCompositeProjections;
-class CFloat32Data3DMemory;
-class CFloat32ProjectionData3DMemory;
-class CFloat32VolumeData3DMemory;
+class CFloat32Data3D;
+class CFloat32ProjectionData3D;
+class CFloat32VolumeData3D;
class CVolumeGeometry3D;
class CProjectionGeometry3D;
class CProjector3D;
@@ -77,7 +77,7 @@ public:
PART_VOL, PART_PROJ
} eType;
- CFloat32Data3DMemory* pData;
+ CFloat32Data3D* pData;
unsigned int subX;
unsigned int subY;
unsigned int subZ;
@@ -88,8 +88,11 @@ public:
virtual void splitY(TPartList& out, size_t maxSize, size_t maxDim, int div) = 0;
virtual void splitZ(TPartList& out, size_t maxSize, size_t maxDim, int div) = 0;
virtual CPart* reduce(const CPart *other) = 0;
- virtual void getDims(size_t &x, size_t &y, size_t &z) = 0;
- size_t getSize();
+ virtual void getDims(size_t &x, size_t &y, size_t &z) const = 0;
+ size_t getSize() const;
+
+ bool canSplitAndReduce() const;
+ bool isFull() const;
};
class CVolumePart : public CPart {
@@ -104,7 +107,7 @@ public:
virtual void splitY(TPartList& out, size_t maxSize, size_t maxDim, int div);
virtual void splitZ(TPartList& out, size_t maxSize, size_t maxDim, int div);
virtual CPart* reduce(const CPart *other);
- virtual void getDims(size_t &x, size_t &y, size_t &z);
+ virtual void getDims(size_t &x, size_t &y, size_t &z) const;
CVolumePart* clone() const;
};
@@ -120,7 +123,7 @@ public:
virtual void splitY(TPartList& out, size_t maxSize, size_t maxDim, int div);
virtual void splitZ(TPartList& out, size_t maxSize, size_t maxDim, int div);
virtual CPart* reduce(const CPart *other);
- virtual void getDims(size_t &x, size_t &y, size_t &z);
+ virtual void getDims(size_t &x, size_t &y, size_t &z) const;
CProjectionPart* clone() const;
};
@@ -150,23 +153,23 @@ public:
bool doJobs(TJobList &jobs);
SJob createJobFP(CProjector3D *pProjector,
- CFloat32VolumeData3DMemory *pVolData,
- CFloat32ProjectionData3DMemory *pProjData);
+ CFloat32VolumeData3D *pVolData,
+ CFloat32ProjectionData3D *pProjData);
SJob createJobBP(CProjector3D *pProjector,
- CFloat32VolumeData3DMemory *pVolData,
- CFloat32ProjectionData3DMemory *pProjData);
+ CFloat32VolumeData3D *pVolData,
+ CFloat32ProjectionData3D *pProjData);
// Convenience functions for creating and running a single FP or BP job
- bool doFP(CProjector3D *pProjector, CFloat32VolumeData3DMemory *pVolData,
- CFloat32ProjectionData3DMemory *pProjData);
- bool doBP(CProjector3D *pProjector, CFloat32VolumeData3DMemory *pVolData,
- CFloat32ProjectionData3DMemory *pProjData);
- bool doFDK(CProjector3D *pProjector, CFloat32VolumeData3DMemory *pVolData,
- CFloat32ProjectionData3DMemory *pProjData, bool bShortScan,
+ bool doFP(CProjector3D *pProjector, CFloat32VolumeData3D *pVolData,
+ CFloat32ProjectionData3D *pProjData);
+ bool doBP(CProjector3D *pProjector, CFloat32VolumeData3D *pVolData,
+ CFloat32ProjectionData3D *pProjData);
+ bool doFDK(CProjector3D *pProjector, CFloat32VolumeData3D *pVolData,
+ CFloat32ProjectionData3D *pProjData, bool bShortScan,
const float *pfFilter = 0);
- bool doFP(CProjector3D *pProjector, const std::vector<CFloat32VolumeData3DMemory *>& volData, const std::vector<CFloat32ProjectionData3DMemory *>& projData);
- bool doBP(CProjector3D *pProjector, const std::vector<CFloat32VolumeData3DMemory *>& volData, const std::vector<CFloat32ProjectionData3DMemory *>& projData);
+ bool doFP(CProjector3D *pProjector, const std::vector<CFloat32VolumeData3D *>& volData, const std::vector<CFloat32ProjectionData3D *>& projData);
+ bool doBP(CProjector3D *pProjector, const std::vector<CFloat32VolumeData3D *>& volData, const std::vector<CFloat32ProjectionData3D *>& projData);
void setGPUIndices(const std::vector<int>& GPUIndices);
diff --git a/include/astra/CudaBackProjectionAlgorithm3D.h b/include/astra/CudaBackProjectionAlgorithm3D.h
index 6738988..114d6f3 100644
--- a/include/astra/CudaBackProjectionAlgorithm3D.h
+++ b/include/astra/CudaBackProjectionAlgorithm3D.h
@@ -69,8 +69,8 @@ public:
* @param _pReconstruction VolumeData3D object for storing the reconstructed volume.
*/
CCudaBackProjectionAlgorithm3D(CProjector3D* _pProjector,
- CFloat32ProjectionData3DMemory* _pProjectionData,
- CFloat32VolumeData3DMemory* _pReconstruction);
+ CFloat32ProjectionData3D* _pProjectionData,
+ CFloat32VolumeData3D* _pReconstruction);
/** Copy constructor.
*/
@@ -99,8 +99,8 @@ public:
* @return initialization successful?
*/
bool initialize(CProjector3D* _pProjector,
- CFloat32ProjectionData3DMemory* _pSinogram,
- CFloat32VolumeData3DMemory* _pReconstruction);
+ CFloat32ProjectionData3D* _pSinogram,
+ CFloat32VolumeData3D* _pReconstruction);
/** Get all information parameters
*
diff --git a/include/astra/CudaFDKAlgorithm3D.h b/include/astra/CudaFDKAlgorithm3D.h
index 386129e..1c4c622 100644
--- a/include/astra/CudaFDKAlgorithm3D.h
+++ b/include/astra/CudaFDKAlgorithm3D.h
@@ -81,8 +81,8 @@ public:
* @param _pReconstruction VolumeData3D object for storing the reconstructed volume.
*/
CCudaFDKAlgorithm3D(CProjector3D* _pProjector,
- CFloat32ProjectionData3DMemory* _pProjectionData,
- CFloat32VolumeData3DMemory* _pReconstruction);
+ CFloat32ProjectionData3D* _pProjectionData,
+ CFloat32VolumeData3D* _pReconstruction);
/** Copy constructor.
*/
@@ -111,8 +111,8 @@ public:
* @return initialization successful?
*/
bool initialize(CProjector3D* _pProjector,
- CFloat32ProjectionData3DMemory* _pSinogram,
- CFloat32VolumeData3DMemory* _pReconstruction);
+ CFloat32ProjectionData3D* _pSinogram,
+ CFloat32VolumeData3D* _pReconstruction);
/** Get all information parameters
*
diff --git a/include/astra/CudaForwardProjectionAlgorithm3D.h b/include/astra/CudaForwardProjectionAlgorithm3D.h
index 95af73a..9dc889e 100644
--- a/include/astra/CudaForwardProjectionAlgorithm3D.h
+++ b/include/astra/CudaForwardProjectionAlgorithm3D.h
@@ -71,8 +71,8 @@ public:
* @return initialization successful?
*/
bool initialize(CProjector3D* _pProjector,
- CFloat32ProjectionData3DMemory* _pSinogram,
- CFloat32VolumeData3DMemory* _pReconstruction,
+ CFloat32ProjectionData3D* _pSinogram,
+ CFloat32VolumeData3D* _pReconstruction,
int _iGPUindex = -1, int _iDetectorSuperSampling = 1);
@@ -116,8 +116,8 @@ public:
protected:
CProjector3D* m_pProjector;
- CFloat32ProjectionData3DMemory* m_pProjections;
- CFloat32VolumeData3DMemory* m_pVolume;
+ CFloat32ProjectionData3D* m_pProjections;
+ CFloat32VolumeData3D* m_pVolume;
int m_iGPUIndex;
int m_iDetectorSuperSampling;
diff --git a/include/astra/Float32Data3D.h b/include/astra/Float32Data3D.h
index 2b3b88e..aca82ab 100644
--- a/include/astra/Float32Data3D.h
+++ b/include/astra/Float32Data3D.h
@@ -32,6 +32,8 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
#include "Float32Data.h"
#include "Float32Data2D.h"
+#include "../../cuda/3d/mem3d.h"
+
namespace astra {
/**
diff --git a/include/astra/Float32Data3DGPU.h b/include/astra/Float32Data3DGPU.h
new file mode 100644
index 0000000..0802105
--- /dev/null
+++ b/include/astra/Float32Data3DGPU.h
@@ -0,0 +1,108 @@
+/*
+-----------------------------------------------------------------------
+Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp
+ 2014-2015, CWI, Amsterdam
+
+Contact: astra@uantwerpen.be
+Website: http://sf.net/projects/astra-toolbox
+
+This file is part of the ASTRA Toolbox.
+
+
+The ASTRA Toolbox is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+The ASTRA Toolbox is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+#ifndef _INC_ASTRA_FLOAT32DATA3DGPU
+#define _INC_ASTRA_FLOAT32DATA3DGPU
+
+#ifdef ASTRA_CUDA
+
+#include "Globals.h"
+#include "Float32Data3D.h"
+
+#include "../../cuda/3d/mem3d.h"
+
+namespace astra {
+
+
+astraCUDA3d::MemHandle3D wrapHandle(float *D_ptr, unsigned int x, unsigned int y, unsigned int z, unsigned int pitch);
+
+
+/**
+ * This class represents a three-dimensional block of float32ing point data.
+ * The data block is stored on a GPU, and owned by external code.
+ *
+ * TODO: Store/remember which GPU the data is stored on
+ */
+class _AstraExport CFloat32Data3DGPU : public virtual CFloat32Data3D {
+
+protected:
+ /** Handle for the memory block */
+ astraCUDA3d::MemHandle3D m_hnd;
+
+ /** Clear all member variables, setting all numeric variables to 0 and all pointers to NULL.
+ */
+ void _clear();
+
+ /** Un-initialize the object, bringing it back in the unitialized state.
+ */
+ void _unInit();
+
+ /** Initialization. Initializes an instance of the CFloat32Data3DGPU class.
+ * Can only be called by derived classes.
+ *
+ * This function does not set m_bInitialized to true if everything is ok.
+ *
+ * @param _iWidth width of the 2D data (x-axis), must be > 0
+ * @param _iHeight height of the 2D data (y-axis), must be > 0
+ * @param _iDepth depth of the 2D data (z-axis), must be > 0
+ * @param _hnd the CUDA memory handle
+ */
+
+ bool _initialize(int _iWidth, int _iHeight, int _iDepth, astraCUDA3d::MemHandle3D _hnd);
+
+public:
+
+ /** Default constructor. Sets all numeric member variables to 0 and all pointer member variables to NULL.
+ *
+ * If an object is constructed using this default constructor, it must always be followed by a call
+ * to one of the initialize() methods before the object can be used. Any use before calling init() is not allowed,
+ * except calling the member function isInitialized().
+ *
+ */
+ CFloat32Data3DGPU();
+
+ /** Destructor.
+ */
+ virtual ~CFloat32Data3DGPU();
+
+ /** which type is this class?
+ *
+ * @return DataType: ASTRA_DATATYPE_FLOAT32_PROJECTION or
+ * ASTRA_DATATYPE_FLOAT32_VOLUME
+ */
+ virtual EDataType getType() const { return BASE; }
+
+ astraCUDA3d::MemHandle3D getHandle() const { return m_hnd; }
+
+};
+
+} // end namespace astra
+
+#endif
+
+#endif // _INC_ASTRA_FLOAT32DATA3DGPU
diff --git a/include/astra/Float32ProjectionData3DGPU.h b/include/astra/Float32ProjectionData3DGPU.h
new file mode 100644
index 0000000..135c718
--- /dev/null
+++ b/include/astra/Float32ProjectionData3DGPU.h
@@ -0,0 +1,92 @@
+/*
+-----------------------------------------------------------------------
+Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp
+ 2014-2015, CWI, Amsterdam
+
+Contact: astra@uantwerpen.be
+Website: http://sf.net/projects/astra-toolbox
+
+This file is part of the ASTRA Toolbox.
+
+
+The ASTRA Toolbox is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+The ASTRA Toolbox is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+#ifndef _INC_ASTRA_FLOAT32PROJECTIONDATA3DGPU
+#define _INC_ASTRA_FLOAT32PROJECTIONDATA3DGPU
+
+#include "Float32Data3DGPU.h"
+#include "ProjectionGeometry3D.h"
+#include "Float32ProjectionData3D.h"
+
+#ifdef ASTRA_CUDA
+
+namespace astra {
+
+/**
+ * This class represents three-dimensional Projection Data where the entire data block is stored in GPU memory.
+ */
+class _AstraExport CFloat32ProjectionData3DGPU : public CFloat32Data3DGPU, public CFloat32ProjectionData3D
+{
+public:
+
+ /** Default constructor. Sets all numeric member variables to 0 and all pointer member variables to NULL.
+ *
+ * If an object is constructed using this default constructor, it must always be followed by a call
+ * to one of the init() methods before the object can be used. Any use before calling init() is not allowed,
+ * except calling the member function isInitialized().
+ *
+ */
+ CFloat32ProjectionData3DGPU();
+
+ /** Construction.
+ *
+ * @param _pGeometry 3D volume geometry
+ * @param _hnd the CUDA memory handle
+ */
+
+ CFloat32ProjectionData3DGPU(CProjectionGeometry3D* _pGeometry, astraCUDA3d::MemHandle3D _hnd);
+
+ virtual ~CFloat32ProjectionData3DGPU();
+
+ /** Initialization.
+ *
+ * @param _pGeometry 3D volume geometry
+ * @param _hnd the CUDA memory handle
+ */
+
+ bool initialize(CProjectionGeometry3D* _pGeometry, astraCUDA3d::MemHandle3D _hnd);
+
+ /** Which type is this class?
+ *
+ * @return DataType: PROJECTION
+ */
+ virtual CFloat32Data3D::EDataType getType() const { return PROJECTION; }
+
+ /** Get the volume geometry.
+ *
+ * @return pointer to volume geometry.
+ */
+ CProjectionGeometry3D* getGeometry() const { ASTRA_ASSERT(m_bInitialized); return m_pGeometry; }
+
+};
+
+} // end namesProjection astra
+
+#endif
+
+#endif // _INC_ASTRA_FLOAT32PROJECTIONDATA3DGPU
diff --git a/include/astra/Float32VolumeData3DGPU.h b/include/astra/Float32VolumeData3DGPU.h
new file mode 100644
index 0000000..377ed75
--- /dev/null
+++ b/include/astra/Float32VolumeData3DGPU.h
@@ -0,0 +1,92 @@
+/*
+-----------------------------------------------------------------------
+Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp
+ 2014-2015, CWI, Amsterdam
+
+Contact: astra@uantwerpen.be
+Website: http://sf.net/projects/astra-toolbox
+
+This file is part of the ASTRA Toolbox.
+
+
+The ASTRA Toolbox is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+The ASTRA Toolbox is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+#ifndef _INC_ASTRA_FLOAT32VOLUMEDATA3DGPU
+#define _INC_ASTRA_FLOAT32VOLUMEDATA3DGPU
+
+#include "Float32Data3DGPU.h"
+#include "VolumeGeometry3D.h"
+#include "Float32VolumeData3D.h"
+
+#ifdef ASTRA_CUDA
+
+namespace astra {
+
+/**
+ * This class represents three-dimensional Volume Data where the entire data block is stored in GPU memory.
+ */
+class _AstraExport CFloat32VolumeData3DGPU : public CFloat32Data3DGPU, public CFloat32VolumeData3D
+{
+public:
+
+ /** Default constructor. Sets all numeric member variables to 0 and all pointer member variables to NULL.
+ *
+ * If an object is constructed using this default constructor, it must always be followed by a call
+ * to one of the init() methods before the object can be used. Any use before calling init() is not allowed,
+ * except calling the member function isInitialized().
+ *
+ */
+ CFloat32VolumeData3DGPU();
+
+ /** Construction.
+ *
+ * @param _pGeometry 3D volume geometry
+ * @param _hnd the CUDA memory handle
+ */
+
+ CFloat32VolumeData3DGPU(CVolumeGeometry3D* _pGeometry, astraCUDA3d::MemHandle3D _hnd);
+
+ virtual ~CFloat32VolumeData3DGPU();
+
+ /** Initialization.
+ *
+ * @param _pGeometry 3D volume geometry
+ * @param _hnd the CUDA memory handle
+ */
+
+ bool initialize(CVolumeGeometry3D* _pGeometry, astraCUDA3d::MemHandle3D _hnd);
+
+ /** Which type is this class?
+ *
+ * @return DataType: VOLUME
+ */
+ virtual CFloat32Data3D::EDataType getType() const { return VOLUME; }
+
+ /** Get the volume geometry.
+ *
+ * @return pointer to volume geometry.
+ */
+ CVolumeGeometry3D* getGeometry() const { ASTRA_ASSERT(m_bInitialized); return m_pGeometry; }
+
+};
+
+} // end namespace astra
+
+#endif
+
+#endif // _INC_ASTRA_FLOAT32VOLUMEDATA3DGPU
diff --git a/python/astra/PyIncludes.pxd b/python/astra/PyIncludes.pxd
index 39f9039..d5da17c 100644
--- a/python/astra/PyIncludes.pxd
+++ b/python/astra/PyIncludes.pxd
@@ -172,6 +172,13 @@ IF HAVE_CUDA==True:
cdef extern from "astra/CudaProjector2D.h" namespace "astra":
cdef cppclass CCudaProjector2D
+ cdef extern from "astra/Float32Data3DGPU.h" namespace "astraCUDA3d":
+ cdef cppclass MemHandle3D:
+ pass
+
+ cdef extern from "astra/Float32Data3DGPU.h" namespace "astraCUDA3d":
+ cdef MemHandle3D wrapHandle(float *D_ptr, unsigned int x, unsigned int y, unsigned int z, unsigned int pitch)
+
cdef extern from "astra/SparseMatrix.h" namespace "astra":
cdef cppclass CSparseMatrix:
@@ -184,14 +191,18 @@ cdef extern from "astra/SparseMatrix.h" namespace "astra":
unsigned int* m_piColIndices
unsigned long* m_plRowStarts
-cdef extern from "astra/Float32Data3DMemory.h" namespace "astra":
- cdef cppclass CFloat32Data3DMemory:
- CFloat32Data3DMemory()
+cdef extern from "astra/Float32Data3D.h" namespace "astra":
+ cdef cppclass CFloat32Data3D:
bool isInitialized()
int getSize()
int getWidth()
int getHeight()
int getDepth()
+
+
+cdef extern from "astra/Float32Data3DMemory.h" namespace "astra":
+ cdef cppclass CFloat32Data3DMemory(CFloat32Data3D):
+ CFloat32Data3DMemory()
void updateStatistics()
float32 *getData()
float32 ***getData3D()
@@ -228,8 +239,6 @@ cdef extern from "astra/Float32VolumeData3DMemory.h" namespace "astra":
int getSliceCount()
bool isInitialized()
-
-
cdef extern from "astra/ParallelProjectionGeometry3D.h" namespace "astra":
cdef cppclass CParallelProjectionGeometry3D:
CParallelProjectionGeometry3D()
@@ -260,12 +269,23 @@ cdef extern from "astra/Float32ProjectionData3DMemory.h" namespace "astra":
int getAngleCount()
bool isInitialized()
-cdef extern from "astra/Float32Data3D.h" namespace "astra":
- cdef cppclass CFloat32Data3D:
- CFloat32Data3D()
- bool isInitialized()
- int getSize()
- int getWidth()
- int getHeight()
- int getDepth()
- void updateStatistics()
+IF HAVE_CUDA==True:
+ cdef extern from "astra/Float32VolumeData3DGPU.h" namespace "astra":
+ cdef cppclass CFloat32VolumeData3DGPU:
+ CFloat32VolumeData3DGPU(CVolumeGeometry3D*, MemHandle3D)
+ CVolumeGeometry3D* getGeometry()
+ void changeGeometry(CVolumeGeometry3D*)
+ int getRowCount()
+ int getColCount()
+ int getSliceCount()
+ bool isInitialized()
+
+ cdef extern from "astra/Float32ProjectionData3DGPU.h" namespace "astra":
+ cdef cppclass CFloat32ProjectionData3DGPU:
+ CFloat32ProjectionData3DGPU(CProjectionGeometry3D*, MemHandle3D)
+ CProjectionGeometry3D* getGeometry()
+ void changeGeometry(CProjectionGeometry3D*)
+ int getRowCount()
+ int getColCount()
+ int getSliceCount()
+ bool isInitialized()
diff --git a/python/astra/data3d.py b/python/astra/data3d.py
index 9c2bea4..a825700 100644
--- a/python/astra/data3d.py
+++ b/python/astra/data3d.py
@@ -26,6 +26,8 @@
from . import data3d_c as d
import numpy as np
+from .pythonutils import GPULink
+
def create(datatype,geometry,data=None):
"""Create a 3D object.
@@ -52,11 +54,11 @@ def link(datatype, geometry, data):
:returns: :class:`int` -- the ID of the constructed object.
"""
- if not isinstance(data,np.ndarray):
+ if not isinstance(data,np.ndarray) and not isinstance(data,GPULink):
raise ValueError("Input should be a numpy array")
- if not data.dtype==np.float32:
+ if not isinstance(data,GPULink) and not data.dtype==np.float32:
raise ValueError("Numpy array should be float32")
- if not (data.flags['C_CONTIGUOUS'] and data.flags['ALIGNED']):
+ if not isinstance(data,GPULink) and not (data.flags['C_CONTIGUOUS'] and data.flags['ALIGNED']):
raise ValueError("Numpy array should be C_CONTIGUOUS and ALIGNED")
return d.create(datatype,geometry,data,True)
diff --git a/python/astra/data3d_c.pyx b/python/astra/data3d_c.pyx
index 3934f22..56247de 100644
--- a/python/astra/data3d_c.pyx
+++ b/python/astra/data3d_c.pyx
@@ -45,12 +45,17 @@ from .PyXMLDocument cimport XMLDocument
cimport utils
from .utils import wrap_from_bytes
-from .pythonutils import geom_size
+from .pythonutils import geom_size, GPULink
import operator
from six.moves import reduce
+include "config.pxi"
+
+cdef extern from "Python.h":
+ void* PyLong_AsVoidPtr(object)
+
cdef CData3DManager * man3d = <CData3DManager * >PyData3DManager.getSingletonPtr()
@@ -65,12 +70,19 @@ def create(datatype,geometry,data=None, link=False):
cdef Config *cfg
cdef CVolumeGeometry3D * pGeometry
cdef CProjectionGeometry3D * ppGeometry
- cdef CFloat32Data3DMemory * pDataObject3D
+ cdef CFloat32Data3D * pDataObject3D
cdef CConeProjectionGeometry3D* pppGeometry
- cdef CFloat32CustomMemory * pCustom
-
- if link and data.shape!=geom_size(geometry):
- raise Exception("The dimensions of the data do not match those specified in the geometry.")
+ cdef CFloat32CustomMemory * pCustom = NULL
+ IF HAVE_CUDA==True:
+ cdef MemHandle3D hnd
+
+ if link:
+ if isinstance(data, GPULink):
+ s = geom_size(geometry)
+ if geom_size(geometry) != ( data.z, data.y, data.x ):
+ raise Exception("The dimensions of the data do not match those specified in the geometry.")
+ elif data.shape!=geom_size(geometry):
+ raise Exception("The dimensions of the data do not match those specified in the geometry.")
if datatype == '-vol':
cfg = utils.dictToConfig(six.b('VolumeGeometry'), geometry)
@@ -80,10 +92,18 @@ def create(datatype,geometry,data=None, link=False):
del pGeometry
raise Exception('Geometry class not initialized.')
if link:
- pCustom = <CFloat32CustomMemory*> new CFloat32CustomPython(data)
- pDataObject3D = <CFloat32Data3DMemory * > new CFloat32VolumeData3DMemory(pGeometry, pCustom)
+ if isinstance(data, GPULink):
+ IF HAVE_CUDA==True:
+ s = geom_size(geometry)
+ hnd = wrapHandle(<float*>PyLong_AsVoidPtr(data.ptr), data.x, data.y, data.z, data.pitch/4)
+ pDataObject3D = <CFloat32Data3D * > new CFloat32VolumeData3DGPU(pGeometry, hnd)
+ ELSE:
+ raise NotImplementedError("CUDA support is not enabled in ASTRA")
+ else:
+ pCustom = <CFloat32CustomMemory*> new CFloat32CustomPython(data)
+ pDataObject3D = <CFloat32Data3D * > new CFloat32VolumeData3DMemory(pGeometry, pCustom)
else:
- pDataObject3D = <CFloat32Data3DMemory * > new CFloat32VolumeData3DMemory(pGeometry)
+ pDataObject3D = <CFloat32Data3D * > new CFloat32VolumeData3DMemory(pGeometry)
del cfg
del pGeometry
elif datatype == '-sino' or datatype == '-proj3d' or datatype == '-sinocone':
@@ -105,8 +125,16 @@ def create(datatype,geometry,data=None, link=False):
del ppGeometry
raise Exception('Geometry class not initialized.')
if link:
- pCustom = <CFloat32CustomMemory*> new CFloat32CustomPython(data)
- pDataObject3D = <CFloat32Data3DMemory * > new CFloat32ProjectionData3DMemory(ppGeometry, pCustom)
+ if isinstance(data, GPULink):
+ IF HAVE_CUDA==True:
+ s = geom_size(geometry)
+ hnd = wrapHandle(<float*>PyLong_AsVoidPtr(data.ptr), data.x, data.y, data.z, data.pitch/4)
+ pDataObject3D = <CFloat32Data3D * > new CFloat32ProjectionData3DGPU(ppGeometry, hnd)
+ ELSE:
+ raise NotImplementedError("CUDA support is not enabled in ASTRA")
+ else:
+ pCustom = <CFloat32CustomMemory*> new CFloat32CustomPython(data)
+ pDataObject3D = <CFloat32Data3D * > new CFloat32ProjectionData3DMemory(ppGeometry, pCustom)
else:
pDataObject3D = <CFloat32Data3DMemory * > new CFloat32ProjectionData3DMemory(ppGeometry)
del ppGeometry
@@ -118,8 +146,7 @@ def create(datatype,geometry,data=None, link=False):
del pDataObject3D
raise Exception("Couldn't initialize data object.")
- if not link: fillDataObject(pDataObject3D, data)
-
+ if not link: fillDataObject(dynamic_cast_mem(pDataObject3D), data)
return man3d.store(<CFloat32Data3D*>pDataObject3D)
diff --git a/python/astra/experimental.pyx b/python/astra/experimental.pyx
index b6c7881..0af3118 100644
--- a/python/astra/experimental.pyx
+++ b/python/astra/experimental.pyx
@@ -36,12 +36,20 @@ IF HAVE_CUDA==True:
cdef extern from "astra/CompositeGeometryManager.h" namespace "astra":
cdef cppclass CCompositeGeometryManager:
- bool doFP(CProjector3D *, vector[CFloat32VolumeData3DMemory *], vector[CFloat32ProjectionData3DMemory *])
- bool doBP(CProjector3D *, vector[CFloat32VolumeData3DMemory *], vector[CFloat32ProjectionData3DMemory *])
+ bool doFP(CProjector3D *, vector[CFloat32VolumeData3D *], vector[CFloat32ProjectionData3D *])
+ bool doBP(CProjector3D *, vector[CFloat32VolumeData3D *], vector[CFloat32ProjectionData3D *])
cdef extern from *:
- CFloat32VolumeData3DMemory * dynamic_cast_vol_mem "dynamic_cast<astra::CFloat32VolumeData3DMemory*>" (CFloat32Data3D * ) except NULL
- CFloat32ProjectionData3DMemory * dynamic_cast_proj_mem "dynamic_cast<astra::CFloat32ProjectionData3DMemory*>" (CFloat32Data3D * ) except NULL
+ CFloat32VolumeData3D * dynamic_cast_vol_mem "dynamic_cast<astra::CFloat32VolumeData3D*>" (CFloat32Data3D * ) except NULL
+ CFloat32ProjectionData3D * dynamic_cast_proj_mem "dynamic_cast<astra::CFloat32ProjectionData3D*>" (CFloat32Data3D * ) except NULL
+
+ cdef extern from "astra/Float32ProjectionData3D.h" namespace "astra":
+ cdef cppclass CFloat32ProjectionData3D:
+ bool isInitialized()
+ cdef extern from "astra/Float32VolumeData3D.h" namespace "astra":
+ cdef cppclass CFloat32VolumeData3D:
+ bool isInitialized()
+
cimport PyProjector3DManager
from .PyProjector3DManager cimport CProjector3DManager
@@ -52,9 +60,9 @@ IF HAVE_CUDA==True:
cdef CData3DManager * man3d = <CData3DManager * >PyData3DManager.getSingletonPtr()
def do_composite(projector_id, vol_ids, proj_ids, t):
- cdef vector[CFloat32VolumeData3DMemory *] vol
- cdef CFloat32VolumeData3DMemory * pVolObject
- cdef CFloat32ProjectionData3DMemory * pProjObject
+ cdef vector[CFloat32VolumeData3D *] vol
+ cdef CFloat32VolumeData3D * pVolObject
+ cdef CFloat32ProjectionData3D * pProjObject
for v in vol_ids:
pVolObject = dynamic_cast_vol_mem(man3d.get(v))
if pVolObject == NULL:
@@ -62,7 +70,7 @@ IF HAVE_CUDA==True:
if not pVolObject.isInitialized():
raise Exception("Data object not initialized properly")
vol.push_back(pVolObject)
- cdef vector[CFloat32ProjectionData3DMemory *] proj
+ cdef vector[CFloat32ProjectionData3D *] proj
for v in proj_ids:
pProjObject = dynamic_cast_proj_mem(man3d.get(v))
if pProjObject == NULL:
diff --git a/python/astra/pythonutils.py b/python/astra/pythonutils.py
index 3bd3321..27fa8fd 100644
--- a/python/astra/pythonutils.py
+++ b/python/astra/pythonutils.py
@@ -61,3 +61,21 @@ def geom_size(geom, dim=None):
s = s[dim]
return s
+
+class GPULink(object):
+ """Utility class for astra.data3d.link with a CUDA pointer
+
+ The CUDA pointer ptr must point to an array of floats.
+
+ x is the fastest-changing coordinate, z the slowest-changing.
+
+ pitch is the width in bytes of the memory block. For a contiguous
+ memory block, pitch is equal to sizeof(float) * x. For a memory block
+ allocated by cudaMalloc3D, pitch is the pitch as returned by cudaMalloc3D.
+ """
+ def __init__(self, ptr, x, y, z, pitch):
+ self.ptr = ptr
+ self.x = x
+ self.y = y
+ self.z = z
+ self.pitch = pitch
diff --git a/src/CompositeGeometryManager.cpp b/src/CompositeGeometryManager.cpp
index c3af228..74466db 100644
--- a/src/CompositeGeometryManager.cpp
+++ b/src/CompositeGeometryManager.cpp
@@ -39,6 +39,8 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
#include "astra/CudaProjector3D.h"
#include "astra/Float32ProjectionData3DMemory.h"
#include "astra/Float32VolumeData3DMemory.h"
+#include "astra/Float32ProjectionData3DGPU.h"
+#include "astra/Float32VolumeData3DGPU.h"
#include "astra/Logging.h"
#include "../cuda/3d/mem3d.h"
@@ -97,6 +99,127 @@ CCompositeGeometryManager::CCompositeGeometryManager()
// (First approach: 0.5/0.5)
+
+
+
+class _AstraExport CFloat32CustomGPUMemory {
+public:
+ astraCUDA3d::MemHandle3D hnd; // Only required to be valid between allocate/free
+ virtual bool allocateGPUMemory(unsigned int x, unsigned int y, unsigned int z, astraCUDA3d::Mem3DZeroMode zero)=0;
+ virtual bool copyToGPUMemory(const astraCUDA3d::SSubDimensions3D &pos)=0;
+ virtual bool copyFromGPUMemory(const astraCUDA3d::SSubDimensions3D &pos)=0;
+ virtual bool freeGPUMemory()=0;
+ virtual ~CFloat32CustomGPUMemory() { }
+};
+
+class CFloat32ExistingGPUMemory : public astra::CFloat32CustomGPUMemory {
+public:
+ CFloat32ExistingGPUMemory(CFloat32Data3DGPU *d);
+ virtual bool allocateGPUMemory(unsigned int x, unsigned int y, unsigned int z, astraCUDA3d::Mem3DZeroMode zero);
+ virtual bool copyToGPUMemory(const astraCUDA3d::SSubDimensions3D &pos);
+ virtual bool copyFromGPUMemory(const astraCUDA3d::SSubDimensions3D &pos);
+ virtual bool freeGPUMemory();
+
+protected:
+ unsigned int x, y, z;
+};
+
+class CFloat32DefaultGPUMemory : public astra::CFloat32CustomGPUMemory {
+public:
+ CFloat32DefaultGPUMemory(CFloat32Data3DMemory* d) {
+ ptr = d->getData();
+ }
+ virtual bool allocateGPUMemory(unsigned int x, unsigned int y, unsigned int z, astraCUDA3d::Mem3DZeroMode zero) {
+ hnd = astraCUDA3d::allocateGPUMemory(x, y, z, zero);
+ return (bool)hnd;
+ }
+ virtual bool copyToGPUMemory(const astraCUDA3d::SSubDimensions3D &pos) {
+ return astraCUDA3d::copyToGPUMemory(ptr, hnd, pos);
+ }
+ virtual bool copyFromGPUMemory(const astraCUDA3d::SSubDimensions3D &pos) {
+ return astraCUDA3d::copyFromGPUMemory(ptr, hnd, pos);
+ }
+ virtual bool freeGPUMemory() {
+ return astraCUDA3d::freeGPUMemory(hnd);
+ }
+
+protected:
+ float *ptr;
+};
+
+
+
+CFloat32ExistingGPUMemory::CFloat32ExistingGPUMemory(CFloat32Data3DGPU *d)
+{
+ hnd = d->getHandle();
+ x = d->getWidth();
+ y = d->getHeight();
+ z = d->getDepth();
+}
+
+bool CFloat32ExistingGPUMemory::allocateGPUMemory(unsigned int x_, unsigned int y_, unsigned int z_, astraCUDA3d::Mem3DZeroMode zero) {
+ assert(x_ == x);
+ assert(y_ == y);
+ assert(z_ == z);
+
+ if (zero == astraCUDA3d::INIT_ZERO)
+ return astraCUDA3d::zeroGPUMemory(hnd, x, y, z);
+ else
+ return true;
+}
+bool CFloat32ExistingGPUMemory::copyToGPUMemory(const astraCUDA3d::SSubDimensions3D &pos) {
+ assert(pos.nx == x);
+ assert(pos.ny == y);
+ assert(pos.nz == z);
+ assert(pos.pitch == x);
+ assert(pos.subx == 0);
+ assert(pos.suby == 0);
+ assert(pos.subnx == x);
+ assert(pos.subny == y);
+
+ // These are less necessary than x/y, but allowing access to
+ // subvolumes needs an interface change
+ assert(pos.subz == 0);
+ assert(pos.subnz == z);
+
+ return true;
+}
+bool CFloat32ExistingGPUMemory::copyFromGPUMemory(const astraCUDA3d::SSubDimensions3D &pos) {
+ assert(pos.nx == x);
+ assert(pos.ny == y);
+ assert(pos.nz == z);
+ assert(pos.pitch == x);
+ assert(pos.subx == 0);
+ assert(pos.suby == 0);
+ assert(pos.subnx == x);
+ assert(pos.subny == y);
+
+ // These are less necessary than x/y, but allowing access to
+ // subvolumes needs an interface change
+ assert(pos.subz == 0);
+ assert(pos.subnz == z);
+
+ return true;
+}
+bool CFloat32ExistingGPUMemory::freeGPUMemory() {
+ return true;
+}
+
+
+CFloat32CustomGPUMemory * createGPUMemoryHandler(CFloat32Data3D *d) {
+ CFloat32Data3DMemory *dMem = dynamic_cast<CFloat32Data3DMemory*>(d);
+ CFloat32Data3DGPU *dGPU = dynamic_cast<CFloat32Data3DGPU*>(d);
+
+ if (dMem)
+ return new CFloat32DefaultGPUMemory(dMem);
+ else
+ return new CFloat32ExistingGPUMemory(dGPU);
+}
+
+
+
+
+
bool CCompositeGeometryManager::splitJobs(TJobSet &jobs, size_t maxSize, int div, TJobSet &split)
{
int maxBlockDim = astraCUDA3d::maxBlockDimension();
@@ -280,7 +403,7 @@ CCompositeGeometryManager::CVolumePart::~CVolumePart()
delete pGeom;
}
-void CCompositeGeometryManager::CVolumePart::getDims(size_t &x, size_t &y, size_t &z)
+void CCompositeGeometryManager::CVolumePart::getDims(size_t &x, size_t &y, size_t &z) const
{
if (!pGeom) {
x = y = z = 0;
@@ -292,13 +415,28 @@ void CCompositeGeometryManager::CVolumePart::getDims(size_t &x, size_t &y, size_
z = pGeom->getGridSliceCount();
}
-size_t CCompositeGeometryManager::CPart::getSize()
+size_t CCompositeGeometryManager::CPart::getSize() const
{
size_t x, y, z;
getDims(x, y, z);
return x * y * z;
}
+bool CCompositeGeometryManager::CPart::isFull() const
+{
+ size_t x, y, z;
+ getDims(x, y, z);
+ return x == pData->getWidth() &&
+ y == pData->getHeight() &&
+ z == pData->getDepth();
+}
+
+bool CCompositeGeometryManager::CPart::canSplitAndReduce() const
+{
+ return dynamic_cast<CFloat32Data3DMemory *>(pData) != 0;
+}
+
+
static bool testVolumeRange(const std::pair<double, double>& fullRange,
const CVolumeGeometry3D *pVolGeom,
@@ -334,6 +472,9 @@ static bool testVolumeRange(const std::pair<double, double>& fullRange,
CCompositeGeometryManager::CPart* CCompositeGeometryManager::CVolumePart::reduce(const CPart *_other)
{
+ if (!canSplitAndReduce())
+ return clone();
+
const CProjectionPart *other = dynamic_cast<const CProjectionPart *>(_other);
assert(other);
@@ -654,7 +795,7 @@ static CProjectionGeometry3D* getSubProjectionGeometryV(const CProjectionGeometr
// - maybe all approximately the same size?
void CCompositeGeometryManager::CVolumePart::splitX(CCompositeGeometryManager::TPartList& out, size_t maxSize, size_t maxDim, int div)
{
- if (true) {
+ if (canSplitAndReduce()) {
// Split in vertical direction only at first, until we figure out
// a model for splitting in other directions
@@ -698,12 +839,14 @@ void CCompositeGeometryManager::CVolumePart::splitX(CCompositeGeometryManager::T
out.push_back(boost::shared_ptr<CPart>(sub));
}
+ } else {
+ out.push_back(boost::shared_ptr<CPart>(clone()));
}
}
void CCompositeGeometryManager::CVolumePart::splitY(CCompositeGeometryManager::TPartList& out, size_t maxSize, size_t maxDim, int div)
{
- if (true) {
+ if (canSplitAndReduce()) {
// Split in vertical direction only at first, until we figure out
// a model for splitting in other directions
@@ -747,12 +890,14 @@ void CCompositeGeometryManager::CVolumePart::splitY(CCompositeGeometryManager::T
out.push_back(boost::shared_ptr<CPart>(sub));
}
+ } else {
+ out.push_back(boost::shared_ptr<CPart>(clone()));
}
}
void CCompositeGeometryManager::CVolumePart::splitZ(CCompositeGeometryManager::TPartList& out, size_t maxSize, size_t maxDim, int div)
{
- if (true) {
+ if (canSplitAndReduce()) {
// Split in vertical direction only at first, until we figure out
// a model for splitting in other directions
@@ -796,6 +941,8 @@ void CCompositeGeometryManager::CVolumePart::splitZ(CCompositeGeometryManager::T
out.push_back(boost::shared_ptr<CPart>(sub));
}
+ } else {
+ out.push_back(boost::shared_ptr<CPart>(clone()));
}
}
@@ -815,7 +962,7 @@ CCompositeGeometryManager::CProjectionPart::~CProjectionPart()
delete pGeom;
}
-void CCompositeGeometryManager::CProjectionPart::getDims(size_t &x, size_t &y, size_t &z)
+void CCompositeGeometryManager::CProjectionPart::getDims(size_t &x, size_t &y, size_t &z) const
{
if (!pGeom) {
x = y = z = 0;
@@ -831,6 +978,9 @@ void CCompositeGeometryManager::CProjectionPart::getDims(size_t &x, size_t &y, s
CCompositeGeometryManager::CPart* CCompositeGeometryManager::CProjectionPart::reduce(const CPart *_other)
{
+ if (!canSplitAndReduce())
+ return clone();
+
const CVolumePart *other = dynamic_cast<const CVolumePart *>(_other);
assert(other);
@@ -868,7 +1018,7 @@ CCompositeGeometryManager::CPart* CCompositeGeometryManager::CProjectionPart::re
void CCompositeGeometryManager::CProjectionPart::splitX(CCompositeGeometryManager::TPartList &out, size_t maxSize, size_t maxDim, int div)
{
- if (true) {
+ if (canSplitAndReduce()) {
// Split in vertical direction only at first, until we figure out
// a model for splitting in other directions
@@ -903,6 +1053,8 @@ void CCompositeGeometryManager::CProjectionPart::splitX(CCompositeGeometryManage
out.push_back(boost::shared_ptr<CPart>(sub));
}
+ } else {
+ out.push_back(boost::shared_ptr<CPart>(clone()));
}
}
@@ -914,7 +1066,7 @@ void CCompositeGeometryManager::CProjectionPart::splitY(CCompositeGeometryManage
void CCompositeGeometryManager::CProjectionPart::splitZ(CCompositeGeometryManager::TPartList &out, size_t maxSize, size_t maxDim, int div)
{
- if (true) {
+ if (canSplitAndReduce()) {
// Split in vertical direction only at first, until we figure out
// a model for splitting in other directions
@@ -949,6 +1101,8 @@ void CCompositeGeometryManager::CProjectionPart::splitZ(CCompositeGeometryManage
out.push_back(boost::shared_ptr<CPart>(sub));
}
+ } else {
+ out.push_back(boost::shared_ptr<CPart>(clone()));
}
}
@@ -959,8 +1113,8 @@ CCompositeGeometryManager::CProjectionPart* CCompositeGeometryManager::CProjecti
}
CCompositeGeometryManager::SJob CCompositeGeometryManager::createJobFP(CProjector3D *pProjector,
- CFloat32VolumeData3DMemory *pVolData,
- CFloat32ProjectionData3DMemory *pProjData)
+ CFloat32VolumeData3D *pVolData,
+ CFloat32ProjectionData3D *pProjData)
{
ASTRA_DEBUG("CCompositeGeometryManager::createJobFP");
// Create single job for FP
@@ -992,8 +1146,8 @@ CCompositeGeometryManager::SJob CCompositeGeometryManager::createJobFP(CProjecto
}
CCompositeGeometryManager::SJob CCompositeGeometryManager::createJobBP(CProjector3D *pProjector,
- CFloat32VolumeData3DMemory *pVolData,
- CFloat32ProjectionData3DMemory *pProjData)
+ CFloat32VolumeData3D *pVolData,
+ CFloat32ProjectionData3D *pProjData)
{
ASTRA_DEBUG("CCompositeGeometryManager::createJobBP");
// Create single job for BP
@@ -1022,8 +1176,8 @@ CCompositeGeometryManager::SJob CCompositeGeometryManager::createJobBP(CProjecto
return BP;
}
-bool CCompositeGeometryManager::doFP(CProjector3D *pProjector, CFloat32VolumeData3DMemory *pVolData,
- CFloat32ProjectionData3DMemory *pProjData)
+bool CCompositeGeometryManager::doFP(CProjector3D *pProjector, CFloat32VolumeData3D *pVolData,
+ CFloat32ProjectionData3D *pProjData)
{
TJobList L;
L.push_back(createJobFP(pProjector, pVolData, pProjData));
@@ -1031,8 +1185,8 @@ bool CCompositeGeometryManager::doFP(CProjector3D *pProjector, CFloat32VolumeDat
return doJobs(L);
}
-bool CCompositeGeometryManager::doBP(CProjector3D *pProjector, CFloat32VolumeData3DMemory *pVolData,
- CFloat32ProjectionData3DMemory *pProjData)
+bool CCompositeGeometryManager::doBP(CProjector3D *pProjector, CFloat32VolumeData3D *pVolData,
+ CFloat32ProjectionData3D *pProjData)
{
TJobList L;
L.push_back(createJobBP(pProjector, pVolData, pProjData));
@@ -1041,8 +1195,8 @@ bool CCompositeGeometryManager::doBP(CProjector3D *pProjector, CFloat32VolumeDat
}
-bool CCompositeGeometryManager::doFDK(CProjector3D *pProjector, CFloat32VolumeData3DMemory *pVolData,
- CFloat32ProjectionData3DMemory *pProjData, bool bShortScan,
+bool CCompositeGeometryManager::doFDK(CProjector3D *pProjector, CFloat32VolumeData3D *pVolData,
+ CFloat32ProjectionData3D *pProjData, bool bShortScan,
const float *pfFilter)
{
if (!dynamic_cast<CConeProjectionGeometry3D*>(pProjData->getGeometry())) {
@@ -1061,11 +1215,11 @@ bool CCompositeGeometryManager::doFDK(CProjector3D *pProjector, CFloat32VolumeDa
return doJobs(L);
}
-bool CCompositeGeometryManager::doFP(CProjector3D *pProjector, const std::vector<CFloat32VolumeData3DMemory *>& volData, const std::vector<CFloat32ProjectionData3DMemory *>& projData)
+bool CCompositeGeometryManager::doFP(CProjector3D *pProjector, const std::vector<CFloat32VolumeData3D *>& volData, const std::vector<CFloat32ProjectionData3D *>& projData)
{
ASTRA_DEBUG("CCompositeGeometryManager::doFP, multi-volume");
- std::vector<CFloat32VolumeData3DMemory *>::const_iterator i;
+ std::vector<CFloat32VolumeData3D *>::const_iterator i;
std::vector<boost::shared_ptr<CPart> > inputs;
for (i = volData.begin(); i != volData.end(); ++i) {
@@ -1079,7 +1233,7 @@ bool CCompositeGeometryManager::doFP(CProjector3D *pProjector, const std::vector
inputs.push_back(boost::shared_ptr<CPart>(input));
}
- std::vector<CFloat32ProjectionData3DMemory *>::const_iterator j;
+ std::vector<CFloat32ProjectionData3D *>::const_iterator j;
std::vector<boost::shared_ptr<CPart> > outputs;
for (j = projData.begin(); j != projData.end(); ++j) {
@@ -1115,12 +1269,12 @@ bool CCompositeGeometryManager::doFP(CProjector3D *pProjector, const std::vector
return doJobs(L);
}
-bool CCompositeGeometryManager::doBP(CProjector3D *pProjector, const std::vector<CFloat32VolumeData3DMemory *>& volData, const std::vector<CFloat32ProjectionData3DMemory *>& projData)
+bool CCompositeGeometryManager::doBP(CProjector3D *pProjector, const std::vector<CFloat32VolumeData3D *>& volData, const std::vector<CFloat32ProjectionData3D *>& projData)
{
ASTRA_DEBUG("CCompositeGeometryManager::doBP, multi-volume");
- std::vector<CFloat32VolumeData3DMemory *>::const_iterator i;
+ std::vector<CFloat32VolumeData3D *>::const_iterator i;
std::vector<boost::shared_ptr<CPart> > outputs;
for (i = volData.begin(); i != volData.end(); ++i) {
@@ -1134,7 +1288,7 @@ bool CCompositeGeometryManager::doBP(CProjector3D *pProjector, const std::vector
outputs.push_back(boost::shared_ptr<CPart>(output));
}
- std::vector<CFloat32ProjectionData3DMemory *>::const_iterator j;
+ std::vector<CFloat32ProjectionData3D *>::const_iterator j;
std::vector<boost::shared_ptr<CPart> > inputs;
for (j = projData.begin(); j != projData.end(); ++j) {
@@ -1188,14 +1342,25 @@ static bool doJob(const CCompositeGeometryManager::TJobSet::const_iterator& iter
if (L.begin()->eType == CCompositeGeometryManager::SJob::JOB_NOP) {
// just zero output?
if (zero) {
- for (size_t z = 0; z < outz; ++z) {
- for (size_t y = 0; y < outy; ++y) {
- float* ptr = output->pData->getData();
- ptr += (z + output->subX) * (size_t)output->pData->getHeight() * (size_t)output->pData->getWidth();
- ptr += (y + output->subY) * (size_t)output->pData->getWidth();
- ptr += output->subX;
- memset(ptr, 0, sizeof(float) * outx);
+ // TODO: This function shouldn't have to know about this difference
+ // between Memory/GPU
+ CFloat32Data3DMemory *hostMem = dynamic_cast<CFloat32Data3DMemory *>(output->pData);
+ if (hostMem) {
+ for (size_t z = 0; z < outz; ++z) {
+ for (size_t y = 0; y < outy; ++y) {
+ float* ptr = hostMem->getData();
+ ptr += (z + output->subX) * (size_t)output->pData->getHeight() * (size_t)output->pData->getWidth();
+ ptr += (y + output->subY) * (size_t)output->pData->getWidth();
+ ptr += output->subX;
+ memset(ptr, 0, sizeof(float) * outx);
+ }
}
+ } else {
+ CFloat32Data3DGPU *gpuMem = dynamic_cast<CFloat32Data3DGPU *>(output->pData);
+ assert(gpuMem);
+ assert(output->isFull()); // TODO: zero subset?
+
+ zeroGPUMemory(gpuMem->getHandle(), outx, outy, outz);
}
}
return true;
@@ -1214,10 +1379,11 @@ static bool doJob(const CCompositeGeometryManager::TJobSet::const_iterator& iter
dstdims.subx = output->subX;
dstdims.suby = output->subY;
dstdims.subz = output->subZ;
- float *dst = output->pData->getData();
- astraCUDA3d::MemHandle3D outputMem = astraCUDA3d::allocateGPUMemory(outx, outy, outz, zero ? astraCUDA3d::INIT_ZERO : astraCUDA3d::INIT_NO);
- bool ok = outputMem;
+ CFloat32CustomGPUMemory *dstMem = createGPUMemoryHandler(output->pData);
+
+ bool ok = dstMem->allocateGPUMemory(outx, outy, outz, zero ? astraCUDA3d::INIT_ZERO : astraCUDA3d::INIT_NO);
+ if (!ok) ASTRA_ERROR("Error allocating GPU memory");
for (CCompositeGeometryManager::TJobList::const_iterator i = L.begin(); i != L.end(); ++i) {
const CCompositeGeometryManager::SJob &j = *i;
@@ -1238,7 +1404,8 @@ static bool doJob(const CCompositeGeometryManager::TJobSet::const_iterator& iter
size_t inx, iny, inz;
j.pInput->getDims(inx, iny, inz);
- astraCUDA3d::MemHandle3D inputMem = astraCUDA3d::allocateGPUMemory(inx, iny, inz, astraCUDA3d::INIT_NO);
+
+ CFloat32CustomGPUMemory *srcMem = createGPUMemoryHandler(j.pInput->pData);
astraCUDA3d::SSubDimensions3D srcdims;
srcdims.nx = j.pInput->pData->getWidth();
@@ -1251,9 +1418,11 @@ static bool doJob(const CCompositeGeometryManager::TJobSet::const_iterator& iter
srcdims.subx = j.pInput->subX;
srcdims.suby = j.pInput->subY;
srcdims.subz = j.pInput->subZ;
- const float *src = j.pInput->pData->getDataConst();
- ok = astraCUDA3d::copyToGPUMemory(src, inputMem, srcdims);
+ ok = srcMem->allocateGPUMemory(inx, iny, inz, astraCUDA3d::INIT_NO);
+ if (!ok) ASTRA_ERROR("Error allocating GPU memory");
+
+ ok = srcMem->copyToGPUMemory(srcdims);
if (!ok) ASTRA_ERROR("Error copying input data to GPU");
switch (j.eType) {
@@ -1264,7 +1433,7 @@ static bool doJob(const CCompositeGeometryManager::TJobSet::const_iterator& iter
ASTRA_DEBUG("CCompositeGeometryManager::doJobs: doing FP");
- ok = astraCUDA3d::FP(((CCompositeGeometryManager::CProjectionPart*)j.pOutput.get())->pGeom, outputMem, ((CCompositeGeometryManager::CVolumePart*)j.pInput.get())->pGeom, inputMem, detectorSuperSampling, projKernel);
+ ok = astraCUDA3d::FP(((CCompositeGeometryManager::CProjectionPart*)j.pOutput.get())->pGeom, dstMem->hnd, ((CCompositeGeometryManager::CVolumePart*)j.pInput.get())->pGeom, srcMem->hnd, detectorSuperSampling, projKernel);
if (!ok) ASTRA_ERROR("Error performing sub-FP");
ASTRA_DEBUG("CCompositeGeometryManager::doJobs: FP done");
}
@@ -1276,7 +1445,7 @@ static bool doJob(const CCompositeGeometryManager::TJobSet::const_iterator& iter
ASTRA_DEBUG("CCompositeGeometryManager::doJobs: doing BP");
- ok = astraCUDA3d::BP(((CCompositeGeometryManager::CProjectionPart*)j.pInput.get())->pGeom, inputMem, ((CCompositeGeometryManager::CVolumePart*)j.pOutput.get())->pGeom, outputMem, voxelSuperSampling, densityWeighting);
+ ok = astraCUDA3d::BP(((CCompositeGeometryManager::CProjectionPart*)j.pInput.get())->pGeom, srcMem->hnd, ((CCompositeGeometryManager::CVolumePart*)j.pOutput.get())->pGeom, dstMem->hnd, voxelSuperSampling, densityWeighting);
if (!ok) ASTRA_ERROR("Error performing sub-BP");
ASTRA_DEBUG("CCompositeGeometryManager::doJobs: BP done");
}
@@ -1292,7 +1461,7 @@ static bool doJob(const CCompositeGeometryManager::TJobSet::const_iterator& iter
} else {
ASTRA_DEBUG("CCompositeGeometryManager::doJobs: doing FDK");
- ok = astraCUDA3d::FDK(((CCompositeGeometryManager::CProjectionPart*)j.pInput.get())->pGeom, inputMem, ((CCompositeGeometryManager::CVolumePart*)j.pOutput.get())->pGeom, outputMem, j.FDKSettings.bShortScan, j.FDKSettings.pfFilter);
+ ok = astraCUDA3d::FDK(((CCompositeGeometryManager::CProjectionPart*)j.pInput.get())->pGeom, srcMem->hnd, ((CCompositeGeometryManager::CVolumePart*)j.pOutput.get())->pGeom, dstMem->hnd, j.FDKSettings.bShortScan, j.FDKSettings.pfFilter);
if (!ok) ASTRA_ERROR("Error performing sub-FDK");
ASTRA_DEBUG("CCompositeGeometryManager::doJobs: FDK done");
}
@@ -1302,17 +1471,20 @@ static bool doJob(const CCompositeGeometryManager::TJobSet::const_iterator& iter
assert(false);
}
- ok = astraCUDA3d::freeGPUMemory(inputMem);
+ ok = srcMem->freeGPUMemory();
if (!ok) ASTRA_ERROR("Error freeing GPU memory");
+ delete srcMem;
}
- ok = astraCUDA3d::copyFromGPUMemory(dst, outputMem, dstdims);
+ ok = dstMem->copyFromGPUMemory(dstdims);
if (!ok) ASTRA_ERROR("Error copying output data from GPU");
- ok = astraCUDA3d::freeGPUMemory(outputMem);
+ ok = dstMem->freeGPUMemory();
if (!ok) ASTRA_ERROR("Error freeing GPU memory");
+ delete dstMem;
+
return true;
}
@@ -1455,6 +1627,8 @@ void CCompositeGeometryManager::setGPUIndices(const std::vector<int>& GPUIndices
bool CCompositeGeometryManager::doJobs(TJobList &jobs)
{
+ // TODO: Proper clean up if substeps fail (Or as proper as possible)
+
ASTRA_DEBUG("CCompositeGeometryManager::doJobs");
// Sort job list into job set by output part
diff --git a/src/CudaBackProjectionAlgorithm3D.cpp b/src/CudaBackProjectionAlgorithm3D.cpp
index 223a9a4..27bb968 100644
--- a/src/CudaBackProjectionAlgorithm3D.cpp
+++ b/src/CudaBackProjectionAlgorithm3D.cpp
@@ -60,8 +60,8 @@ CCudaBackProjectionAlgorithm3D::CCudaBackProjectionAlgorithm3D()
//----------------------------------------------------------------------------------------
// Constructor with initialization
CCudaBackProjectionAlgorithm3D::CCudaBackProjectionAlgorithm3D(CProjector3D* _pProjector,
- CFloat32ProjectionData3DMemory* _pProjectionData,
- CFloat32VolumeData3DMemory* _pReconstruction)
+ CFloat32ProjectionData3D* _pProjectionData,
+ CFloat32VolumeData3D* _pReconstruction)
{
_clear();
initialize(_pProjector, _pProjectionData, _pReconstruction);
@@ -145,8 +145,8 @@ bool CCudaBackProjectionAlgorithm3D::initialize(const Config& _cfg)
//----------------------------------------------------------------------------------------
// Initialize - C++
bool CCudaBackProjectionAlgorithm3D::initialize(CProjector3D* _pProjector,
- CFloat32ProjectionData3DMemory* _pSinogram,
- CFloat32VolumeData3DMemory* _pReconstruction)
+ CFloat32ProjectionData3D* _pSinogram,
+ CFloat32VolumeData3D* _pReconstruction)
{
// if already initialized, clear first
if (m_bIsInitialized) {
@@ -187,17 +187,21 @@ void CCudaBackProjectionAlgorithm3D::run(int _iNrIterations)
// check initialized
ASTRA_ASSERT(m_bIsInitialized);
- CFloat32ProjectionData3DMemory* pSinoMem = dynamic_cast<CFloat32ProjectionData3DMemory*>(m_pSinogram);
+ CFloat32ProjectionData3D* pSinoMem = dynamic_cast<CFloat32ProjectionData3D*>(m_pSinogram);
ASTRA_ASSERT(pSinoMem);
- CFloat32VolumeData3DMemory* pReconMem = dynamic_cast<CFloat32VolumeData3DMemory*>(m_pReconstruction);
+ CFloat32VolumeData3D* pReconMem = dynamic_cast<CFloat32VolumeData3D*>(m_pReconstruction);
ASTRA_ASSERT(pReconMem);
const CProjectionGeometry3D* projgeom = pSinoMem->getGeometry();
const CVolumeGeometry3D& volgeom = *pReconMem->getGeometry();
if (m_bSIRTWeighting) {
- astraCudaBP_SIRTWeighted(pReconMem->getData(),
- pSinoMem->getDataConst(),
+ CFloat32ProjectionData3DMemory* pSinoMemory = dynamic_cast<CFloat32ProjectionData3DMemory*>(m_pSinogram);
+ ASTRA_ASSERT(pSinoMemory);
+ CFloat32VolumeData3DMemory* pReconMemory = dynamic_cast<CFloat32VolumeData3DMemory*>(m_pReconstruction);
+ ASTRA_ASSERT(pReconMemory);
+ astraCudaBP_SIRTWeighted(pReconMemory->getData(),
+ pSinoMemory->getDataConst(),
&volgeom, projgeom,
m_iGPUIndex, m_iVoxelSuperSampling);
} else {
diff --git a/src/CudaFDKAlgorithm3D.cpp b/src/CudaFDKAlgorithm3D.cpp
index d02db6d..d503351 100644
--- a/src/CudaFDKAlgorithm3D.cpp
+++ b/src/CudaFDKAlgorithm3D.cpp
@@ -59,8 +59,8 @@ CCudaFDKAlgorithm3D::CCudaFDKAlgorithm3D()
//----------------------------------------------------------------------------------------
// Constructor with initialization
CCudaFDKAlgorithm3D::CCudaFDKAlgorithm3D(CProjector3D* _pProjector,
- CFloat32ProjectionData3DMemory* _pProjectionData,
- CFloat32VolumeData3DMemory* _pReconstruction)
+ CFloat32ProjectionData3D* _pProjectionData,
+ CFloat32VolumeData3D* _pReconstruction)
{
_clear();
initialize(_pProjector, _pProjectionData, _pReconstruction);
@@ -179,8 +179,8 @@ bool CCudaFDKAlgorithm3D::initialize(const Config& _cfg)
//----------------------------------------------------------------------------------------
// Initialize - C++
bool CCudaFDKAlgorithm3D::initialize(CProjector3D* _pProjector,
- CFloat32ProjectionData3DMemory* _pSinogram,
- CFloat32VolumeData3DMemory* _pReconstruction)
+ CFloat32ProjectionData3D* _pSinogram,
+ CFloat32VolumeData3D* _pReconstruction)
{
// if already initialized, clear first
if (m_bIsInitialized) {
@@ -225,9 +225,9 @@ void CCudaFDKAlgorithm3D::run(int _iNrIterations)
ASTRA_ASSERT(conegeom);
- CFloat32ProjectionData3DMemory* pSinoMem = dynamic_cast<CFloat32ProjectionData3DMemory*>(m_pSinogram);
+ CFloat32ProjectionData3D* pSinoMem = dynamic_cast<CFloat32ProjectionData3D*>(m_pSinogram);
ASTRA_ASSERT(pSinoMem);
- CFloat32VolumeData3DMemory* pReconMem = dynamic_cast<CFloat32VolumeData3DMemory*>(m_pReconstruction);
+ CFloat32VolumeData3D* pReconMem = dynamic_cast<CFloat32VolumeData3D*>(m_pReconstruction);
ASTRA_ASSERT(pReconMem);
const float *filter = NULL;
diff --git a/src/CudaForwardProjectionAlgorithm3D.cpp b/src/CudaForwardProjectionAlgorithm3D.cpp
index 6783093..ce808eb 100644
--- a/src/CudaForwardProjectionAlgorithm3D.cpp
+++ b/src/CudaForwardProjectionAlgorithm3D.cpp
@@ -101,14 +101,14 @@ bool CCudaForwardProjectionAlgorithm3D::initialize(const Config& _cfg)
node = _cfg.self.getSingleNode("ProjectionDataId");
ASTRA_CONFIG_CHECK(node, "CudaForwardProjection3D", "No ProjectionDataId tag specified.");
id = node.getContentInt();
- m_pProjections = dynamic_cast<CFloat32ProjectionData3DMemory*>(CData3DManager::getSingleton().get(id));
+ m_pProjections = dynamic_cast<CFloat32ProjectionData3D*>(CData3DManager::getSingleton().get(id));
CC.markNodeParsed("ProjectionDataId");
// reconstruction data
node = _cfg.self.getSingleNode("VolumeDataId");
ASTRA_CONFIG_CHECK(node, "CudaForwardProjection3D", "No VolumeDataId tag specified.");
id = node.getContentInt();
- m_pVolume = dynamic_cast<CFloat32VolumeData3DMemory*>(CData3DManager::getSingleton().get(id));
+ m_pVolume = dynamic_cast<CFloat32VolumeData3D*>(CData3DManager::getSingleton().get(id));
CC.markNodeParsed("VolumeDataId");
// optional: projector
@@ -140,8 +140,8 @@ bool CCudaForwardProjectionAlgorithm3D::initialize(const Config& _cfg)
bool CCudaForwardProjectionAlgorithm3D::initialize(CProjector3D* _pProjector,
- CFloat32ProjectionData3DMemory* _pProjections,
- CFloat32VolumeData3DMemory* _pVolume,
+ CFloat32ProjectionData3D* _pProjections,
+ CFloat32VolumeData3D* _pVolume,
int _iGPUindex, int _iDetectorSuperSampling)
{
m_pProjector = _pProjector;
diff --git a/src/Float32Data3D.cpp b/src/Float32Data3D.cpp
index cad1f18..cc824bd 100644
--- a/src/Float32Data3D.cpp
+++ b/src/Float32Data3D.cpp
@@ -28,6 +28,10 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
#include "astra/Float32Data3D.h"
#include <sstream>
+#ifdef ASTRA_CUDA
+#include "../../cuda/3d/mem3d.h"
+#endif
+
using namespace std;
namespace astra {
@@ -60,7 +64,5 @@ std::string CFloat32Data3D::description() const
if (getType() == CFloat32Data3D::VOLUME) res << " volume data \t";
return res.str();
}
-//----------------------------------------------------------------------------------------
-
} // end namespace astra
diff --git a/src/Float32Data3DGPU.cpp b/src/Float32Data3DGPU.cpp
new file mode 100644
index 0000000..cd9c4ad
--- /dev/null
+++ b/src/Float32Data3DGPU.cpp
@@ -0,0 +1,98 @@
+/*
+-----------------------------------------------------------------------
+Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp
+ 2014-2015, CWI, Amsterdam
+
+Contact: astra@uantwerpen.be
+Website: http://sf.net/projects/astra-toolbox
+
+This file is part of the ASTRA Toolbox.
+
+
+The ASTRA Toolbox is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+The ASTRA Toolbox is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+#include "astra/Float32Data3DGPU.h"
+
+namespace astra {
+
+//----------------------------------------------------------------------------------------
+// Default constructor.
+CFloat32Data3DGPU::CFloat32Data3DGPU()
+{
+ _clear();
+ m_bInitialized = false;
+}
+
+//----------------------------------------------------------------------------------------
+// Destructor.
+CFloat32Data3DGPU::~CFloat32Data3DGPU()
+{
+ if (m_bInitialized)
+ {
+ _unInit();
+ }
+}
+
+//----------------------------------------------------------------------------------------
+// Initializes an instance of the CFloat32Data3DGPU class with pre-allocated memory
+bool CFloat32Data3DGPU::_initialize(int _iWidth, int _iHeight, int _iDepth, astraCUDA3d::MemHandle3D _hnd)
+{
+ // basic checks
+ ASTRA_ASSERT(_iWidth > 0);
+ ASTRA_ASSERT(_iHeight > 0);
+ ASTRA_ASSERT(_iDepth > 0);
+ //ASTRA_ASSERT(_pCustomMemory != NULL);
+
+ if (m_bInitialized) {
+ _unInit();
+ }
+
+ // calculate size
+ m_iWidth = _iWidth;
+ m_iHeight = _iHeight;
+ m_iDepth = _iDepth;
+ m_iSize = (size_t)m_iWidth * m_iHeight * m_iDepth;
+
+ m_hnd = _hnd;
+
+ // initialization complete
+ return true;
+}
+//----------------------------------------------------------------------------------------
+// Clear all member variables, setting all numeric variables to 0 and all pointers to NULL.
+void CFloat32Data3DGPU::_clear()
+{
+ m_iWidth = 0;
+ m_iHeight = 0;
+ m_iDepth = 0;
+ m_iSize = 0;
+
+ m_hnd.d.reset();
+}
+
+//----------------------------------------------------------------------------------------
+// Un-initialize the object, bringing it back in the unitialized state.
+void CFloat32Data3DGPU::_unInit()
+{
+ ASTRA_ASSERT(m_bInitialized);
+
+ _clear();
+ m_bInitialized = false;
+}
+
+} // end namespace astra
diff --git a/src/Float32Data3DMemory.cpp b/src/Float32Data3DMemory.cpp
index 7e60527..5c5c310 100644
--- a/src/Float32Data3DMemory.cpp
+++ b/src/Float32Data3DMemory.cpp
@@ -163,7 +163,7 @@ bool CFloat32Data3DMemory::_initialize(int _iWidth, int _iHeight, int _iDepth, C
ASTRA_ASSERT(_iWidth > 0);
ASTRA_ASSERT(_iHeight > 0);
ASTRA_ASSERT(_iDepth > 0);
- ASTRA_ASSERT(_pCustomMemory != NULL);
+ //ASTRA_ASSERT(_pCustomMemory != NULL);
if (m_bInitialized) {
_unInit();
diff --git a/src/Float32ProjectionData3DGPU.cpp b/src/Float32ProjectionData3DGPU.cpp
new file mode 100644
index 0000000..0e063d6
--- /dev/null
+++ b/src/Float32ProjectionData3DGPU.cpp
@@ -0,0 +1,71 @@
+/*
+-----------------------------------------------------------------------
+Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp
+ 2014-2015, CWI, Amsterdam
+
+Contact: astra@uantwerpen.be
+Website: http://sf.net/projects/astra-toolbox
+
+This file is part of the ASTRA Toolbox.
+
+
+The ASTRA Toolbox is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+The ASTRA Toolbox is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+#include "astra/Float32ProjectionData3DGPU.h"
+
+using namespace std;
+
+namespace astra
+{
+
+//----------------------------------------------------------------------------------------
+// Default constructor
+CFloat32ProjectionData3DGPU::CFloat32ProjectionData3DGPU() :
+ CFloat32Data3DGPU()
+{
+ m_pGeometry = NULL;
+ m_bInitialized = false;
+}
+
+//----------------------------------------------------------------------------------------
+// Create an instance of the CFloat32ProjectionData2D class with pre-allocated data
+CFloat32ProjectionData3DGPU::CFloat32ProjectionData3DGPU(CProjectionGeometry3D* _pGeometry, astraCUDA3d::MemHandle3D _hnd)
+{
+ m_bInitialized = false;
+ m_bInitialized = initialize(_pGeometry, _hnd);
+}
+
+
+//----------------------------------------------------------------------------------------
+// Destructor
+CFloat32ProjectionData3DGPU::~CFloat32ProjectionData3DGPU()
+{
+ delete m_pGeometry;
+ m_pGeometry = 0;
+}
+
+//----------------------------------------------------------------------------------------
+// Initialization
+bool CFloat32ProjectionData3DGPU::initialize(CProjectionGeometry3D* _pGeometry, astraCUDA3d::MemHandle3D _hnd)
+{
+ m_pGeometry = _pGeometry->clone();
+ m_bInitialized = _initialize(m_pGeometry->getDetectorColCount(), m_pGeometry->getProjectionCount(), m_pGeometry->getDetectorRowCount(), _hnd);
+ return m_bInitialized;
+}
+
+} // end namespace astra
diff --git a/src/Float32ProjectionData3DMemory.cpp b/src/Float32ProjectionData3DMemory.cpp
index 81daf9e..69033d5 100644
--- a/src/Float32ProjectionData3DMemory.cpp
+++ b/src/Float32ProjectionData3DMemory.cpp
@@ -114,7 +114,7 @@ bool CFloat32ProjectionData3DMemory::initialize(CProjectionGeometry3D* _pGeometr
//----------------------------------------------------------------------------------------
// Initialization
-bool CFloat32ProjectionData3DMemory::initialize(CProjectionGeometry3D* _pGeometry, CFloat32CustomMemory* _pCustomMemory)
+bool CFloat32ProjectionData3DMemory::initialize(CProjectionGeometry3D* _pGeometry, CFloat32CustomMemory* _pCustomMemory)
{
m_pGeometry = _pGeometry->clone();
m_bInitialized = _initialize(m_pGeometry->getDetectorColCount(), m_pGeometry->getProjectionCount(), m_pGeometry->getDetectorRowCount(), _pCustomMemory);
diff --git a/src/Float32VolumeData3DGPU.cpp b/src/Float32VolumeData3DGPU.cpp
new file mode 100644
index 0000000..82a222f
--- /dev/null
+++ b/src/Float32VolumeData3DGPU.cpp
@@ -0,0 +1,71 @@
+/*
+-----------------------------------------------------------------------
+Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp
+ 2014-2015, CWI, Amsterdam
+
+Contact: astra@uantwerpen.be
+Website: http://sf.net/projects/astra-toolbox
+
+This file is part of the ASTRA Toolbox.
+
+
+The ASTRA Toolbox is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+The ASTRA Toolbox is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+#include "astra/Float32VolumeData3DGPU.h"
+
+using namespace std;
+
+namespace astra
+{
+
+//----------------------------------------------------------------------------------------
+// Default constructor
+CFloat32VolumeData3DGPU::CFloat32VolumeData3DGPU() :
+ CFloat32Data3DGPU()
+{
+ m_pGeometry = NULL;
+ m_bInitialized = false;
+}
+
+//----------------------------------------------------------------------------------------
+// Create an instance of the CFloat32VolumeData2D class with pre-allocated data
+CFloat32VolumeData3DGPU::CFloat32VolumeData3DGPU(CVolumeGeometry3D* _pGeometry, astraCUDA3d::MemHandle3D _hnd)
+{
+ m_bInitialized = false;
+ m_bInitialized = initialize(_pGeometry, _hnd);
+}
+
+
+//----------------------------------------------------------------------------------------
+// Destructor
+CFloat32VolumeData3DGPU::~CFloat32VolumeData3DGPU()
+{
+ delete m_pGeometry;
+ m_pGeometry = 0;
+}
+
+//----------------------------------------------------------------------------------------
+// Initialization
+bool CFloat32VolumeData3DGPU::initialize(CVolumeGeometry3D* _pGeometry, astraCUDA3d::MemHandle3D _hnd)
+{
+ m_pGeometry = _pGeometry->clone();
+ m_bInitialized = _initialize(m_pGeometry->getGridColCount(), m_pGeometry->getGridRowCount(), m_pGeometry->getGridSliceCount(), _hnd);
+ return m_bInitialized;
+}
+
+} // end namespace astra
diff --git a/src/Float32VolumeData3DMemory.cpp b/src/Float32VolumeData3DMemory.cpp
index 9f81c85..27ae87b 100644
--- a/src/Float32VolumeData3DMemory.cpp
+++ b/src/Float32VolumeData3DMemory.cpp
@@ -114,7 +114,7 @@ bool CFloat32VolumeData3DMemory::initialize(CVolumeGeometry3D* _pGeometry, float
}
//----------------------------------------------------------------------------------------
// Initialization
-bool CFloat32VolumeData3DMemory::initialize(CVolumeGeometry3D* _pGeometry, CFloat32CustomMemory* _pCustomMemory)
+bool CFloat32VolumeData3DMemory::initialize(CVolumeGeometry3D* _pGeometry, CFloat32CustomMemory* _pCustomMemory)
{
m_pGeometry = _pGeometry->clone();
m_bInitialized = _initialize(m_pGeometry->getGridColCount(), m_pGeometry->getGridRowCount(), m_pGeometry->getGridSliceCount(), _pCustomMemory);