diff --git a/CMakeLists.txt b/CMakeLists.txt index 6568ea4..77bd8b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,11 +5,13 @@ project(CosmoToolbox) include(GetGitRevisionDescription) include(ExternalProject) +include(FindOpenMP) get_git_head_revision(HEAD GIT_VER) option(BUILD_SHARED_LIBS "Build shared libraries." OFF) option(BUILD_STATIC_LIBS "Build static libraries." ON) +option(ENABLE_OPENMP "Enable OpenMP support." OFF) find_path(NETCDF_INCLUDE_PATH NAMES netcdf.h) find_path(NETCDFCPP_INCLUDE_PATH NAMES netcdfcpp.h netcdf) @@ -39,6 +41,9 @@ ExternalProject_Add(sharp ) SET(SHARP_LIBRARY ${DEP_BUILD}/lib/libsharp.a) +SET(FFTPACK_LIBRARY ${DEP_BUILD}/lib/libfftpack.a) +SET(CUTILS_LIBRARY ${DEP_BUILD}/lib/libc_utils.a) +SET(SHARP_LIBRARIES ${SHARP_LIBRARY} ${FFTPACK_LIBRARY} ${CUTILS_LIBRARY}) SET(SHARP_INCLUDE_PATH ${DEP_BUILD}/include) set(HDF5_FIND_COMPONENTS HL CXX) diff --git a/sample/CMakeLists.txt b/sample/CMakeLists.txt index 52b5ba2..816d7bb 100644 --- a/sample/CMakeLists.txt +++ b/sample/CMakeLists.txt @@ -49,7 +49,9 @@ if (FFTW3_FOUND AND EIGEN3_FOUND) target_link_libraries(test_fft_calls ${tolink} ${FFTW3_LIBRARIES}) endif (FFTW3_FOUND AND EIGEN3_FOUND) -#if (SHARP_LIBRARY AND SHARP_INCLUDE_PATH AND EIGEN3_FOUND) -# add_executable(test_sharp_calls test_sharp_calls.cpp) -# target_link_libraries(test_sharp_calls ${tolink} ${SHARP_LIBRARY}) -#endif (SHARP_LIBRARY AND SHARP_INCLUDE_PATH AND EIGEN3_FOUND) +if (SHARP_LIBRARY AND SHARP_INCLUDE_PATH AND EIGEN3_FOUND) + include_directories(${SHARP_INCLUDE_PATH}) + add_executable(test_healpix_calls test_healpix_calls.cpp) + target_link_libraries(test_healpix_calls ${tolink} ${SHARP_LIBRARIES}) + set_target_properties(test_healpix_calls PROPERTIES COMPILE_FLAGS ${OpenMP_CXX_FLAGS} LINK_FLAGS ${OpenMP_CXX_FLAGS}) +endif (SHARP_LIBRARY AND SHARP_INCLUDE_PATH AND EIGEN3_FOUND) diff --git a/sample/test_healpix_calls.cpp b/sample/test_healpix_calls.cpp new file mode 100644 index 0000000..ae1844e --- /dev/null +++ b/sample/test_healpix_calls.cpp @@ -0,0 +1,20 @@ +#include +#include "fourier/healpix.hpp" + +using namespace CosmoTool; +using namespace std; + +int main() +{ + HealpixFourierTransform dft(128,3*128,3*128, 40); + long Npix = dft.realSpace().size(); + + dft.realSpace().eigen().setRandom(); + dft.analysis(); + cout << "Map dot-product = " << dft.realSpace().dot_product(dft.realSpace()) << endl; + cout << "Fourier dot-product = " << dft.fourierSpace().dot_product(dft.fourierSpace()).real()*Npix/(4*M_PI) << endl; + dft.synthesis(); + cout << "Resynthesis dot-product = " << dft.realSpace().dot_product(dft.realSpace()) << endl; + return 0; + +} diff --git a/src/fourier/healpix.hpp b/src/fourier/healpix.hpp index 11ffddd..8aac379 100644 --- a/src/fourier/healpix.hpp +++ b/src/fourier/healpix.hpp @@ -4,20 +4,26 @@ #include #include #include +#include #include #include #include -#include +#include "base_types.hpp" +#include +#include +#include namespace CosmoTool { template - class HealpixSpectrum: public FourierSpectrum + class HealpixSpectrum: public SpectrumFunction { protected: std::vector cls; public: - typedef typename FourierSpectrum::FourierMapType FourierMapType; + typedef typename SpectrumFunction::FourierMapType FourierMapType; + typedef boost::shared_ptr ptr_map; + HealpixSpectrum(long Lmax) : cls(Lmax+1) {} @@ -26,8 +32,7 @@ namespace CosmoTool const T *data() const { return &cls[0]; } long size() const { return cls.size(); } - boost::shared_ptr - newRandomFourier(gsl_rng *rng, const FourierMapType& like_map) const = 0; + ptr_map newRandomFourier(gsl_rng *rng, const FourierMapType& like_map) const = 0; }; template @@ -35,20 +40,21 @@ namespace CosmoTool { private: T *m_data; - long Npix, Nside; + long Npix, m_Nside; Eigen::aligned_allocator alloc; public: HealpixFourierMap(long nSide) - : Npix(12*nSide*nSide), Nside(nSide) + : Npix(12*nSide*nSide), m_Nside(nSide) { m_data = alloc.allocate(Npix); } virtual ~HealpixFourierMap() { - alloc.deallocate(m_data); + alloc.deallocate(m_data, Npix); } + long Nside() const { return m_Nside; } virtual const T* data() const { return m_data; } virtual T *data() { return m_data; } virtual long size() const { return Npix; } @@ -56,8 +62,10 @@ namespace CosmoTool virtual T dot_product(const FourierMap& other) const throw(std::bad_cast) { + typedef typename FourierMap::MapType MapType; + const HealpixFourierMap& mfm = dynamic_cast&>(other); - if (Npix() != mfm.Npix()) + if (Npix != mfm.size()) throw std::bad_cast(); MapType m1(m_data, Npix); @@ -68,7 +76,7 @@ namespace CosmoTool virtual FourierMap *mimick() const { - return new HealpixFourierMap(Nside); + return new HealpixFourierMap(m_Nside); } }; @@ -78,7 +86,7 @@ namespace CosmoTool { private: std::complex *alms; - long size; + long m_size; long Lmax_, Mmax_, TVal_; Eigen::aligned_allocator > alloc; public: @@ -105,18 +113,18 @@ namespace CosmoTool HealpixFourierALM(LType lmax, LType mmax) : Lmax_(lmax), Mmax_(mmax), TVal_(2*lmax+1) { - size = Num_Alms(); - alms = alloc.allocate(size); + m_size = Num_Alms(); + alms = alloc.allocate(m_size); } virtual ~HealpixFourierALM() { - alloc.deallocate(alms); + alloc.deallocate(alms, m_size); } - virtual const T* data() const { return alms; } - virtual T * data() { return alms;} - virtual long size() const { return size; } + virtual const std::complex* data() const { return alms; } + virtual std::complex * data() { return alms;} + virtual long size() const { return m_size; } virtual FourierMap > *mimick() const { @@ -127,35 +135,52 @@ namespace CosmoTool throw(std::bad_cast) { const HealpixFourierALM& mfm = dynamic_cast&>(other); + typedef typename FourierMap >::MapType MapType; std::complex S; - if (size != mfm.size) + if (m_size != mfm.m_size) throw std::bad_cast(); - MapType m1(m_data, Npix); - MapType m2(mfm.m_data, mfm.Npix); + MapType m1(alms, m_size); + MapType m2(mfm.alms, mfm.m_size); - S = (m1.block(0,0,1,Lmax_+1).adjoint() * m2(0,0,1,Lmax_+1)).sum(); - S += 2*(m1.block(0,1+Lmax_,1,size-1-Lmax_).adjoint() * m2(0,1+Lmax_,1,size-1-Lmax_)).sum(); + S = (m1.block(0,0,1,Lmax_+1).conjugate() * m2.block(0,0,1,Lmax_+1)).sum(); + S += std::complex(2,0)*(m1.block(0,1+Lmax_,1,m_size-1-Lmax_).conjugate() * m2.block(0,1+Lmax_,1,m_size-1-Lmax_)).sum(); return S; } }; + template struct HealpixJobHelper__ {}; + + template<> struct HealpixJobHelper__ + { enum {val=1}; }; + + template<> struct HealpixJobHelper__ + { enum {val=0}; }; + + template - class HealpixFourierTransform: public FourierTransform, public sharp_base + class HealpixFourierTransform: public FourierTransform { private: + sharp_alm_info *ainfo; + sharp_geom_info *ginfo; HealpixFourierMap realMap; HealpixFourierALM fourierMap; + int m_iterate; public: - HealpixFourierTransform(long nSide, long Lmax, long Mmax) - : realMap(nSide), fourierMap(Lmax, Mmax) + HealpixFourierTransform(long nSide, long Lmax, long Mmax, int iterate = 0) + : realMap(nSide), fourierMap(Lmax, Mmax), ainfo(0), ginfo(0), m_iterate(iterate) { - set_Healpix_geometry(nSide); - set_triangular_alm_info(Lmax, Mmax); + sharp_make_healpix_geom_info (nSide, 1, &ginfo); + sharp_make_triangular_alm_info (Lmax, Mmax, 1, &ainfo); } - virtual ~HealpixFourierTransform() {} + virtual ~HealpixFourierTransform() + { + sharp_destroy_geom_info(ginfo); + sharp_destroy_alm_info(ainfo); + } virtual const FourierMap >& fourierSpace() const { return fourierMap; } @@ -167,7 +192,7 @@ namespace CosmoTool virtual FourierTransform *mimick() const { - return new HealpixFourierTransform(realMap.Nside, fourierMap.Lmax, fourierMap.Mmax); + return new HealpixFourierTransform(realMap.Nside(), fourierMap.Lmax(), fourierMap.Mmax()); } virtual void analysis() @@ -175,7 +200,20 @@ namespace CosmoTool void *aptr=reinterpret_cast(fourierMap.data()), *mptr=reinterpret_cast(realMap.data()); sharp_execute (SHARP_MAP2ALM, 0, 0, &aptr, &mptr, ginfo, ainfo, 1, - cxxjobhelper__::val,0,0,0); + HealpixJobHelper__::val,0,0,0); + for (int i = 0; i < m_iterate; i++) + { + HealpixFourierMap tmp_map(realMap.Nside()); + void *tmp_ptr=reinterpret_cast(tmp_map.data()); + typename HealpixFourierMap::MapType m0 = tmp_map.eigen(); + typename HealpixFourierMap::MapType m1 = realMap.eigen(); + + sharp_execute (SHARP_ALM2MAP, 0, 0, &aptr, &tmp_ptr, ginfo, ainfo, 1, + HealpixJobHelper__::val,0,0,0); + m0 = m1 - m0; + sharp_execute (SHARP_MAP2ALM, 0, 1, &aptr, &tmp_ptr, ginfo, ainfo, 1, + HealpixJobHelper__::val,0,0,0); + } } virtual void synthesis() @@ -183,30 +221,30 @@ namespace CosmoTool void *aptr=reinterpret_cast(fourierMap.data()), *mptr=reinterpret_cast(realMap.data()); sharp_execute (SHARP_ALM2MAP, 0, 0, &aptr, &mptr, ginfo, ainfo, 1, - cxxjobhelper__::val,0,0,0); + HealpixJobHelper__::val,0,0,0); } virtual void analysis_conjugate() { synthesis(); - realMap.scale(4*M_PI/realMap.Npix()); + realMap.scale(4*M_PI/realMap.size()); } virtual void synthesis_conjugate() { analysis(); - fourierMap.scale(realMap.Npix()/(4*M_PI)); + fourierMap.scale(realMap.size()/(4*M_PI)); } }; template - boost::shared_ptr::FourierMapType> + typename HealpixSpectrum::ptr_map HealpixSpectrum::newRandomFourier(gsl_rng *rng, const FourierMapType& like_map) const { const HealpixFourierALM& alms = dynamic_cast&>(like_map); HealpixFourierALM *new_alms; - boost::shared_ptr r(new_alms = new HealpixFourierALM(alms.Lmax(), alms.Mmax())); + ptr_map r(new_alms = new HealpixFourierALM(alms.Lmax(), alms.Mmax())); long lmaxGen = std::min(cls.size()-1, alms.Lmax()); std::complex *new_data = new_alms->data();