diff options
Diffstat (limited to 'src/CompositeGeometryManager.cpp')
-rw-r--r-- | src/CompositeGeometryManager.cpp | 281 |
1 files changed, 230 insertions, 51 deletions
diff --git a/src/CompositeGeometryManager.cpp b/src/CompositeGeometryManager.cpp index 7c4f8e6..a4dace2 100644 --- a/src/CompositeGeometryManager.cpp +++ b/src/CompositeGeometryManager.cpp @@ -1,10 +1,10 @@ /* ----------------------------------------------------------------------- -Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp - 2014-2015, CWI, Amsterdam +Copyright: 2010-2016, iMinds-Vision Lab, University of Antwerp + 2014-2016, CWI, Amsterdam Contact: astra@uantwerpen.be -Website: http://sf.net/projects/astra-toolbox +Website: http://www.astra-toolbox.com/ This file is part of the ASTRA Toolbox. @@ -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(); @@ -205,6 +328,7 @@ static std::pair<double, double> reduceProjectionVertical(const CVolumeGeometry3 // reduce self to only cover intersection with projection of VolumePart // (Project corners of volume, take bounding box) + assert(pProjGeom->getProjectionCount() > 0); for (int i = 0; i < pProjGeom->getProjectionCount(); ++i) { double vol_u[8]; @@ -280,7 +404,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 +416,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 == (size_t)pData->getWidth() && + y == (size_t)pData->getHeight() && + z == (size_t)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 +473,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 +796,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 @@ -664,7 +806,7 @@ void CCompositeGeometryManager::CVolumePart::splitX(CCompositeGeometryManager::T size_t blockSize = computeLinearSplit(m, div, sliceCount); int rem = blockSize - (sliceCount % blockSize); - if (rem == blockSize) + if ((size_t)rem == blockSize) rem = 0; ASTRA_DEBUG("From %d to %d step %d", -(rem / 2), sliceCount, blockSize); @@ -698,12 +840,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 @@ -713,7 +857,7 @@ void CCompositeGeometryManager::CVolumePart::splitY(CCompositeGeometryManager::T size_t blockSize = computeLinearSplit(m, div, sliceCount); int rem = blockSize - (sliceCount % blockSize); - if (rem == blockSize) + if ((size_t)rem == blockSize) rem = 0; ASTRA_DEBUG("From %d to %d step %d", -(rem / 2), sliceCount, blockSize); @@ -747,12 +891,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 @@ -762,7 +908,7 @@ void CCompositeGeometryManager::CVolumePart::splitZ(CCompositeGeometryManager::T size_t blockSize = computeLinearSplit(m, div, sliceCount); int rem = blockSize - (sliceCount % blockSize); - if (rem == blockSize) + if ((size_t)rem == blockSize) rem = 0; ASTRA_DEBUG("From %d to %d step %d", -(rem / 2), sliceCount, blockSize); @@ -796,6 +942,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 +963,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 +979,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 +1019,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 @@ -878,7 +1029,7 @@ void CCompositeGeometryManager::CProjectionPart::splitX(CCompositeGeometryManage size_t blockSize = computeLinearSplit(m, div, sliceCount); int rem = blockSize - (sliceCount % blockSize); - if (rem == blockSize) + if ((size_t)rem == blockSize) rem = 0; ASTRA_DEBUG("From %d to %d step %d", -(rem / 2), sliceCount, blockSize); @@ -903,6 +1054,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 +1067,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 @@ -924,7 +1077,7 @@ void CCompositeGeometryManager::CProjectionPart::splitZ(CCompositeGeometryManage size_t blockSize = computeLinearSplit(m, div, sliceCount); int rem = blockSize - (sliceCount % blockSize); - if (rem == blockSize) + if ((size_t)rem == blockSize) rem = 0; ASTRA_DEBUG("From %d to %d step %d", -(rem / 2), sliceCount, blockSize); @@ -949,6 +1102,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 +1114,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 +1147,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 +1177,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 +1186,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 +1196,9 @@ 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())) { ASTRA_ERROR("CCompositeGeometryManager::doFDK: cone geometry required"); @@ -1052,6 +1208,7 @@ bool CCompositeGeometryManager::doFDK(CProjector3D *pProjector, CFloat32VolumeDa SJob job = createJobBP(pProjector, pVolData, pProjData); job.eType = SJob::JOB_FDK; job.FDKSettings.bShortScan = bShortScan; + job.FDKSettings.pfFilter = pfFilter; TJobList L; L.push_back(job); @@ -1059,11 +1216,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) { @@ -1077,7 +1234,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) { @@ -1113,12 +1270,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) { @@ -1132,7 +1289,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) { @@ -1186,14 +1343,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; @@ -1212,10 +1380,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; @@ -1226,15 +1395,18 @@ static bool doJob(const CCompositeGeometryManager::TJobSet::const_iterator& iter Cuda3DProjectionKernel projKernel = ker3d_default; int detectorSuperSampling = 1; int voxelSuperSampling = 1; + bool densityWeighting = false; if (projector) { projKernel = projector->getProjectionKernel(); detectorSuperSampling = projector->getDetectorSuperSampling(); voxelSuperSampling = projector->getVoxelSuperSampling(); + densityWeighting = projector->getDensityWeighting(); } 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(); @@ -1247,9 +1419,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) { @@ -1260,7 +1434,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"); } @@ -1272,7 +1446,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); + 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"); } @@ -1288,7 +1462,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); + 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"); } @@ -1298,17 +1472,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; } @@ -1451,6 +1628,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 |