├── .clang-format ├── .github └── workflows │ ├── build.yml │ └── docs.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── Makefile ├── Makefile.option ├── README.md ├── config ├── FindScaLAPACK.cmake ├── check_openmpi.cc ├── check_sgimpt.cc ├── cxx11.cmake └── intel.cmake ├── doc ├── doxygen │ ├── .gitignore │ ├── CMakeLists.txt │ ├── Doxyfile │ ├── Doxyfile.in │ ├── Makefile │ └── theme │ │ ├── doxygen-awesome-darkmode-toggle.js │ │ ├── doxygen-awesome-fragment-copy-button.js │ │ ├── doxygen-awesome-paragraph-link.js │ │ ├── doxygen-awesome-tabs.js │ │ ├── doxygen-awesome.css │ │ └── header.html └── img │ ├── mptensor_logo.pdf │ ├── mptensor_logo.png │ ├── mptensor_logo.svg │ └── mptensor_logo_w200.png ├── examples ├── CMakeLists.txt ├── Ising_2D │ ├── CMakeLists.txt │ ├── Makefile │ ├── atrg.cc │ ├── hotrg.cc │ ├── ising.cc │ ├── ising.hpp │ └── trg.cc ├── benchmark │ ├── CMakeLists.txt │ ├── Makefile │ ├── reshape.cc │ ├── rsvd.cc │ ├── slice.cc │ ├── timer.hpp │ └── transpose.cc ├── output │ ├── CMakeLists.txt │ ├── Makefile │ ├── output.cc │ └── output.py ├── save_load │ ├── .gitignore │ ├── CMakeLists.txt │ ├── Makefile │ └── save_load.cc └── simple_example │ ├── CMakeLists.txt │ ├── Makefile │ └── simple_example.cc ├── include └── mptensor │ ├── complex.hpp │ ├── doxygen_module.hpp │ ├── file_io │ ├── io_helper.hpp │ ├── load.hpp │ └── save.hpp │ ├── index.hpp │ ├── index_constructor.hpp │ ├── index_constructor.py │ ├── lapack │ ├── matrix_lapack.hpp │ └── matrix_lapack_impl.hpp │ ├── matrix.hpp │ ├── matrix_interface │ ├── matrix_interface.hpp │ └── matrix_interface_doc.hpp │ ├── mpi_wrapper.hpp │ ├── mptensor.hpp │ ├── rsvd.hpp │ ├── rsvd_impl.hpp │ ├── scalapack │ ├── blacsgrid.hpp │ ├── matrix_scalapack.hpp │ └── matrix_scalapack_impl.hpp │ ├── tensor.hpp │ ├── tensor_impl.hpp │ └── version.hpp ├── src ├── CMakeLists.txt ├── Makefile ├── index.cc ├── lapack │ └── matrix_lapack.cc ├── mpi_wrapper.cc ├── rsvd.cc ├── scalapack │ ├── blacsgrid.cc │ └── matrix_scalapack.cc └── tensor.cc └── tests ├── CMakeLists.txt ├── Makefile ├── arithmetic.cc ├── contract.cc ├── eigh.cc ├── eigh_general.cc ├── eigh_rank2.cc ├── file_io ├── CMakeLists.txt ├── common.hpp ├── load.cc └── save.cc ├── functions.hpp ├── kron.cc ├── mpi_tool.cc ├── mpi_tool.hpp ├── qr.cc ├── qr_rank2.cc ├── reshape.cc ├── set_slice.cc ├── slice.cc ├── svd.cc ├── tensor_test.cc ├── tensor_test.hpp ├── tensordot.cc ├── timer.hpp ├── trace.cc ├── transpose.cc └── typedef.hpp /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: Google 3 | Standard: Cpp03 4 | 5 | ... 6 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | env: 10 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) 11 | BUILD_TYPE: Debug 12 | 13 | jobs: 14 | build: 15 | # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. 16 | # You can convert this to a matrix build if you need cross-platform coverage. 17 | # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 18 | runs-on: ubuntu-latest 19 | 20 | steps: 21 | - uses: actions/checkout@v3 22 | 23 | - name: apt 24 | run: | 25 | sudo apt update 26 | sudo apt install openmpi-bin libopenmpi-dev libscalapack-openmpi-dev 27 | 28 | - name: Configure CMake 29 | # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. 30 | # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type 31 | run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DENABLE_TEST=ON -DMPIEXEC_PREFLAGS="--oversubscribe" 32 | 33 | - name: Build 34 | # Build your program with the given configuration 35 | run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} 36 | 37 | - name: Test 38 | working-directory: ${{github.workspace}}/build 39 | # Execute tests defined by the CMake configuration. 40 | # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail 41 | run: ctest -C ${{env.BUILD_TYPE}} -V 42 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: docs 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v3 13 | 14 | - name: apt 15 | run: sudo apt install doxygen graphviz 16 | shell: bash 17 | 18 | - name: Generate Doxygen Documentation 19 | working-directory: ${{ github.workspace }}/doc/doxygen 20 | run: doxygen Doxyfile 21 | shell: bash 22 | 23 | - name: Create .nojekyll (ensures pages with underscores work on gh pages) 24 | run: touch ${{ github.workspace }}/doc/doxygen/html/.nojekyll 25 | shell: bash 26 | 27 | - name: Deploy to GitHub Pages 28 | uses: JamesIves/github-pages-deploy-action@v4 29 | with: 30 | token: ${{ secrets.GITHUB_TOKEN }} 31 | branch: "gh-pages" 32 | folder: ${{ github.workspace }}/doc/doxygen/html 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | 30 | # generated by g++ in Makefile 31 | *.depend 32 | 33 | # build directory for cmake 34 | build/ 35 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.6...3.17) 2 | 3 | message(STATUS "Start configuration of mptesnor") 4 | message(STATUS "CMake version: ${CMAKE_VERSION}") 5 | 6 | project(mptensor 7 | VERSION 0.3.0 8 | LANGUAGES CXX) 9 | 10 | option(MPTENSOR_BUILD_LIBS_ONLY "Build only library" OFF) 11 | option(BUILD_SHARED_LIBS "Build as shared library" OFF) 12 | option(BUILD_DOCS "Build documents" OFF) 13 | option(ENABLE_MPI "Use MPI and ScaLAPACK" ON) 14 | option(ENABLE_TEST "Enable tests" OFF) 15 | 16 | if(ENABLE_TEST) 17 | enable_testing() 18 | if(NOT CMAKE_BUILD_TYPE) 19 | set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Type of build" FORCE) 20 | endif() 21 | endif() 22 | 23 | list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/config) 24 | if(CONFIG) 25 | message(STATUS "Loading configration: " ${PROJECT_SOURCE_DIR}/config/${CONFIG}.cmake) 26 | include(${PROJECT_SOURCE_DIR}/config/${CONFIG}.cmake) 27 | endif(CONFIG) 28 | if(NOT CMAKE_BUILD_TYPE) 29 | set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Type of build" FORCE) 30 | endif(NOT CMAKE_BUILD_TYPE) 31 | message(STATUS "Build type: " ${CMAKE_BUILD_TYPE}) 32 | 33 | set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") 34 | set(CMAKE_SKIP_BUILD_RPATH FALSE) 35 | set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 36 | set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) 37 | set(CMAKE_MACOSX_RPATH 1) 38 | 39 | set(CMAKE_CXX_STANDARD 11) 40 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 41 | set(CMAKE_CXX_EXTENSIONS OFF) 42 | 43 | find_package(OpenMP) 44 | if(OpenMP_CXX_FOUND OR OPENMP_FOUND) 45 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") 46 | endif(OpenMP_CXX_FOUND OR OPENMP_FOUND) 47 | 48 | find_package(LAPACK) 49 | if(NOT LAPACK_FOUND) 50 | message(STATUS "Could NOT find LAPACK library. Retry a search with C language.") 51 | enable_language(C) 52 | find_package(LAPACK REQUIRED) 53 | endif() 54 | 55 | if(ENABLE_MPI) 56 | find_package(MPI REQUIRED) 57 | include_directories(${MPI_CXX_INCLUDE_PATH}) 58 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MPI_CXX_LINK_FLAGS}") 59 | 60 | find_package(ScaLAPACK REQUIRED) 61 | else() 62 | add_definitions(-D_NO_MPI) 63 | endif() 64 | 65 | add_subdirectory(src) 66 | 67 | if(NOT MPTENSOR_BUILD_LIBS_ONLY) 68 | add_subdirectory(examples EXCLUDE_FROM_ALL) 69 | if(ENABLE_TEST) 70 | add_subdirectory(tests) 71 | else() 72 | add_subdirectory(tests EXCLUDE_FROM_ALL) 73 | endif() 74 | endif() 75 | 76 | if(BUILD_DOCS) 77 | add_subdirectory(doc/doxygen) 78 | endif() 79 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CXX=mpicxx 2 | CXXFLAGS=-O3 3 | LDFLAGS=-L/opt/local/lib -lscalapack 4 | 5 | -include Makefile.option 6 | 7 | .PHONY: all mptensor tests clean doc doxygen 8 | 9 | all: mptensor 10 | 11 | mptensor: 12 | $(MAKE) -C src 13 | 14 | tests: 15 | $(MAKE) -C tests 16 | 17 | doc doxygen: 18 | $(MAKE) -C doc/doxygen 19 | 20 | clean: 21 | $(MAKE) -C src clean 22 | $(MAKE) -C tests clean 23 | $(MAKE) -C doc/doxygen clean 24 | rm -rf doxygen_docs 25 | -------------------------------------------------------------------------------- /Makefile.option: -------------------------------------------------------------------------------- 1 | ##### default ##### 2 | # CXX = mpicxx 3 | # CXXFLAGS = -std=c++11 -O3 -fopenmp 4 | # LDFLAGS = -lscalapack -llapack -lblas 5 | 6 | ##### OpenMPI + Intel MKL ##### 7 | # CXX = mpicxx 8 | # CXXFLAGS = -std=c++11 -O3 -no-prec-div -xSSE2 -qopenmp -parallel 9 | # LDFLAGS = -lmkl_scalapack_lp64 -lmkl_blacs_openmpi_lp64 -mkl=parallel 10 | 11 | ##### MPICH + Intel MKL ##### 12 | # CXX = mpicxx 13 | # CXXFLAGS = -std=c++11 -O3 -no-prec-div -xSSE2 -qopenmp -parallel 14 | # LDFLAGS = -lmkl_scalapack_lp64 -lmkl_blacs_intelmpi_lp64 -mkl=parallel 15 | 16 | ##### K computer ##### 17 | # CXX = mpiFCCpx 18 | # CXXFLAGS = -std=c++11 -Kfast,parallel,ocl,openmp -std=c++11 -Xg -Nstl=libc++ 19 | # LDFLAGS = -SCALAPACK -SSL2BLAMP 20 | 21 | ##### ISSP System B (sekirei) ##### 22 | # CXX = mpicxx 23 | # CXXFLAGS = -std=c++11 -O3 -xCORE-AVX2 -qopenmp -parallel 24 | # LDFLAGS = -lmkl_scalapack_lp64 -lmkl_blacs_sgimpt_lp64 -mkl=parallel -lmpi 25 | 26 | ##### without MPI + Intel MKL ##### 27 | # CXX = icc -D_NO_MPI 28 | # CXXFLAGS = -std=c++11 -O3 -no-prec-div -xSSE2 -qopenmp -parallel 29 | # LDFLAGS = -mkl=parallel 30 | 31 | ##### Ubuntu Xeninal 16.04, Trusty 14.04 ##### 32 | CXX = mpicxx 33 | CXXFLAGS = -std=c++11 -O3 -fopenmp 34 | LDFLAGS = -lscalapack-openmpi -lblacsCinit-openmpi -lblacs-openmpi -llapack -lblas 35 | 36 | ##### Ubuntu Bionic 18.04 ##### 37 | # CXX = mpicxx 38 | # CXXFLAGS = -std=c++11 -O3 -fopenmp 39 | # LDFLAGS = -lscalapack-openmpi -llapack -lblas 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mptensor 2 | 3 | [![GitHub](https://img.shields.io/github/license/smorita/mptensor)][License] 4 | [![build](https://github.com/smorita/mptensor/actions/workflows/build.yml/badge.svg)](https://github.com/smorita/mptensor/actions/workflows/build.yml) 5 | [![docs](https://github.com/smorita/mptensor/actions/workflows/docs.yml/badge.svg)](https://smorita.github.io/mptensor/) 6 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3735474.svg)](https://doi.org/10.5281/zenodo.3735474) 7 | 8 | 9 | "mptensor" is parallel C++ libarary for tensor calculations. 10 | It provides similar interfaces as Numpy and Scipy in Python. 11 | 12 | ## Prerequisites 13 | 14 | - C++11 compiler 15 | - CMake (>= 3.6) 16 | - [LAPACK](https://www.netlib.org/lapack/) 17 | 18 | ### For parallel computing 19 | 20 | - MPI Library 21 | - [ScaLAPACK](https://www.netlib.org/scalapack/) 22 | 23 | ### For document generation 24 | 25 | - Doxygen (>= 1.9.1) 26 | 27 | ## How to Use 28 | 29 | 1. Build and install mptensor library 30 | 31 | # Modern CMake (>= 3.15) 32 | cmake -B build 33 | cmake --build build 34 | sudo cmake --install build 35 | 36 | # Traditional way 37 | mkdir build 38 | cd build 39 | cmake ../ 40 | make 41 | sudo cmake install 42 | 43 | 2. Include the header file `mptensor/mptensor.hpp` in your codes. 44 | 3. Complie your applications with link option `-lmptensor` . 45 | 46 | The default install directory is `/usr/local`. It can be changed by `-DCMAKE_INSTALL_PREFIX` option. 47 | 48 | # Modern CMake 49 | cmake --install build --prefix your_install_prefix 50 | # Traditional way 51 | cmake -DCMAKE_INSTALL_PREFIX=your_install_path ../ 52 | 53 | See also the [CMake documentation](https://cmake.org/cmake/help/latest/manual/cmake.1.html). 54 | 55 | ## Documents 56 | 57 | The HTML documents are available in [here][Documents]. 58 | 59 | ## Examples 60 | 61 | #include 62 | using namespace mptensor; 63 | typedef Tensor ptensor; 64 | ptensor A(Shape(3,4,5)); 65 | 66 | Example codes of TRG and HOTRG for the 2D Ising model are in `examples/Ising_2D`. 67 | 68 | ## License 69 | 70 | GNU Lesser General Public License v3.0 (see [LICENSE][License]) 71 | 72 | ## Links 73 | 74 | - [TeNeS](https://www.pasums.issp.u-tokyo.ac.jp/tenes/en): Parallel tensor network solver for 2D quantum lattice systems 75 | - [Tensordot](https://github.com/smorita/Tensordot): Code generator for tensor contraction 76 | - [cuscalapack](https://github.com/smorita/cuscalapack): pdgemm and pzgemm with cuBLAS 77 | 78 | [Documents]: https://smorita.github.io/mptensor/ 79 | [License]: https://github.com/smorita/mptensor/blob/master/LICENSE 80 | [TravisCI]: https://travis-ci.org/smorita/mptensor 81 | -------------------------------------------------------------------------------- /config/FindScaLAPACK.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find ScaLAPACK 2 | # Once done this will define 3 | # 4 | # SCALAPACK_FOUND - system has ScaLAPACK 5 | # SCALAPACK_LIBRARIES - libraries for ScaLAPACK 6 | 7 | if(DEFINED SCALAPACK_FOUND) 8 | return() 9 | endif(DEFINED SCALAPACK_FOUND) 10 | 11 | message(STATUS "Checking for ScaLAPACK library") 12 | 13 | if(DEFINED SCALAPACK_LIB) 14 | set(SCALAPACK_FOUND TRUE) 15 | set(SCALAPACK_LIBRARIES ${SCALAPACK_LIB}) 16 | message(STATUS "ScaLAPACK libraries: ${SCALAPACK_LIBRARIES}") 17 | return() 18 | endif(DEFINED SCALAPACK_LIB) 19 | 20 | unset(_SCALAPACK_LIBRARY) 21 | 22 | if(DEFINED BLAS_mkl_core_LIBRARY) 23 | 24 | find_library(_SCALAPACK_LIBRARY 25 | NAMES mkl_scalapack_lp64 26 | PATHS $ENV{MKLROOT}/lib/intel64 $ENV{MKLROOT}/lib/em64t 27 | DOC "The ScaLAPACK library") 28 | 29 | else(DEFINED BLAS_mkl_core_LIBRARY) 30 | 31 | # Standard search path 32 | set(_PATHS "") 33 | if(SCALAPACK_DIR) 34 | set(_PATHS ${SCALAPACK_DIR}) 35 | else(SCALAPACK_DIR) 36 | list(APPEND _PATHS 37 | ${SCALAPACK_ROOT}/${CMAKE_BUILD_TYPE} 38 | ${SCALAPACK_ROOT} 39 | $ENV{SCALAPACK_ROOT}/${CMAKE_BUILD_TYPE} 40 | $ENV{SCALAPACK_ROOT} 41 | ${ROKKO_SOLVER_ROOT}/scalapack/${CMAKE_BUILD_TYPE} 42 | ${ROKKO_SOLVER_ROOT}/scalapack 43 | $ENV{ROKKO_SOLVER_ROOT}/scalapack/${CMAKE_BUILD_TYPE} 44 | $ENV{ROKKO_SOLVER_ROOT}/scalapack 45 | ${CMAKE_INSTALL_PREFIX}/scalapack/${CMAKE_BUILD_TYPE} 46 | ${CMAKE_INSTALL_PREFIX}/${CMAKE_BUILD_TYPE} 47 | $ENV{HOME}/rokko/scalapack/${CMAKE_BUILD_TYPE} 48 | $ENV{HOME}/rokko/scalapack 49 | /opt/rokko/scalapack/${CMAKE_BUILD_TYPE} 50 | /opt/rokko/scalapack 51 | /opt/rokko/${CMAKE_BUILD_TYPE} 52 | /opt/rokko 53 | /opt/local /opt 54 | ) 55 | list(APPEND _PATHS /usr/lib64/openmpi) # for CentOS 56 | endif(SCALAPACK_DIR) 57 | 58 | foreach (_PATH ${_PATHS}) 59 | list(APPEND _LIBPATHS "${_PATH}/lib") 60 | endforeach() 61 | 62 | find_library(_SCALAPACK_LIBRARY 63 | NAMES scalapack scalapack-openmpi scalapack-mpich 64 | PATHS ${_LIBPATHS} 65 | DOC "The ScaLAPACK library") 66 | endif(DEFINED BLAS_mkl_core_LIBRARY) 67 | 68 | find_package_handle_standard_args(ScaLAPACK 69 | FOUND_VAR SCALAPACK_FOUND 70 | REQUIRED_VARS _SCALAPACK_LIBRARY 71 | FAIL_MESSAGE "Could NOT find ScaLAPACK library.\nFor Intel MKL, try a option '-DBLA_VENDOR=Intel10_64lp'.\nSee also FindBLAS cmake-module.\n" 72 | ) 73 | 74 | unset(_SCALAPACK_LIBRARIES) 75 | 76 | if(SCALAPACK_FOUND) 77 | list(APPEND SCALAPACK_LIBRARIES ${_SCALAPACK_LIBRARY}) 78 | if(DEFINED BLAS_mkl_core_LIBRARY) 79 | # For CMake <3.10, we need to set MPI_CXX_INCLUDE_DIRS 80 | if((NOT MPI_CXX_INCLUDE_DIRS) AND MPI_CXX_INCLUDE_PATH) 81 | set(MPI_CXX_INCLUDE_DIRS ${MPI_CXX_INCLUDE_PATH}) 82 | endif() 83 | # Check whether SGI MPT is used 84 | try_compile(_SGI_MPT 85 | ${CMAKE_CURRENT_BINARY_DIR} 86 | ${CMAKE_CURRENT_SOURCE_DIR}/config/check_sgimpt.cc 87 | CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${MPI_CXX_INCLUDE_DIRS}" 88 | LINK_LIBRARIES ${MPI_CXX_LIBRARIES} 89 | OUTPUT_VARIABLE LOG) 90 | if(_SGI_MPT) 91 | find_library(_SCALAPACK_BLACS_LIBRARY 92 | NAMES mkl_blacs_sgimpt_lp64 93 | PATHS $ENV{MKLROOT}/lib/intel64 $ENV{MKLROOT}/lib/em64t 94 | DOC "The BLACS library") 95 | MESSAGE(STATUS "SGI MPT is used") 96 | else(_SGI_MPT) 97 | try_compile(_OPENMPI 98 | ${CMAKE_CURRENT_BINARY_DIR} 99 | ${CMAKE_CURRENT_SOURCE_DIR}/config/check_openmpi.cc 100 | CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${MPI_CXX_INCLUDE_DIRS}" 101 | LINK_LIBRARIES ${MPI_CXX_LIBRARIES} 102 | OUTPUT_VARIABLE LOG) 103 | if(_OPENMPI) 104 | find_library(_SCALAPACK_BLACS_LIBRARY 105 | NAMES mkl_blacs_openmpi_lp64 106 | PATHS $ENV{MKLROOT}/lib/intel64 $ENV{MKLROOT}/lib/em64t 107 | DOC "The BLACS library") 108 | MESSAGE(STATUS "OpenMPI is used") 109 | else(_OPENMPI) 110 | find_library(_SCALAPACK_BLACS_LIBRARY 111 | NAMES mkl_blacs_intelmpi_lp64 112 | PATHS $ENV{MKLROOT}/lib/intel64 $ENV{MKLROOT}/lib/em64t 113 | DOC "The BLACS library") 114 | MESSAGE(STATUS "Intel MPI/MPICH2/MVAPICH is used") 115 | endif(_OPENMPI) 116 | endif(_SGI_MPT) 117 | if(_SCALAPACK_BLACS_LIBRARY) 118 | list(APPEND SCALAPACK_LIBRARIES ${_SCALAPACK_BLACS_LIBRARY}) 119 | message(STATUS "Add BLACS to ScaLAPACK: ${_SCALAPACK_BLACS_LIBRARY}") 120 | endif(_SCALAPACK_BLACS_LIBRARY) 121 | 122 | else(DEFINED BLAS_mkl_core_LIBRARY) 123 | find_library(_BLACS_LIBRARY 124 | NAMES blacs blacs-openmpi blacs-mpich 125 | PATHS ${_LIBPATHS} 126 | DOC "The ScaLAPACK BLACS library") 127 | if(_BLACS_LIBRARY) 128 | list(APPEND SCALAPACK_LIBRARIES ${_BLACS_LIBRARY}) 129 | message(STATUS "Add BLACS to ScaLAPACK: ${_BLACS_LIBRARY}") 130 | endif(_BLACS_LIBRARY) 131 | 132 | find_library(_BLACSCINIT_LIBRARY 133 | NAMES blacsCinit blacsCinit-openmpi blacsCinit-mpich 134 | PATHS ${_LIBPATHS} 135 | DOC "The ScaLAPACK BLACS Cinit library") 136 | if(_BLACSCINIT_LIBRARY) 137 | list(APPEND SCALAPACK_LIBRARIES ${_BLACSCINIT_LIBRARY}) 138 | message(STATUS "Add blacsCinit to ScaLAPACK: ${_BLACSCINIT_LIBRARY}") 139 | endif(_BLACSCINIT_LIBRARY) 140 | 141 | endif(DEFINED BLAS_mkl_core_LIBRARY) 142 | endif(SCALAPACK_FOUND) 143 | -------------------------------------------------------------------------------- /config/check_openmpi.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef OMPI_MPI_H // OpenMPI 4 | int main(int argc, char** argv) { 5 | return 0; 6 | } 7 | #else 8 | #error 9 | #endif 10 | -------------------------------------------------------------------------------- /config/check_sgimpt.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef MPT_VERSION 4 | #error 5 | #endif 6 | 7 | int main(int argc, char** argv) { 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /config/cxx11.cmake: -------------------------------------------------------------------------------- 1 | include(CheckCXXCompilerFlag) 2 | 3 | macro(cxx11) 4 | set(ENABLED_CXX11 ON) 5 | check_cxx_compiler_flag("-std=c++11" supports_cxx11) 6 | check_cxx_compiler_flag("-std=c++0x" supports_cxx0x) 7 | if(supports_cxx11) 8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 9 | elseif(supports_cxx0x) 10 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") 11 | else() 12 | message(WARNING "The compiler seems not to support C++11.") 13 | set(ENABLED_CXX11 OFF) 14 | endif() 15 | endmacro() 16 | -------------------------------------------------------------------------------- /config/intel.cmake: -------------------------------------------------------------------------------- 1 | # for Intel Compiler & MKL 2 | set(CMAKE_C_COMPILER "icc" CACHE STRING "" FORCE) 3 | set(CMAKE_CXX_COMPILER "icpc" CACHE STRING "" FORCE) 4 | set(BLA_VENDOR "Intel10_64lp" CACHE STRING "" FORCE) 5 | -------------------------------------------------------------------------------- /doc/doxygen/.gitignore: -------------------------------------------------------------------------------- 1 | # generated by Doxygen 2 | latex 3 | html 4 | *.pdf 5 | -------------------------------------------------------------------------------- /doc/doxygen/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(MPTENSOR_DOC_INSTALL_DIR share/mptensor/${mptensor_version}) 2 | set(MPTENSOR_PDF_FILE ${PROJECT_BINARY_DIR}/mptensor.pdf) 3 | 4 | find_package(Doxygen REQUIRED) 5 | configure_file(Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) 6 | 7 | add_custom_target(doxygen ALL COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile) 8 | install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION ${MPTENSOR_DOC_INSTALL_DIR}/html) 9 | 10 | find_package(LATEX) 11 | if(LATEX_FOUND) 12 | add_custom_target(doxygen_pdf ALL 13 | COMMAND make -C ${CMAKE_CURRENT_BINARY_DIR}/latex 14 | COMMAND cp ${CMAKE_CURRENT_BINARY_DIR}/latex/refman.pdf ${MPTENSOR_PDF_FILE} 15 | DEPENDS doxygen 16 | ) 17 | install(FILES ${MPTENSOR_PDF_FILE} DESTINATION ${MPTENSOR_DOC_INSTALL_DIR}) 18 | endif() 19 | -------------------------------------------------------------------------------- /doc/doxygen/Makefile: -------------------------------------------------------------------------------- 1 | PDF=manual_doxygen.pdf 2 | 3 | .PHONY: all doc pdf clean 4 | 5 | all: doc 6 | 7 | doc: 8 | doxygen Doxyfile 9 | 10 | pdf: doc 11 | make -C latex 12 | cp latex/refman.pdf $(PDF) 13 | 14 | clean: 15 | rm -rf html latex $(PDF) 16 | -------------------------------------------------------------------------------- /doc/doxygen/theme/doxygen-awesome-fragment-copy-button.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Doxygen Awesome 4 | https://github.com/jothepro/doxygen-awesome-css 5 | 6 | MIT License 7 | 8 | Copyright (c) 2022 - 2023 jothepro 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | */ 29 | 30 | class DoxygenAwesomeFragmentCopyButton extends HTMLElement { 31 | constructor() { 32 | super(); 33 | this.onclick=this.copyContent 34 | } 35 | static title = "Copy to clipboard" 36 | static copyIcon = `` 37 | static successIcon = `` 38 | static successDuration = 980 39 | static init() { 40 | $(function() { 41 | $(document).ready(function() { 42 | if(navigator.clipboard) { 43 | const fragments = document.getElementsByClassName("fragment") 44 | for(const fragment of fragments) { 45 | const fragmentWrapper = document.createElement("div") 46 | fragmentWrapper.className = "doxygen-awesome-fragment-wrapper" 47 | const fragmentCopyButton = document.createElement("doxygen-awesome-fragment-copy-button") 48 | fragmentCopyButton.innerHTML = DoxygenAwesomeFragmentCopyButton.copyIcon 49 | fragmentCopyButton.title = DoxygenAwesomeFragmentCopyButton.title 50 | 51 | fragment.parentNode.replaceChild(fragmentWrapper, fragment) 52 | fragmentWrapper.appendChild(fragment) 53 | fragmentWrapper.appendChild(fragmentCopyButton) 54 | 55 | } 56 | } 57 | }) 58 | }) 59 | } 60 | 61 | 62 | copyContent() { 63 | const content = this.previousSibling.cloneNode(true) 64 | // filter out line number from file listings 65 | content.querySelectorAll(".lineno, .ttc").forEach((node) => { 66 | node.remove() 67 | }) 68 | let textContent = content.textContent 69 | // remove trailing newlines that appear in file listings 70 | let numberOfTrailingNewlines = 0 71 | while(textContent.charAt(textContent.length - (numberOfTrailingNewlines + 1)) == '\n') { 72 | numberOfTrailingNewlines++; 73 | } 74 | textContent = textContent.substring(0, textContent.length - numberOfTrailingNewlines) 75 | navigator.clipboard.writeText(textContent); 76 | this.classList.add("success") 77 | this.innerHTML = DoxygenAwesomeFragmentCopyButton.successIcon 78 | window.setTimeout(() => { 79 | this.classList.remove("success") 80 | this.innerHTML = DoxygenAwesomeFragmentCopyButton.copyIcon 81 | }, DoxygenAwesomeFragmentCopyButton.successDuration); 82 | } 83 | } 84 | 85 | customElements.define("doxygen-awesome-fragment-copy-button", DoxygenAwesomeFragmentCopyButton) 86 | -------------------------------------------------------------------------------- /doc/doxygen/theme/doxygen-awesome-paragraph-link.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Doxygen Awesome 4 | https://github.com/jothepro/doxygen-awesome-css 5 | 6 | MIT License 7 | 8 | Copyright (c) 2022 - 2023 jothepro 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | */ 29 | 30 | class DoxygenAwesomeParagraphLink { 31 | // Icon from https://fonts.google.com/icons 32 | // Licensed under the Apache 2.0 license: 33 | // https://www.apache.org/licenses/LICENSE-2.0.html 34 | static icon = `` 35 | static title = "Permanent Link" 36 | static init() { 37 | $(function() { 38 | $(document).ready(function() { 39 | document.querySelectorAll(".contents a.anchor[id], .contents .groupheader > a[id]").forEach((node) => { 40 | let anchorlink = document.createElement("a") 41 | anchorlink.setAttribute("href", `#${node.getAttribute("id")}`) 42 | anchorlink.setAttribute("title", DoxygenAwesomeParagraphLink.title) 43 | anchorlink.classList.add("anchorlink") 44 | node.classList.add("anchor") 45 | anchorlink.innerHTML = DoxygenAwesomeParagraphLink.icon 46 | node.parentElement.appendChild(anchorlink) 47 | }) 48 | }) 49 | }) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /doc/doxygen/theme/doxygen-awesome-tabs.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Doxygen Awesome 4 | https://github.com/jothepro/doxygen-awesome-css 5 | 6 | MIT License 7 | 8 | Copyright (c) 2023 jothepro 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | */ 29 | 30 | class DoxygenAwesomeTabs { 31 | 32 | static init() { 33 | window.addEventListener("load", () => { 34 | document.querySelectorAll(".tabbed:not(:empty)").forEach((tabbed, tabbedIndex) => { 35 | let tabLinkList = [] 36 | tabbed.querySelectorAll("li").forEach((tab, tabIndex) => { 37 | tab.id = "tab_" + tabbedIndex + "_" + tabIndex 38 | let header = tab.querySelector(".tab-title") 39 | let tabLink = document.createElement("button") 40 | tabLink.classList.add("tab-button") 41 | tabLink.appendChild(header) 42 | tabLink.addEventListener("click", () => { 43 | tabbed.querySelectorAll("li").forEach((tab) => { 44 | tab.classList.remove("selected") 45 | }) 46 | tabLinkList.forEach((tabLink) => { 47 | tabLink.classList.remove("active") 48 | }) 49 | tab.classList.add("selected") 50 | tabLink.classList.add("active") 51 | }) 52 | tabLinkList.push(tabLink) 53 | if(tabIndex == 0) { 54 | tab.classList.add("selected") 55 | tabLink.classList.add("active") 56 | } 57 | }) 58 | let tabsOverview = document.createElement("div") 59 | tabsOverview.classList.add("tabs-overview") 60 | let tabsOverviewContainer = document.createElement("div") 61 | tabsOverviewContainer.classList.add("tabs-overview-container") 62 | tabLinkList.forEach((tabLink) => { 63 | tabsOverview.appendChild(tabLink) 64 | }) 65 | tabsOverviewContainer.appendChild(tabsOverview) 66 | tabbed.before(tabsOverviewContainer) 67 | }) 68 | }) 69 | } 70 | } -------------------------------------------------------------------------------- /doc/doxygen/theme/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | $projectname: $title 10 | $title 11 | 12 | 13 | 14 | $treeview 15 | $search 16 | $mathjax 17 | 18 | $extrastylesheet 19 | 20 | 21 | 22 | 23 | 28 | 29 | 30 |
31 | 32 | 33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 47 | 48 | 49 | 50 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
42 |
$projectname 43 |  $projectnumber 44 |
45 |
$projectbrief
46 |
51 |
$projectbrief
52 |
$searchbox
63 |
64 | 65 | 66 | -------------------------------------------------------------------------------- /doc/img/mptensor_logo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorita/mptensor/57ec8e923e8d4fe1bda634059286cdde96fa2e6a/doc/img/mptensor_logo.pdf -------------------------------------------------------------------------------- /doc/img/mptensor_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorita/mptensor/57ec8e923e8d4fe1bda634059286cdde96fa2e6a/doc/img/mptensor_logo.png -------------------------------------------------------------------------------- /doc/img/mptensor_logo.svg: -------------------------------------------------------------------------------- 1 | mptensor_logo -------------------------------------------------------------------------------- /doc/img/mptensor_logo_w200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smorita/mptensor/57ec8e923e8d4fe1bda634059286cdde96fa2e6a/doc/img/mptensor_logo_w200.png -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(Ising_2D) 2 | add_subdirectory(benchmark) 3 | add_subdirectory(output) 4 | add_subdirectory(save_load) 5 | add_subdirectory(simple_example) 6 | -------------------------------------------------------------------------------- /examples/Ising_2D/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PROGS trg hotrg atrg) 2 | foreach(name ${PROGS}) 3 | add_executable(${name} ${name}.cc ising.cc) 4 | target_link_libraries(${name} mptensor) 5 | endforeach(name ${PROGS}) 6 | -------------------------------------------------------------------------------- /examples/Ising_2D/Makefile: -------------------------------------------------------------------------------- 1 | -include ../../Makefile.option 2 | 3 | .PHONY: all clean depend 4 | .SUFFIXES: .cc .hpp .o .out 5 | 6 | TARGET = trg.out hotrg.out atrg.out 7 | SRC = ising.cc trg.cc hotrg.cc atrg.cc 8 | OBJS = ising.o 9 | 10 | MPTENSOR_SOURCE_DIR = ../../src 11 | MPTENSOR_INCLUDE_DIR = ../../include 12 | MPTENSOR_FLAGS = -I$(MPTENSOR_INCLUDE_DIR) -L$(MPTENSOR_SOURCE_DIR) -lmptensor 13 | 14 | 15 | all: $(TARGET) 16 | 17 | %.out : %.o $(OBJS) 18 | $(CXX) -o $@ $< $(OBJS) $(MPTENSOR_FLAGS) $(LDFLAGS) $(CXXFLAGS) 19 | 20 | %.o : %.cc 21 | $(CXX) -c $< $(MPTENSOR_FLAGS) $(LDFLAGS) $(CXXFLAGS) 22 | 23 | clean: 24 | rm -vf *.out *.o 25 | 26 | depend Makefile.depend: 27 | g++ -MM -MG $(MPTENSOR_FLAGS) $(SRC) > Makefile.depend 28 | 29 | -include Makefile.depend 30 | -------------------------------------------------------------------------------- /examples/Ising_2D/ising.cc: -------------------------------------------------------------------------------- 1 | /* 2 | mptensor - Parallel Library for Tensor Network Methods 3 | 4 | Copyright 2016 Satoshi Morita 5 | 6 | mptensor is free software: you can redistribute it and/or modify it 7 | under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation, either version 3 of the 9 | License, or (at your option) any later version. 10 | 11 | mptensor is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with mptensor. If not, see 18 | . 19 | */ 20 | 21 | /*! 22 | \file ising.cc 23 | \author Satoshi Morita 24 | \date Thu Nov 5 2015 25 | \brief Two-dimensional Ising model 26 | */ 27 | 28 | #include 29 | 30 | #include "ising.hpp" 31 | 32 | namespace examples { 33 | namespace Ising_2D { 34 | 35 | double exact_free_energy_integrand(double beta, double x) { 36 | double k = 2.0 * sinh(2.0 * beta) / (cosh(2.0 * beta) * cosh(2.0 * beta)); 37 | return log(1.0 + sqrt(fabs(1.0 - k * k * cos(x) * cos(x)))); 38 | } 39 | 40 | double exact_free_energy(double temp) { 41 | const double pi = M_PI; 42 | const double beta = 1.0 / temp; 43 | 44 | // Simpson's rule 45 | // integral(0.0, pi/2.0, func(x)); 46 | double integral = 0.0; 47 | { 48 | const int n = 500000; 49 | const double x_start = 0.0; 50 | const double x_end = 0.5 * pi; 51 | const double h = (x_end - x_start) / static_cast(2 * n); 52 | double sum_even = 0.0; 53 | double sum_odd = 0.0; 54 | for (int i = 0; i < n; ++i) { 55 | sum_odd += exact_free_energy_integrand(beta, h * (2 * i + 1)); 56 | } 57 | for (int i = 1; i < n; ++i) { 58 | sum_even += exact_free_energy_integrand(beta, h * (2 * i)); 59 | } 60 | integral += exact_free_energy_integrand(beta, x_start); 61 | integral += exact_free_energy_integrand(beta, x_end); 62 | integral += 2.0 * sum_even + 4.0 * sum_odd; 63 | integral *= h / 3.0; 64 | } 65 | 66 | return -temp * (log(sqrt(2.0) * cosh(2.0 * beta)) + integral / pi); 67 | } 68 | 69 | } // namespace Ising_2D 70 | } // namespace examples 71 | -------------------------------------------------------------------------------- /examples/Ising_2D/ising.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | mptensor - Parallel Library for Tensor Network Methods 3 | 4 | Copyright 2016 Satoshi Morita 5 | 6 | mptensor is free software: you can redistribute it and/or modify it 7 | under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation, either version 3 of the 9 | License, or (at your option) any later version. 10 | 11 | mptensor is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with mptensor. If not, see 18 | . 19 | */ 20 | 21 | /*! 22 | \file ising.hpp 23 | \author Satoshi Morita 24 | \date Thu Nov 5 2015 25 | \brief Two-dimensional Ising model 26 | */ 27 | 28 | #ifndef _ISING_HPP_ 29 | #define _ISING_HPP_ 30 | 31 | #include 32 | 33 | namespace examples { 34 | namespace Ising_2D { 35 | 36 | //! Tc of the Ising model on the square lattice 37 | const double Ising_Tc = 2.0 / log(1.0 + sqrt(2.0)); 38 | double exact_free_energy(double temp); 39 | 40 | } // namespace Ising_2D 41 | } // namespace examples 42 | 43 | #endif // _ISING_HPP_ 44 | -------------------------------------------------------------------------------- /examples/Ising_2D/trg.cc: -------------------------------------------------------------------------------- 1 | /* 2 | mptensor - Parallel Library for Tensor Network Methods 3 | 4 | Copyright 2016 Satoshi Morita 5 | 6 | mptensor is free software: you can redistribute it and/or modify it 7 | under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation, either version 3 of the 9 | License, or (at your option) any later version. 10 | 11 | mptensor is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with mptensor. If not, see 18 | . 19 | */ 20 | 21 | /*! 22 | \file trg.cc 23 | \author Satoshi Morita 24 | \date Aug 25 2016 25 | 26 | \brief Two-dimensional Ising model by TRG 27 | 28 | This sample program calculates the free energy of the two-dimensional Ising 29 | model by using a tensor renormalization group (TRG). 30 | 31 | \par Reference 32 | M. Levin and C. P. Nave: Phys. Rev. Lett. \b 99, 120601 (2007) 33 | */ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include 41 | #include 42 | 43 | #include "ising.hpp" 44 | 45 | namespace examples { 46 | namespace Ising_2D { 47 | 48 | using namespace mptensor; 49 | typedef Tensor tensor; 50 | 51 | //! class for TRG 52 | class Trg { 53 | public: 54 | Trg(double temp); 55 | double free_energy() const; 56 | double n_spin() const; 57 | void update(size_t chi); 58 | 59 | double temp; 60 | tensor a; // 4-leg tensor. [Top][Right][Down][Left] 61 | double log_factor; 62 | double log_n_spin; 63 | }; 64 | 65 | Trg::Trg(double t) : temp(t) { 66 | a = tensor(Shape(2, 2, 2, 2)); 67 | const double c = cosh(1.0 / temp); 68 | const double s = sinh(1.0 / temp); 69 | Index idx; 70 | for (size_t i = 0; i < a.local_size(); ++i) { 71 | idx = a.global_index(i); 72 | size_t sum = idx[0] + idx[1] + idx[2] + idx[3]; 73 | if (sum == 0) { 74 | a[i] = 2 * c * c; 75 | } else if (sum == 2) { 76 | a[i] = 2 * c * s; 77 | } else if (sum == 4) { 78 | a[i] = 2 * s * s; 79 | } 80 | } 81 | double val = trace(a, Axes(0, 1), Axes(2, 3)); 82 | a /= val; 83 | log_factor = log(val); 84 | log_n_spin = log(1.0); 85 | } 86 | 87 | inline double Trg::free_energy() const { 88 | return -temp * (log_factor + log(trace(a, Axes(0, 1), Axes(2, 3)))) / 89 | exp(log_n_spin); 90 | } 91 | 92 | inline double Trg::n_spin() const { return exp(log_n_spin); } 93 | 94 | void Trg::update(size_t chi) { 95 | Shape shape = a.shape(); 96 | size_t size = std::min(chi, shape[0] * shape[1]); 97 | tensor c0, c1, c2, c3; 98 | tensor u, v; 99 | std::vector s, sqrt_s(size); 100 | 101 | // SVD (top,right) - (bottom,left) 102 | svd(a, Axes(0, 1), Axes(2, 3), u, s, v); 103 | for (size_t i = 0; i < size; ++i) sqrt_s[i] = sqrt(s[i]); 104 | c3 = slice(u, 2, 0, size).multiply_vector(sqrt_s, 2); 105 | c1 = slice(v, 0, 0, size).multiply_vector(sqrt_s, 0); 106 | 107 | // SVD (top,left) - (right,bottom) 108 | svd(a, Axes(0, 3), Axes(1, 2), u, s, v); 109 | for (size_t i = 0; i < size; ++i) sqrt_s[i] = sqrt(s[i]); 110 | c2 = slice(u, 2, 0, size).multiply_vector(sqrt_s, 2); 111 | c0 = slice(v, 0, 0, size).multiply_vector(sqrt_s, 0); 112 | 113 | a = tensordot(tensordot(c0, c1, 1, 2), tensordot(c2, c3, 1, 1), Axes(1, 3), 114 | Axes(2, 0)); 115 | 116 | log_factor *= 2.0; // factor_new = factor_old^2 117 | log_n_spin += log(2.0); // n_new = 2*n_old 118 | 119 | double val = trace(a, Axes(0, 1), Axes(2, 3)); 120 | a /= val; 121 | log_factor += log(val); 122 | return; 123 | } 124 | 125 | } // namespace Ising_2D 126 | } // namespace examples 127 | 128 | namespace { 129 | 130 | MPI_Comm comm; 131 | int mpirank; 132 | int mpisize; 133 | bool mpiroot; 134 | 135 | void output(int step, double n_spin, double f, double f_exact) { 136 | if (mpiroot) { 137 | std::cout << step << "\t" << std::scientific << std::setprecision(6) 138 | << n_spin << "\t" << std::scientific << std::setprecision(10) << f 139 | << "\t" << (f - f_exact) / std::abs(f_exact) << std::endl; 140 | } 141 | } 142 | 143 | } // namespace 144 | 145 | /* Main function */ 146 | int main(int argc, char **argv) { 147 | using namespace examples::Ising_2D; 148 | /* Start */ 149 | MPI_Init(&argc, &argv); 150 | comm = MPI_COMM_WORLD; 151 | MPI_Comm_rank(comm, &mpirank); 152 | MPI_Comm_size(comm, &mpisize); 153 | mpiroot = (mpirank == 0); 154 | 155 | /* Get arguments */ 156 | if (mpiroot) { 157 | if (argc < 4) std::cerr << "Usage: trg.out chi step T\n"; 158 | if (argc < 2) std::cerr << "Warning: Assuming chi = 8\n"; 159 | if (argc < 3) std::cerr << "Warning: Assuming step = 16\n"; 160 | if (argc < 4) std::cerr << "Warning: Assuming T = T_c\n"; 161 | } 162 | const int chi = (argc < 2) ? 8 : atoi(argv[1]); 163 | const int step = (argc < 3) ? 16 : atoi(argv[2]); 164 | const double temp = (argc < 4) ? Ising_Tc : atof(argv[3]); 165 | const double f_exact = exact_free_energy(temp); 166 | 167 | if (mpiroot) { 168 | std::cout << "##### parameters #####\n" 169 | << "# T= " << std::setprecision(10) << temp << "\n" 170 | << "# chi= " << chi << "\n" 171 | << "# f_exact= " << std::setprecision(10) << f_exact << "\n" 172 | << "##### keys #####\n" 173 | << "# 1: step" 174 | << "\n" 175 | << "# 2: N_spin" 176 | << "\n" 177 | << "# 3: free energy (f)" 178 | << "\n" 179 | << "# 4: relative error ((f-f_exact)/|f_exact|)" 180 | << "\n" 181 | << "##### output #####\n"; 182 | } 183 | 184 | Trg trg(temp); 185 | output(0, trg.n_spin(), trg.free_energy(), f_exact); 186 | 187 | for (int i = 0; i < step; ++i) { 188 | trg.update(chi); 189 | output(i + 1, trg.n_spin(), trg.free_energy(), f_exact); 190 | } 191 | 192 | /* End */ 193 | MPI_Finalize(); 194 | } 195 | -------------------------------------------------------------------------------- /examples/benchmark/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PROGS reshape rsvd slice transpose) 2 | foreach(name ${PROGS}) 3 | add_executable(${name} ${name}.cc) 4 | target_link_libraries(${name} mptensor) 5 | endforeach(name ${PROGS}) 6 | -------------------------------------------------------------------------------- /examples/benchmark/Makefile: -------------------------------------------------------------------------------- 1 | -include ../../Makefile.option 2 | 3 | .PHONY: all clean depend 4 | .SUFFIXES: .cc .hpp .o .out 5 | SRC=$(shell ls *.cc) 6 | HED=$(shell ls *.hpp) 7 | OBJ=$(SRC:.cc=.o) 8 | TARGET=$(SRC:.cc=.out) 9 | 10 | MPTENSOR_SOURCE_DIR = ../../src 11 | MPTENSOR_INCLUDE_DIR = ../../include 12 | MPTENSOR_FLAGS = -I$(MPTENSOR_INCLUDE_DIR) -L$(MPTENSOR_SOURCE_DIR) -lmptensor 13 | 14 | 15 | all: $(TARGET) 16 | 17 | %.out : %.cc 18 | $(CXX) -o $@ $< $(MPTENSOR_FLAGS) $(LDFLAGS) $(CXXFLAGS) 19 | 20 | clean: 21 | @rm -vf *.out *.o 22 | @rm -vf Makefile.depend 23 | 24 | depend Makefile.depend: 25 | g++ -MM -MG -I$(MPTENSOR_FLAGS) $(SRC) > Makefile.depend 26 | 27 | -include Makefile.depend 28 | -------------------------------------------------------------------------------- /examples/benchmark/reshape.cc: -------------------------------------------------------------------------------- 1 | /* 2 | mptensor - Parallel Library for Tensor Network Methods 3 | 4 | Copyright 2016 Satoshi Morita 5 | 6 | mptensor is free software: you can redistribute it and/or modify it 7 | under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation, either version 3 of the 9 | License, or (at your option) any later version. 10 | 11 | mptensor is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with mptensor. If not, see 18 | . 19 | */ 20 | 21 | /*! 22 | \file benchmark/reshape.cc 23 | \author Satoshi Morita 24 | \date Dec 24 2015 25 | \brief Benchmark of reshape 26 | */ 27 | 28 | #include 29 | 30 | #include 31 | #include 32 | 33 | #include "timer.hpp" 34 | 35 | #ifdef _OPENMP 36 | extern "C" { 37 | int omp_get_max_threads(); 38 | } 39 | #else 40 | int omp_get_max_threads() { return 1; } 41 | #endif 42 | 43 | inline double elem(mptensor::Index index) { 44 | return double(index[0] - 2.0 * index[1] + 3.0 * index[2] - 4.0 * index[3]); 45 | } 46 | 47 | /* Main function */ 48 | int main(int argc, char **argv) { 49 | using namespace mptensor; 50 | using examples::benchmark::Timer; 51 | typedef Tensor ptensor; 52 | 53 | /* Start */ 54 | MPI_Init(&argc, &argv); 55 | MPI_Comm comm = MPI_COMM_WORLD; 56 | int mpirank; 57 | int mpisize; 58 | bool mpiroot; 59 | MPI_Comm_rank(comm, &mpirank); 60 | MPI_Comm_size(comm, &mpisize); 61 | mpiroot = (mpirank == 0); 62 | 63 | /* Get arguments */ 64 | int n; 65 | if (argc < 2) { 66 | if (mpiroot) 67 | std::cerr << "Usage: a.out N\n" 68 | << "waring: assuming N=10" << std::endl; 69 | n = 10; 70 | } else { 71 | n = atoi(argv[1]); 72 | } 73 | 74 | Timer timer_all; 75 | std::vector timer(2); 76 | 77 | Shape shape4(n, n + 1, n + 2, n + 3); 78 | Shape shape2(n * (n + 1), (n + 2) * (n + 3)); 79 | ptensor A(shape4); 80 | Index index; 81 | for (int i = 0; i < A.local_size(); ++i) { 82 | index = A.global_index(i); 83 | A[i] = elem(index); 84 | } 85 | ptensor T = A; 86 | 87 | timer_all.start(); 88 | { 89 | timer[0].start(); 90 | T = reshape(T, shape2); 91 | timer[0].stop(); 92 | 93 | timer[1].start(); 94 | T = reshape(T, shape4); 95 | timer[1].stop(); 96 | } 97 | timer_all.stop(); 98 | 99 | double error = 0.0; 100 | for (int i = 0; i < T.local_size(); ++i) { 101 | double diff = A[i] - T[i]; 102 | if (error < std::abs(diff)) error = diff; 103 | } 104 | double max_error; 105 | MPI_Reduce(&error, &max_error, 1, MPI_DOUBLE, MPI_MAX, 0, comm); 106 | 107 | if (mpiroot) { 108 | std::cout << "# "; 109 | T.print_info(std::cout); 110 | std::cout << "# mpisize= " << mpisize << "\n"; 111 | std::cout << "# num_threads= " << omp_get_max_threads() << "\n"; 112 | std::cout << "# error= " << max_error << "\n"; 113 | std::cout << "all: " << timer_all.result() << "\n"; 114 | std::cout << "time[0]: " << timer[0].result() << "\t" << shape4 << " -> " 115 | << shape2 << "\n"; 116 | std::cout << "time[1]: " << timer[1].result() << "\t" << shape2 << " -> " 117 | << shape4 << "\n"; 118 | } 119 | assert(error < 1.0e-10); 120 | 121 | /* End */ 122 | MPI_Finalize(); 123 | } 124 | -------------------------------------------------------------------------------- /examples/benchmark/rsvd.cc: -------------------------------------------------------------------------------- 1 | /* 2 | mptensor - Parallel Library for Tensor Network Methods 3 | 4 | Copyright 2016 Satoshi Morita 5 | 6 | mptensor is free software: you can redistribute it and/or modify it 7 | under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation, either version 3 of the 9 | License, or (at your option) any later version. 10 | 11 | mptensor is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with mptensor. If not, see 18 | . 19 | */ 20 | 21 | /*! 22 | \file benchmark/rsvd.cc 23 | \author Satoshi Morita 24 | \date Feb 32016 25 | 26 | \brief Benchmark for RSVD. 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | 36 | #include "timer.hpp" 37 | 38 | #ifdef _OPENMP 39 | extern "C" { 40 | int omp_get_max_threads(); 41 | } 42 | #else 43 | int omp_get_max_threads() { return 1; } 44 | #endif 45 | 46 | using namespace mptensor; 47 | typedef Tensor ptensor; 48 | 49 | namespace { 50 | 51 | double singular_value(size_t i) { return std::pow(1.0 + i, -2.0); } 52 | 53 | ptensor test_tensor(size_t n) { 54 | MPI_Comm comm = MPI_COMM_WORLD; 55 | ptensor D(Shape(n * n, n * n)); 56 | { 57 | const int m = D.local_size(); 58 | Index idx; 59 | for (size_t i = 0; i < m; ++i) { 60 | idx = D.global_index(i); 61 | if (idx[0] == idx[1]) { 62 | D[i] = singular_value(idx[0]); 63 | } 64 | } 65 | } 66 | ptensor U1, U2; 67 | { 68 | ptensor o1(comm, Shape(n + 2, n, n * n), 2); 69 | ptensor o2(comm, Shape(n + 3, n + 1, n * n), 2); 70 | random_tensor::fill(o1); 71 | random_tensor::fill(o2); 72 | ptensor r; 73 | qr(o1, Axes(0, 1), Axes(2), U1, r); 74 | qr(o2, Axes(0, 1), Axes(2), U2, r); 75 | } 76 | 77 | return transpose( 78 | tensordot(tensordot(U1, D, Axes(2), Axes(0)), U2, Axes(2), Axes(2)), 79 | Axes(1, 3, 0, 2)); 80 | } 81 | 82 | class Multiply_row_02 { 83 | public: 84 | Multiply_row_02(const ptensor& t) : t_(t){}; 85 | ptensor operator()(const ptensor& t) { 86 | return tensordot(t, t_, Axes(0, 1), Axes(0, 2)); 87 | }; 88 | 89 | private: 90 | const ptensor& t_; 91 | }; 92 | 93 | class Multiply_col_13 { 94 | public: 95 | Multiply_col_13(const ptensor& t) : t_(t){}; 96 | ptensor operator()(const ptensor& t) { 97 | return tensordot(t_, t, Axes(1, 3), Axes(0, 1)); 98 | }; 99 | 100 | private: 101 | const ptensor& t_; 102 | }; 103 | 104 | } // namespace 105 | 106 | /* Main function */ 107 | int main(int argc, char** argv) { 108 | using examples::benchmark::Timer; 109 | 110 | /* Start */ 111 | MPI_Init(&argc, &argv); 112 | MPI_Comm comm = MPI_COMM_WORLD; 113 | int mpirank; 114 | int mpisize; 115 | bool mpiroot; 116 | MPI_Comm_rank(comm, &mpirank); 117 | MPI_Comm_size(comm, &mpisize); 118 | mpiroot = (mpirank == 0); 119 | 120 | /* Get arguments */ 121 | int n, target, oversamp; 122 | unsigned int seed; 123 | if (argc < 2) { 124 | if (mpiroot) 125 | std::cerr << "Usage: a.out [N [target_rank [oversamp [seed]]]]\n" 126 | << "waring: assuming N=10" << std::endl; 127 | } 128 | n = (argc > 1) ? atoi(argv[1]) : 10; 129 | target = (argc > 2) ? atoi(argv[2]) : n; 130 | oversamp = (argc > 3) ? atoi(argv[3]) : target; 131 | seed = (argc > 4) ? atoi(argv[4]) : std::time(NULL); 132 | set_seed(seed + mpirank); 133 | 134 | Timer timer_full, timer_rsvd, timer_rsvd_func; 135 | 136 | ptensor A = test_tensor(n); 137 | 138 | timer_full.start(); 139 | std::vector s0; 140 | ptensor u0, vt0; 141 | svd(A, Axes(0, 2), Axes(1, 3), u0, s0, vt0); 142 | timer_full.stop(); 143 | 144 | timer_rsvd.start(); 145 | std::vector s1; 146 | ptensor u1, vt1; 147 | rsvd(A, Axes(0, 2), Axes(1, 3), u1, s1, vt1, target, oversamp); 148 | timer_rsvd.stop(); 149 | 150 | timer_rsvd_func.start(); 151 | std::vector s2; 152 | ptensor u2, vt2; 153 | { 154 | Multiply_row_02 mr02(A); 155 | Multiply_col_13 mc13(A); 156 | Shape shape = A.shape(); 157 | Shape shape_row(shape[0], shape[2]); 158 | Shape shape_col(shape[1], shape[3]); 159 | rsvd(mr02, mc13, shape_row, shape_col, u2, s2, vt2, target, oversamp); 160 | } 161 | timer_rsvd_func.stop(); 162 | 163 | if (mpiroot) { 164 | std::cout << "# "; 165 | A.print_info(std::cout); 166 | std::cout << "# mpisize= " << mpisize << "\n" 167 | << "# num_threads= " << omp_get_max_threads() << "\n" 168 | << "# n= " << n << "\n" 169 | << "# target_rank= " << target << "\n" 170 | << "# oversamp= " << oversamp << "\n" 171 | << "# seed= " << seed << "\n" 172 | << "# time_full= " << timer_full.result() << "\n" 173 | << "# time_rsvd= " << timer_rsvd.result() << "\n" 174 | << "# time_rsvd_func= " << timer_rsvd_func.result() << "\n"; 175 | std::cout << "# index s_exact s_full s_rsvd s_rsvd_f s_full-s_rsvd " 176 | "s_full-s_rsvd_f\n"; 177 | for (size_t i = 0; i < target; ++i) { 178 | std::cout << i << " " << std::scientific << std::setprecision(10) 179 | << singular_value(i) << " " << s0[i] << " " << s1[i] << " " 180 | << s2[i] << " " << s0[i] - s1[i] << " " << s0[i] - s2[i] 181 | << "\n"; 182 | } 183 | } 184 | 185 | /* End */ 186 | MPI_Finalize(); 187 | } 188 | -------------------------------------------------------------------------------- /examples/benchmark/slice.cc: -------------------------------------------------------------------------------- 1 | /* 2 | mptensor - Parallel Library for Tensor Network Methods 3 | 4 | Copyright 2016 Satoshi Morita 5 | 6 | mptensor is free software: you can redistribute it and/or modify it 7 | under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation, either version 3 of the 9 | License, or (at your option) any later version. 10 | 11 | mptensor is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with mptensor. If not, see 18 | . 19 | */ 20 | 21 | /*! 22 | \file benchmark/slice.cc 23 | \author Satoshi Morita 24 | \date Dec 24 2015 25 | 26 | \brief Benchmark of slice 27 | */ 28 | 29 | #include 30 | 31 | #include 32 | #include 33 | 34 | #include "timer.hpp" 35 | 36 | #ifdef _OPENMP 37 | extern "C" { 38 | int omp_get_max_threads(); 39 | } 40 | #else 41 | int omp_get_max_threads() { return 1; } 42 | #endif 43 | 44 | inline double elem(mptensor::Index index) { 45 | return double(index[0] - 2.0 * index[1] + 3.0 * index[2] - 4.0 * index[3]); 46 | } 47 | 48 | /* Main function */ 49 | int main(int argc, char **argv) { 50 | using namespace mptensor; 51 | typedef Tensor ptensor; 52 | using examples::benchmark::Timer; 53 | 54 | /* Start */ 55 | MPI_Init(&argc, &argv); 56 | MPI_Comm comm = MPI_COMM_WORLD; 57 | int mpirank; 58 | int mpisize; 59 | bool mpiroot; 60 | MPI_Comm_rank(comm, &mpirank); 61 | MPI_Comm_size(comm, &mpisize); 62 | mpiroot = (mpirank == 0); 63 | 64 | /* Get arguments */ 65 | int n; 66 | if (argc < 2) { 67 | if (mpiroot) 68 | std::cerr << "Usage: a.out N\n" 69 | << "waring: assuming N=10" << std::endl; 70 | n = 10; 71 | } else { 72 | n = atoi(argv[1]); 73 | } 74 | 75 | Timer timer_all; 76 | std::vector timer(2); 77 | 78 | size_t m = (n / 2 > 0) ? n / 2 : 1; 79 | Shape shape0(n, n + 1, n + 2, n + 3); 80 | Shape shape1(n, m, m, n + 3); 81 | Shape shape2(n, m, m + 1, n + 3); 82 | 83 | ptensor A(shape0); 84 | Index index; 85 | for (int i = 0; i < A.local_size(); ++i) { 86 | index = A.global_index(i); 87 | A[i] = elem(index); 88 | } 89 | ptensor T = A; 90 | 91 | timer_all.start(); 92 | { 93 | timer[0].start(); 94 | T = slice(T, 1, 0, m); 95 | timer[0].stop(); 96 | 97 | timer[1].start(); 98 | T = slice(T, 2, 0, m); 99 | timer[1].stop(); 100 | } 101 | timer_all.stop(); 102 | 103 | double error = 0.0; 104 | for (int i = 0; i < T.local_size(); ++i) { 105 | index = T.global_index(i); 106 | double diff = elem(index) - T[i]; 107 | if (error < std::abs(diff)) error = diff; 108 | } 109 | double max_error; 110 | MPI_Reduce(&error, &max_error, 1, MPI_DOUBLE, MPI_MAX, 0, comm); 111 | 112 | if (mpiroot) { 113 | std::cout << "# "; 114 | T.print_info(std::cout); 115 | std::cout << "# mpisize= " << mpisize << "\n"; 116 | std::cout << "# num_threads= " << omp_get_max_threads() << "\n"; 117 | std::cout << "# error= " << max_error << "\n"; 118 | std::cout << "all: " << timer_all.result() << "\n"; 119 | std::cout << "time[0]: " << timer[0].result() << "\t" << shape0 << " -> " 120 | << shape1 << "\n"; 121 | std::cout << "time[1]: " << timer[1].result() << "\t" << shape1 << " -> " 122 | << shape2 << "\n"; 123 | } 124 | assert(error < 1.0e-10); 125 | 126 | /* End */ 127 | MPI_Finalize(); 128 | } 129 | -------------------------------------------------------------------------------- /examples/benchmark/timer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | mptensor - Parallel Library for Tensor Network Methods 3 | 4 | Copyright 2016 Satoshi Morita 5 | 6 | mptensor is free software: you can redistribute it and/or modify it 7 | under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation, either version 3 of the 9 | License, or (at your option) any later version. 10 | 11 | mptensor is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with mptensor. If not, see 18 | . 19 | */ 20 | 21 | /*! 22 | \file benchmark/timer.hpp 23 | \author Satoshi Morita 24 | \date Thu Aug 25 25 | \brief Timer class 26 | */ 27 | 28 | #include 29 | 30 | #ifndef _TIMER_HPP_ 31 | #define _TIMER_HPP_ 32 | 33 | namespace examples { 34 | namespace benchmark { 35 | 36 | class Timer { 37 | public: 38 | Timer(){}; 39 | void start() { t_start = MPI_Wtime(); }; 40 | void stop() { t_end = MPI_Wtime(); }; 41 | double result() { return t_end - t_start; }; 42 | 43 | private: 44 | double t_start; 45 | double t_end; 46 | }; 47 | 48 | } // namespace benchmark 49 | } // namespace examples 50 | 51 | #endif // _TIMER_HPP_ 52 | -------------------------------------------------------------------------------- /examples/benchmark/transpose.cc: -------------------------------------------------------------------------------- 1 | /* 2 | mptensor - Parallel Library for Tensor Network Methods 3 | 4 | Copyright 2016 Satoshi Morita 5 | 6 | mptensor is free software: you can redistribute it and/or modify it 7 | under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation, either version 3 of the 9 | License, or (at your option) any later version. 10 | 11 | mptensor is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with mptensor. If not, see 18 | . 19 | */ 20 | 21 | /*! 22 | \file benchmark/transpose.cc 23 | \author Satoshi Morita 24 | \date Dec 02 2015 25 | \brief Benchmark of transpose 26 | */ 27 | 28 | #include 29 | 30 | #include 31 | #include 32 | 33 | #include "timer.hpp" 34 | 35 | #ifdef _OPENMP 36 | extern "C" { 37 | int omp_get_max_threads(); 38 | } 39 | #else 40 | int omp_get_max_threads() { return 1; } 41 | #endif 42 | 43 | inline double elem(mptensor::Index index) { 44 | return double(index[0] - 2.0 * index[1] + 3.0 * index[2] - 4.0 * index[3]); 45 | } 46 | 47 | inline mptensor::Index permutation(size_t n) { 48 | mptensor::Index idx(0, 1, 2, 3); 49 | size_t x, val; 50 | { 51 | x = n / 6; 52 | val = idx[x]; 53 | for (size_t i = x; i > 0; --i) idx[i] = idx[i - 1]; 54 | idx[0] = val; 55 | } 56 | { 57 | x = (n % 6) / 2 + 1; 58 | val = idx[x]; 59 | for (size_t i = x; i > 1; --i) idx[i] = idx[i - 1]; 60 | idx[1] = val; 61 | } 62 | { 63 | if ((n % 2) == 1) { 64 | val = idx[2]; 65 | idx[2] = idx[3]; 66 | idx[3] = val; 67 | } 68 | } 69 | return idx; 70 | } 71 | 72 | /* Main function */ 73 | int main(int argc, char **argv) { 74 | using namespace mptensor; 75 | typedef Tensor ptensor; 76 | using examples::benchmark::Timer; 77 | 78 | /* Start */ 79 | MPI_Init(&argc, &argv); 80 | MPI_Comm comm = MPI_COMM_WORLD; 81 | int mpirank; 82 | int mpisize; 83 | bool mpiroot; 84 | MPI_Comm_rank(comm, &mpirank); 85 | MPI_Comm_size(comm, &mpisize); 86 | mpiroot = (mpirank == 0); 87 | 88 | /* Get arguments */ 89 | int n; 90 | if (argc < 2) { 91 | if (mpiroot) 92 | std::cerr << "Usage: a.out N\n" 93 | << "waring: assuming N=10" << std::endl; 94 | n = 10; 95 | } else { 96 | n = atoi(argv[1]); 97 | } 98 | 99 | Timer timer_all; 100 | std::vector timer(24); 101 | std::vector axes(24); 102 | for (int i = 0; i < 24; ++i) { 103 | axes[i] = permutation(i); 104 | } 105 | 106 | ptensor A(Shape(n, n + 1, n + 2, n + 3)); 107 | Index index; 108 | for (int i = 0; i < A.local_size(); ++i) { 109 | index = A.global_index(i); 110 | A[i] = elem(index); 111 | } 112 | ptensor T = A; 113 | 114 | timer_all.start(); 115 | for (int i = 0; i < 24; ++i) { 116 | timer[i].start(); 117 | T = transpose(T, axes[i]); 118 | timer[i].stop(); 119 | } 120 | timer_all.stop(); 121 | 122 | double error = 0.0; 123 | T = transpose(T, Index(2, 3, 0, 1)); 124 | for (int i = 0; i < T.local_size(); ++i) { 125 | double diff = A[i] - T[i]; 126 | if (error < std::abs(diff)) error = diff; 127 | } 128 | double max_error; 129 | MPI_Reduce(&error, &max_error, 1, MPI_DOUBLE, MPI_MAX, 0, comm); 130 | 131 | if (mpiroot) { 132 | std::cout << "# "; 133 | T.print_info(std::cout); 134 | std::cout << "# mpisize= " << mpisize << "\n"; 135 | std::cout << "# num_threads= " << omp_get_max_threads() << "\n"; 136 | std::cout << "# error= " << max_error << "\n"; 137 | std::cout << "all: " << timer_all.result() << "\n"; 138 | for (int i = 0; i < 24; ++i) { 139 | std::cout << "time[i]: " << timer[i].result() << "\t" << axes[i] << "\n"; 140 | } 141 | } 142 | assert(error < 1.0e-10); 143 | 144 | /* End */ 145 | MPI_Finalize(); 146 | } 147 | -------------------------------------------------------------------------------- /examples/output/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PROGS output) 2 | foreach(name ${PROGS}) 3 | add_executable(${name} ${name}.cc) 4 | target_link_libraries(${name} mptensor) 5 | endforeach(name ${PROGS}) 6 | -------------------------------------------------------------------------------- /examples/output/Makefile: -------------------------------------------------------------------------------- 1 | -include ../../Makefile.option 2 | 3 | .PHONY: all clean depend 4 | .SUFFIXES: .cc .hpp .o .out 5 | 6 | TARGET = output.out 7 | 8 | MPTENSOR_SOURCE_DIR = ../../src 9 | MPTENSOR_INCLUDE_DIR = ../../include 10 | MPTENSOR_FLAGS = -I$(MPTENSOR_INCLUDE_DIR) -L$(MPTENSOR_SOURCE_DIR) -lmptensor 11 | 12 | 13 | all: $(TARGET) 14 | 15 | %.out : %.cc 16 | $(CXX) -o $@ $< $(MPTENSOR_FLAGS) $(LDFLAGS) $(CXXFLAGS) 17 | 18 | clean: 19 | @rm -vf *.out *.o 20 | -------------------------------------------------------------------------------- /examples/output/output.cc: -------------------------------------------------------------------------------- 1 | /* 2 | mptensor - Parallel Library for Tensor Network Methods 3 | 4 | Copyright 2016 Satoshi Morita 5 | 6 | mptensor is free software: you can redistribute it and/or modify it 7 | under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation, either version 3 of the 9 | License, or (at your option) any later version. 10 | 11 | mptensor is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with mptensor. If not, see 18 | . 19 | */ 20 | 21 | /*! 22 | \file output.cc 23 | \author Synge Todo 24 | \date February 16 2017 25 | \brief Print out of mptensor 26 | */ 27 | 28 | #include 29 | 30 | #include 31 | #include 32 | 33 | /* Main function */ 34 | int main(int argc, char **argv) { 35 | using namespace mptensor; 36 | typedef Tensor ptensor; 37 | 38 | MPI_Init(&argc, &argv); 39 | 40 | Shape shape = Shape(2, 3); 41 | ptensor A2(shape); 42 | for (int i0 = 0; i0 < shape[0]; ++i0) 43 | for (int i1 = 0; i1 < shape[1]; ++i1) 44 | A2.set_value(Index(i0, i1), i0 * 3 + i1); 45 | std::cout << A2; 46 | 47 | shape = Shape(2, 3, 4); 48 | ptensor A3(shape); 49 | for (int i0 = 0; i0 < shape[0]; ++i0) 50 | for (int i1 = 0; i1 < shape[1]; ++i1) 51 | for (int i2 = 0; i2 < shape[2]; ++i2) 52 | A3.set_value(Index(i0, i1, i2), i0 * 12 + i1 * 4 + i2); 53 | std::cout << A3; 54 | 55 | shape = Shape(2, 3, 4, 5); 56 | ptensor A4(shape); 57 | for (int i0 = 0; i0 < shape[0]; ++i0) 58 | for (int i1 = 0; i1 < shape[1]; ++i1) 59 | for (int i2 = 0; i2 < shape[2]; ++i2) 60 | for (int i3 = 0; i3 < shape[3]; ++i3) 61 | A4.set_value(Index(i0, i1, i2, i3), i0 * 60 + i1 * 20 + i2 * 5 + i3); 62 | std::cout << A4; 63 | 64 | MPI_Finalize(); 65 | } 66 | -------------------------------------------------------------------------------- /examples/output/output.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # mptensor - Parallel Library for Tensor Network Methods 4 | # 5 | # Copyright 2016 Satoshi Morita 6 | # 7 | # mptensor is free software: you can redistribute it and/or modify it 8 | # under the terms of the GNU Lesser General Public License as 9 | # published by the Free Software Foundation, either version 3 of the 10 | # License, or (at your option) any later version. 11 | # 12 | # mptensor is distributed in the hope that it will be useful, but 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # Lesser General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public 18 | # License along with mptensor. If not, see 19 | # . 20 | 21 | # \file output.py 22 | # \author Synge Todo 23 | # \date February 16 2017 24 | # \brief Print out of mptensor 25 | 26 | import numpy as np 27 | 28 | shape = (2, 3) 29 | A2 = np.zeros(shape) 30 | for i0 in range(shape[0]): 31 | for i1 in range(shape[1]): 32 | A2[i0, i1] = i0 * 3 + i1 33 | print A2 34 | 35 | shape = (2, 3, 4) 36 | A3 = np.zeros(shape) 37 | for i0 in range(shape[0]): 38 | for i1 in range(shape[1]): 39 | for i2 in range(shape[2]): 40 | A3[i0, i1, i2] = i0 * 12 + i1 * 4 + i2 41 | print A3 42 | 43 | shape = (2, 3, 4, 5) 44 | A4 = np.zeros(shape) 45 | for i0 in range(shape[0]): 46 | for i1 in range(shape[1]): 47 | for i2 in range(shape[2]): 48 | for i3 in range(shape[3]): 49 | A4[i0, i1, i2, i3] = i0 * 60 + i1 * 20 + i2 * 5 + i3 50 | print A4 51 | -------------------------------------------------------------------------------- /examples/save_load/.gitignore: -------------------------------------------------------------------------------- 1 | A.dat* 2 | -------------------------------------------------------------------------------- /examples/save_load/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PROGS save_load) 2 | foreach(name ${PROGS}) 3 | add_executable(${name} ${name}.cc) 4 | target_link_libraries(${name} mptensor) 5 | endforeach(name ${PROGS}) 6 | -------------------------------------------------------------------------------- /examples/save_load/Makefile: -------------------------------------------------------------------------------- 1 | -include ../../Makefile.option 2 | 3 | .PHONY: all clean depend 4 | .SUFFIXES: .cc .hpp .o .out 5 | 6 | TARGET = save_load.out 7 | 8 | MPTENSOR_SOURCE_DIR = ../../src 9 | MPTENSOR_INCLUDE_DIR = ../../include 10 | MPTENSOR_FLAGS = -I$(MPTENSOR_INCLUDE_DIR) -L$(MPTENSOR_SOURCE_DIR) -lmptensor 11 | 12 | 13 | all: $(TARGET) 14 | 15 | %.out : %.cc 16 | $(CXX) -o $@ $< $(MPTENSOR_FLAGS) $(LDFLAGS) $(CXXFLAGS) 17 | 18 | clean: 19 | @rm -vf *.out *.o A.dat* 20 | -------------------------------------------------------------------------------- /examples/save_load/save_load.cc: -------------------------------------------------------------------------------- 1 | /* 2 | mptensor - Parallel Library for Tensor Network Methods 3 | 4 | Copyright 2016 Satoshi Morita 5 | 6 | mptensor is free software: you can redistribute it and/or modify it 7 | under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation, either version 3 of the 9 | License, or (at your option) any later version. 10 | 11 | mptensor is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with mptensor. If not, see 18 | . 19 | */ 20 | 21 | /*! 22 | \file save_load.cc 23 | \author Satoshi Morita 24 | \date Mar 03 2015 25 | \brief Example of save and load 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | /* Main function */ 36 | int main(int argc, char **argv) { 37 | using namespace mptensor; 38 | // typedef Tensor ptensor; 39 | typedef Tensor ptensor; 40 | 41 | /* Start */ 42 | MPI_Init(&argc, &argv); 43 | MPI_Comm comm = MPI_COMM_WORLD; 44 | int mpirank; 45 | int mpisize; 46 | bool mpiroot; 47 | MPI_Comm_rank(comm, &mpirank); 48 | MPI_Comm_size(comm, &mpisize); 49 | mpiroot = (mpirank == 0); 50 | 51 | /* Get arguments */ 52 | int n; 53 | if (argc < 2) { 54 | if (mpiroot) 55 | std::cerr << "Usage: a.out N\n" 56 | << "waring: assuming N=10" << std::endl; 57 | n = 10; 58 | } else { 59 | n = atoi(argv[1]); 60 | } 61 | 62 | /* Construct a tensor */ 63 | ptensor A(Shape(n, n + 1, n + 2, n + 3)); 64 | 65 | /* Do something here */ 66 | set_seed(std::time(NULL) + mpirank); 67 | random_tensor::fill(A); 68 | A.transpose(Axes(3, 1, 0, 2)); 69 | A.save("A.dat"); 70 | 71 | ptensor B; 72 | B.load("A.dat"); 73 | 74 | /* Output */ 75 | if (mpiroot) std::cout << "########## Saved Tensor ##########\n"; 76 | for (int i = 0; i < mpisize; ++i) { 77 | if (i == mpirank) { 78 | std::cout << "rank=" << i << ": "; 79 | A.print_info(std::cout); 80 | } 81 | MPI_Barrier(comm); 82 | } 83 | if (mpiroot) std::cout << "########## Loaded Tensor ##########\n"; 84 | for (int i = 0; i < mpisize; ++i) { 85 | if (i == mpirank) { 86 | std::cout << "rank=" << i << ": "; 87 | B.print_info(std::cout); 88 | } 89 | MPI_Barrier(comm); 90 | } 91 | 92 | double val = max_abs(B - A); 93 | if (mpiroot) { 94 | std::cout << "########## Error ##########\n" 95 | << std::scientific << std::setprecision(10) << val << std::endl; 96 | } 97 | 98 | /* End */ 99 | MPI_Finalize(); 100 | } 101 | -------------------------------------------------------------------------------- /examples/simple_example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PROGS simple_example) 2 | foreach(name ${PROGS}) 3 | add_executable(${name} ${name}.cc) 4 | target_link_libraries(${name} PRIVATE mptensor) 5 | endforeach(name ${PROGS}) 6 | -------------------------------------------------------------------------------- /examples/simple_example/Makefile: -------------------------------------------------------------------------------- 1 | -include ../../Makefile.option 2 | 3 | .PHONY: all clean depend 4 | .SUFFIXES: .cc .hpp .o .out 5 | 6 | TARGET = simple_example.out 7 | 8 | MPTENSOR_SOURCE_DIR = ../../src 9 | MPTENSOR_INCLUDE_DIR = ../../include 10 | MPTENSOR_FLAGS = -I$(MPTENSOR_INCLUDE_DIR) -L$(MPTENSOR_SOURCE_DIR) -lmptensor 11 | 12 | 13 | all: $(TARGET) 14 | 15 | %.out : %.cc 16 | $(CXX) -o $@ $< $(MPTENSOR_FLAGS) $(LDFLAGS) $(CXXFLAGS) 17 | 18 | clean: 19 | @rm -vf *.out *.o 20 | -------------------------------------------------------------------------------- /examples/simple_example/simple_example.cc: -------------------------------------------------------------------------------- 1 | /* 2 | mptensor - Parallel Library for Tensor Network Methods 3 | 4 | Copyright 2016 Satoshi Morita 5 | 6 | mptensor is free software: you can redistribute it and/or modify it 7 | under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation, either version 3 of the 9 | License, or (at your option) any later version. 10 | 11 | mptensor is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with mptensor. If not, see 18 | . 19 | */ 20 | 21 | /*! 22 | \file example.cc 23 | \author Satoshi Morita 24 | \date Mar 03 2015 25 | \brief Simple example of mptensor 26 | */ 27 | 28 | #include 29 | 30 | #include 31 | #include "mptensor/mptensor.hpp" 32 | 33 | /* Main function */ 34 | int main(int argc, char **argv) { 35 | using namespace mptensor; 36 | typedef Tensor ptensor; 37 | 38 | /* Start */ 39 | MPI_Init(&argc, &argv); 40 | MPI_Comm comm = MPI_COMM_WORLD; 41 | int mpirank; 42 | int mpisize; 43 | bool mpiroot; 44 | MPI_Comm_rank(comm, &mpirank); 45 | MPI_Comm_size(comm, &mpisize); 46 | mpiroot = (mpirank == 0); 47 | 48 | /* Get arguments */ 49 | int n; 50 | if (argc < 2) { 51 | if (mpiroot) 52 | std::cerr << "Usage: a.out N\n" 53 | << "waring: assuming N=10" << std::endl; 54 | n = 10; 55 | } else { 56 | n = atoi(argv[1]); 57 | } 58 | 59 | /* Construct a tensor */ 60 | ptensor A(Shape(n, n + 1, n + 2, n + 3)); 61 | 62 | /* Do something here */ 63 | 64 | /* Output */ 65 | for (int i = 0; i < mpisize; ++i) { 66 | if (i == mpirank) { 67 | std::cout << "rank=" << i << ": "; 68 | A.print_info(std::cout); 69 | } 70 | MPI_Barrier(comm); 71 | } 72 | 73 | /* End */ 74 | MPI_Finalize(); 75 | } 76 | -------------------------------------------------------------------------------- /include/mptensor/complex.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | mptensor - Parallel Library for Tensor Network Methods 3 | 4 | Copyright 2016 Satoshi Morita 5 | 6 | mptensor is free software: you can redistribute it and/or modify it 7 | under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation, either version 3 of the 9 | License, or (at your option) any later version. 10 | 11 | mptensor is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with mptensor. If not, see 18 | . 19 | */ 20 | 21 | /*! 22 | \file complex.hpp 23 | \author Satoshi Morita 24 | \date Jan 13 2015 25 | 26 | \brief Define the type of a complex number. 27 | */ 28 | 29 | #ifndef _COMPLEX_HPP_ 30 | #define _COMPLEX_HPP_ 31 | 32 | #include 33 | 34 | namespace mptensor { 35 | 36 | //! Alias for the value type of complex numbers 37 | //! \ingroup Complex 38 | typedef std::complex complex; 39 | 40 | template 41 | constexpr size_t value_type_tag(); 42 | template <> 43 | constexpr size_t value_type_tag() { 44 | return 0; 45 | }; 46 | template <> 47 | constexpr size_t value_type_tag() { 48 | return 1; 49 | }; 50 | 51 | template 52 | constexpr char* value_type_name(); 53 | template <> 54 | constexpr char* value_type_name() { 55 | return (char*)"double"; 56 | }; 57 | template <> 58 | constexpr char* value_type_name() { 59 | return (char*)"complex"; 60 | }; 61 | 62 | } // namespace mptensor 63 | 64 | #endif // _COMPLEX_HPP_ 65 | -------------------------------------------------------------------------------- /include/mptensor/doxygen_module.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | mptensor - Parallel Library for Tensor Network Methods 3 | 4 | Copyright 2016 Satoshi Morita 5 | 6 | mptensor is free software: you can redistribute it and/or modify it 7 | under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation, either version 3 of the 9 | License, or (at your option) any later version. 10 | 11 | mptensor is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with mptensor. If not, see 18 | . 19 | */ 20 | 21 | /*! 22 | \file doxygen_module.hpp 23 | \author Satoshi Morita 24 | \date Sep 4 2019 25 | \brief Define modules for doxygen 26 | */ 27 | 28 | /*! 29 | \defgroup Tensor Tensor class 30 | \{ 31 | \defgroup TensorConstructor Constructors 32 | \defgroup TensorOps Tensor operations 33 | \{ 34 | \defgroup ShapeChange Shape change 35 | Operations in order to change the shape of a tensor 36 | \defgroup LinearAlgebra Linear algebra 37 | Operations for linear algebra. 38 | \{ 39 | \defgroup Decomposition Decompositions 40 | Functions to decompose a tensor into some tensors. 41 | \defgroup LinearEq Linear equation 42 | Functions to solve a linear equation. 43 | \} 44 | \defgroup Arithmetic Arithmetic operations 45 | Functions for arithmetic operations. 46 | \defgroup Misc Useful operations 47 | Other useful operations. 48 | \defgroup Output Output 49 | Function to output information of a tensor. 50 | \defgroup Random Randomized algorithm 51 | Function to decompose a tensor by randomized algorithms. 52 | \} 53 | \} 54 | \defgroup Index Index class 55 | \defgroup Matrix Matrix class 56 | \{ 57 | \defgroup ScaLAPACK ScaLAPACK 58 | Parallelized matrix class using ScaLAPACK 59 | \defgroup LAPACK LAPACK 60 | Non-parallelized matrix class using LAPACK 61 | \} 62 | \defgroup Complex Complex numbers 63 | Value type of complex numbers 64 | */ 65 | -------------------------------------------------------------------------------- /include/mptensor/file_io/io_helper.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | mptensor - Parallel Library for Tensor Network Methods 3 | 4 | Copyright 2016 Satoshi Morita 5 | 6 | mptensor is free software: you can redistribute it and/or modify it 7 | under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation, either version 3 of the 9 | License, or (at your option) any later version. 10 | 11 | mptensor is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with mptensor. If not, see 18 | . 19 | */ 20 | 21 | /*! 22 | \file io_helper.hpp 23 | \author Satoshi Morita 24 | \date Mar 18 2020 25 | 26 | \brief Header file of helper functions for file io. 27 | */ 28 | 29 | #ifndef _MPTENSOR_LOAD_HELPER_HPP_ 30 | #define _MPTENSOR_LOAD_HELPER_HPP_ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include "mptensor/matrix.hpp" 39 | 40 | namespace mptensor { 41 | namespace io_helper { 42 | 43 | #if defined(NDEBUG) 44 | constexpr bool debug = false; 45 | #else 46 | constexpr bool debug = true; 47 | #endif 48 | 49 | inline std::string binary_filename(const std::string& prefix, int comm_rank) { 50 | std::ostringstream ss; 51 | ss << prefix << "."; 52 | ss << std::setw(4) << std::setfill('0') << comm_rank; 53 | ss << ".bin"; 54 | return ss.str(); 55 | } 56 | 57 | inline std::string index_filename(const std::string& prefix, int comm_rank) { 58 | std::ostringstream ss; 59 | ss << prefix << "."; 60 | ss << std::setw(4) << std::setfill('0') << comm_rank; 61 | ss << ".idx"; 62 | return ss.str(); 63 | } 64 | 65 | template 66 | void load_binary(const std::string& prefix, int comm_rank, C* data_head, 67 | std::size_t local_size) { 68 | std::string filename; 69 | filename = io_helper::binary_filename(prefix, comm_rank); 70 | std::ifstream fin(filename, std::ofstream::binary); 71 | assert(fin.is_open()); 72 | fin.read(reinterpret_cast(data_head), sizeof(C) * local_size); 73 | fin.close(); 74 | } 75 | 76 | template