diff options
66 files changed, 623 insertions, 454 deletions
| diff --git a/.travis.yml b/.travis.yml index 1cd7420..aca9940 100644 --- a/.travis.yml +++ b/.travis.yml @@ -60,6 +60,8 @@ before_install:  install:    - conda install python=$TRAVIS_PYTHON_VERSION six numpy scipy cython    - conda info -a + +script:    - cd build/linux    - ./autogen.sh    - if [ x$CLANG == xyes ]; then export CXX=clang++; export CC=clang; fi @@ -67,6 +69,4 @@ install:    - make -j 4    - make test    - make install - -script: -  - python -c "import astra" +  - python -c "import astra; astra.test_noCUDA()" @@ -8,6 +8,15 @@ License: Open Source under GPLv3  Contact: astra@uantwerpen.be  Website: http://www.astra-toolbox.com/  ----------------------------------------------------------------------- +1.8.3 (2017-11-06) +  * fix geometry memory leak in 3D FP/BP +  * fix FDK short scan weighting +  * add preliminary support for building on macOS +  * add experimental support for using externally managed GPU memory from python +    (see samples/python/s021_pygpu.py) +  * our Linux conda python packages now have variants depending on the +    cudatoolkit version +  * add basic post-install tests test_CUDA/test_noCUDA (see README)  1.8 (2016-12-05)    * the Windows binary release now requires CUDA 8.0 @@ -107,7 +107,7 @@ Requirements: Visual Studio 2015 (full or community), boost (recent), CUDA 8.0,  Using the Visual Studio IDE:  Set the environment variable MATLAB_ROOT to your matlab install location. -Copy boost headers to lib\include\boost, and boost libraries to bin\x64. +Copy boost headers to lib\include\boost, and boost libraries to lib\x64.  Open astra_vc14.sln in Visual Studio.  Select the appropriate solution configuration (typically Release_CUDA|x64).  Build the solution. @@ -123,7 +123,24 @@ Run build_setup.bat to automatically copy the boost headers and libraries.  For matlab: Run build_matlab.bat. The .dll and .mexw64 files will be in bin\x64\Release_Cuda.  For python 2.7/3.5: Run build_python27.bat or build_python35.bat. Astra will be directly installed into site-packages. +## Testing your installation +To perform a (very) basic test of your ASTRA installation in Python, you can +run the following Python commands. You can choose to skip the test of the GPU +functionality for systems without a NVIDIA GPU. + +``` +import astra +astra.test_noCUDA() # To skip GPU tests +astra.test_CUDA()   # To also perform GPU tests +``` + +To test your ASTRA installation in Matlab, the equivalent commands are: + +``` +astra_test_noCUDA   % To skip GPU tests +astra_test_CUDA     % To also perform GPU tests +```  ## References @@ -134,7 +134,7 @@ Requirements: Visual Studio 2015 (full or community), boost (recent), CUDA 8.0,  Using the Visual Studio IDE:  Set the environment variable MATLAB_ROOT to your matlab install location. -Copy boost headers to lib\include\boost, and boost libraries to bin\x64. +Copy boost headers to lib\include\boost, and boost libraries to lib\x64.  Open astra_vc14.sln in Visual Studio.  Select the appropriate solution configuration (typically Release_CUDA|x64).  Build the solution. @@ -151,6 +151,24 @@ For matlab: Run build_matlab.bat. The .dll and .mexw64 files will be in bin\x64\  For python 2.7/3.5: Run build_python27.bat or build_python35.bat. Astra will be directly installed into site-packages. +Testing your installation: +--------------------------- + +To perform a (very) basic test of your ASTRA installation in Python, you can +run the following Python commands. You can choose to skip the test of the GPU +functionality for systems without a NVIDIA GPU. + +import astra +astra.test_noCUDA() # To skip GPU tests +astra.test_CUDA()   # To also perform GPU tests + + +To test your ASTRA installation in Matlab, the equivalent commands are: + +astra_test_noCUDA   % To skip GPU tests +astra_test_CUDA     % To also perform GPU tests + +  References:  ------------ diff --git a/build/linux/Makefile.in b/build/linux/Makefile.in index d7d6488..77e89e7 100644 --- a/build/linux/Makefile.in +++ b/build/linux/Makefile.in @@ -181,8 +181,7 @@ BASE_OBJECTS=\  	src/VolumeGeometry2D.lo \  	src/VolumeGeometry3D.lo \  	src/XMLDocument.lo \ -	src/XMLNode.lo \ -	src/swrap.lo +	src/XMLNode.lo  CUDA_CXX_OBJECTS=\  	src/CudaProjector2D.lo \ diff --git a/build/linux/configure.ac b/build/linux/configure.ac index b95d94f..0091388 100644 --- a/build/linux/configure.ac +++ b/build/linux/configure.ac @@ -23,7 +23,7 @@ dnl along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  dnl  dnl ----------------------------------------------------------------------- -AC_INIT(astra, 1.8.0) +AC_INIT(astra, 1.8.3)  AC_CONFIG_SRCDIR([Makefile.in])  LT_INIT([disable-static]) diff --git a/build/msvc/build_env.bat b/build/msvc/build_env.bat index 8cb7c96..56c811f 100644 --- a/build/msvc/build_env.bat +++ b/build/msvc/build_env.bat @@ -12,5 +12,5 @@ set B_VCREDIST=D:\wjp\vs2015u3_redist\vc_redist.x64.exe  set B_README_WP27=C:\WinPython-64bit-%B_WP27%\python-%B_WP27:~0,-2%.amd64\Lib\site-packages  set B_README_WP35=C:\WinPython-64bit-%B_WP35%\python-%B_WP35:~0,-2%.amd64\Lib\site-packages -set B_RELEASE_TAG=v1.8 -set B_RELEASE=1.8 +set B_RELEASE_TAG=v1.8.3 +set B_RELEASE=1.8.3 diff --git a/cuda/2d/algo.h b/cuda/2d/algo.h index c1d932c..d70859f 100644 --- a/cuda/2d/algo.h +++ b/cuda/2d/algo.h @@ -28,7 +28,8 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #ifndef _CUDA_ALGO_H  #define _CUDA_ALGO_H -#include "util.h" +#include "astra/Globals.h" +#include "dims.h"  namespace astra { diff --git a/cuda/2d/astra.cu b/cuda/2d/astra.cu index 279b57d..81459de 100644 --- a/cuda/2d/astra.cu +++ b/cuda/2d/astra.cu @@ -441,7 +441,6 @@ bool convertAstraGeometry(const CVolumeGeometry2D* pVolGeom,  	return true;  } -  bool convertAstraGeometry(const CVolumeGeometry2D* pVolGeom,                            const CProjectionGeometry2D* pProjGeom,                            astraCUDA::SParProjection*& pParProjs, @@ -488,6 +487,47 @@ bool convertAstraGeometry_dims(const CVolumeGeometry2D* pVolGeom, +} + +namespace astraCUDA { + + +_AstraExport std::string getCudaDeviceString(int device) +{ +	char buf[1024]; +	cudaError_t err; +	if (device == -1) { +		err = cudaGetDevice(&device); +		if (err != cudaSuccess) { +			return "Error getting current GPU index"; +		} +	} + +	cudaDeviceProp prop; +	err = cudaGetDeviceProperties(&prop, device); +	if (err != cudaSuccess) { +		snprintf(buf, 1024, "GPU #%d: Invalid device (%d): %s", device, err, cudaGetErrorString(err)); +		return buf; +	} + +	long mem = prop.totalGlobalMem / (1024*1024); +	snprintf(buf, 1024, "GPU #%d: %s, with %ldMB", device, prop.name, mem); +	return buf; +} + +_AstraExport bool setGPUIndex(int iGPUIndex) +{ +        if (iGPUIndex != -1) { +                cudaSetDevice(iGPUIndex); +                cudaError_t err = cudaGetLastError(); + +                // Ignore errors caused by calling cudaSetDevice multiple times +                if (err != cudaSuccess && err != cudaErrorSetOnActiveProcess) +                        return false; +        } + +        return true; +}  } diff --git a/cuda/2d/astra.h b/cuda/2d/astra.h index a20b830..9355cb4 100644 --- a/cuda/2d/astra.h +++ b/cuda/2d/astra.h @@ -111,6 +111,15 @@ _AstraExport bool convertAstraGeometry(const CVolumeGeometry2D* pVolGeom,                            astraCUDA::SParProjection*& pParProjs,                            astraCUDA::SFanProjection*& pFanProjs,                            float& outputScale); +} + +namespace astraCUDA { + +// Return string with CUDA device number, name and memory size. +// Use device == -1 to get info for the current device. +_AstraExport std::string getCudaDeviceString(int device); + +_AstraExport bool setGPUIndex(int index);  }  #endif diff --git a/cuda/2d/cgls.h b/cuda/2d/cgls.h index 804f943..c45b5a4 100644 --- a/cuda/2d/cgls.h +++ b/cuda/2d/cgls.h @@ -28,7 +28,6 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #ifndef _CUDA_CGLS_H  #define _CUDA_CGLS_H -#include "util.h"  #include "algo.h"  namespace astraCUDA { diff --git a/cuda/2d/darthelper.cu b/cuda/2d/darthelper.cu index 744184e..d4b5220 100644 --- a/cuda/2d/darthelper.cu +++ b/cuda/2d/darthelper.cu @@ -356,20 +356,4 @@ void dartSmoothing(float* out, const float* in, float b, unsigned int radius, un  } - -_AstraExport bool setGPUIndex(int iGPUIndex) -{ -	if (iGPUIndex != -1) { -		cudaSetDevice(iGPUIndex); -		cudaError_t err = cudaGetLastError(); - -		// Ignore errors caused by calling cudaSetDevice multiple times -		if (err != cudaSuccess && err != cudaErrorSetOnActiveProcess) -			return false; -	} - -	return true; -} - -  } diff --git a/cuda/2d/darthelper.h b/cuda/2d/darthelper.h index a2f1f45..67a6a7d 100644 --- a/cuda/2d/darthelper.h +++ b/cuda/2d/darthelper.h @@ -28,7 +28,7 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #ifndef _CUDA_ARITH2_H  #define _CUDA_ARITH2_H -#include "util.h" +#include "astra/Globals.h"  namespace astraCUDA { @@ -36,8 +36,6 @@ namespace astraCUDA {  	void dartMask(float* out, const float* in, unsigned int conn, unsigned int radius, unsigned int threshold, unsigned int width, unsigned int height);  	void dartSmoothing(float* out, const float* in, float b, unsigned int radius, unsigned int width, unsigned int height); -	_AstraExport bool setGPUIndex(int index); -  }  #endif diff --git a/cuda/2d/em.h b/cuda/2d/em.h index f99e798..15795f7 100644 --- a/cuda/2d/em.h +++ b/cuda/2d/em.h @@ -28,7 +28,6 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #ifndef _CUDA_EM_H  #define _CUDA_EM_H -#include "util.h"  #include "algo.h"  namespace astraCUDA { diff --git a/cuda/2d/fbp.cu b/cuda/2d/fbp.cu index 04cac1e..365fc88 100644 --- a/cuda/2d/fbp.cu +++ b/cuda/2d/fbp.cu @@ -30,6 +30,7 @@ $Id$  #include "fft.h"  #include "par_bp.h"  #include "fan_bp.h" +#include "util.h"  // For fan-beam preweighting  #include "../3d/fdk.h" diff --git a/cuda/2d/sart.h b/cuda/2d/sart.h index ab99e66..06051ae 100644 --- a/cuda/2d/sart.h +++ b/cuda/2d/sart.h @@ -28,7 +28,6 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #ifndef _CUDA_SART_H  #define _CUDA_SART_H -#include "util.h"  #include "algo.h"  namespace astraCUDA { diff --git a/cuda/2d/sirt.h b/cuda/2d/sirt.h index 488ab0a..7c440d5 100644 --- a/cuda/2d/sirt.h +++ b/cuda/2d/sirt.h @@ -28,7 +28,6 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #ifndef _CUDA_SIRT_H  #define _CUDA_SIRT_H -#include "util.h"  #include "algo.h"  namespace astraCUDA { diff --git a/cuda/2d/util.cu b/cuda/2d/util.cu index 09d1a2b..871e139 100644 --- a/cuda/2d/util.cu +++ b/cuda/2d/util.cu @@ -274,5 +274,4 @@ void reportCudaError(cudaError_t err)  } -  } diff --git a/cuda/2d/util.h b/cuda/2d/util.h index 875aae3..382d862 100644 --- a/cuda/2d/util.h +++ b/cuda/2d/util.h @@ -30,22 +30,9 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #include <cuda.h>  #include <driver_types.h> +#include <string> -#ifdef _MSC_VER - -#ifdef DLL_EXPORTS -#define _AstraExport __declspec(dllexport) -#define EXPIMP_TEMPLATE -#else -#define _AstraExport __declspec(dllimport) -#define EXPIMP_TEMPLATE extern -#endif - -#else - -#define _AstraExport - -#endif +#include "astra/Globals.h"  #include "dims.h" @@ -92,7 +79,6 @@ void reportCudaError(cudaError_t err);  float dotProduct2D(float* D_data, unsigned int pitch,                     unsigned int width, unsigned int height); -  }  #endif diff --git a/cuda/3d/cgls3d.h b/cuda/3d/cgls3d.h index e09fcfb..2ed2b1d 100644 --- a/cuda/3d/cgls3d.h +++ b/cuda/3d/cgls3d.h @@ -28,7 +28,6 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #ifndef _CUDA_CGLS3D_H  #define _CUDA_CGLS3D_H -#include "util3d.h"  #include "algo3d.h"  namespace astraCUDA3d { diff --git a/cuda/3d/darthelper3d.h b/cuda/3d/darthelper3d.h index 71ea5b0..539fa06 100644 --- a/cuda/3d/darthelper3d.h +++ b/cuda/3d/darthelper3d.h @@ -28,10 +28,7 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #ifndef _CUDA_DARTHELPER3_H  #define _CUDA_DARTHELPER3_H -#include <cuda.h> -#include <driver_types.h> -#include "util3d.h" -#include "algo3d.h" +#include "dims3d.h"  namespace astraCUDA3d { diff --git a/cuda/3d/mem3d.cu b/cuda/3d/mem3d.cu index ed779fa..2369149 100644 --- a/cuda/3d/mem3d.cu +++ b/cuda/3d/mem3d.cu @@ -326,7 +326,7 @@ 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) +_AstraExport MemHandle3D wrapHandle(float *D_ptr, unsigned int x, unsigned int y, unsigned int z, unsigned int pitch)  {  	cudaPitchedPtr ptr;  	ptr.ptr = D_ptr; diff --git a/cuda/3d/mem3d.h b/cuda/3d/mem3d.h index 7a87ae6..619354b 100644 --- a/cuda/3d/mem3d.h +++ b/cuda/3d/mem3d.h @@ -80,7 +80,7 @@ enum Mem3DZeroMode {  size_t availableGPUMemory();  int maxBlockDimension(); -MemHandle3D wrapHandle(float *D_ptr, unsigned int x, unsigned int y, unsigned int z, unsigned int pitch); +_AstraExport 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); diff --git a/cuda/3d/sirt3d.h b/cuda/3d/sirt3d.h index 69031b8..337ca89 100644 --- a/cuda/3d/sirt3d.h +++ b/cuda/3d/sirt3d.h @@ -28,7 +28,6 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #ifndef _CUDA_SIRT3D_H  #define _CUDA_SIRT3D_H -#include "util3d.h"  #include "algo3d.h"  namespace astraCUDA3d { diff --git a/include/astra/Float32Data3DMemory.h b/include/astra/Float32Data3DMemory.h index 876aa37..4ebe60b 100644 --- a/include/astra/Float32Data3DMemory.h +++ b/include/astra/Float32Data3DMemory.h @@ -52,22 +52,10 @@ protected:  	 */  	 float32* m_pfData;	 -	/** Array of float32 pointers, each pointing to a single row  -	 * in the m_pfData memory block. -	 * To access element (ix, iy, iz) internally, use m_ppfDataRowInd[iz * m_iHeight + iy][ix] -	*/ -	float32** m_ppfDataRowInd; - -	/** Array of float32 pointers, each pointing to a single slice  -	 * in the m_pfData memory block. -	 * To access element (ix, iy, iz) internally, use m_pppfDataSliceInd[iz][iy][ix] -	*/ -	float32*** m_pppfDataSliceInd;	 -  	float32 m_fGlobalMin;	///< minimum value of the data  	float32 m_fGlobalMax;	///< maximum value of the data -	/** Allocate memory for m_pfData, m_ppfDataRowInd and m_pppfDataSliceInd arrays. +	/** Allocate memory for m_pfData.  	 *  	 * The allocated block consists of m_iSize float32s. The block is  	 * not cleared after allocation and its contents is undefined.  @@ -75,7 +63,7 @@ protected:  	 */  	void _allocateData(); -	/** Free memory for m_pfData, m_ppfDataRowInd and m_pppfDataSliceInd arrays. +	/** Free memory for m_pfData.  	 *  	 * This function may ONLY be called if the memory for both blocks has been   	 * allocated before. @@ -299,23 +287,6 @@ inline const float32* CFloat32Data3DMemory::getDataConst() const  	return (const float32*)m_pfData;  } -//---------------------------------------------------------------------------------------- -// Get a float32** to the data block, represented as a 3-dimensional array of float32 values. -inline float32*** CFloat32Data3DMemory::getData3D() -{ -	ASTRA_ASSERT(m_bInitialized); -	return m_pppfDataSliceInd; -} - -//---------------------------------------------------------------------------------------- -// Get a const float32** to the data block, represented as a 3-dimensional array of float32 values. -inline const float32*** CFloat32Data3DMemory::getData3DConst() const -{ -	ASTRA_ASSERT(m_bInitialized); -	return (const float32***)m_pppfDataSliceInd; -} -//---------------------------------------------------------------------------------------- -  } // end namespace astra  #endif // _INC_ASTRA_FLOAT32DATA2D diff --git a/include/astra/Globals.h b/include/astra/Globals.h index 0adc3e5..2ae1f78 100644 --- a/include/astra/Globals.h +++ b/include/astra/Globals.h @@ -60,7 +60,7 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #define ASTRA_TOOLBOXVERSION_MAJOR 1  #define ASTRA_TOOLBOXVERSION_MINOR 8  #define ASTRA_TOOLBOXVERSION ((ASTRA_TOOLBOXVERSION_MAJOR)*100 + (ASTRA_TOOLBOXVERSION_MINOR)) -#define ASTRA_TOOLBOXVERSION_STRING "1.8" +#define ASTRA_TOOLBOXVERSION_STRING "1.8.3"  #define ASTRA_ASSERT(a) assert(a) @@ -121,21 +121,6 @@ namespace astra {  //}  //---------------------------------------------------------------------------------------- -// errors -namespace astra { - -typedef enum {ASTRA_SUCCESS,  -			  ASTRA_ERROR_NOT_INITIALIZED, -			  ASTRA_ERROR_INVALID_FILE, -			  ASTRA_ERROR_OUT_OF_RANGE, -			  ASTRA_ERROR_DIMENSION_MISMATCH, -			  ASTRA_ERROR_EXTERNAL_LIBRARY, -			  ASTRA_ERROR_ALLOCATION, -			  ASTRA_ERROR_NOT_IMPLEMENTED} AstraError; -} - - -//----------------------------------------------------------------------------------------  // variables  namespace astra {  	const float32 PI = 3.14159265358979323846264338328f; @@ -148,51 +133,6 @@ namespace astra {  }  //---------------------------------------------------------------------------------------- -// math -namespace astra { - -	inline float32 cos_73s(float32 x)  -	{  -		/* -		const float32 c1 =  0.999999953464f; -		const float32 c2 = -0.4999999053455f; -		const float32 c3 =  0.0416635846769f; -		const float32 c4 = -0.0013853704264f; -		const float32 c5 =  0.000023233f; -		*/ -		const float c1= (float)0.99940307; -		const float c2= (float)-0.49558072; -		const float c3= (float)0.03679168; - -		float32 x2; -		x2 = x * x; -		//return (c1 + x2*(c2 + x2*(c3 + x2*(c4 + c5*x2)))); -		return (c1 + x2*(c2 + c3 * x2)); -	} - -	inline float32 fast_cos(float32 x)  -	{ -		int quad;  - -		//x = fmod(x, 2*PI);		// Get rid of values > 2* pi -		if (x < 0) x = -x;		// cos(-x) = cos(x) -		quad = int(x/PIdiv2);	// Get quadrant # (0 to 3)  -		switch (quad) { -			case 0: return  cos_73s(x); -			case 1: return -cos_73s(PI-x); -			case 2: return -cos_73s(x-PI); -			case 3: return  cos_73s(2*PI-x); -		} -		return 0.0f; -	} - -	inline float32 fast_sin(float32 x){ -		return fast_cos(PIdiv2-x); -	} - -} - -//----------------------------------------------------------------------------------------  // structs  namespace astra {  	/** @@ -226,47 +166,6 @@ namespace astra {  	};  } -//---------------------------------------------------------------------------------------- -// functions for testing -template<typename T> -inline void writeArray(T*** arr, int dim1, int dim2, int dim3, const std::string& filename) -{ -	std::ofstream out(filename.c_str()); -	int i1, i2, i3; -	for (i1 = 0; i1 < dim1; ++i1) { -		for (i2 = 0; i2 < dim2; ++i2) { -			for (i3 = 0; i3 < dim3; ++i3) { -				out << arr[i1][i2][i3] << " "; -			} -			out << std::endl; -		} -		out << std::endl; -	} -	out.close(); -} - -template<typename T> -inline void writeArray(T** arr, int dim1, int dim2, const std::string& filename) -{ -	std::ofstream out(filename.c_str()); -	for (int i1 = 0; i1 < dim1; i1++) { -		for (int i2 = 0; i2 < dim2; i2++) { -			out << arr[i1][i2] << " "; -		} -		out << std::endl; -	} -	out.close(); -} - -template<typename T> -inline void writeArray(T* arr, int dim1, const std::string& filename) -{ -	std::ofstream out(filename.c_str()); -	for (int i1 = 0; i1 < dim1; i1++) { -		out << arr[i1] << " "; -	} -	out.close(); -}  namespace astra {  _AstraExport inline int getVersion() { return ASTRA_TOOLBOXVERSION; }  _AstraExport inline const char* getVersionString() { return ASTRA_TOOLBOXVERSION_STRING; } @@ -280,7 +179,6 @@ _AstraExport inline bool cudaEnabled() { return false; }  // portability between MSVC and Linux/gcc  #ifndef _MSC_VER -#include "swrap.h"  #define EXPIMP_TEMPLATE  #if !defined(FORCEINLINE) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) diff --git a/include/astra/swrap.h b/include/astra/swrap.h deleted file mode 100644 index cd479f3..0000000 --- a/include/astra/swrap.h +++ /dev/null @@ -1,40 +0,0 @@ -/* ------------------------------------------------------------------------ -Copyright: 2010-2016, iMinds-Vision Lab, University of Antwerp -           2014-2016, CWI, Amsterdam - -Contact: astra@uantwerpen.be -Website: http://www.astra-toolbox.com/ - -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/>. - ------------------------------------------------------------------------ -*/ - -#ifndef _INC_ASTRA_SWRAP_H -#define _INC_ASTRA_SWRAP_H - -#ifndef _MSC_VER - -#include <cstdio> - -typedef int errno_t; -errno_t fopen_s(FILE** pFile, const char *filename, const char *mode); - -#endif - -#endif diff --git a/matlab/algorithms/DART/StatisticsDefault.m b/matlab/algorithms/DART/StatisticsDefault.m index 02e877b..84275d9 100644 --- a/matlab/algorithms/DART/StatisticsDefault.m +++ b/matlab/algorithms/DART/StatisticsDefault.m @@ -42,7 +42,7 @@ classdef StatisticsDefault < matlab.mixin.Copyable  			% projection difference  			if strcmp(this.proj_diff, 'yes')  -				new_sino = DART.tomography.createForwardProjection(DART, DART.S); +				new_sino = DART.tomography.project(DART.S);  				stats.proj_diff = sum((new_sino(:) - DART.base.sinogram(:)) .^2 ) ./ (sum(DART.base.sinogram(:)) );  				stats.proj_diff_hist(DART.iterationcount) = stats.proj_diff;  			end diff --git a/matlab/algorithms/DART/tools/DARToptimizerBoneStudy.m b/matlab/algorithms/DART/tools/DARToptimizerBoneStudy.m index c641f87..f488cd6 100644 --- a/matlab/algorithms/DART/tools/DARToptimizerBoneStudy.m +++ b/matlab/algorithms/DART/tools/DARToptimizerBoneStudy.m @@ -97,7 +97,7 @@ function rmse = optim_func(values, D_base, params, Optim)  	% compute rmse  	ROI = load('roi.mat');  	[rmse, f_250, f_100, w_250, w_125] = compute_rmse(D.S, ROI); -	%projection = D.tomography.createForwardProjection(D, D.S); +	%projection = D.tomography.project(D.S);  	%proj_diff = sum((projection(:) - D.base.sinogram(:)).^2);  	% save diff --git a/matlab/algorithms/DART/tools/ProjDiffOptimFunc.m b/matlab/algorithms/DART/tools/ProjDiffOptimFunc.m index 72b328f..64d71fd 100644 --- a/matlab/algorithms/DART/tools/ProjDiffOptimFunc.m +++ b/matlab/algorithms/DART/tools/ProjDiffOptimFunc.m @@ -19,7 +19,7 @@ classdef ProjDiffOptimFunc < handle  	methods (Access=public)	  		function proj_diff = calculate(~, D, ~) -			projection = D.tomography.createForwardProjection(D, D.S); +			projection = D.tomography.project(D.S);  			proj_diff = sum((projection(:) - D.base.sinogram(:)).^2);  		end diff --git a/matlab/mex/astra_mex_c.cpp b/matlab/mex/astra_mex_c.cpp index d9ff8f3..017946a 100644 --- a/matlab/mex/astra_mex_c.cpp +++ b/matlab/mex/astra_mex_c.cpp @@ -38,7 +38,8 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #include "astra/AstraObjectManager.h"  #ifdef ASTRA_CUDA -#include "../cuda/2d/darthelper.h" +#include "../cuda/2d/astra.h" +#include "../cuda/2d/util.h"  #include "astra/CompositeGeometryManager.h"  #endif @@ -131,6 +132,22 @@ void astra_mex_set_gpu_index(int nlhs, mxArray* plhs[], int nrhs, const mxArray*  #endif  } +/** get_gpu_info = astra_mex('get_gpu_info'); + *  + * Get GPU info + */ +void astra_mex_get_gpu_info(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ +#ifdef ASTRA_CUDA +	int device = -1; +	if (nrhs >= 2 && mxIsDouble(prhs[1]) && mxGetN(prhs[1]) * mxGetM(prhs[1]) == 1 ) { +		device = (int)mxGetScalar(prhs[1]); +	} +	mexPrintf("%s\n", astraCUDA::getCudaDeviceString(device).c_str()); +#endif +} + +  //-----------------------------------------------------------------------------------------  /** version_number = astra_mex('version');   *  @@ -222,6 +239,8 @@ void mexFunction(int nlhs, mxArray* plhs[],  		astra_mex_credits(nlhs, plhs, nrhs, prhs);   	} else if (sMode == std::string("set_gpu_index")) {  		astra_mex_set_gpu_index(nlhs, plhs, nrhs, prhs); +	} else if (sMode == std::string("get_gpu_info")) { +		astra_mex_get_gpu_info(nlhs, plhs, nrhs, prhs);  	} else if (sMode == std::string("info")) {  		astra_mex_info(nlhs, plhs, nrhs, prhs);  	} else if (sMode == std::string("delete")) { diff --git a/matlab/tools/astra_create_vol_geom.m b/matlab/tools/astra_create_vol_geom.m index bf24609..24fa957 100644 --- a/matlab/tools/astra_create_vol_geom.m +++ b/matlab/tools/astra_create_vol_geom.m @@ -38,21 +38,12 @@ if numel(varargin) == 1 && numel(varargin{1}) == 1  	vol_geom = struct();  	vol_geom.GridRowCount = varargin{1}(1);  	vol_geom.GridColCount =	varargin{1}(1); -	vol_geom.option.WindowMinX = -varargin{1}(1) / 2; -	vol_geom.option.WindowMaxX = varargin{1}(1) / 2; -	vol_geom.option.WindowMinY = -varargin{1}(1) / 2; -	vol_geom.option.WindowMaxY = varargin{1}(1) / 2; -  % astra_create_vol_geom([row_count col_count])  elseif numel(varargin) == 1 && numel(varargin{1}) == 2  	vol_geom = struct();  	vol_geom.GridRowCount = varargin{1}(1);  	vol_geom.GridColCount =	varargin{1}(2); -	vol_geom.option.WindowMinX = -varargin{1}(2) / 2; -	vol_geom.option.WindowMaxX = varargin{1}(2) / 2; -	vol_geom.option.WindowMinY = -varargin{1}(1) / 2; -	vol_geom.option.WindowMaxY = varargin{1}(1) / 2;  % astra_create_vol_geom([row_count col_count slice_count])  elseif numel(varargin) == 1 && numel(varargin{1}) == 3 @@ -60,22 +51,12 @@ elseif numel(varargin) == 1 && numel(varargin{1}) == 3  	vol_geom.GridRowCount = varargin{1}(1);  	vol_geom.GridColCount =	varargin{1}(2);  	vol_geom.GridSliceCount = varargin{1}(3);	 -	vol_geom.option.WindowMinX = -varargin{1}(2) / 2; -	vol_geom.option.WindowMaxX = varargin{1}(2) / 2; -	vol_geom.option.WindowMinY = -varargin{1}(1) / 2; -	vol_geom.option.WindowMaxY = varargin{1}(1) / 2; -	vol_geom.option.WindowMinZ = -varargin{1}(3) / 2; -	vol_geom.option.WindowMaxZ = varargin{1}(3) / 2;	  % astra_create_vol_geom(row_count, col_count)  elseif numel(varargin) == 2  	vol_geom = struct();  	vol_geom.GridRowCount = varargin{1};  	vol_geom.GridColCount =	varargin{2}; -	vol_geom.option.WindowMinX = -varargin{2} / 2; -	vol_geom.option.WindowMaxX = varargin{2} / 2; -	vol_geom.option.WindowMinY = -varargin{1} / 2; -	vol_geom.option.WindowMaxY = varargin{1} / 2;  % astra_create_vol_geom(row_count, col_count, min_x, max_x, min_y, max_y)  elseif numel(varargin) == 6 @@ -108,3 +89,15 @@ elseif numel(varargin) == 9  	vol_geom.option.WindowMaxZ = varargin{9};  end + +% set the window options, if not set already. +if ~isfield(vol_geom, 'option') || ~isfield(vol_geom.option, 'WindowMinX') +	vol_geom.option.WindowMinX = -vol_geom.GridColCount / 2; +	vol_geom.option.WindowMaxX =  vol_geom.GridColCount / 2; +	vol_geom.option.WindowMinY = -vol_geom.GridRowCount / 2; +	vol_geom.option.WindowMaxY =  vol_geom.GridRowCount / 2; +	if isfield(vol_geom, 'GridSliceCount') +		vol_geom.option.WindowMinZ = -vol_geom.GridSliceCount / 2; +		vol_geom.option.WindowMaxZ =  vol_geom.GridSliceCount / 2; +	end +end diff --git a/matlab/tools/astra_get_gpu_info.m b/matlab/tools/astra_get_gpu_info.m new file mode 100644 index 0000000..c220371 --- /dev/null +++ b/matlab/tools/astra_get_gpu_info.m @@ -0,0 +1,20 @@ +function astra_set_gpu_index(index) + +%-------------------------------------------------------------------------- +% Set the index of the GPU to use +%-------------------------------------------------------------------------- +%-------------------------------------------------------------------------- +% This file is part of the ASTRA Toolbox +%  +% Copyright: 2010-2016, iMinds-Vision Lab, University of Antwerp +%            2014-2016, CWI, Amsterdam +% License: Open Source under GPLv3 +% Contact: astra@uantwerpen.be +% Website: http://www.astra-toolbox.com/ +%-------------------------------------------------------------------------- + +if nargin < 1 +    astra_mex('get_gpu_info'); +else +    astra_mex('get_gpu_info', index); +end diff --git a/matlab/tools/astra_test_CUDA.m b/matlab/tools/astra_test_CUDA.m new file mode 100644 index 0000000..4171f20 --- /dev/null +++ b/matlab/tools/astra_test_CUDA.m @@ -0,0 +1,59 @@ +%-------------------------------------------------------------------------- +% Clears and frees memory of all objects (data, projectors, algorithms)  +% currently in the astra-library. +%-------------------------------------------------------------------------- +%-------------------------------------------------------------------------- +% This file is part of the ASTRA Toolbox +%  +% Copyright: 2010-2017, iMinds-Vision Lab, University of Antwerp +%            2014-2017, CWI, Amsterdam +% License: Open Source under GPLv3 +% Contact: astra@uantwerpen.be +% Website: http://www.astra-toolbox.com/ +%-------------------------------------------------------------------------- + +%% +fprintf('Getting GPU info...') +astra_get_gpu_info() + +%% +astra_test_noCUDA() + +%% +fprintf('Testing basic CUDA 2D functionality...') + +vg = astra_create_vol_geom(2, 32); +pg = astra_create_proj_geom('parallel', 1, 32, [0]); +proj_id = astra_create_projector('cuda', pg, vg); + +vol = rand(2, 32); +[sino_id, sino] = astra_create_sino(vol, proj_id); +astra_mex_data2d('delete', sino_id); +astra_mex_projector('delete', proj_id); + +err = max(abs(sino - sum(vol))); + +if err < 1e-6 +  disp('Ok') +else +  disp('Error') +end + +%% +fprintf('Testing basic CUDA 3D functionality...') + +vg = astra_create_vol_geom(2, 32, 32); +pg = astra_create_proj_geom('parallel3d', 1, 1, 32, 32, [0]); + +vol = rand(32, 2, 32); +[sino_id, sino] = astra_create_sino3d_cuda(vol, pg, vg); +astra_mex_data3d('delete', sino_id); + +err = max(max(abs(sino - sum(vol,2)))); + +if err < 1e-6 +  disp('Ok') +else +  disp('Error') +end + diff --git a/matlab/tools/astra_test_noCUDA.m b/matlab/tools/astra_test_noCUDA.m new file mode 100644 index 0000000..6437661 --- /dev/null +++ b/matlab/tools/astra_test_noCUDA.m @@ -0,0 +1,32 @@ +%-------------------------------------------------------------------------- +% Clears and frees memory of all objects (data, projectors, algorithms)  +% currently in the astra-library. +%-------------------------------------------------------------------------- +%-------------------------------------------------------------------------- +% This file is part of the ASTRA Toolbox +%  +% Copyright: 2010-2017, iMinds-Vision Lab, University of Antwerp +%            2014-2017, CWI, Amsterdam +% License: Open Source under GPLv3 +% Contact: astra@uantwerpen.be +% Website: http://www.astra-toolbox.com/ +%-------------------------------------------------------------------------- + +fprintf('Testing basic CPU 2D functionality...') + +vg = astra_create_vol_geom(2, 32); +pg = astra_create_proj_geom('parallel', 1, 32, [0]); +proj_id = astra_create_projector('line', pg, vg); + +vol = rand(2, 32); +[sino_id, sino] = astra_create_sino(vol, proj_id); +astra_mex_data2d('delete', sino_id); +astra_mex_projector('delete', proj_id); + +err = max(abs(sino - sum(vol))); + +if err < 1e-6 +  disp('Ok') +else +  disp('Error') +end diff --git a/python/astra/PyIncludes.pxd b/python/astra/PyIncludes.pxd index bba47f3..84469aa 100644 --- a/python/astra/PyIncludes.pxd +++ b/python/astra/PyIncludes.pxd @@ -156,6 +156,10 @@ cdef extern from "astra/ReconstructionAlgorithm2D.h" namespace "astra":      cdef cppclass CReconstructionAlgorithm2D:          bool getResidualNorm(float32&) +cdef extern from "astra/ReconstructionAlgorithm3D.h" namespace "astra": +    cdef cppclass CReconstructionAlgorithm3D: +        bool getResidualNorm(float32&) +  cdef extern from "astra/Projector2D.h" namespace "astra":      cdef cppclass CProjector2D:          bool isInitialized() @@ -211,7 +215,6 @@ cdef extern from "astra/Float32Data3DMemory.h" namespace "astra":          CFloat32Data3DMemory()          void updateStatistics()          float32 *getData() -        float32 ***getData3D()          THREEEDataType getType() diff --git a/python/astra/__init__.py b/python/astra/__init__.py index b73fff5..5e52a1c 100644 --- a/python/astra/__init__.py +++ b/python/astra/__init__.py @@ -27,6 +27,7 @@ from . import matlab as m  from .creators import astra_dict,create_vol_geom, create_proj_geom, create_backprojection, create_sino, create_reconstruction, create_projector,create_sino3d_gpu, create_backprojection3d_gpu  from .functions import data_op, add_noise_to_sino, clear, move_vol_geom  from .extrautils import clipCircle +from .astra import set_gpu_index, get_gpu_info  from . import data2d  from . import astra  from . import data3d @@ -38,11 +39,12 @@ from . import plugin  from . import plugins  from . import log  from .optomo import OpTomo +from .tests import test_noCUDA, test_CUDA -__version__ = '1.8' +__version__ = '1.8.3'  import os  if 'ASTRA_GPU_INDEX' in os.environ:      L = [ int(x) for x in os.environ['ASTRA_GPU_INDEX'].split(',') ] -    astra.set_gpu_index(L) +    set_gpu_index(L) diff --git a/python/astra/algorithm_c.pyx b/python/astra/algorithm_c.pyx index 9ed0634..161fe98 100644 --- a/python/astra/algorithm_c.pyx +++ b/python/astra/algorithm_c.pyx @@ -44,7 +44,8 @@ from .utils import wrap_from_bytes  cdef CAlgorithmManager * manAlg = <CAlgorithmManager * >PyAlgorithmManager.getSingletonPtr()  cdef extern from *: -    CReconstructionAlgorithm2D * dynamic_cast_recAlg "dynamic_cast<astra::CReconstructionAlgorithm2D*>" (CAlgorithm * ) except NULL +    CReconstructionAlgorithm2D * dynamic_cast_recAlg2D "dynamic_cast<astra::CReconstructionAlgorithm2D*>" (CAlgorithm * ) +    CReconstructionAlgorithm3D * dynamic_cast_recAlg3D "dynamic_cast<astra::CReconstructionAlgorithm3D*>" (CAlgorithm * )  def create(config): @@ -79,12 +80,18 @@ def run(i, iterations=0):  def get_res_norm(i):      cdef CReconstructionAlgorithm2D * pAlg2D +    cdef CReconstructionAlgorithm3D * pAlg3D      cdef CAlgorithm * alg = getAlg(i)      cdef float32 res = 0.0 -    pAlg2D = dynamic_cast_recAlg(alg) -    if pAlg2D == NULL: -        raise Exception("Operation not supported.") -    if not pAlg2D.getResidualNorm(res): +    pAlg2D = dynamic_cast_recAlg2D(alg) +    pAlg3D = dynamic_cast_recAlg3D(alg) +    if pAlg2D != NULL: +        if not pAlg2D.getResidualNorm(res): +            raise Exception("Operation not supported.") +    elif pAlg3D != NULL: +        if not pAlg3D.getResidualNorm(res): +            raise Exception("Operation not supported.") +    else:          raise Exception("Operation not supported.")      return res diff --git a/python/astra/astra.py b/python/astra/astra.py index 3804d51..434ccb9 100644 --- a/python/astra/astra.py +++ b/python/astra/astra.py @@ -45,6 +45,16 @@ def set_gpu_index(idx, memory=0):      """      a.set_gpu_index(idx, memory) +def get_gpu_info(idx=-1): +    """Get GPU info. +     +    :param idx: GPU index, or -1 for current device +    :type idx: :class:`int` +    :returns: :class:`str` -- GPU info +    """ +    return a.get_gpu_info(idx) + +  def delete(ids):      """Delete an astra object. diff --git a/python/astra/astra_c.pyx b/python/astra/astra_c.pyx index 6de10da..f25fc2a 100644 --- a/python/astra/astra_c.pyx +++ b/python/astra/astra_c.pyx @@ -40,11 +40,15 @@ cdef extern from "astra/Globals.h" namespace "astra":      bool cudaEnabled()  IF HAVE_CUDA==True: -  cdef extern from "../cuda/2d/darthelper.h" namespace "astraCUDA": +  cdef extern from "../cuda/2d/astra.h" namespace "astraCUDA":        bool setGPUIndex(int) +      string getCudaDeviceString(int)  ELSE:    def setGPUIndex():      pass +  def getCudaDeviceString(idx): +    pass +  cdef extern from "astra/CompositeGeometryManager.h" namespace "astra":      cdef cppclass SGPUParams:          vector[int] GPUIndices @@ -85,9 +89,13 @@ IF HAVE_CUDA==True:          ret = setGPUIndex(params.GPUIndices[0])          if not ret:              six.print_("Failed to set GPU " + str(params.GPUIndices[0])) +  def get_gpu_info(idx=-1): +    return wrap_from_bytes(getCudaDeviceString(idx))  ELSE:    def set_gpu_index(idx, memory=0):      raise NotImplementedError("CUDA support is not enabled in ASTRA") +  def get_gpu_info(idx=-1): +    raise NotImplementedError("CUDA support is not enabled in ASTRA")  def delete(ids):      import collections diff --git a/python/astra/creators.py b/python/astra/creators.py index 4ddaf0c..85daf82 100644 --- a/python/astra/creators.py +++ b/python/astra/creators.py @@ -81,37 +81,19 @@ This method can be called in a number of ways:      if len(varargin) == 1 and isinstance(varargin[0], int) == 1:          vol_geom['GridRowCount'] = varargin[0]          vol_geom['GridColCount'] = varargin[0] -        vol_geom['option']['WindowMinX'] = -varargin[0] / 2. -        vol_geom['option']['WindowMaxX'] = varargin[0] / 2. -        vol_geom['option']['WindowMinY'] = -varargin[0] / 2. -        vol_geom['option']['WindowMaxY'] = varargin[0] / 2.      # astra_create_vol_geom([row_count col_count])      elif len(varargin) == 1 and len(varargin[0]) == 2:          vol_geom['GridRowCount'] = varargin[0][0]          vol_geom['GridColCount'] = varargin[0][1] -        vol_geom['option']['WindowMinX'] = -varargin[0][1] / 2. -        vol_geom['option']['WindowMaxX'] = varargin[0][1] / 2. -        vol_geom['option']['WindowMinY'] = -varargin[0][0] / 2. -        vol_geom['option']['WindowMaxY'] = varargin[0][0] / 2.      # astra_create_vol_geom([row_count col_count slice_count])      elif len(varargin) == 1 and len(varargin[0]) == 3:          vol_geom['GridRowCount'] = varargin[0][0]          vol_geom['GridColCount'] = varargin[0][1]          vol_geom['GridSliceCount'] = varargin[0][2] -        vol_geom['option']['WindowMinX'] = -varargin[0][1] / 2. -        vol_geom['option']['WindowMaxX'] = varargin[0][1] / 2. -        vol_geom['option']['WindowMinY'] = -varargin[0][0] / 2. -        vol_geom['option']['WindowMaxY'] = varargin[0][0] / 2. -        vol_geom['option']['WindowMinZ'] = -varargin[0][2] / 2. -        vol_geom['option']['WindowMaxZ'] = varargin[0][2] / 2.      # astra_create_vol_geom(row_count, col_count)      elif len(varargin) == 2:          vol_geom['GridRowCount'] = varargin[0]          vol_geom['GridColCount'] = varargin[1] -        vol_geom['option']['WindowMinX'] = -varargin[1] / 2. -        vol_geom['option']['WindowMaxX'] = varargin[1] / 2. -        vol_geom['option']['WindowMinY'] = -varargin[0] / 2. -        vol_geom['option']['WindowMaxY'] = varargin[0] / 2.      # astra_create_vol_geom(row_count, col_count, min_x, max_x, min_y, max_y)      elif len(varargin) == 6:          vol_geom['GridRowCount'] = varargin[0] @@ -136,6 +118,17 @@ This method can be called in a number of ways:          vol_geom['option']['WindowMaxY'] = varargin[6]          vol_geom['option']['WindowMinZ'] = varargin[7]          vol_geom['option']['WindowMaxZ'] = varargin[8] + +    # set the window options, if not set already. +    if not 'WindowMinX' in vol_geom['option']: +        vol_geom['option']['WindowMinX'] = -vol_geom['GridColCount'] / 2. +        vol_geom['option']['WindowMaxX'] =  vol_geom['GridColCount'] / 2. +        vol_geom['option']['WindowMinY'] = -vol_geom['GridRowCount'] / 2. +        vol_geom['option']['WindowMaxY'] =  vol_geom['GridRowCount'] / 2. +        if 'GridSliceCount' in vol_geom: +            vol_geom['option']['WindowMinZ'] = -vol_geom['GridSliceCount'] / 2. +            vol_geom['option']['WindowMaxZ'] =  vol_geom['GridSliceCount'] / 2. +      return vol_geom diff --git a/python/astra/data3d_c.pyx b/python/astra/data3d_c.pyx index 78ed620..897634b 100644 --- a/python/astra/data3d_c.pyx +++ b/python/astra/data3d_c.pyx @@ -60,7 +60,13 @@ cdef extern from "Python.h":  cdef CData3DManager * man3d = <CData3DManager * >PyData3DManager.getSingletonPtr()  cdef extern from *: -    CFloat32Data3DMemory * dynamic_cast_mem "dynamic_cast<astra::CFloat32Data3DMemory*>" (CFloat32Data3D * ) except NULL +    CFloat32Data3DMemory * dynamic_cast_mem "dynamic_cast<astra::CFloat32Data3DMemory*>" (CFloat32Data3D * ) + +cdef CFloat32Data3DMemory * dynamic_cast_mem_safe(CFloat32Data3D *obj) except NULL: +    cdef CFloat32Data3DMemory *ret = dynamic_cast_mem(obj) +    if not ret: +        raise RuntimeError("Not a memory 3D data object") +    return ret  cdef extern from "CFloat32CustomPython.h":      cdef cppclass CFloat32CustomPython: @@ -154,12 +160,12 @@ def create(datatype,geometry,data=None, link=False):          raise RuntimeError("Couldn't initialize data object.")      if not link: -        fillDataObject(dynamic_cast_mem(pDataObject3D), data) +        fillDataObject(dynamic_cast_mem_safe(pDataObject3D), data)      return man3d.store(<CFloat32Data3D*>pDataObject3D)  def get_geometry(i): -    cdef CFloat32Data3DMemory * pDataObject = dynamic_cast_mem(getObject(i)) +    cdef CFloat32Data3DMemory * pDataObject = dynamic_cast_mem_safe(getObject(i))      cdef CFloat32ProjectionData3DMemory * pDataObject2      cdef CFloat32VolumeData3DMemory * pDataObject3      if pDataObject.getType() == THREEPROJECTION: @@ -173,7 +179,7 @@ def get_geometry(i):      return geom  def change_geometry(i, geom): -    cdef CFloat32Data3DMemory * pDataObject = dynamic_cast_mem(getObject(i)) +    cdef CFloat32Data3DMemory * pDataObject = dynamic_cast_mem_safe(getObject(i))      cdef CFloat32ProjectionData3DMemory * pDataObject2      cdef CFloat32VolumeData3DMemory * pDataObject3      if pDataObject.getType() == THREEPROJECTION: @@ -248,7 +254,7 @@ cdef fillDataObjectScalar(CFloat32Data3DMemory * obj, float s):  @cython.boundscheck(False)  @cython.wraparound(False)  cdef fillDataObjectArray(CFloat32Data3DMemory * obj, float [:,:,::1] data): -    cdef float [:,:,::1] cView = <float[:data.shape[0],:data.shape[1],:data.shape[2]]> obj.getData3D()[0][0] +    cdef float [:,:,::1] cView = <float[:data.shape[0],:data.shape[1],:data.shape[2]]> obj.getData()      cView[:] = data  cdef CFloat32Data3D * getObject(i) except NULL: @@ -262,28 +268,28 @@ cdef CFloat32Data3D * getObject(i) except NULL:  @cython.boundscheck(False)  @cython.wraparound(False)  def get(i): -    cdef CFloat32Data3DMemory * pDataObject = dynamic_cast_mem(getObject(i)) +    cdef CFloat32Data3DMemory * pDataObject = dynamic_cast_mem_safe(getObject(i))      outArr = np.empty((pDataObject.getDepth(),pDataObject.getHeight(), pDataObject.getWidth()),dtype=np.float32,order='C')      cdef float [:,:,::1] mView = outArr -    cdef float [:,:,::1] cView = <float[:outArr.shape[0],:outArr.shape[1],:outArr.shape[2]]> pDataObject.getData3D()[0][0] +    cdef float [:,:,::1] cView = <float[:outArr.shape[0],:outArr.shape[1],:outArr.shape[2]]> pDataObject.getData()      mView[:] = cView      return outArr  def get_shared(i): -    cdef CFloat32Data3DMemory * pDataObject = dynamic_cast_mem(getObject(i)) +    cdef CFloat32Data3DMemory * pDataObject = dynamic_cast_mem_safe(getObject(i))      outArr = np.empty((pDataObject.getDepth(),pDataObject.getHeight(), pDataObject.getWidth()),dtype=np.float32,order='C')      cdef np.npy_intp shape[3]      shape[0] = <np.npy_intp> pDataObject.getDepth()      shape[1] = <np.npy_intp> pDataObject.getHeight()      shape[2] = <np.npy_intp> pDataObject.getWidth() -    return np.PyArray_SimpleNewFromData(3,shape,np.NPY_FLOAT32,<void *>pDataObject.getData3D()[0][0]) +    return np.PyArray_SimpleNewFromData(3,shape,np.NPY_FLOAT32,<void *>pDataObject.getData())  def get_single(i):      raise NotImplementedError("Not yet implemented")  def store(i,data):      cdef CFloat32Data3D * pDataObject = getObject(i) -    fillDataObject(dynamic_cast_mem(pDataObject), data) +    fillDataObject(dynamic_cast_mem_safe(pDataObject), data)  def dimensions(i):      cdef CFloat32Data3D * pDataObject = getObject(i) diff --git a/python/astra/experimental.pyx b/python/astra/experimental.pyx index 0af3118..136165b 100644 --- a/python/astra/experimental.pyx +++ b/python/astra/experimental.pyx @@ -40,8 +40,8 @@ IF HAVE_CUDA==True:              bool doBP(CProjector3D *, vector[CFloat32VolumeData3D *], vector[CFloat32ProjectionData3D *])      cdef extern from *: -        CFloat32VolumeData3D * dynamic_cast_vol_mem "dynamic_cast<astra::CFloat32VolumeData3D*>" (CFloat32Data3D * ) except NULL -        CFloat32ProjectionData3D * dynamic_cast_proj_mem "dynamic_cast<astra::CFloat32ProjectionData3D*>" (CFloat32Data3D * ) except NULL +        CFloat32VolumeData3D * dynamic_cast_vol_mem "dynamic_cast<astra::CFloat32VolumeData3D*>" (CFloat32Data3D * ) +        CFloat32ProjectionData3D * dynamic_cast_proj_mem "dynamic_cast<astra::CFloat32ProjectionData3D*>" (CFloat32Data3D * )      cdef extern from "astra/Float32ProjectionData3D.h" namespace "astra":          cdef cppclass CFloat32ProjectionData3D: diff --git a/python/astra/tests.py b/python/astra/tests.py new file mode 100644 index 0000000..32afd36 --- /dev/null +++ b/python/astra/tests.py @@ -0,0 +1,97 @@ +# ----------------------------------------------------------------------- +# Copyright: 2010-2017, iMinds-Vision Lab, University of Antwerp +#            2013-2017, CWI, Amsterdam +# +# Contact: astra@uantwerpen.be +# Website: http://www.astra-toolbox.com/ +# +# 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/>. +# +# ----------------------------------------------------------------------- + +from __future__ import print_function, absolute_import + +def _basic_par2d_fp(type): +  import astra +  import numpy as np +  vg = astra.create_vol_geom(2, 32) +  pg = astra.create_proj_geom('parallel', 1, 32, [0]) +  proj_id = astra.create_projector(type, pg, vg) +  vol = np.random.rand(2, 32) +  (sino_id, sino) = astra.create_sino(vol, proj_id) +  astra.data2d.delete(sino_id) +  astra.projector.delete(proj_id) +  err = np.max(np.abs(sino[0,:] - np.sum(vol,axis=0))) +  return err < 1e-6 + +def _basic_par3d_fp(): +  import astra +  import numpy as np +  vg = astra.create_vol_geom(2, 32, 32) +  pg = astra.create_proj_geom('parallel3d', 1, 1, 32, 32, [0]) +  vol = np.random.rand(32, 2, 32) +  (sino_id, sino) = astra.create_sino3d_gpu(vol, pg, vg) +  astra.data3d.delete(sino_id) +  err = np.max(np.abs(sino[:,0,:] - np.sum(vol,axis=1))) +  return err < 1e-6 + + +def _basic_par2d(): +  print("Testing basic CPU 2D functionality... ", end="") +  if _basic_par2d_fp('line'): +    print("Ok") +    return True +  else: +    print("Error") +    return False + +def _basic_par2d_cuda(): +  print("Testing basic CUDA 2D functionality... ", end="") +  if _basic_par2d_fp('cuda'): +    print("Ok") +    return True +  else: +    print("Error") +    return False + +def _basic_par3d_cuda(): +  print("Testing basic CUDA 3D functionality... ", end="") +  if _basic_par3d_fp(): +    print("Ok") +    return True +  else: +    print("Error") +    return False + +def test_noCUDA(): +  """Perform a very basic functionality test, without CUDA""" +   +  ok = _basic_par2d() +  if not ok: +    raise RuntimeError("Test failed") + +def test_CUDA(): +  """Perform a very basic functionality test, including CUDA""" +   +  import astra +  print("Getting GPU info... ", end="") +  print(astra.get_gpu_info()) +  ok1 = _basic_par2d() +  ok2 = _basic_par2d_cuda() +  ok3 = _basic_par3d_cuda() +  if not (ok1 and ok2 and ok3): +    raise RuntimeError("Test failed") diff --git a/python/astra/utils.pyx b/python/astra/utils.pyx index a40916b..bcff6c3 100644 --- a/python/astra/utils.pyx +++ b/python/astra/utils.pyx @@ -171,6 +171,7 @@ def stringToPythonValue(inputIn):      input = castString(inputIn)      # matrix      if ';' in input: +        input = input.rstrip(';')          row_strings = input.split(';')          col_strings = row_strings[0].split(',')          nRows = len(row_strings) @@ -185,6 +186,7 @@ def stringToPythonValue(inputIn):      # vector      if ',' in input: +        input = input.rstrip(',')          items = input.split(',')          out = np.empty(len(items))          for idx,item in enumerate(items): diff --git a/python/builder.py b/python/builder.py index ec0bd23..01f4203 100644 --- a/python/builder.py +++ b/python/builder.py @@ -71,7 +71,7 @@ for m in ext_modules:                                        'PythonPluginAlgorithm.cpp'))  setup(name='astra-toolbox', -      version='1.8', +      version='1.8.3',        description='Python interface to the ASTRA Toolbox',        author='D.M. Pelt',        author_email='D.M.Pelt@cwi.nl', diff --git a/python/conda/astra-toolbox/build.sh b/python/conda/astra-toolbox/build.sh index 951fd88..0468037 100644 --- a/python/conda/astra-toolbox/build.sh +++ b/python/conda/astra-toolbox/build.sh @@ -1,4 +1,10 @@  #!/bin/sh +case `uname` in +  Darwin*) +    CC="gcc -stdlib=libstdc++" +    ;; +esac +  cd $SRC_DIR/python/ -CPPFLAGS="-DASTRA_CUDA -DASTRA_PYTHON $CPPFLAGS -I$SRC_DIR/ -I$SRC_DIR/include -I$CUDA_ROOT/include" CC=$CC python ./builder.py build install +CPPFLAGS="-DASTRA_CUDA -DASTRA_PYTHON $CPPFLAGS -I$SRC_DIR/ -I$SRC_DIR/include" CC=$CC python ./builder.py build install diff --git a/python/conda/astra-toolbox/conda_build_config.yaml b/python/conda/astra-toolbox/conda_build_config.yaml new file mode 100644 index 0000000..bd38ac6 --- /dev/null +++ b/python/conda/astra-toolbox/conda_build_config.yaml @@ -0,0 +1,9 @@ +python: +  - 2.7 +  - 3.5 +  - 3.6 + +numpy: +  - 1.11 +  - 1.12 +  - 1.13 diff --git a/python/conda/astra-toolbox/meta.yaml b/python/conda/astra-toolbox/meta.yaml index 942397e..88a9172 100644 --- a/python/conda/astra-toolbox/meta.yaml +++ b/python/conda/astra-toolbox/meta.yaml @@ -1,41 +1,41 @@  package:    name: astra-toolbox -  version: '1.8' +  version: '1.8.3'  source:    git_url: https://github.com/astra-toolbox/astra-toolbox.git -  git_tag: v1.8 +  git_tag: v1.8.3  build:    number: 0    script_env: -    - CC # [not win] -    - CUDA_ROOT # [not win] +    - CC # [linux]  test:    imports:      - astra -    requires:      # To avoid large downloads just for testing after build phase      - nomkl # [not win] +    # import scipy.sparse.linalg fails with mkl-2017.0.4 on Windows +    - mkl !=2017.0.4 # [win]  requirements:    build:      - python      - cython >=0.13      - nomkl # [not win] -    - numpy +    - numpy {{ numpy }}      - scipy      - six -    - libastra ==1.8 +    - libastra ==1.8.3    run:      - python -    - numpy x.x +    - {{ pin_compatible('numpy', max_pin='x.x') }}      - scipy      - six -    - libastra ==1.8 +    - libastra ==1.8.3  about: diff --git a/python/conda/libastra/build.sh b/python/conda/libastra/build.sh index 304c053..aa9a4ce 100644 --- a/python/conda/libastra/build.sh +++ b/python/conda/libastra/build.sh @@ -1,5 +1,19 @@  #!/bin/sh +case `uname` in +  Darwin*) +    CUDA_ROOT=/usr/local/cuda +    CC=gcc +    CXX=g++ +    ;; +  Linux*) +    [ -n "$cudatoolkit" ] || exit 1 +    CUDA_ROOT=/usr/local/cuda-$cudatoolkit +    ;; +esac + +[ -x "$CUDA_ROOT" ] || exit 1 +  cd $SRC_DIR/build/linux  $SRC_DIR/build/linux/autogen.sh @@ -12,7 +26,11 @@ rm -f $CONDA_PREFIX/test.out  $SRC_DIR/build/linux/configure --with-install-type=prefix --with-cuda=$CUDA_ROOT --prefix=$CONDA_PREFIX NVCCFLAGS="-ccbin $CC -I$CONDA_PREFIX/include $EXTRA_NVCCFLAGS" CC=$CC CXX=$CXX CPPFLAGS="-I$CONDA_PREFIX/include" -make install-libraries +# Clean, because we may be re-using this source tree when building +# multiple variants of this conda package. +make clean + +make -j $CPU_COUNT install-libraries  test -d $CUDA_ROOT/lib64 && LIBPATH="$CUDA_ROOT/lib64" || LIBPATH="$CUDA_ROOT/lib" @@ -22,8 +40,13 @@ case `uname` in      cp -P $LIBPATH/libcudart.*.dylib $CONDA_PREFIX/lib      cp -P $LIBPATH/libcufft.*.dylib $CONDA_PREFIX/lib      ;; -  *) -    cp -P $LIBPATH/libcudart.so.* $CONDA_PREFIX/lib -    cp -P $LIBPATH/libcufft.so.* $CONDA_PREFIX/lib +  Linux*) +    if [ "$cudatoolkit" = "7.0" ]; then +      # For some reason conda-build adds these symlinks automatically for +      # cudatoolkit-5.5 and 6.0, but not 7.0. For 7.5 these symlinks are not +      # necessary, and for 8.0 the cudatoolkit packages includes them. +      ln -T -s libcudart.so.7.0.28 $CONDA_PREFIX/lib/libcudart.so.7.0 +      ln -T -s libcufft.so.7.0.35 $CONDA_PREFIX/lib/libcufft.so.7.0 +    fi      ;;  esac diff --git a/python/conda/libastra/linux_build_config.yaml b/python/conda/libastra/linux_build_config.yaml new file mode 100644 index 0000000..c5d2319 --- /dev/null +++ b/python/conda/libastra/linux_build_config.yaml @@ -0,0 +1,6 @@ +cudatoolkit: +  - 5.5 +  - 6.0 +  - 7.0 +  - 7.5 +  - 8.0 diff --git a/python/conda/libastra/meta.yaml b/python/conda/libastra/meta.yaml index 68cf47a..e4622b7 100644 --- a/python/conda/libastra/meta.yaml +++ b/python/conda/libastra/meta.yaml @@ -1,17 +1,16 @@  package:    name: libastra -  version: '1.8' +  version: '1.8.3'  source:    git_url: https://github.com/astra-toolbox/astra-toolbox.git -  git_tag: v1.8 +  git_tag: v1.8.3  build:    number: 0    script_env: -    - CC # [not win] -    - CXX # [not win] -    - CUDA_ROOT # [not win] +    - CC # [linux] +    - CXX # [linux]  requirements:    build: @@ -20,15 +19,13 @@ requirements:      - automake # [osx]      - autoconf # [osx]      - libtool # [osx] +    - cudatoolkit {{ cudatoolkit }} # [linux]    run:      - vs2015_runtime # [win] +    - cudatoolkit {{ cudatoolkit }} # [linux]  about:    home: http://www.astra-toolbox.com    license: GPLv3    summary: 'The ASTRA Toolbox is a Python toolbox of high-performance GPU primitives for 2D and 3D tomography.' - -# See -# http://docs.continuum.io/conda/build.html for -# more information about meta.yaml diff --git a/python/conda/linux_release/buildenv/Dockerfile b/python/conda/linux_release/buildenv/Dockerfile index c73e4b9..17e9c5b 100644 --- a/python/conda/linux_release/buildenv/Dockerfile +++ b/python/conda/linux_release/buildenv/Dockerfile @@ -1,15 +1,55 @@ -FROM debian:7 -ENV PATH /root/miniconda3/bin:$PATH +FROM debian:7 AS BUILDBASE  ENV DEBIAN_FRONTEND noninteractive -# http://developer.download.nvidia.com/compute/cuda/5_5/rel/installers/cuda_5.5.22_linux_64.run -ADD cuda_5.5.22_linux_64.run /root/ -# https://repo.continuum.io/miniconda/Miniconda3-4.2.12-Linux-x86_64.sh -ADD Miniconda3-4.2.12-Linux-x86_64.sh /root/ -RUN apt-get update -RUN apt-get install -y perl-modules build-essential autoconf libtool automake libboost-dev git -RUN /bin/bash /root/Miniconda3-4.2.12-Linux-x86_64.sh -b -RUN /bin/bash /root/cuda_5.5.22_linux_64.run -toolkit -silent +RUN apt-get update && apt-get install -y perl-modules build-essential autoconf libtool automake libboost-dev git && rm -rf /var/lib/apt/lists/* + +FROM BUILDBASE AS CUDA80 +RUN touch /root/cuda80 +COPY cuda_8.0.61_375.26_linux-run /root +RUN /bin/bash /root/cuda_8.0.61_375.26_linux-run --toolkit --silent && \ +	rm -f /root/cuda_8.0.61_375.26_linux-run +COPY cuda_8.0.61.2_linux-run /root +RUN /bin/bash /root/cuda_8.0.61.2_linux-run --silent --accept-eula && \ +	rm -f /root/cuda_8.0.61.2_linux-run + +FROM BUILDBASE AS CUDA75 +RUN touch /root/cuda75 +COPY cuda_7.5.18_linux.run /root +RUN /bin/bash /root/cuda_7.5.18_linux.run --toolkit --silent && \ +	rm -f /root/cuda_7.5.18_linux.run + +FROM BUILDBASE AS CUDA70 +RUN touch /root/cuda70 +COPY cuda_7.0.28_linux.run /root +RUN /bin/bash /root/cuda_7.0.28_linux.run -toolkit -silent && \ +	rm -f /root/cuda_7.0.28_linux.run + +COPY cufft_patch_linux.tar.gz /root +RUN cd /usr/local/cuda-7.0 && \ +	tar xf /root/cufft_patch_linux.tar.gz && \ +	rm -f /root/cufft_patch_linux.tar.gz + +FROM BUILDBASE AS CUDA60 +RUN touch /root/cuda60 +COPY cuda_6.0.37_linux_64.run /root +RUN /bin/bash /root/cuda_6.0.37_linux_64.run -toolkit -silent && \ +	rm -f /root/cuda_6.0.37_linux_64.run + +FROM BUILDBASE AS CUDA55 +RUN touch /root/cuda55 +COPY cuda_5.5.22_linux_64.run /root +RUN /bin/bash /root/cuda_5.5.22_linux_64.run -toolkit -silent && \ +	rm /root/cuda_5.5.22_linux_64.run + +FROM BUILDBASE +RUN touch /root/cuda +COPY --from=CUDA80 /usr/local/cuda-8.0 /usr/local/cuda-8.0 +COPY --from=CUDA75 /usr/local/cuda-7.5 /usr/local/cuda-7.5 +COPY --from=CUDA70 /usr/local/cuda-7.0 /usr/local/cuda-7.0 +COPY --from=CUDA60 /usr/local/cuda-6.0 /usr/local/cuda-6.0 +COPY --from=CUDA55 /usr/local/cuda-5.5 /usr/local/cuda-5.5 + +ENV PATH /root/miniconda3/bin:$PATH +COPY Miniconda3-4.3.27.1-Linux-x86_64.sh /root/ +RUN /bin/bash /root/Miniconda3-4.3.27.1-Linux-x86_64.sh -b && \ +	rm -f /root/Miniconda3*  RUN conda install -y conda-build -ENV CUDA_ROOT /usr/local/cuda -ENV CC gcc -ENV CXX g++ diff --git a/python/conda/linux_release/buildenv/build.sh b/python/conda/linux_release/buildenv/build.sh new file mode 100644 index 0000000..1cc0830 --- /dev/null +++ b/python/conda/linux_release/buildenv/build.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +export CC=gcc +export CXX=g++ + +cd /root +git clone --depth 1 --branch master https://github.com/astra-toolbox/astra-toolbox +[ $# -eq 0 ] || perl -pi -e "s/^(\s*number:\s*)[0-9]+$/\${1}$1/" astra-toolbox/python/conda/libastra/meta.yaml astra-toolbox/python/conda/astra-toolbox/meta.yaml + +conda-build -m astra-toolbox/python/conda/libastra/linux_build_config.yaml astra-toolbox/python/conda/libastra +conda-build astra-toolbox/python/conda/astra-toolbox + +cp /root/miniconda3/conda-bld/linux-64/*astra* /out diff --git a/python/conda/linux_release/builder/Dockerfile b/python/conda/linux_release/builder/Dockerfile deleted file mode 100644 index 2404609..0000000 --- a/python/conda/linux_release/builder/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM astra-build-env -ARG BUILD_NUMBER= -WORKDIR /root -RUN git clone --depth 1 https://github.com/astra-toolbox/astra-toolbox -RUN [ -z $BUILD_NUMBER ] || perl -pi -e "s/^(\s*number:\s*)[0-9]+$/\${1}$BUILD_NUMBER/" astra-toolbox/python/conda/libastra/meta.yaml astra-toolbox/python/conda/astra-toolbox/meta.yaml -RUN conda-build --python=3.5 astra-toolbox/python/conda/libastra -RUN conda-build --python 2.7 --numpy 1.8 astra-toolbox/python/conda/astra-toolbox -RUN conda-build --python 2.7 --numpy 1.9 astra-toolbox/python/conda/astra-toolbox -RUN conda-build --python 2.7 --numpy 1.10 astra-toolbox/python/conda/astra-toolbox -RUN conda-build --python 2.7 --numpy 1.11 astra-toolbox/python/conda/astra-toolbox -RUN conda-build --python 2.7 --numpy 1.12 astra-toolbox/python/conda/astra-toolbox -RUN conda-build --python 3.5 --numpy 1.9 astra-toolbox/python/conda/astra-toolbox -RUN conda-build --python 3.5 --numpy 1.10 astra-toolbox/python/conda/astra-toolbox -RUN conda-build --python 3.5 --numpy 1.11 astra-toolbox/python/conda/astra-toolbox -RUN conda-build --python 3.5 --numpy 1.12 astra-toolbox/python/conda/astra-toolbox -RUN conda-build --python 3.6 --numpy 1.11 astra-toolbox/python/conda/astra-toolbox -RUN conda-build --python 3.6 --numpy 1.12 astra-toolbox/python/conda/astra-toolbox diff --git a/python/conda/linux_release/release.sh b/python/conda/linux_release/release.sh index cf62bd5..91c13e4 100644 --- a/python/conda/linux_release/release.sh +++ b/python/conda/linux_release/release.sh @@ -2,19 +2,19 @@  D=`mktemp -d` -[ -f buildenv/cuda_5.5.22_linux_64.run ] || (cd buildenv; wget http://developer.download.nvidia.com/compute/cuda/5_5/rel/installers/cuda_5.5.22_linux_64.run ) -[ -f buildenv/Miniconda3-4.2.12-Linux-x86_64.sh ] || (cd buildenv; wget https://repo.continuum.io/miniconda/Miniconda3-4.2.12-Linux-x86_64.sh ) +for F in https://repo.continuum.io/miniconda/Miniconda3-4.2.12-Linux-x86_64.sh  http://developer.download.nvidia.com/compute/cuda/5_5/rel/installers/cuda_5.5.22_linux_64.run http://developer.download.nvidia.com/compute/cuda/6_0/rel/installers/cuda_6.0.37_linux_64.run  http://developer.download.nvidia.com/compute/cuda/7_0/Prod/local_installers/cuda_7.0.28_linux.run http://developer.download.nvidia.com/compute/cuda/7_0/Prod/cufft_update/cufft_patch_linux.tar.gz http://developer.download.nvidia.com/compute/cuda/7.5/Prod/local_installers/cuda_7.5.18_linux.run https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda_8.0.61_375.26_linux-run https://developer.nvidia.com/compute/cuda/8.0/Prod2/patches/2/cuda_8.0.61.2_linux-run; do +	[ -f buildenv/`basename $F` ] || (cd buildenv; wget $F ) +done  docker build -t astra-build-env buildenv -#docker build --no-cache --build-arg=BUILD_NUMBER=0 -t astra-builder builder -docker build --no-cache -t astra-builder builder -docker run --name astra-build-cnt -v $D:/out:z astra-builder /bin/bash -c "cp /root/miniconda3/conda-bld/linux-64/*astra* /out" +cp buildenv/build.sh $D + +docker run -v $D:/out:z astra-build-env /bin/bash /out/build.sh + +rm -f $D/build.sh  mkdir -p pkgs  mv $D/* pkgs  rmdir $D -docker rm astra-build-cnt -docker rmi astra-builder - diff --git a/samples/python/s020_3d_multiGPU.py b/samples/python/s020_3d_multiGPU.py index 11a1e11..e872870 100644 --- a/samples/python/s020_3d_multiGPU.py +++ b/samples/python/s020_3d_multiGPU.py @@ -28,11 +28,11 @@ import numpy as np  # Set up multi-GPU usage.  # This only works for 3D GPU forward projection and back projection. -astra.astra.set_gpu_index([0,1]) +astra.set_gpu_index([0,1])  # Optionally, you can also restrict the amount of GPU memory ASTRA will use.  # The line commented below sets this to 1GB. -#astra.astra.set_gpu_index([0,1], memory=1024*1024*1024) +#astra.set_gpu_index([0,1], memory=1024*1024*1024)  vol_geom = astra.create_vol_geom(1024, 1024, 1024) diff --git a/src/CompositeGeometryManager.cpp b/src/CompositeGeometryManager.cpp index a4dace2..184144c 100644 --- a/src/CompositeGeometryManager.cpp +++ b/src/CompositeGeometryManager.cpp @@ -1386,6 +1386,12 @@ static bool doJob(const CCompositeGeometryManager::TJobSet::const_iterator& iter  	bool ok = dstMem->allocateGPUMemory(outx, outy, outz, zero ? astraCUDA3d::INIT_ZERO : astraCUDA3d::INIT_NO);  	if (!ok) ASTRA_ERROR("Error allocating GPU memory"); +	if (!zero) { +		// instead of zeroing output memory, copy from host +		ok = dstMem->copyToGPUMemory(dstdims); +		if (!ok) ASTRA_ERROR("Error copying output data to GPU"); +	} +  	for (CCompositeGeometryManager::TJobList::const_iterator i = L.begin(); i != L.end(); ++i) {  		const CCompositeGeometryManager::SJob &j = *i; diff --git a/src/CudaDartMaskAlgorithm.cpp b/src/CudaDartMaskAlgorithm.cpp index 375d565..a2e1ee6 100644 --- a/src/CudaDartMaskAlgorithm.cpp +++ b/src/CudaDartMaskAlgorithm.cpp @@ -29,6 +29,7 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #include "astra/CudaDartMaskAlgorithm.h" +#include "../cuda/2d/astra.h"  #include "../cuda/2d/darthelper.h"  #include "../cuda/2d/algo.h" diff --git a/src/CudaDartSmoothingAlgorithm.cpp b/src/CudaDartSmoothingAlgorithm.cpp index 0759ea0..9e586c0 100644 --- a/src/CudaDartSmoothingAlgorithm.cpp +++ b/src/CudaDartSmoothingAlgorithm.cpp @@ -29,6 +29,7 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #include "astra/CudaDartSmoothingAlgorithm.h" +#include "../cuda/2d/astra.h"  #include "../cuda/2d/darthelper.h"  #include "../cuda/2d/algo.h" diff --git a/src/CudaDataOperationAlgorithm.cpp b/src/CudaDataOperationAlgorithm.cpp index f9466e2..6c6b27c 100644 --- a/src/CudaDataOperationAlgorithm.cpp +++ b/src/CudaDataOperationAlgorithm.cpp @@ -31,6 +31,7 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #include "../cuda/2d/algo.h"  #include "../cuda/2d/darthelper.h" +#include "../cuda/2d/astra.h"  #include "../cuda/2d/arith.h"  #include "astra/AstraObjectManager.h" diff --git a/src/CudaRoiSelectAlgorithm.cpp b/src/CudaRoiSelectAlgorithm.cpp index baf8a6f..2b0ba15 100644 --- a/src/CudaRoiSelectAlgorithm.cpp +++ b/src/CudaRoiSelectAlgorithm.cpp @@ -29,6 +29,7 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #include "astra/CudaRoiSelectAlgorithm.h" +#include "../cuda/2d/astra.h"  #include "../cuda/2d/darthelper.h"  #include "../cuda/2d/algo.h" diff --git a/src/Float32Data3DMemory.cpp b/src/Float32Data3DMemory.cpp index 5c5c310..017625b 100644 --- a/src/Float32Data3DMemory.cpp +++ b/src/Float32Data3DMemory.cpp @@ -71,8 +71,6 @@ bool CFloat32Data3DMemory::_initialize(int _iWidth, int _iHeight, int _iDepth)  	// allocate memory for the data, but do not fill it  	m_pfData = NULL; -	m_ppfDataRowInd = NULL; -	m_pppfDataSliceInd = NULL;  	m_pCustomMemory = 0;  	_allocateData(); @@ -103,8 +101,6 @@ bool CFloat32Data3DMemory::_initialize(int _iWidth, int _iHeight, int _iDepth, c  	// allocate memory for the data, but do not fill it  	m_pfData = NULL; -	m_ppfDataRowInd = NULL; -	m_pppfDataSliceInd = NULL;  	m_pCustomMemory = 0;  	_allocateData(); @@ -140,8 +136,6 @@ bool CFloat32Data3DMemory::_initialize(int _iWidth, int _iHeight, int _iDepth, f  	// allocate memory for the data, but do not fill it  	m_pfData = NULL; -	m_ppfDataRowInd = NULL; -	m_pppfDataSliceInd = NULL;  	m_pCustomMemory = 0;  	_allocateData(); @@ -178,8 +172,6 @@ bool CFloat32Data3DMemory::_initialize(int _iWidth, int _iHeight, int _iDepth, C  	// allocate memory for the data, but do not fill it  	m_pCustomMemory = _pCustomMemory;  	m_pfData = NULL; -	m_ppfDataRowInd = NULL; -	m_pppfDataSliceInd = NULL;  	_allocateData();  	// initialization complete @@ -198,8 +190,6 @@ void CFloat32Data3DMemory::_allocateData()  	ASTRA_ASSERT(m_iSize > 0);  	ASTRA_ASSERT(m_iSize == (size_t)m_iWidth * m_iHeight * m_iDepth);  	ASTRA_ASSERT(m_pfData == NULL); -	ASTRA_ASSERT(m_ppfDataRowInd == NULL); -	ASTRA_ASSERT(m_pppfDataSliceInd == NULL);  	if (!m_pCustomMemory) {  		// allocate contiguous block @@ -213,20 +203,6 @@ void CFloat32Data3DMemory::_allocateData()  	} else {  		m_pfData = m_pCustomMemory->m_fPtr;  	} - -	// create array of pointers to each row of the data block -	m_ppfDataRowInd = new float32*[m_iHeight*m_iDepth]; -	for (int iy = 0; iy < m_iHeight*m_iDepth; iy++) -	{ -		m_ppfDataRowInd[iy] = &(m_pfData[iy * m_iWidth]); -	} - -	// create array of pointers to each row of the data block -	m_pppfDataSliceInd = new float32**[m_iDepth]; -	for (int iy = 0; iy < m_iDepth; iy++) -	{ -		m_pppfDataSliceInd[iy] = &(m_ppfDataRowInd[iy * m_iHeight]); -	}  }  //---------------------------------------------------------------------------------------- @@ -235,13 +211,6 @@ void CFloat32Data3DMemory::_freeData()  {  	// basic checks  	ASTRA_ASSERT(m_pfData != NULL); -	ASTRA_ASSERT(m_ppfDataRowInd != NULL); -	ASTRA_ASSERT(m_pppfDataSliceInd != NULL); - -	// free memory for index table -	delete[] m_pppfDataSliceInd; -	// free memory for index table -	delete[] m_ppfDataRowInd;  	if (!m_pCustomMemory) {  		// free memory for data block @@ -266,8 +235,6 @@ void CFloat32Data3DMemory::_clear()  	m_iSize = 0;  	m_pfData = NULL; -	m_ppfDataRowInd = NULL; -	m_pppfDataSliceInd = NULL;  	m_pCustomMemory = NULL;  } diff --git a/src/Utilities.cpp b/src/Utilities.cpp index eb06d8b..2ae1b66 100644 --- a/src/Utilities.cpp +++ b/src/Utilities.cpp @@ -66,20 +66,44 @@ double stringToDouble(const std::string& s)  template<> float stringTo(const std::string& s) { return stringToFloat(s); }  template<> double stringTo(const std::string& s) { return stringToDouble(s); } -std::vector<float> stringToFloatVector(const std::string &s) +template<typename T> +std::vector<T> stringToNumericVector(const std::string &s)  { -	return stringToVector<float>(s); +	std::vector<T> out; +	out.reserve(100); +	std::istringstream iss; +	iss.imbue(std::locale::classic()); +	size_t length = s.size(); +	size_t current = 0; +	size_t next; +	do { +		next = s.find_first_of(",;", current); +		std::string t = s.substr(current, next - current); +		iss.str(t); +		iss.clear(); +		T f; +		iss >> f; +		out.push_back(f); +		current = next + 1; +	} while (next != std::string::npos && current != length); + +	return out;  } +std::vector<float> stringToFloatVector(const std::string &s) +{ +	return stringToNumericVector<float>(s); +}  std::vector<double> stringToDoubleVector(const std::string &s)  { -	return stringToVector<double>(s); +	return stringToNumericVector<double>(s);  }  template<typename T>  std::vector<T> stringToVector(const std::string& s)  {  	std::vector<T> out; +	size_t length = s.size();  	size_t current = 0;  	size_t next;  	do { @@ -87,7 +111,7 @@ std::vector<T> stringToVector(const std::string& s)  		std::string t = s.substr(current, next - current);  		out.push_back(stringTo<T>(t));  		current = next + 1; -	} while (next != std::string::npos); +	} while (next != std::string::npos && current != length);  	return out;  } @@ -117,13 +141,14 @@ void splitString(std::vector<std::string> &items, const std::string& s,                   const char *delim)  {  	items.clear(); +	size_t length = s.size();  	size_t current = 0;  	size_t next;  	do {  		next = s.find_first_of(delim, current);  		items.push_back(s.substr(current, next - current));  		current = next + 1; -	} while (next != std::string::npos); +	} while (next != std::string::npos && current != length);  }  } diff --git a/src/XMLNode.cpp b/src/XMLNode.cpp index 3b7237f..2bf1330 100644 --- a/src/XMLNode.cpp +++ b/src/XMLNode.cpp @@ -30,6 +30,9 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.  #include "rapidxml/rapidxml.hpp"  #include "rapidxml/rapidxml_print.hpp" +#include <sstream> +#include <iomanip> +  using namespace rapidxml;  using namespace astra; @@ -376,9 +379,9 @@ void XMLNode::setContent(float32 _fValue)  template<typename T>  static std::string setContentList_internal(T* pfList, int _iSize) { -	std::string str = (_iSize > 0) ? StringUtil::toString(pfList[0]) : ""; -	for (int i = 1; i < _iSize; i++) { -		str += "," + StringUtil::toString(pfList[i]); +	std::string str; +	for (int i = 0; i < _iSize; i++) { +		str += StringUtil::toString(pfList[i]) + ",";  	}  	return str;  } @@ -399,8 +402,6 @@ void XMLNode::setContent(double* pfList, int _iSize)  template<typename T>  static std::string setContentMatrix_internal(T* _pfMatrix, int _iWidth, int _iHeight, bool transposed)  { -	std::string str = ""; -  	int s1,s2;  	if (!transposed) { @@ -411,17 +412,20 @@ static std::string setContentMatrix_internal(T* _pfMatrix, int _iWidth, int _iHe  		s2 = 1;  	} +	std::ostringstream s; +	s.imbue(std::locale::classic()); +	s << std::setprecision(17); +  	for (int y = 0; y < _iHeight; ++y) {  		if (_iWidth > 0) -			str += StringUtil::toString(_pfMatrix[0*s1 + y*s2]); +			s << _pfMatrix[0*s1 + y*s2];  		for (int x = 1; x < _iWidth; x++) -			str += "," + StringUtil::toString(_pfMatrix[x*s1 + y*s2]); +			s << "," << _pfMatrix[x*s1 + y*s2]; -		if (y != _iHeight-1) -			str += ";"; +		s << ";";  	} -	return str; +	return s.str();  }  void XMLNode::setContent(float32* _pfMatrix, int _iWidth, int _iHeight, bool transposed) diff --git a/src/swrap.cpp b/src/swrap.cpp deleted file mode 100644 index c970ab5..0000000 --- a/src/swrap.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* ------------------------------------------------------------------------ -Copyright: 2010-2016, iMinds-Vision Lab, University of Antwerp -           2014-2016, CWI, Amsterdam - -Contact: astra@uantwerpen.be -Website: http://www.astra-toolbox.com/ - -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/>. - ------------------------------------------------------------------------ -*/ - -#ifndef _MSC_VER - -#include "astra/swrap.h" -#include <cerrno> - -errno_t fopen_s(FILE** pFile, const char* filename, const char* mode) -{ -	if (!pFile) -		return EINVAL; - -	FILE* x = fopen(filename, mode); -	if (!x) -		return errno; - -	*pFile = x; -	return 0; -} - -#endif | 
