├── .clang-format ├── .codedocs ├── .gitignore ├── .gitmodules ├── .travis.yml ├── .travis ├── cmake_install.sh ├── cuda_install.sh └── gtest_install.sh ├── Aptfile ├── CMakeLists.txt ├── LICENSE ├── NOTICE ├── Procfile ├── README.md ├── appveyor.yml ├── benchmark └── CMakeLists.txt ├── cmake ├── FindMAGMA.cmake ├── feature_test.cmake └── feature_test │ └── cuda_gencode_test.cpp ├── docs ├── Doxyfile.in ├── customdoxygen.css ├── footer.html ├── header.html ├── logo.png └── logo_small.png ├── examples ├── CMakeLists.txt ├── LSTM │ ├── CMakeLists.txt │ └── main.cpp └── MLP │ ├── CMakeLists.txt │ ├── MLP.cpp │ ├── drawwidget.cpp │ ├── drawwidget.h │ ├── mainwindow.cpp │ ├── mainwindow.h │ ├── mainwindow.ui │ └── model_h_moved.txt ├── format.sh ├── include └── mgcpp │ ├── adapters │ ├── adapter_base.hpp │ ├── adapters.hpp │ └── blaze.hpp │ ├── allocators │ ├── allocator.hpp │ ├── allocator.tpp │ ├── cudamalloc_resource.hpp │ ├── device_memory_resource.hpp │ ├── memory_resource.hpp │ └── new_delete_resource.hpp │ ├── context │ ├── forward.hpp │ ├── global_context.hpp │ ├── thread_context.hpp │ ├── thread_guard.hpp │ └── thread_guard.ipp │ ├── cuda │ ├── device.hpp │ ├── memory.hpp │ └── memory.tpp │ ├── cuda_libs │ ├── cublas.hpp │ └── cufft_fft.hpp │ ├── expressions │ ├── constant_expr.hpp │ ├── dmat_dmat_add.hpp │ ├── dmat_dmat_add.tpp │ ├── dmat_dmat_mult.hpp │ ├── dmat_dmat_mult.tpp │ ├── dmat_dvec_mult.hpp │ ├── dmat_dvec_mult.tpp │ ├── dmat_expr.hpp │ ├── dmat_reduce_expr.hpp │ ├── dmat_reduce_expr.tpp │ ├── dmat_ref_expr.hpp │ ├── dmat_ref_expr.tpp │ ├── dmat_trans_expr.hpp │ ├── dmat_trans_expr.tpp │ ├── dvec_dvec_add.hpp │ ├── dvec_dvec_add.tpp │ ├── dvec_dvec_outer.hpp │ ├── dvec_expr.hpp │ ├── dvec_map.hpp │ ├── dvec_map.tpp │ ├── dvec_reduce_expr.hpp │ ├── dvec_reduce_expr.tpp │ ├── dvec_ref_expr.hpp │ ├── dvec_ref_expr.tpp │ ├── eval_cache.hpp │ ├── eval_context.hpp │ ├── eval_context.tpp │ ├── evaluator.hpp │ ├── evaluator.tpp │ ├── expression.hpp │ ├── expression.tpp │ ├── forward.hpp │ ├── generic_expr.hpp │ ├── generic_expr.tpp │ ├── gradients.hpp │ ├── gradients.tpp │ ├── inspect_graph.hpp │ ├── inspect_graph.tpp │ ├── placeholder.hpp │ ├── scalar_dmat_mult.hpp │ ├── scalar_dmat_mult.tpp │ ├── scalar_dvec_mult.hpp │ ├── scalar_dvec_mult.tpp │ ├── scalar_expr.hpp │ ├── scalar_expr.tpp │ ├── shape_evaluator.hpp │ ├── shape_evaluator.tpp │ ├── symbolic_shape_expr.hpp │ ├── tie_expr.hpp │ └── tie_expr.tpp │ ├── global │ ├── complex.hpp │ ├── half_precision.hpp │ ├── init.hpp │ ├── shape.hpp │ ├── shape.tpp │ ├── tuple_utils.hpp │ ├── type_erased.hpp │ └── type_erased.tpp │ ├── kernels │ ├── bits │ │ ├── convert.cuh │ │ ├── fill.cuh │ │ ├── hadamard.cuh │ │ ├── map.cuh │ │ └── reduce.cuh │ ├── mgblas_error_code.hpp │ ├── mgblas_helpers.hpp │ ├── mgblas_helpers.tpp │ ├── mgblas_lv1.hpp │ └── mgblas_lv1.tpp │ ├── matrix │ ├── column_view.hpp │ ├── column_view.tpp │ ├── dense_matrix.hpp │ ├── device_matrix.hpp │ ├── device_matrix.tpp │ ├── forward.hpp │ ├── matrix_base.hpp │ ├── matrix_base.tpp │ ├── row_view.hpp │ └── row_view.tpp │ ├── mgcpp.hpp │ ├── operations │ ├── add.hpp │ ├── add.tpp │ ├── fft.hpp │ ├── fft.tpp │ ├── gemm.hpp │ ├── gemm.tpp │ ├── hdmd.hpp │ ├── hdmd.tpp │ ├── map.hpp │ ├── map.tpp │ ├── mean.hpp │ ├── mean.tpp │ ├── mult.hpp │ ├── mult.tpp │ ├── outer.hpp │ ├── outer.tpp │ ├── pad.hpp │ ├── pad.tpp │ ├── sub.hpp │ ├── sub.tpp │ ├── sum.hpp │ ├── sum.tpp │ ├── trans.hpp │ └── trans.tpp │ ├── system │ ├── assert.hpp │ ├── concept.hpp │ ├── cublas_error.hpp │ ├── cuda_error.hpp │ ├── cufft_error.hpp │ ├── error_code.hpp │ ├── exception.hpp │ ├── mgblas_error.hpp │ ├── outcome.hpp │ └── pun_cast.hpp │ ├── type_traits │ ├── device_value_type.hpp │ ├── host_value_type.hpp │ ├── is_scalar.hpp │ ├── is_supported_type.hpp │ ├── mat_mat_mult_expr.hpp │ ├── shape_type.hpp │ ├── trans_expr.hpp │ └── type_traits.hpp │ └── vector │ ├── dense_vector.hpp │ ├── device_vector.hpp │ ├── device_vector.tpp │ ├── forward.hpp │ ├── vector_base.hpp │ └── vector_base.tpp ├── requirements.txt ├── run_format.py ├── src ├── cublas_error.cpp ├── cuda │ └── device.cpp ├── cuda_error.cpp ├── cuda_libs │ ├── cublas.cpp │ └── cufft_fft.cpp ├── cudamalloc_resource.cpp ├── cufft_error.cpp ├── device_memory_resource.cpp ├── error_code.cpp ├── eval_cache.cpp ├── expression.cpp ├── global_context.cpp ├── init.cpp ├── kernels │ ├── convert.cu │ ├── fill.cu │ ├── hadamard.cu │ ├── map.cu │ └── reduce.cu ├── mgblas_error.cpp ├── new_delete_resource.cpp └── thread_context.cpp └── test ├── CMakeLists.txt ├── blaslv1_expression_test.cpp ├── blaslv1_operation_test.cpp ├── blaslv2_expression_test.cpp ├── blaslv3_expression_test.cpp ├── blaslv3_operation_test.cpp ├── cpu_matrix.hpp ├── cuda_error_test.cpp ├── cuda_exception_test.cpp ├── cuda_memory_test.cpp ├── device_allocators_test.cpp ├── device_vector_test.cpp ├── fft_test.cpp ├── global_context_test.cpp ├── gradient_test.cpp ├── main.cpp ├── matrix └── device_matrix_test.cpp ├── matrix_view_test.cpp ├── memory_leak_detector.cpp ├── memory_leak_detector.hpp ├── mgblas_helpers_test.cpp ├── mgcpp_test.hpp ├── operations └── fft_test.cpp ├── test_policy.cpp ├── test_policy.hpp ├── test_utils.cpp ├── test_utils.hpp ├── thread_context_test.cpp └── type_trait_test.cpp /.clang-format: -------------------------------------------------------------------------------- 1 | # version: 3.9 2 | # include: *.h 3 | # include: *.hpp 4 | # include: *.tpp 5 | # include: *.ipp 6 | # include: *.cpp 7 | # include: *.cxx 8 | # exclude: tpl/* 9 | # exlcude: third_party/* 10 | 11 | # Defines the Chromium style for automatic reformatting. 12 | # http://clang.llvm.org/docs/ClangFormatStyleOptions.html 13 | 14 | BasedOnStyle: Chromium 15 | 16 | # This defaults to 'Auto'. Explicitly set it for a while, so that 17 | # 'vector >' in existing files gets formatted to 18 | # 'vector>'. ('Auto' means that clang-format will only use 19 | # 'int>>' if the file already contains at least one such instance.) 20 | Standard: Cpp11 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ############################################### 2 | # Based on github/gitignore # 3 | # # 4 | # https://github.com/github/gitignore?fref=gc # 5 | # # 6 | # License: CC0-1.0. # 7 | ############################################### 8 | 9 | ## Emacs Generated Types 10 | *~ 11 | \#*\# 12 | .\#* 13 | 14 | ## Vim Generated Types 15 | # Swap 16 | [._]*.s[a-v][a-z] 17 | [._]*.sw[a-p] 18 | [._]s[a-v][a-z] 19 | [._]sw[a-p] 20 | 21 | # Session 22 | Session.vim 23 | 24 | # Temporary 25 | .netrwhist 26 | *~ 27 | # Auto-generated tag files 28 | tags 29 | 30 | # CMake Generated Types 31 | CMakeCache.txt 32 | CMakeFiles 33 | CMakeScripts 34 | Testing 35 | Makefile 36 | cmake_install.cmake 37 | install_manifest.txt 38 | compile_commands.json 39 | CTestTestfile.cmake 40 | 41 | # Prerequisites 42 | *.d 43 | 44 | # Compiled Object files 45 | *.slo 46 | *.lo 47 | *.o 48 | *.obj 49 | 50 | # Precompiled Headers 51 | *.gch 52 | *.pch 53 | 54 | # Compiled Dynamic libraries 55 | *.so 56 | *.dylib 57 | *.dll 58 | 59 | # Fortran module files 60 | *.mod 61 | *.smod 62 | 63 | # Compiled Static libraries 64 | *.lai 65 | *.la 66 | *.a 67 | *.lib 68 | 69 | # Executables 70 | *.exe 71 | *.out 72 | *.app 73 | 74 | # Build directory 75 | build/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third_party/boost-outcome"] 2 | path = third_party/boost-outcome 3 | url = https://github.com/ned14/boost-outcome 4 | [submodule "half"] 5 | path = third_party/half 6 | url = https://github.com/Melown/half.git 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | language: generic 3 | group: deprecated-2017Q4 4 | 5 | matrix: 6 | include: 7 | - env: CXX=g++-6 CC=gcc-6 8 | os: linux 9 | addons: 10 | apt: 11 | sources: 12 | - ubuntu-toolchain-r-test 13 | - llvm-toolchain-trusty-3.5 14 | packages: 15 | - g++-6 16 | - clang-3.5 17 | 18 | # - env: CXX=g++-7 CC=gcc-7 19 | # os: linux 20 | # addons: 21 | # apt: 22 | # sources: 23 | # - ubuntu-toolchain-r-test 24 | # - llvm-toolchain-trusty-3.5 25 | # packages: 26 | # - g++-7 27 | # - clang-3.5 28 | 29 | - env: CXX=clang++-3.9 CC=clang-3.9 30 | os: linux 31 | addons: 32 | apt: 33 | sources: 34 | - ubuntu-toolchain-r-test 35 | - llvm-toolchain-trusty-3.5 36 | packages: 37 | - g++-6 38 | - clang-3.5 39 | - clang-3.9 40 | 41 | - env: CXX=clang++-4.0 CC=clang-4.0 42 | addons: 43 | apt: 44 | sources: 45 | - ubuntu-toolchain-r-test 46 | - llvm-toolchain-trusty-4.0 47 | - llvm-toolchain-trusty-3.5 48 | packages: 49 | - g++-6 50 | - clang-3.5 51 | - clang-4.0 52 | 53 | - env: CXX=clang++-5.0 CC=clang-5.0 54 | os: linux 55 | addons: 56 | apt: 57 | sources: 58 | - ubuntu-toolchain-r-test 59 | - llvm-toolchain-trusty-5.0 60 | - llvm-toolchain-trusty-3.5 61 | packages: 62 | - g++-6 63 | - clang-3.5 64 | - clang-5.0 65 | 66 | before_install: 67 | - eval "${MATRIX_EVAL}" 68 | - echo ${CC} 69 | - echo ${CXX} 70 | - ${CXX} --version 71 | - sudo add-apt-repository -y ppa:nschloe/boost-nightly 72 | - sudo apt-get update -qq 73 | 74 | install: 75 | - sudo apt-get install libboost-all-dev 76 | 77 | - source .travis/cuda_install.sh 78 | 79 | - echo "installing cmake" 80 | - source .travis/cmake_install.sh 81 | - ~/cmake-${CMAKE_VER}/bin/cmake --version 82 | 83 | - echo "installing googletest" 84 | - source .travis/gtest_install.sh 85 | 86 | script: 87 | - ~/cmake-${CMAKE_VER}/bin/cmake -DCUDA_ARCH=61 -DUSE_HALF=OFF -DCUDA_HOST_COMPILER=/usr/bin/clang++-3.5 -G "Unix Makefiles" 88 | - make -j2 89 | - make install 90 | -------------------------------------------------------------------------------- /.travis/cmake_install.sh: -------------------------------------------------------------------------------- 1 | pushd . 2 | cd ~ 3 | 4 | travis_retry wget https://cmake.org/files/v3.9/cmake-3.9.4.tar.gz 5 | 6 | tar -xzf cmake-3.9.4.tar.gz 7 | cd cmake-3.9.4/ 8 | 9 | ./bootstrap 10 | 11 | make -j2 > trash.txt 12 | sudo make install 13 | 14 | CMAKE_VER="3.9.4" 15 | 16 | popd 17 | 18 | -------------------------------------------------------------------------------- /.travis/cuda_install.sh: -------------------------------------------------------------------------------- 1 | travis_retry wget -P ./ https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda-repo-ubuntu1404-8-0-local-ga2_8.0.61-1_amd64-deb 2 | 3 | sudo dpkg -i cuda-repo-ubuntu1404-8-0-local-ga2_8.0.61-1_amd64-deb 4 | travis_retry sudo apt-get update 5 | travis_retry sudo apt-get install cuda 6 | 7 | export CUDA_HOME=/usr/local/cuda-8.0 8 | export LD_LIBRARY_PATH=${CUDA_HOME}/lib64:${LD_LIBRARY_PATH} 9 | export LD_LIBRARY_PATH=${CUDA_HOME}/lib64:${LD_LIBRARY_PATH} 10 | -------------------------------------------------------------------------------- /.travis/gtest_install.sh: -------------------------------------------------------------------------------- 1 | pushd . 2 | cd ~ 3 | 4 | travis_retry git clone https://github.com/google/googletest.git 5 | 6 | cd googletest 7 | 8 | ~/cmake-${CMAKE_VER}/bin/cmake -G "Unix Makefiles" 9 | 10 | make -j2 -s > trash.txt 11 | sudo make install 12 | 13 | popd 14 | 15 | -------------------------------------------------------------------------------- /Aptfile: -------------------------------------------------------------------------------- 1 | 2 | clang-format-3.3 3 | clang-format-3.4 4 | clang-format-3.5 5 | clang-format-3.6 6 | clang-format-3.7 7 | clang-format-3.8 8 | clang-format-3.9 9 | git 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | 2 | web: python run_format.py 3 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | build: off 2 | -------------------------------------------------------------------------------- /benchmark/CMakeLists.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MGfoundation/mgcpp/a14ff0d6d6a9ece200b7b7aaa14b90b5486510ac/benchmark/CMakeLists.txt -------------------------------------------------------------------------------- /cmake/FindMAGMA.cmake: -------------------------------------------------------------------------------- 1 | # Taken from eigen-magma 2 | # https://github.com/bravegag/eigen-magma 3 | 4 | # - Find the MAGMA library 5 | # 6 | # Usage: 7 | # find_package(MAGMA [REQUIRED] [QUIET] ) 8 | # 9 | # It sets the following variables: 10 | # MAGMA_FOUND ... true if magma is found on the system 11 | # MAGMA_LIBRARY_DIRS ... full path to magma library 12 | # MAGMA_INCLUDE_DIRS ... magma include directory 13 | # MAGMA_LIBRARIES ... magma libraries 14 | # 15 | # The following variables will be checked by the function 16 | # MAGMA_USE_STATIC_LIBS ... if true, only static libraries are found 17 | # MAGMA_ROOT ... if set, the libraries are exclusively searched 18 | # under this path 19 | 20 | #If environment variable MAGMA_ROOT is specified, it has same effect as MAGMA_ROOT 21 | if( NOT MAGMA_ROOT AND NOT $ENV{MAGMA_ROOT} STREQUAL "" ) 22 | set( MAGMA_ROOT $ENV{MAGMA_ROOT} ) 23 | # set library directories 24 | set(MAGMA_LIBRARY_DIRS ${MAGMA_ROOT}/lib) 25 | # set include directories 26 | set(MAGMA_INCLUDE_DIRS ${MAGMA_ROOT}/include) 27 | # set libraries 28 | find_library( 29 | MAGMA_LIBRARIES 30 | NAMES "magma" 31 | PATHS ${MAGMA_ROOT} 32 | PATH_SUFFIXES "lib" 33 | NO_DEFAULT_PATH) 34 | 35 | set(MAGMA_FOUND TRUE) 36 | else() 37 | set(MAGMA_FOUND FALSE) 38 | endif() 39 | -------------------------------------------------------------------------------- /cmake/feature_test.cmake: -------------------------------------------------------------------------------- 1 | 2 | set(FEATURE_TEST_DIR ${CMAKE_CURRENT_LIST_DIR}/feature_test) 3 | 4 | message(STATUS "compiling and running feature test") 5 | 6 | find_package(CUDA REQUIRED) 7 | try_run(CUDA_GENCODE_TEST_RESULT BUILD_RESULT 8 | "${CMAKE_CURRENT_BINARY_DIR}/FeatureTest" 9 | SOURCES "${FEATURE_TEST_DIR}/cuda_gencode_test.cpp" 10 | LINK_LIBRARIES "${CUDA_LIBRARIES}" 11 | CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${CUDA_INCLUDE_DIRS}" 12 | "-DLINK_DIRECTORIES=${CUDA_LIBRARIES}" 13 | COMPILE_OUTPUT_VARIABLE BUILD_STATUS 14 | RUN_OUTPUT_VARIABLE CUDA_GENCODE_TEST_STATUS) 15 | 16 | if(NOT BUILD_RESULT) 17 | message(${BUILD_STATUS}) 18 | message(FATAL_ERROR "failed to build feature test") 19 | endif() 20 | message(STATUS "successfully compiled feature test") 21 | 22 | if(NOT ${CUDA_GENCODE_TEST_RESULT} EQUAL "0") 23 | message(STATUS "running feature test - failed") 24 | message(FATAL_ERROR "${CUDA_GENCODE_TEST_STATUS}") 25 | else() 26 | string(REGEX REPLACE "\n$" "" 27 | CUDA_GENCODE_TEST_STATUS "${CUDA_GENCODE_TEST_STATUS}") 28 | 29 | message(STATUS "running feature test - success") 30 | message(STATUS "setting NVCC flags ${CUDA_GENCODE_TEST_STATUS}") 31 | set(CUDA_GEN_CODE "${CUDA_GENCODE_TEST_STATUS}") 32 | endif() 33 | 34 | -------------------------------------------------------------------------------- /cmake/feature_test/cuda_gencode_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | cudaDeviceProp prop; 6 | cudaError_t status = cudaGetDeviceProperties(&prop, 0); 7 | 8 | if (status != cudaSuccess) { 9 | printf("%s", cudaGetErrorString(status)); 10 | return 1; 11 | } 12 | 13 | int v = prop.major * 10 + prop.minor; 14 | printf("-gencode arch=compute_%d,code=sm_%d\n", v, v); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /docs/customdoxygen.css: -------------------------------------------------------------------------------- 1 | 2 | html, body 3 | { 4 | margin: 0; 5 | padding: 0; 6 | font-family: sans-serif; 7 | background-color: #EEE; 8 | } 9 | 10 | header { 11 | width: 100%; 12 | background-color: rgba(0,0,0,0.8); 13 | box-shadow: rgba(0,0,0,0.2) 0 0 10px; 14 | height: 72px; 15 | margin-bottom: 10px; 16 | color: #eee; 17 | line-height: 72px; 18 | padding-left: 20px; 19 | font-size: 28pt; 20 | } 21 | 22 | div.contents 23 | { 24 | margin: auto; 25 | width: 1200px; 26 | background-color: #FEFEFE; 27 | padding: 30px; 28 | box-shadow: rgba(0,0,0,0.2) 0 0 10px; 29 | } 30 | 31 | .title 32 | { 33 | display: none; 34 | } 35 | 36 | span.icon 37 | { 38 | display: none; 39 | } 40 | -------------------------------------------------------------------------------- /docs/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | mgcpp: Main Page 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
mgcpp
20 | 21 | -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MGfoundation/mgcpp/a14ff0d6d6a9ece200b7b7aaa14b90b5486510ac/docs/logo.png -------------------------------------------------------------------------------- /docs/logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MGfoundation/mgcpp/a14ff0d6d6a9ece200b7b7aaa14b90b5486510ac/docs/logo_small.png -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(MLP) 2 | add_subdirectory(LSTM) 3 | -------------------------------------------------------------------------------- /examples/LSTM/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set(CMAKE_CXX_STANDARD 14) 3 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 4 | set(CMAKE_CXX_EXTENSIONS OFF) 5 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 6 | set(CMAKE_AUTOMOC ON) 7 | 8 | set(EXAMPLE_DIR ${PROJECT_SOURCE_DIR}/examples/LSTM) 9 | 10 | set(EXAMPLE_SOURCE_FILES 11 | ${EXAMPLE_DIR}/main.cpp) 12 | 13 | # add example target 14 | add_executable(${PROJECT_NAME}_example_LSTM ${EXAMPLE_SOURCE_FILES}) 15 | 16 | target_include_directories(${PROJECT_NAME}_example_LSTM 17 | PUBLIC 18 | ${PROJECT_SOURCE_DIR}/include) 19 | 20 | target_link_libraries(${PROJECT_NAME}_example_LSTM 21 | ${PROJECT_NAME}) 22 | 23 | set(EXAMPLE_BUILD_FLAGS ${BUILD_FLAGS}) 24 | 25 | set_target_properties(${PROJECT_NAME}_example_LSTM 26 | PROPERTIES COMPILE_FLAGS "${EXAMPLE_BUILD_FLAGS}") 27 | -------------------------------------------------------------------------------- /examples/LSTM/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | template 6 | class LSTM { 7 | // all gates are fused into one matrix for performance 8 | mgcpp::device_matrix w; 9 | mgcpp::device_vector b; 10 | }; 11 | 12 | int main() {} 13 | -------------------------------------------------------------------------------- /examples/MLP/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # example source files 2 | 3 | find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets) 4 | 5 | option(DOWNLOAD_EXAMPLE_MLP_MODEL "automatically download MLP model weights from internet" ON) 6 | 7 | set(CMAKE_CXX_STANDARD 14) 8 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 9 | set(CMAKE_CXX_EXTENSIONS OFF) 10 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 11 | set(CMAKE_AUTOMOC ON) 12 | 13 | set(EXAMPLE_DIR ${PROJECT_SOURCE_DIR}/examples/MLP) 14 | 15 | set(MLP_MODEL_URL https://www.dropbox.com/s/7nc8310oncyxcez/model.h) 16 | 17 | if(DOWNLOAD_MODEL AND NOT(EXISTS ${EXAMPLE_DIR}/model.h)) 18 | message(STATUS "downloading model.h for example/MLP") 19 | set(DOWNLOAD_STATUS 1) 20 | file(DOWNLOAD ${MLP_MODEL_URL} ${EXAMPLE_DIR}/model.h 21 | INACTIVITY_TIMEOUT 10 22 | STATUS DOWNLOAD_STATUS) 23 | if(NOT(DOWNLOAD_STATUS EQUAL 0)) 24 | message(FATAL "building example MLP requires internet connection") 25 | else() 26 | message(STATUS "downloading model.h for example/MLP - success") 27 | endif() 28 | endif() 29 | 30 | set(EXAMPLE_SOURCE_FILES 31 | ${EXAMPLE_DIR}/MLP.cpp 32 | ${EXAMPLE_DIR}/mainwindow.cpp 33 | ${EXAMPLE_DIR}/drawwidget.cpp) 34 | 35 | set(EXAMPLE_FORMS 36 | ${EXAMPLE_DIR}/mainwindow.ui) 37 | qt5_wrap_ui(EXAMPLE_FORMS_H ${EXAMPLE_FORMS}) 38 | 39 | # add example target 40 | add_executable(${PROJECT_NAME}_example_MLP ${EXAMPLE_SOURCE_FILES} ${EXAMPLE_FORMS_H}) 41 | 42 | set(MGCPP_TARGETS ${MGCPP_TARGETS} 43 | "${PROJECT_NAME}_example_MLP") 44 | 45 | target_include_directories(${PROJECT_NAME}_example_MLP 46 | PUBLIC 47 | ${PROJECT_SOURCE_DIR}/include) 48 | 49 | target_link_libraries(${PROJECT_NAME}_example_MLP 50 | ${PROJECT_NAME} 51 | Qt5::Widgets) 52 | 53 | set(EXAMPLE_BUILD_FLAGS ${BUILD_FLAGS}) 54 | 55 | set_target_properties(${PROJECT_NAME}_example_MLP 56 | PROPERTIES COMPILE_FLAGS "${EXAMPLE_BUILD_FLAGS}") 57 | -------------------------------------------------------------------------------- /examples/MLP/MLP.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | // Example code for executing Multi-layer perception model 8 | // for the MNIST dataset. 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | #include "mainwindow.h" 19 | 20 | int main(int argc, char* argv[]) { 21 | QApplication a(argc, argv); 22 | MainWindow w; 23 | w.show(); 24 | 25 | return a.exec(); 26 | } 27 | -------------------------------------------------------------------------------- /examples/MLP/drawwidget.cpp: -------------------------------------------------------------------------------- 1 | #include "drawwidget.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "model.h" 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | template 18 | struct Layer { 19 | using matrix = mgcpp::device_matrix; 20 | using vector = mgcpp::device_vector; 21 | matrix W; 22 | vector b; 23 | 24 | Layer() { 25 | W = mgcpp::strict::trans(matrix::from_c_array(Weights)); 26 | b = vector::from_c_array(Bias); 27 | } 28 | 29 | template 30 | auto operator()(T const& input) { 31 | return mgcpp::ref(W) * input + mgcpp::ref(b); 32 | } 33 | }; 34 | 35 | DrawWidget::DrawWidget(QWidget* parent) : QWidget(parent) {} 36 | 37 | DrawWidget::~DrawWidget() {} 38 | 39 | void DrawWidget::drawPixel(QPoint pt) { 40 | if (0 <= pt.x() && pt.x() < width() && 0 <= pt.y() && pt.y() < height()) { 41 | QPainter p(&m_canvas); 42 | p.setRenderHints(QPainter::HighQualityAntialiasing); 43 | p.setPen(QPen(QColor(0, 0, 0, 200), 2.0)); 44 | p.drawLine(last_point / 10, pt / 10); 45 | p.end(); 46 | } 47 | } 48 | 49 | void DrawWidget::mousePressEvent(QMouseEvent* event) { 50 | if (event->buttons() & Qt::LeftButton) { 51 | last_point = event->pos(); 52 | repaint(); 53 | } 54 | } 55 | 56 | void DrawWidget::predict() { 57 | std::vector data(28 * 28); 58 | for (int i = 0; i < 28; ++i) { 59 | for (int j = 0; j < 28; ++j) { 60 | data[i * 28 + j] = 1.f - (m_canvas.pixel(j, i) & 0xff) / 256.f; 61 | } 62 | } 63 | 64 | mgcpp::device_vector input(28 * 28, data.data()); 65 | 66 | Layer<28 * 28, 200, w1, b1> l_input; 67 | auto y1 = mgcpp::relu(l_input(ref(input))); 68 | 69 | Layer<200, 100, w2, b2> l_hidden1; 70 | auto y2 = mgcpp::relu(l_hidden1(y1)); 71 | 72 | Layer<100, 100, w3, b3> l_hidden2; 73 | auto y3 = mgcpp::relu(l_hidden2(y2)); 74 | 75 | Layer<100, 10, w4, b4> l_output; 76 | auto result = l_output(y3); 77 | 78 | auto output = result.eval(); 79 | 80 | std::vector pr(10); 81 | output.copy_to_host(pr.data()); 82 | 83 | int answer = std::max_element(pr.begin(), pr.end()) - pr.begin(); 84 | 85 | emit predictNumber(answer); 86 | } 87 | 88 | void DrawWidget::mouseMoveEvent(QMouseEvent* event) { 89 | if (event->buttons() & Qt::LeftButton) { 90 | drawPixel(event->pos()); 91 | last_point = event->pos(); 92 | predict(); 93 | repaint(); 94 | } 95 | } 96 | 97 | void DrawWidget::resizeEvent(QResizeEvent*) { 98 | m_canvas = QImage(28, 28, QImage::Format_RGBA8888); 99 | clear(); 100 | } 101 | 102 | void DrawWidget::clear() { 103 | m_canvas.fill(0xFFFFFFFF); 104 | repaint(); 105 | } 106 | 107 | void DrawWidget::paintEvent(QPaintEvent* event) { 108 | QWidget::paintEvent(event); 109 | QPainter painter(this); 110 | 111 | painter.drawPixmap(QRect(0, 0, 280, 280), QPixmap::fromImage(m_canvas), 112 | QRect(0, 0, 28, 28)); 113 | } 114 | -------------------------------------------------------------------------------- /examples/MLP/drawwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef DRAWWIDGET_H 2 | #define DRAWWIDGET_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class QPaintEvent; 9 | class QMouseEvent; 10 | class DrawWidget : public QWidget 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit DrawWidget(QWidget *parent = 0); 15 | ~DrawWidget(); 16 | 17 | void drawPixel(QPoint pt); 18 | 19 | void predict(); 20 | 21 | signals: 22 | void predictNumber(int num); 23 | 24 | public slots: 25 | void clear(); 26 | void paintEvent(QPaintEvent *); 27 | void mousePressEvent(QMouseEvent *); 28 | void mouseMoveEvent(QMouseEvent *); 29 | void resizeEvent(QResizeEvent *); 30 | 31 | private: 32 | QImage m_canvas; 33 | QPoint last_point; 34 | }; 35 | 36 | #endif // DRAWWIDGET_H 37 | -------------------------------------------------------------------------------- /examples/MLP/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | 4 | #include 5 | 6 | MainWindow::MainWindow(QWidget* parent) 7 | : QMainWindow(parent), 8 | ui(new Ui::MainWindow), 9 | draw_widget(new DrawWidget(parent)) { 10 | ui->setupUi(this); 11 | ui->centralWidget->setLayout(new QVBoxLayout); 12 | draw_widget->setMaximumSize(280, 280); 13 | ui->centralWidget->layout()->addWidget(draw_widget); 14 | auto font = ui->plainTextEdit->font(); 15 | font.setPointSize(30); 16 | ui->plainTextEdit->setFont(font); 17 | QObject::connect(ui->pushButton, &QPushButton::clicked, draw_widget, 18 | &DrawWidget::clear); 19 | QObject::connect(draw_widget, &DrawWidget::predictNumber, [=](int num) { 20 | ui->plainTextEdit->document()->setPlainText(QString("%1").arg(num)); 21 | }); 22 | } 23 | 24 | MainWindow::~MainWindow() { 25 | delete ui; 26 | delete draw_widget; 27 | } 28 | -------------------------------------------------------------------------------- /examples/MLP/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | 6 | #include "drawwidget.h" 7 | 8 | namespace Ui { 9 | class MainWindow; 10 | } 11 | 12 | class MainWindow : public QMainWindow 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit MainWindow(QWidget *parent = 0); 18 | ~MainWindow(); 19 | 20 | private: 21 | Ui::MainWindow *ui; 22 | DrawWidget *draw_widget; 23 | }; 24 | 25 | #endif // MAINWINDOW_H 26 | -------------------------------------------------------------------------------- /examples/MLP/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | 15 | 400 16 | 300 17 | 18 | 19 | 20 | 21 | 400 22 | 300 23 | 24 | 25 | 26 | MainWindow 27 | 28 | 29 | 30 | 31 | 32 | 290 33 | 10 34 | 104 35 | 70 36 | 37 | 38 | 39 | Qt::NoFocus 40 | 41 | 42 | true 43 | 44 | 45 | 46 | 47 | 48 | 300 49 | 90 50 | 80 51 | 27 52 | 53 | 54 | 55 | Qt::ClickFocus 56 | 57 | 58 | Clear 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /examples/MLP/model_h_moved.txt: -------------------------------------------------------------------------------- 1 | 2 | model should be downloaded automatically using CMake. 3 | 4 | In case you want to provide the file manually, 5 | Download the file here: https://www.dropbox.com/s/7nc8310oncyxcez/model.h?dl=0 6 | and set the option DOWNLOAD_EXAMPLE_MLP_MODEL=OFF. 7 | -------------------------------------------------------------------------------- /format.sh: -------------------------------------------------------------------------------- 1 | find ./ -iname *.hpp -o -iname *.ipp -o -iname *.tpp -o -iname *.cpp | xargs clang-format -i 2 | -------------------------------------------------------------------------------- /include/mgcpp/adapters/adapter_base.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_ADAPTERS_ADAPTER_BASE_HPP_ 8 | #define _MGCPP_ADAPTERS_ADAPTER_BASE_HPP_ 9 | 10 | #include 11 | 12 | namespace mgcpp { 13 | template 14 | struct adapter : std::false_type {}; 15 | } // namespace mgcpp 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /include/mgcpp/adapters/adapters.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_ADAPTERS_ADAPTERS_HPP_ 8 | #define _MGCPP_ADAPTERS_ADAPTERS_HPP_ 9 | 10 | #include 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /include/mgcpp/adapters/blaze.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_ADAPTERS_BLAZE_HPP_ 8 | #define _MGCPP_ADAPTERS_BLAZE_HPP_ 9 | 10 | #include 11 | #include 12 | 13 | namespace blaze { 14 | template 15 | class DynamicMatrix; 16 | 17 | template 18 | class DynamicVector; 19 | } // namespace blaze 20 | 21 | namespace mgcpp { 22 | template 23 | struct adapter> : std::true_type { 24 | void operator()(blaze::DynamicMatrix const& mat, 25 | Type** out_p, 26 | size_t* m, 27 | size_t* n) { 28 | *out_p = mat.data(); 29 | if (SO) { 30 | *m = mat.rows(); 31 | } else { 32 | *n = mat.rows(); 33 | } 34 | } 35 | }; 36 | 37 | template 38 | struct adapter> : std::true_type { 39 | void operator()(blaze::DynamicMatrix const& mat, 40 | Type** out_p, 41 | size_t* size) { 42 | *out_p = mat.data(); 43 | *size = mat.size(); 44 | } 45 | }; 46 | } // namespace mgcpp 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /include/mgcpp/allocators/allocator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MGCPP_ALLOCATOR_HPP 2 | #define MGCPP_ALLOCATOR_HPP 3 | 4 | #include 5 | 6 | namespace mgcpp { 7 | 8 | class memory_resource; 9 | class device_memory_resource; 10 | 11 | template 12 | class allocator { 13 | memory_resource* m_host_resource; 14 | device_memory_resource* m_device_resource; 15 | 16 | public: 17 | using host_value_type = Type; 18 | using host_pointer = host_value_type*; 19 | using host_const_pointer = host_value_type const*; 20 | 21 | using device_value_type = typename device_value_type::type; 22 | using device_pointer = device_value_type*; 23 | using device_const_pointer = device_value_type const*; 24 | 25 | template 26 | using rebind_alloc = allocator; 27 | 28 | allocator(); 29 | allocator(memory_resource* host, device_memory_resource* device); 30 | 31 | template 32 | allocator(const allocator& other); 33 | 34 | host_pointer allocate_host(size_t n); 35 | void deallocate_host(host_pointer p, size_t n); 36 | 37 | device_pointer allocate_device(size_t n); 38 | void deallocate_device(device_pointer p, size_t n); 39 | 40 | void copy_from_host(device_pointer device, 41 | device_const_pointer host, 42 | size_t n) const; 43 | 44 | void copy_to_host(device_pointer host, 45 | device_const_pointer device, 46 | size_t n) const; 47 | 48 | // Return a default-constructed instance of this class 49 | allocator select_on_container_copy_construction() const; 50 | 51 | memory_resource* host_resource() const noexcept; 52 | device_memory_resource* device_resource() const noexcept; 53 | size_t device_id() const noexcept; 54 | }; 55 | 56 | template 57 | bool operator==(allocator const& a, allocator const& b); 58 | 59 | template 60 | bool operator!=(allocator const& a, allocator const& b); 61 | 62 | } // namespace mgcpp 63 | 64 | #include 65 | #endif // MGCPP_ALLOCATOR_HPP 66 | -------------------------------------------------------------------------------- /include/mgcpp/allocators/cudamalloc_resource.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CUDA_RESOURCE_HPP 2 | #define CUDA_RESOURCE_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace mgcpp { 9 | 10 | class cudamalloc_resource final : public device_memory_resource { 11 | public: 12 | static cudamalloc_resource* instance(size_t device_id); 13 | size_t allocated_bytes() const noexcept; 14 | 15 | protected: 16 | void* do_allocate(size_t bytes) override; 17 | 18 | void do_deallocate(void* p, size_t bytes) override; 19 | 20 | bool do_is_equal(const memory_resource& other) const noexcept override; 21 | 22 | private: 23 | explicit cudamalloc_resource(size_t device_id); 24 | 25 | std::atomic _allocated_bytes{0}; 26 | }; 27 | 28 | } // namespace mgcpp 29 | 30 | #endif // CUDA_RESOURCE_HPP 31 | -------------------------------------------------------------------------------- /include/mgcpp/allocators/device_memory_resource.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DEVICE_MEMORY_RESOURCE_HPP 2 | #define DEVICE_MEMORY_RESOURCE_HPP 3 | 4 | #include 5 | 6 | namespace mgcpp { 7 | 8 | class device_memory_resource : public memory_resource { 9 | size_t _device_id; 10 | 11 | public: 12 | device_memory_resource(size_t device_id); 13 | 14 | size_t device_id() const; 15 | }; 16 | 17 | } // namespace mgcpp 18 | 19 | #endif // DEVICE_MEMORY_RESOURCE_HPP 20 | -------------------------------------------------------------------------------- /include/mgcpp/allocators/memory_resource.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MEMORY_RESOURCE_HPP 2 | #define MEMORY_RESOURCE_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace mgcpp { 8 | 9 | enum class byte : unsigned char {}; 10 | 11 | // Taken & modified from https://github.com/phalpern/CppCon2017Code 12 | class memory_resource { 13 | public: 14 | virtual ~memory_resource() = default; 15 | 16 | void* allocate(size_t bytes) { return do_allocate(bytes); } 17 | void deallocate(void* p, size_t bytes) { return do_deallocate(p, bytes); } 18 | 19 | // `is_equal` is needed because polymorphic allocators are sometimes 20 | // produced as a result of type erasure. In that case, two different 21 | // instances of a polymorphic_memory_resource may actually represent 22 | // the same underlying allocator and should compare equal, even though 23 | // their addresses are different. 24 | bool is_equal(const memory_resource& other) const noexcept { 25 | return do_is_equal(other); 26 | } 27 | 28 | protected: 29 | virtual void* do_allocate(size_t bytes) = 0; 30 | virtual void do_deallocate(void* p, size_t bytes) = 0; 31 | virtual bool do_is_equal(const memory_resource& other) const noexcept = 0; 32 | }; 33 | 34 | inline bool operator==(const memory_resource& a, const memory_resource& b) { 35 | // Call `is_equal` rather than using address comparisons because some 36 | // polymorphic allocators are produced as a result of type erasure. In 37 | // that case, `a` and `b` may contain `memory_resource`s with different 38 | // addresses which, nevertheless, should compare equal. 39 | return &a == &b || a.is_equal(b); 40 | } 41 | 42 | inline bool operator!=(const memory_resource& a, const memory_resource& b) { 43 | return !(a == b); 44 | } 45 | 46 | } // namespace mgcpp 47 | 48 | #endif // MEMORY_RESOURCE_HPP 49 | -------------------------------------------------------------------------------- /include/mgcpp/allocators/new_delete_resource.hpp: -------------------------------------------------------------------------------- 1 | #ifndef NEW_DELETE_RESOURCE_HPP 2 | #define NEW_DELETE_RESOURCE_HPP 3 | 4 | #include 5 | 6 | namespace mgcpp { 7 | 8 | class new_delete_resource final : public memory_resource { 9 | public: 10 | static new_delete_resource* instance(); 11 | 12 | protected: 13 | void* do_allocate(size_t bytes) override; 14 | 15 | void do_deallocate(void* p, size_t bytes) override; 16 | 17 | bool do_is_equal(const memory_resource&) const noexcept override; 18 | 19 | private: 20 | new_delete_resource() = default; 21 | }; 22 | 23 | } // namespace mgcpp 24 | 25 | #endif // NEW_DELETE_RESOURCE_HPP 26 | -------------------------------------------------------------------------------- /include/mgcpp/context/forward.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _MGCPP_CONTEXT_FORWARD_HPP_ 2 | #define _MGCPP_CONTEXT_FORWARD_HPP_ 3 | 4 | namespace mgcpp {} 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /include/mgcpp/context/global_context.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_CONTEXT_GLOBAL_CONTEXT_HPP_ 8 | #define _MGCPP_CONTEXT_GLOBAL_CONTEXT_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | namespace mgcpp { 19 | class global_context { 20 | private: 21 | std::mutex _mtx; 22 | hash_table _thread_ctx; 23 | hash_table _context_ref_cnt; 24 | 25 | void reference_cnt_incr(); 26 | 27 | public: 28 | global_context() = default; 29 | 30 | global_context(global_context const& other) = delete; 31 | global_context(global_context&& other) = delete; 32 | global_context& operator=(global_context const& other) = delete; 33 | global_context& operator=(global_context&& other) = delete; 34 | 35 | static global_context& global_context_setting(); 36 | 37 | static void reference_cnt_decr(); 38 | 39 | static thread_context& get_thread_context(); 40 | }; 41 | } // namespace mgcpp 42 | #endif 43 | -------------------------------------------------------------------------------- /include/mgcpp/context/thread_context.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_CONTEXT_THREAD_CONTEXT_HPP_ 8 | #define _MGCPP_CONTEXT_THREAD_CONTEXT_HPP_ 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | namespace mgcpp { 17 | template 18 | using hash_table = std::unordered_map; 19 | 20 | class thread_context { 21 | private: 22 | using cublas_handle_unique_ptr = 23 | std::unique_ptr>; 24 | 25 | hash_table _cublas_handle; 26 | 27 | public: 28 | thread_context() = default; 29 | thread_context(thread_context const& other) = delete; 30 | thread_context& operator=(thread_context const& other) = delete; 31 | 32 | thread_context(thread_context&& other) noexcept; 33 | 34 | thread_context& operator=(thread_context&& other) noexcept; 35 | 36 | cublasHandle_t get_cublas_context(size_t device_id); 37 | }; 38 | } // namespace mgcpp 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /include/mgcpp/context/thread_guard.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_CONTEXT_THREAD_GUARD_HPP_ 8 | #define _MGCPP_CONTEXT_THREAD_GUARD_HPP_ 9 | 10 | #include 11 | #include 12 | 13 | namespace mgcpp { 14 | class thread_guard { 15 | public: 16 | inline explicit thread_guard(std::initializer_list device, 17 | bool cublas); 18 | 19 | inline explicit thread_guard(size_t device, bool cublas); 20 | 21 | inline ~thread_guard(); 22 | }; 23 | } // namespace mgcpp 24 | 25 | #include 26 | #endif 27 | -------------------------------------------------------------------------------- /include/mgcpp/context/thread_guard.ipp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace mgcpp { 13 | thread_guard::thread_guard(std::initializer_list device, bool cublas) { 14 | auto& ctx = global_context::get_thread_context(); 15 | 16 | if (cublas) { 17 | for (auto i : device) { 18 | (void)ctx.get_cublas_context(i); 19 | } 20 | } 21 | } 22 | 23 | thread_guard::thread_guard(size_t device, bool cublas) { 24 | auto& ctx = global_context::get_thread_context(); 25 | 26 | if (cublas) { 27 | (void)ctx.get_cublas_context(device); 28 | } 29 | } 30 | 31 | thread_guard::~thread_guard() { 32 | global_context::reference_cnt_decr(); 33 | } 34 | } // namespace mgcpp 35 | -------------------------------------------------------------------------------- /include/mgcpp/cuda/device.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_CUDA_DEVICE_HPP_ 8 | #define _MGCPP_CUDA_DEVICE_HPP_ 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace mgcpp { 16 | outcome::result cuda_set_device(size_t device_id) noexcept; 17 | } 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/constant_expr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CONSTANT_EXPR_HPP 2 | #define CONSTANT_EXPR_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace mgcpp { 10 | 11 | struct zeros_mat_expr_type; 12 | 13 | template 14 | using zeros_mat_expr = generic_expr>; 20 | 21 | template 22 | zeros_mat_expr make_zeros_like(dmat_expr const& expr) { 23 | return zeros_mat_expr(sym_shape(~expr)); 24 | } 25 | 26 | struct ones_mat_expr_type; 27 | 28 | template 29 | using ones_mat_expr = generic_expr>; 35 | 36 | template 37 | ones_mat_expr make_ones_like(dmat_expr const& expr) { 38 | return ones_mat_expr(sym_shape(~expr)); 39 | } 40 | 41 | struct zeros_vec_expr_type; 42 | 43 | template 44 | using zeros_vec_expr = generic_expr>; 50 | 51 | template 52 | zeros_vec_expr make_zeros_like(dvec_expr const& expr) { 53 | return zeros_vec_expr(sym_shape(~expr)); 54 | } 55 | 56 | struct ones_vec_expr_type; 57 | 58 | template 59 | using ones_vec_expr = generic_expr>; 65 | 66 | template 67 | ones_vec_expr make_ones_like(dvec_expr const& expr) { 68 | return ones_vec_expr(sym_shape(~expr)); 69 | } 70 | 71 | } // namespace mgcpp 72 | 73 | #endif // CONSTANT_EXPR_HPP 74 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dmat_dmat_add.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_EXPRESSIONS_DMAT_DMAT_ADD_EXPR_HPP_ 8 | #define _MGCPP_EXPRESSIONS_DMAT_DMAT_ADD_EXPR_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace mgcpp { 15 | 16 | struct dmat_dmat_add_expr_type; 17 | 18 | template 19 | using dmat_dmat_add_expr = binary_expr; 24 | 25 | template 26 | inline auto operator+(dmat_expr const& lhs, 27 | dmat_expr const& rhs) noexcept; 28 | 29 | template 30 | inline auto add(dmat_expr const& lhs, 31 | dmat_expr const& rhs) noexcept; 32 | 33 | template 34 | inline auto operator-(dmat_expr const& lhs, 35 | dmat_expr const& rhs) noexcept; 36 | 37 | template 38 | inline auto sub(dmat_expr const& lhs, 39 | dmat_expr const& rhs) noexcept; 40 | 41 | } // namespace mgcpp 42 | 43 | #include 44 | #endif 45 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dmat_dmat_add.tpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | // Copyright RedPortal, mujjingun 2017 - 2018. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See accompanying file LICENSE or copy at 6 | // http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | namespace mgcpp { 14 | namespace internal { 15 | template 16 | auto dmat_dmat_add_impl(dmat_expr const& lhs, 17 | dmat_expr const& rhs) noexcept { 18 | return dmat_dmat_add_expr(~lhs, ~rhs); 19 | } 20 | 21 | // TODO: check shape compatibility?? 22 | template 23 | auto dmat_dmat_add_impl(zeros_mat_expr const&, 24 | dmat_expr const& rhs) noexcept { 25 | return ~rhs; 26 | } 27 | 28 | template 29 | auto dmat_dmat_add_impl(dmat_expr const& lhs, 30 | zeros_mat_expr const&) noexcept { 31 | return ~lhs; 32 | } 33 | } // namespace internal 34 | 35 | template 36 | auto operator+(dmat_expr const& lhs, 37 | dmat_expr const& rhs) noexcept { 38 | return internal::dmat_dmat_add_impl(~lhs, ~rhs); 39 | } 40 | 41 | template 42 | auto add(dmat_expr const& lhs, 43 | dmat_expr const& rhs) noexcept { 44 | return internal::dmat_dmat_add_impl(~lhs, ~rhs); 45 | } 46 | 47 | template 48 | inline auto operator-(dmat_expr const& lhs, 49 | dmat_expr const& rhs) noexcept { 50 | return lhs + static_cast(-1) * rhs; 51 | } 52 | 53 | template 54 | inline auto sub(dmat_expr const& lhs, 55 | dmat_expr const& rhs) noexcept { 56 | return lhs + static_cast(-1) * rhs; 57 | } 58 | } // namespace mgcpp 59 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dmat_dmat_mult.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_EXPRESSIONS_DMAT_DMAT_MULT_EXPR_HPP_ 8 | #define _MGCPP_EXPRESSIONS_DMAT_DMAT_MULT_EXPR_HPP_ 9 | 10 | #include 11 | #include 12 | 13 | namespace mgcpp { 14 | 15 | struct dmat_dmat_mult_expr_type; 16 | 17 | template 18 | using dmat_dmat_mult_expr = binary_expr; 23 | 24 | /** Returns a dense matrix product expression. 25 | * \param lhs the left-hand side dense matrix 26 | * \param rhs the right-hand side dense matrix 27 | */ 28 | template 29 | inline dmat_dmat_mult_expr operator*( 30 | dmat_expr const& lhs, 31 | dmat_expr const& rhs) noexcept; 32 | 33 | /** Returns a dense matrix product expression. 34 | * \param lhs the left-hand side dense matrix 35 | * \param rhs the right-hand side dense matrix 36 | */ 37 | template 38 | inline dmat_dmat_mult_expr mult( 39 | dmat_expr const& lhs, 40 | dmat_expr const& rhs) noexcept; 41 | } // namespace mgcpp 42 | 43 | #include 44 | #endif 45 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dmat_dvec_mult.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_EXPRESSIONS_DMAT_DVEC_MULT_EXPR_HPP_ 8 | #define _MGCPP_EXPRESSIONS_DMAT_DVEC_MULT_EXPR_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace mgcpp { 15 | 16 | struct dmat_dvec_mult_expr_type; 17 | 18 | template 19 | using dmat_dvec_mult_expr = binary_expr; 24 | 25 | /** Returns a dense matrix vector product expression. 26 | * \param lhs the left-hand side dense matrix 27 | * \param rhs the right-hand side dense vector 28 | */ 29 | template 30 | inline dmat_dvec_mult_expr operator*( 31 | dmat_expr const& mat, 32 | dvec_expr const& vec) noexcept; 33 | 34 | /** Returns a dense matrix add expression. 35 | * \param lhs the left-hand side dense matrix 36 | * \param rhs the right-hand side dense vector 37 | */ 38 | template 39 | inline dmat_dvec_mult_expr mult( 40 | dmat_expr const& mat, 41 | dvec_expr const& vec) noexcept; 42 | } // namespace mgcpp 43 | 44 | #include 45 | #endif 46 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dmat_dvec_mult.tpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | namespace mgcpp { 10 | template 11 | inline dmat_dvec_mult_expr operator*( 12 | dmat_expr const& mat, 13 | dvec_expr const& vec) noexcept { 14 | return dmat_dvec_mult_expr(~mat, ~vec); 15 | } 16 | 17 | template 18 | inline dmat_dvec_mult_expr mult( 19 | dmat_expr const& mat, 20 | dvec_expr const& vec) noexcept { 21 | return dmat_dvec_mult_expr(~mat, ~vec); 22 | } 23 | } // namespace mgcpp 24 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dmat_expr.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_EXPRESSIONS_DENSE_MAT_EXPR_HPP_ 8 | #define _MGCPP_EXPRESSIONS_DENSE_MAT_EXPR_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace mgcpp { 18 | template 19 | struct dmat_expr : public expression {}; 20 | } // namespace mgcpp 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dmat_reduce_expr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DMAT_REDUCE_HPP 2 | #define DMAT_REDUCE_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace mgcpp { 9 | 10 | struct dmat_reduce_sum_expr_type; 11 | 12 | template 13 | using dmat_reduce_sum_expr = 14 | generic_expr; 20 | 21 | template 22 | inline decltype(auto) reduce_sum(dmat_expr const& expr) noexcept; 23 | 24 | struct dmat_reduce_mean_expr_type; 25 | 26 | template 27 | using dmat_reduce_mean_expr = 28 | generic_expr; 34 | 35 | template 36 | inline decltype(auto) reduce_mean(dmat_expr const& expr) noexcept; 37 | } // namespace mgcpp 38 | 39 | #include 40 | #endif // DMAT_REDUCE_HPP 41 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dmat_reduce_expr.tpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace mgcpp { 4 | 5 | template 6 | decltype(auto) reduce_sum(const dmat_expr& expr) noexcept { 7 | return dmat_reduce_sum_expr(~expr); 8 | } 9 | 10 | template 11 | decltype(auto) reduce_mean(const dmat_expr& expr) noexcept { 12 | return dmat_reduce_mean_expr(~expr); 13 | } 14 | 15 | } // namespace mgcpp 16 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dmat_ref_expr.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_EXPRESSIONS_DMAT_REF_EXPR_HPP_ 8 | #define _MGCPP_EXPRESSIONS_DMAT_REF_EXPR_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace mgcpp { 16 | 17 | struct dmat_ref_expr_type; 18 | 19 | template 20 | using dmat_ref_expr = 21 | generic_expr; 22 | 23 | template 24 | inline dmat_ref_expr ref( 25 | dense_matrix const& mat); 26 | } // namespace mgcpp 27 | 28 | #include 29 | #endif 30 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dmat_ref_expr.tpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | namespace mgcpp { 10 | 11 | template 12 | inline dmat_ref_expr ref( 13 | dense_matrix const& mat) { 14 | return dmat_ref_expr(~mat); 15 | } 16 | 17 | } // namespace mgcpp 18 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dmat_trans_expr.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_EXPRESSIONS_DMAT_TRANS_EXPR_HPP_ 8 | #define _MGCPP_EXPRESSIONS_DMAT_TRANS_EXPR_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace mgcpp { 15 | 16 | struct dmat_trans_expr_type; 17 | 18 | template 19 | using dmat_trans_expr = unary_expr; 23 | 24 | template 25 | inline dmat_trans_expr trans(dmat_expr const& expr) noexcept; 26 | } // namespace mgcpp 27 | 28 | #include 29 | #endif 30 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dmat_trans_expr.tpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | namespace mgcpp { 10 | 11 | template 12 | inline dmat_trans_expr trans(dmat_expr const& expr) noexcept { 13 | return dmat_trans_expr(~expr); 14 | } 15 | 16 | } // namespace mgcpp 17 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dvec_dvec_add.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_EXPRESSIONS_DVEC_DVEC_ADD_HPP_ 8 | #define _MGCPP_EXPRESSIONS_DVEC_DVEC_ADD_HPP_ 9 | 10 | #include 11 | #include 12 | 13 | namespace mgcpp { 14 | 15 | struct dvec_dvec_add_expr_type; 16 | 17 | template 18 | using dvec_dvec_add_expr = binary_expr; 23 | 24 | /** Returns a dense vector addition expression. 25 | * \param lhs the left-hand side dense vector 26 | * \param rhs the right-hand side dense vector 27 | */ 28 | template 29 | inline dvec_dvec_add_expr operator+( 30 | dvec_expr const& lhs, 31 | dvec_expr const& rhs) noexcept; 32 | 33 | /** Returns a dense vector addition expression. 34 | * \param lhs the left-hand side dense vector 35 | * \param rhs the right-hand side dense vector 36 | */ 37 | template 38 | inline dvec_dvec_add_expr add( 39 | dvec_expr const& lhs, 40 | dvec_expr const& rhs) noexcept; 41 | } // namespace mgcpp 42 | 43 | #include 44 | #endif // _MGCPP_EXPRESSIONS_DVEC_DVEC_ADD_HPP_ 45 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dvec_dvec_add.tpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | namespace mgcpp { 10 | 11 | template 12 | dvec_dvec_add_expr operator+( 13 | dvec_expr const& lhs, 14 | dvec_expr const& rhs) noexcept { 15 | return dvec_dvec_add_expr(~lhs, ~rhs); 16 | } 17 | 18 | template 19 | dvec_dvec_add_expr add( 20 | dvec_expr const& lhs, 21 | dvec_expr const& rhs) noexcept { 22 | return dvec_dvec_add_expr(~lhs, ~rhs); 23 | } 24 | } // namespace mgcpp 25 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dvec_dvec_outer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MGCPP_EXPRESSIONS_DVEC_DVEC_OUTER_HPP 2 | #define MGCPP_EXPRESSIONS_DVEC_DVEC_OUTER_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace mgcpp { 9 | 10 | struct dvec_dvec_outer_expr_type; 11 | 12 | template 13 | using dvec_dvec_outer_expr = 14 | binary_expr, 17 | LhsExpr, 18 | RhsExpr>; 19 | 20 | template 21 | auto outer(dvec_expr const& lhs, 22 | dvec_expr const& rhs) noexcept { 23 | return dvec_dvec_outer_expr(~lhs, ~rhs); 24 | } 25 | 26 | } // namespace mgcpp 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dvec_expr.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_EXPRESSIONS_DENSE_VEC_EXPR_HPP_ 8 | #define _MGCPP_EXPRESSIONS_DENSE_VEC_EXPR_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | namespace mgcpp { 19 | template 20 | struct dvec_expr : public expression {}; 21 | } // namespace mgcpp 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dvec_map.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_EXPRESSIONS_DVEC_ELEMWISE_HPP_ 8 | #define _MGCPP_EXPRESSIONS_DVEC_ELEMWISE_HPP_ 9 | 10 | #include 11 | #include 12 | 13 | namespace mgcpp { 14 | 15 | struct dmat_mat_expr_type; 16 | 17 | template 18 | using dvec_map_expr = 19 | generic_expr; 27 | 28 | template 29 | inline decltype(auto) abs(dvec_expr const& expr) noexcept; 30 | 31 | template 32 | inline decltype(auto) sin(dvec_expr const& expr) noexcept; 33 | 34 | template 35 | inline decltype(auto) cos(dvec_expr const& expr) noexcept; 36 | 37 | template 38 | inline decltype(auto) tan(dvec_expr const& expr) noexcept; 39 | 40 | template 41 | inline decltype(auto) sinh(dvec_expr const& expr) noexcept; 42 | 43 | template 44 | inline decltype(auto) cosh(dvec_expr const& expr) noexcept; 45 | 46 | template 47 | inline decltype(auto) tanh(dvec_expr const& expr) noexcept; 48 | 49 | template 50 | inline decltype(auto) relu(dvec_expr const& expr) noexcept; 51 | } // namespace mgcpp 52 | 53 | #include 54 | #endif 55 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dvec_map.tpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | namespace mgcpp { 11 | 12 | template 13 | inline decltype(auto) abs(dvec_expr const& expr) noexcept { 14 | return dvec_map_expr(strict::abs, ~expr); 15 | } 16 | 17 | template 18 | inline decltype(auto) sin(dvec_expr const& expr) noexcept { 19 | return dvec_map_expr(strict::sin, ~expr); 20 | } 21 | 22 | template 23 | inline decltype(auto) cos(dvec_expr const& expr) noexcept { 24 | return dvec_map_expr(strict::cos, ~expr); 25 | } 26 | 27 | template 28 | inline decltype(auto) tan(dvec_expr const& expr) noexcept { 29 | return dvec_map_expr(strict::tan, ~expr); 30 | } 31 | 32 | template 33 | inline decltype(auto) sinh(dvec_expr const& expr) noexcept { 34 | return dvec_map_expr(strict::sinh, ~expr); 35 | } 36 | 37 | template 38 | inline decltype(auto) cosh(dvec_expr const& expr) noexcept { 39 | return dvec_map_expr(strict::cosh, ~expr); 40 | } 41 | 42 | template 43 | inline decltype(auto) tanh(dvec_expr const& expr) noexcept { 44 | return dvec_map_expr(strict::tanh, ~expr); 45 | } 46 | 47 | template 48 | inline decltype(auto) relu(dvec_expr const& expr) noexcept { 49 | return dvec_map_expr(strict::relu, ~expr); 50 | } 51 | } // namespace mgcpp 52 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dvec_reduce_expr.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_EXPRESSIONS_DVEC_REDUCE_EXPR_HPP_ 8 | #define _MGCPP_EXPRESSIONS_DVEC_REDUCE_EXPR_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace mgcpp { 15 | 16 | struct dvec_reduce_sum_expr_type; 17 | 18 | template 19 | using dvec_reduce_sum_expr = 20 | generic_expr; 26 | 27 | template 28 | inline decltype(auto) reduce_sum(dvec_expr const& expr) noexcept; 29 | 30 | struct dvec_reduce_mean_expr_type; 31 | 32 | template 33 | using dvec_reduce_mean_expr = 34 | generic_expr; 40 | 41 | template 42 | inline decltype(auto) reduce_mean(dvec_expr const& expr) noexcept; 43 | } // namespace mgcpp 44 | 45 | #include 46 | #endif 47 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dvec_reduce_expr.tpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace mgcpp { 12 | template 13 | decltype(auto) reduce_sum(const dvec_expr& expr) noexcept { 14 | return dvec_reduce_sum_expr(~expr); 15 | } 16 | 17 | template 18 | decltype(auto) reduce_mean(const dvec_expr& expr) noexcept { 19 | return dvec_reduce_mean_expr(~expr); 20 | } 21 | } // namespace mgcpp 22 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dvec_ref_expr.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_EXPRESSIONS_DVEC_REF_EXPR_HPP_ 8 | #define _MGCPP_EXPRESSIONS_DVEC_REF_EXPR_HPP_ 9 | 10 | #include 11 | #include 12 | 13 | namespace mgcpp { 14 | 15 | struct dvec_ref_expr_type; 16 | 17 | template 18 | using dvec_ref_expr = 19 | generic_expr; 20 | 21 | template 22 | inline dvec_ref_expr ref( 23 | dense_vector const& mat); 24 | } // namespace mgcpp 25 | 26 | #include 27 | #endif 28 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/dvec_ref_expr.tpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | namespace mgcpp { 10 | 11 | template 12 | inline dvec_ref_expr ref( 13 | dense_vector const& vec) { 14 | return dvec_ref_expr(~vec); 15 | } 16 | } // namespace mgcpp 17 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/eval_cache.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EVAL_CACHE_HPP 2 | #define EVAL_CACHE_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace mgcpp { 8 | 9 | size_t get_last_run_cache_hits(); 10 | 11 | void analyze_graph(size_t id, std::function traverse); 12 | 13 | static_any evaluate_if_needed(size_t id, 14 | bool needs_caching, 15 | std::function traverse, 16 | std::function evaluate); 17 | 18 | } // namespace mgcpp 19 | 20 | #endif // EVAL_CACHE_HPP 21 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/eval_context.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef EVAL_CONTEXT_HPP 8 | #define EVAL_CONTEXT_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace mgcpp { 19 | 20 | struct eval_context { 21 | /** Associate a value to a placeholder. The associated value will be fed to 22 | * the placeholder's place when the graph is evaluated. 23 | * \param ph The placeholder. 24 | * \param val The value associated with the placeholder. 25 | */ 26 | template 27 | void feed(placeholder_node ph, ResultType const& val); 28 | 29 | /** Get the value of the placeholder associated with the PlaceholderID. 30 | * ResultType should be the type of the value when feed() was called. 31 | */ 32 | template 33 | ResultType get_placeholder() const; 34 | 35 | protected: 36 | std::unordered_map _placeholders; 37 | }; 38 | 39 | } // namespace mgcpp 40 | 41 | #include 42 | #endif // EVAL_CONTEXT_HPP 43 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/eval_context.tpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace mgcpp { 4 | 5 | template 6 | void eval_context::feed(placeholder_node, 7 | ResultType const& val) { 8 | _placeholders[Num] = static_any(val); 9 | } 10 | 11 | template 12 | ResultType eval_context::get_placeholder() const { 13 | return _placeholders.at(PlaceholderID).get(); 14 | }; 15 | 16 | } // namespace mgcpp 17 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/evaluator.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef EVALUATOR_HPP 8 | #define EVALUATOR_HPP 9 | 10 | #include 11 | 12 | namespace mgcpp { 13 | namespace evaluator { 14 | template 15 | inline typename Op::result_type eval(Op const& op, eval_context const& ctx); 16 | }; 17 | 18 | template 19 | inline typename T::result_type eval(expression const& expr, 20 | eval_context const& ctx); 21 | 22 | template 23 | inline typename T::result_type eval(expression const& expr); 24 | 25 | } // namespace mgcpp 26 | 27 | #include 28 | #endif // EVALUATOR_HPP 29 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/expression.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_EXPRESSIONS_EXPRESSION_HPP_ 8 | #define _MGCPP_EXPRESSIONS_EXPRESSION_HPP_ 9 | 10 | #include 11 | #include 12 | 13 | namespace mgcpp { 14 | 15 | size_t make_id(); 16 | 17 | template 18 | class expression { 19 | public: 20 | inline Type& operator~() noexcept; 21 | inline Type const& operator~() const noexcept; 22 | 23 | protected: 24 | size_t id = make_id(); 25 | }; 26 | 27 | } // namespace mgcpp 28 | 29 | #include 30 | #endif 31 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/expression.tpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace mgcpp { 4 | 5 | template 6 | Type& expression::operator~() noexcept { 7 | return *static_cast(this); 8 | } 9 | 10 | template 11 | const Type& expression::operator~() const noexcept { 12 | return *static_cast(this); 13 | } 14 | 15 | } // namespace mgcpp 16 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/forward.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_EXPRESSIONS_FORWARD_HPP_ 8 | #define _MGCPP_EXPRESSIONS_FORWARD_HPP_ 9 | 10 | #include 11 | 12 | namespace mgcpp { 13 | 14 | template 15 | class expression; 16 | 17 | struct eval_context; 18 | 19 | template class ResultExprType, 22 | typename ResultType, 23 | size_t NParameters, 24 | typename... OperandTypes> 25 | struct generic_expr; 26 | } // namespace mgcpp 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/gradients.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GRADIENTS_HPP 2 | #define GRADIENTS_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace mgcpp { 8 | 9 | template 10 | inline auto grad(scalar_expr const& expr, 11 | placeholder_node wrt); 12 | 13 | } // namespace mgcpp 14 | 15 | #include 16 | #endif // GRADIENTS_HPP 17 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/inspect_graph.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INSPECT_GRAPH_HPP 2 | #define INSPECT_GRAPH_HPP 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace mgcpp { 9 | 10 | template 11 | std::ostream& operator<<(std::ostream& os, expression const& expr); 12 | } 13 | 14 | #include 15 | #endif // INSPECT_GRAPH_HPP 16 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/placeholder.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PLACEHOLDER_HPP 2 | #define PLACEHOLDER_HPP 3 | 4 | #include 5 | 6 | namespace mgcpp { 7 | 8 | struct placeholder_node_type; 9 | 10 | template 11 | using placeholder_node = generic_expr; 16 | } // namespace mgcpp 17 | 18 | #endif // PLACEHOLDER_HPP 19 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/scalar_expr.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_EXPRESSIONS_SCALAR_EXPR_HPP_ 8 | #define _MGCPP_EXPRESSIONS_SCALAR_EXPR_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace mgcpp { 17 | template 18 | struct scalar_expr : public expression {}; 19 | 20 | struct scalar_constant_expr_type; 21 | 22 | template 23 | using scalar_constant_expr = 24 | generic_expr; 25 | 26 | template 27 | inline scalar_constant_expr scal(Type scalar); 28 | 29 | struct scalar_zero_constant_expr_type; 30 | 31 | template 32 | using scalar_zero_constant_expr = 33 | generic_expr; 34 | 35 | struct scalar_one_constant_expr_type; 36 | 37 | template 38 | using scalar_one_constant_expr = 39 | generic_expr; 40 | 41 | } // namespace mgcpp 42 | 43 | #include 44 | #endif 45 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/scalar_expr.tpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace mgcpp { 4 | 5 | template 6 | scalar_constant_expr scal(Type scalar) { 7 | static_assert(mgcpp::is_scalar::value, "Type is not scalar"); 8 | return scalar_constant_expr(scalar); 9 | } 10 | 11 | } // namespace mgcpp 12 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/shape_evaluator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SHAPE_EVALUATOR_HPP 2 | #define SHAPE_EVALUATOR_HPP 3 | 4 | #include 5 | 6 | namespace mgcpp { 7 | namespace shape_evaluator { 8 | template 9 | inline typename Op::result_type::shape_type shape(Op const& op, 10 | eval_context const& ctx); 11 | }; 12 | } // namespace mgcpp 13 | 14 | #include 15 | 16 | #endif // SHAPE_EVALUATOR_HPP 17 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/symbolic_shape_expr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SYMBOLIC_SHAPE_EXPR_HPP 2 | #define SYMBOLIC_SHAPE_EXPR_HPP 3 | 4 | #include 5 | 6 | namespace mgcpp { 7 | 8 | template 9 | struct shape_expr : expression {}; 10 | 11 | struct symbolic_shape_expr_type; 12 | 13 | template 14 | using symbolic_shape_expr = generic_expr; 20 | 21 | /* 22 | * Obtain the dynamic shape of this expression 23 | */ 24 | template 25 | inline symbolic_shape_expr sym_shape(Expr const& expr) { 26 | return symbolic_shape_expr(expr); 27 | } 28 | 29 | } // namespace mgcpp 30 | 31 | #endif // SYMBOLIC_SHAPE_EXPR_HPP 32 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/tie_expr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TIE_EXPR_HPP 2 | #define TIE_EXPR_HPP 3 | 4 | #include 5 | 6 | namespace mgcpp { 7 | 8 | template 9 | struct tie_expr : public expression {}; 10 | 11 | struct tie_op_type; 12 | 13 | template 14 | using tie_op = generic_expr, 18 | 0, 19 | Exprs...>; 20 | 21 | template 22 | inline tie_op tie(Exprs const&... exprs); 23 | 24 | } // namespace mgcpp 25 | 26 | #include 27 | #endif // TIE_EXPR_HPP 28 | -------------------------------------------------------------------------------- /include/mgcpp/expressions/tie_expr.tpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace mgcpp { 4 | 5 | template 6 | inline tie_op tie(Exprs const&... exprs) { 7 | return tie_op(~exprs...); 8 | } 9 | 10 | } // namespace mgcpp 11 | -------------------------------------------------------------------------------- /include/mgcpp/global/complex.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_TYPE_COMPLEX_HPP_ 8 | #define _MGCPP_TYPE_COMPLEX_HPP_ 9 | 10 | #include 11 | #include 12 | 13 | namespace mgcpp { 14 | template 15 | using complex = std::complex; 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /include/mgcpp/global/half_precision.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_GLOBAL_HALF_PRECISION_HPP_ 8 | #define _MGCPP_GLOBAL_HALF_PRECISION_HPP_ 9 | 10 | #ifdef USE_HALF 11 | #include 12 | #include 13 | #include 14 | namespace mgcpp { 15 | using half = half_float::half; 16 | } 17 | #endif 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/mgcpp/global/init.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_GLOBAL_INIT_HPP_ 8 | #define _MGCPP_GLOBAL_INIT_HPP_ 9 | 10 | namespace mgcpp { 11 | void init(bool print_system_info = true); 12 | } 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /include/mgcpp/global/shape.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _MGCPP_GLOBAL_SHAPE_HPP_ 3 | #define _MGCPP_GLOBAL_SHAPE_HPP_ 4 | 5 | #include 6 | #include 7 | 8 | namespace mgcpp { 9 | template 10 | struct shape { 11 | size_t dims[Dims]; 12 | 13 | using shape_type = shape; 14 | 15 | shape(); 16 | shape(std::initializer_list list); 17 | shape(shape const&) = default; 18 | shape& operator=(shape const&) = default; 19 | 20 | size_t operator[](size_t idx) const; 21 | size_t& operator[](size_t idx); 22 | bool operator==(shape const& rhs) const; 23 | bool operator!=(shape const& rhs) const; 24 | 25 | template 26 | size_t get() const; 27 | }; 28 | 29 | template 30 | shape make_shape(Types... args); 31 | } // namespace mgcpp 32 | 33 | namespace std { 34 | template 35 | class tuple_size> 36 | : std::integral_constant {}; 37 | 38 | template 39 | struct tuple_element> { 40 | using type = std::size_t; 41 | }; 42 | } // namespace std 43 | 44 | #include 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /include/mgcpp/global/shape.tpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | namespace mgcpp { 7 | template 8 | shape::shape() : dims{} {} 9 | 10 | template 11 | shape::shape(std::initializer_list list) { 12 | std::copy(list.begin(), list.end(), dims); 13 | } 14 | 15 | template 16 | size_t shape::operator[](size_t idx) const { 17 | return dims[idx]; 18 | } 19 | 20 | template 21 | size_t& shape::operator[](size_t idx) { 22 | return dims[idx]; 23 | } 24 | 25 | template 26 | bool shape::operator==(shape const& rhs) const { 27 | for (auto i = 0u; i < Dims; ++i) 28 | if (dims[i] != rhs[i]) 29 | return false; 30 | return true; 31 | } 32 | 33 | template 34 | bool shape::operator!=(const shape& rhs) const { 35 | return !(*this == rhs); 36 | } 37 | 38 | template 39 | template 40 | size_t shape::get() const { 41 | return dims[N]; 42 | } 43 | 44 | template 45 | shape make_shape(Types... args) { 46 | return {static_cast(args)...}; 47 | } 48 | } // namespace mgcpp 49 | -------------------------------------------------------------------------------- /include/mgcpp/global/type_erased.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TYPE_ERASED_HPP 2 | #define TYPE_ERASED_HPP 3 | 4 | #include 5 | 6 | namespace mgcpp { 7 | 8 | struct static_any { 9 | static_any() = default; 10 | 11 | template 12 | static_any(T data); 13 | 14 | template 15 | T get() const; 16 | 17 | struct concept { 18 | virtual ~concept() = default; 19 | }; 20 | 21 | template 22 | struct model final : concept { 23 | model(T x); 24 | T data; 25 | }; 26 | 27 | std::shared_ptr m; 28 | }; 29 | 30 | } // namespace mgcpp 31 | 32 | #include 33 | #endif // TYPE_ERASED_HPP 34 | -------------------------------------------------------------------------------- /include/mgcpp/global/type_erased.tpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace mgcpp { 4 | template 5 | static_any::static_any(T data) 6 | : m(std::make_shared>(std::move(data))) {} 7 | 8 | template 9 | T static_any::get() const { 10 | return static_cast const&>(*m).data; 11 | } 12 | 13 | template 14 | static_any::model::model(T x) : data(std::move(x)) {} 15 | 16 | } // namespace mgcpp 17 | -------------------------------------------------------------------------------- /include/mgcpp/kernels/bits/convert.cuh: -------------------------------------------------------------------------------- 1 | #ifndef _MGCPP_KERNELS_BITS_CONVERT_CUH_ 2 | #define _MGCPP_KERNELS_BITS_CONVERT_CUH_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace mgcpp 10 | { 11 | mgblas_error_t 12 | mgblas_HFconvert(__half const* from, float* to, size_t n); 13 | 14 | mgblas_error_t 15 | mgblas_FHconvert(float const* from, __half* to, size_t n); 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /include/mgcpp/kernels/bits/fill.cuh: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_KERNELS_BITS_FILL_CUH_ 8 | #define _MGCPP_KERNELS_BITS_FILL_CUH_ 9 | 10 | #include 11 | 12 | #include 13 | #ifdef USE_HALF 14 | # include 15 | #endif 16 | 17 | namespace mgcpp 18 | { 19 | mgblas_error_t 20 | mgblas_Sfill(float* arr, float value, size_t n); 21 | 22 | mgblas_error_t 23 | mgblas_Dfill(double* arr, double value, size_t n); 24 | 25 | mgblas_error_t 26 | mgblas_Cfill(cuComplex* arr, cuComplex value, size_t n); 27 | 28 | mgblas_error_t 29 | mgblas_Zfill(cuDoubleComplex* arr, cuDoubleComplex value, size_t n); 30 | 31 | #ifdef USE_HALF 32 | mgblas_error_t 33 | mgblas_Hfill(__half* arr, __half value, size_t n); 34 | #endif 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /include/mgcpp/kernels/bits/hadamard.cuh: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_KERNELS_HADAMARD_HPP_ 8 | #define _MGCPP_KERNELS_HADAMARD_HPP_ 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace mgcpp 15 | { 16 | mgblas_error_t 17 | mgblas_Svhp(float const* x, float const* y, 18 | float* z, size_t size); 19 | 20 | mgblas_error_t 21 | mgblas_Dvhp(double const* x, double const* y, 22 | double* z, size_t size); 23 | 24 | mgblas_error_t 25 | mgblas_Hvhp(__half const* x, __half const* y, 26 | __half* z, size_t size); 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /include/mgcpp/kernels/bits/map.cuh: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_KERNELS_ABSOLUTE_HPP_ 8 | #define _MGCPP_KERNELS_ABSOLUTE_HPP_ 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace mgcpp 16 | { 17 | mgblas_error_t 18 | mgblas_Svab(float* x, size_t n); 19 | 20 | mgblas_error_t 21 | mgblas_Dvab(double* x, size_t n); 22 | 23 | // kernel_status_t 24 | // mgblas_Hvab(__half const* x, __half const* y, 25 | // __half* z, size_t size); 26 | 27 | mgblas_error_t 28 | mgblas_Svsin(float* x, size_t n); 29 | 30 | mgblas_error_t 31 | mgblas_Dvsin(double* x, size_t n); 32 | 33 | mgblas_error_t 34 | mgblas_Svcos(float* x, size_t n); 35 | 36 | mgblas_error_t 37 | mgblas_Dvcos(double* x, size_t n); 38 | 39 | mgblas_error_t 40 | mgblas_Svtan(float* x, size_t n); 41 | 42 | mgblas_error_t 43 | mgblas_Dvtan(double* x, size_t n); 44 | 45 | mgblas_error_t 46 | mgblas_Svsinh(float* x, size_t n); 47 | 48 | mgblas_error_t 49 | mgblas_Dvsinh(double* x, size_t n); 50 | 51 | mgblas_error_t 52 | mgblas_Svcosh(float* x, size_t n); 53 | 54 | mgblas_error_t 55 | mgblas_Dvcosh(double* x, size_t n); 56 | 57 | mgblas_error_t 58 | mgblas_Svtanh(float* x, size_t n); 59 | 60 | mgblas_error_t 61 | mgblas_Dvtanh(double* x, size_t n); 62 | 63 | mgblas_error_t 64 | mgblas_Svrelu(float* x, size_t n); 65 | 66 | mgblas_error_t 67 | mgblas_Dvrelu(double* x, size_t n); 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /include/mgcpp/kernels/bits/reduce.cuh: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_KERNELS_REDUCE_HPP_ 8 | #define _MGCPP_KERNELS_REDUCE_HPP_ 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace mgcpp 15 | { 16 | mgblas_error_t 17 | mgblas_Svpr(float const* x, float* y, size_t size); 18 | 19 | mgblas_error_t 20 | mgblas_Dvpr(double const* x, double* y, size_t size); 21 | 22 | #ifdef USE_HALF 23 | mgblas_error_t 24 | mgblas_Hvpr(__half const* x, __half* y, size_t size); 25 | #endif 26 | } 27 | 28 | #endif -------------------------------------------------------------------------------- /include/mgcpp/kernels/mgblas_error_code.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_KERNELS_MGBLAS_ERROR_HPP_ 8 | #define _MGCPP_KERNELS_MGBLAS_ERROR_HPP_ 9 | 10 | namespace mgcpp { 11 | enum mgblas_error_t { 12 | success = 0, 13 | index_out_of_range = 1, 14 | invalid_range = 2, 15 | memory_allocation_failure = 3, 16 | device_to_host_memcpy_failure = 4 17 | }; 18 | } 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /include/mgcpp/kernels/mgblas_helpers.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_KERNELS_MGBLAS_HELPERS_HPP_ 8 | #define _MGCPP_KERNELS_MGBLAS_HELPERS_HPP_ 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace mgcpp { 16 | template 17 | inline outcome::result mgblas_fill(Type* arr, Type value, size_t n); 18 | 19 | template 20 | inline outcome::result mgblas_convert_copy(From const* from, 21 | To* to, 22 | size_t n); 23 | } // namespace mgcpp 24 | 25 | #include 26 | #endif 27 | -------------------------------------------------------------------------------- /include/mgcpp/kernels/mgblas_helpers.tpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace mgcpp { 15 | template <> 16 | inline outcome::result mgblas_fill(float* arr, float value, size_t n) { 17 | std::error_code status = mgblas_Sfill(arr, value, n); 18 | 19 | if (status != status_t::success) 20 | return status; 21 | else 22 | return outcome::success(); 23 | } 24 | 25 | template <> 26 | inline outcome::result mgblas_fill(double* arr, double value, size_t n) { 27 | std::error_code status = mgblas_Dfill(arr, value, n); 28 | 29 | if (status != status_t::success) 30 | return status; 31 | else 32 | return outcome::success(); 33 | } 34 | 35 | template <> 36 | inline outcome::result mgblas_fill(cuComplex* arr, 37 | cuComplex value, 38 | size_t n) { 39 | std::error_code status = mgblas_Cfill(arr, value, n); 40 | 41 | if (status != status_t::success) 42 | return status; 43 | else 44 | return outcome::success(); 45 | } 46 | 47 | template <> 48 | inline outcome::result mgblas_fill(cuDoubleComplex* arr, 49 | cuDoubleComplex value, 50 | size_t n) { 51 | std::error_code status = mgblas_Zfill(arr, value, n); 52 | 53 | if (status != status_t::success) 54 | return status; 55 | else 56 | return outcome::success(); 57 | } 58 | 59 | #ifdef USE_HALF 60 | template <> 61 | inline outcome::result mgblas_fill(__half* arr, __half value, size_t n) { 62 | std::error_code status = mgblas_Hfill(arr, value, n); 63 | 64 | if (status != status_t::success) 65 | return status; 66 | else 67 | return outcome::success(); 68 | } 69 | 70 | template <> 71 | inline outcome::result mgblas_convert_copy(__half const* from, 72 | float* to, 73 | size_t n) { 74 | std::error_code status = mgblas_HFconvert(from, to, n); 75 | 76 | if (status != status_t::success) 77 | return status; 78 | else 79 | return outcome::success(); 80 | } 81 | 82 | template <> 83 | inline outcome::result mgblas_convert_copy(float const* from, 84 | __half* to, 85 | size_t n) { 86 | std::error_code status = mgblas_FHconvert(from, to, n); 87 | 88 | if (status != status_t::success) 89 | return status; 90 | else 91 | return outcome::success(); 92 | } 93 | #endif 94 | } // namespace mgcpp 95 | -------------------------------------------------------------------------------- /include/mgcpp/kernels/mgblas_lv1.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_KERNELS_MGBLAS_LV1_HPP_ 8 | #define _MGCPP_KERNELS_MGBLAS_LV1_HPP_ 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace mgcpp { 15 | /** 16 | * Hadamard product 17 | * \param x x 18 | * \param y y 19 | * \param z pointer to the result 20 | * \param n number of elements 21 | */ 22 | template 23 | inline outcome::result mgblas_vhp(T const* x, T const* y, T* z, size_t n); 24 | 25 | /** 26 | * Absolute value 27 | * \param x x 28 | * \param n number of elements 29 | */ 30 | template 31 | inline outcome::result mgblas_vab(T* x, size_t n); 32 | 33 | /** 34 | * Calculates the sum of all elements 35 | * \param x x 36 | * \param y result 37 | * \param n number of elements 38 | */ 39 | template 40 | inline outcome::result mgblas_vpr(T const* x, T* y, size_t n); 41 | 42 | template 43 | inline outcome::result mgblas_vsin(T* x, size_t n); 44 | 45 | template 46 | inline outcome::result mgblas_vcos(T* x, size_t n); 47 | 48 | template 49 | inline outcome::result mgblas_vtan(T* x, size_t n); 50 | 51 | template 52 | inline outcome::result mgblas_vsinh(T* x, size_t n); 53 | 54 | template 55 | inline outcome::result mgblas_vcosh(T* x, size_t n); 56 | 57 | template 58 | inline outcome::result mgblas_vtanh(T* x, size_t n); 59 | 60 | template 61 | inline outcome::result mgblas_vrelu(T* x, size_t n); 62 | } // namespace mgcpp 63 | 64 | #include 65 | #endif 66 | -------------------------------------------------------------------------------- /include/mgcpp/matrix/column_view.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_MATRIX_COLUMN_VIEW_HPP_ 8 | #define _MGCPP_MATRIX_COLUMN_VIEW_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace mgcpp { 18 | template 19 | class column_view : public dense_vector, Type> { 20 | public: 21 | using this_type = column_view; 22 | using value_type = Type; 23 | using result_type = this_type; 24 | using allocator_type = typename DenseMat::allocator_type; 25 | 26 | private: 27 | DenseMat* _matrix; 28 | size_t _column_idx; 29 | allocator_type _allocator; 30 | 31 | public: 32 | inline column_view() = delete; 33 | 34 | inline ~column_view() = default; 35 | 36 | inline column_view(dense_matrix& mat, size_t i) noexcept; 37 | 38 | inline column_view(column_view const& other) = delete; 39 | 40 | inline column_view(column_view&& other) noexcept; 41 | 42 | inline column_view& operator=( 43 | column_view const& other); 44 | 45 | inline column_view& operator=( 46 | column_view&& other) noexcept; 47 | 48 | inline column_view& operator=( 49 | std::initializer_list const& init); 50 | 51 | template 52 | inline column_view& operator=( 53 | dense_vector const& vec); 54 | 55 | inline void copy_to_host(Type* host_p) const; 56 | 57 | inline Type check_value(size_t i) const; 58 | 59 | inline Type const* data() const noexcept; 60 | 61 | inline Type* data_mutable() noexcept; 62 | 63 | inline thread_context* context() const noexcept; 64 | 65 | inline size_t shape() const noexcept; 66 | }; 67 | } // namespace mgcpp 68 | 69 | #include 70 | #endif 71 | -------------------------------------------------------------------------------- /include/mgcpp/matrix/dense_matrix.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_MATRIX_DENSE_MATRIX_HPP_ 8 | #define _MGCPP_MATRIX_DENSE_MATRIX_HPP_ 9 | 10 | #include 11 | #include 12 | 13 | namespace mgcpp { 14 | template 15 | class dense_matrix : public matrix_base { 16 | using result_type = DenseMatType; 17 | }; 18 | } // namespace mgcpp 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /include/mgcpp/matrix/forward.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_MATRIX_FORWARD_HPP_ 8 | #define _MGCPP_MATRIX_FORWARD_HPP_ 9 | 10 | #include 11 | 12 | namespace mgcpp { 13 | template 14 | class matrix; 15 | 16 | template 17 | class dense_matrix; 18 | 19 | template 20 | class device_matrix; 21 | } // namespace mgcpp 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/mgcpp/matrix/matrix_base.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_MATRIX_MATRIX_BASE_HPP_ 8 | #define _MGCPP_MATRIX_MATRIX_BASE_HPP_ 9 | 10 | #include 11 | 12 | namespace mgcpp { 13 | template 14 | struct matrix_base { 15 | inline MatrixType const& operator~() const noexcept; 16 | 17 | inline MatrixType& operator~() noexcept; 18 | }; 19 | } // namespace mgcpp 20 | 21 | #include 22 | #endif 23 | -------------------------------------------------------------------------------- /include/mgcpp/matrix/matrix_base.tpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | namespace mgcpp { 10 | template 11 | MatrixType const& matrix_base::operator~() const noexcept { 12 | return *static_cast(this); 13 | }; 14 | 15 | template 16 | MatrixType& matrix_base::operator~() noexcept { 17 | return *static_cast(this); 18 | }; 19 | } // namespace mgcpp 20 | -------------------------------------------------------------------------------- /include/mgcpp/matrix/row_view.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_MATRIX_ROW_VIEW_HPP_ 8 | #define _MGCPP_MATRIX_ROW_VIEW_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace mgcpp { 18 | // template 21 | // class row_view 22 | // : public dense_vector, 23 | // Type, 24 | // DeviceId> 25 | // { 26 | // public: 27 | // using this_type = row_view; 28 | // using value_type = Type; 29 | // using result_type = this_type; 30 | // using allocator_type = typename DenseMat::allocator_type; 31 | 32 | // private: 33 | // DenseMat* _matrix; 34 | // size_t _row_idx; 35 | // allocator_type _allocator; 36 | 37 | // public: 38 | // inline row_view() = delete; 39 | 40 | // inline ~row_view() = default; 41 | 42 | // inline 43 | // row_view(dense_matrix& mat, size_t i) noexcept; 44 | 45 | // inline 46 | // row_view(row_view const& other) = delete; 47 | 48 | // inline 49 | // row_view(row_view&& other) noexcept; 50 | 51 | // inline row_view& 52 | // operator=(row_view const& other); 53 | 54 | // inline row_view& 55 | // operator=(row_view&& other) noexcept; 56 | 57 | // inline row_view& 58 | // operator=(std::initializer_list const& init); 59 | 60 | // template 61 | // inline row_view& 62 | // operator=(dense_vector const& vec); 63 | 64 | // inline void 65 | // copy_to_host(Type* host_p) const; 66 | 67 | // inline Type 68 | // check_value(size_t i) const; 69 | 70 | // inline Type const* 71 | // data() const noexcept; 72 | 73 | // inline Type* 74 | // data_mutable() noexcept; 75 | 76 | // inline thread_context* 77 | // context() const noexcept; 78 | 79 | // inline size_t 80 | // shape() const noexcept; 81 | //}; 82 | } // namespace mgcpp 83 | 84 | //#include 85 | #endif 86 | -------------------------------------------------------------------------------- /include/mgcpp/mgcpp.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_MGCPP_HPP_ 8 | #define _MGCPP_MGCPP_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /include/mgcpp/operations/add.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_OPERATIONS_ADDITION_HPP_ 8 | #define _MGCPP_OPERATIONS_ADDITION_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace mgcpp { 18 | namespace strict { 19 | /** Adds two same-sized matrices together. 20 | * \param lhs the left-hand side 21 | * \param rhs the right-hand side 22 | */ 23 | template 24 | inline decltype(auto) add(dense_matrix const& lhs, 25 | dense_matrix const& rhs); 26 | 27 | /** Adds two same-sized vectors together. 28 | * \param first the left-hand side 29 | * \param second the right-hand side 30 | */ 31 | template 32 | inline decltype(auto) add(dense_vector const& first, 33 | dense_vector const& second); 34 | } // namespace strict 35 | } // namespace mgcpp 36 | 37 | #include 38 | #endif 39 | -------------------------------------------------------------------------------- /include/mgcpp/operations/add.tpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace mgcpp { 13 | template 14 | decltype(auto) strict::add(dense_matrix const& lhs, 15 | dense_matrix const& rhs) { 16 | using allocator_type = typename LhsDenseMat::allocator_type; 17 | using value_type = typename LhsDenseMat::value_type; 18 | 19 | auto const& lhs_mat = ~lhs; 20 | auto const& rhs_mat = ~rhs; 21 | 22 | MGCPP_ASSERT(lhs_mat.shape() == rhs_mat.shape(), 23 | "matrix dimensions didn't match"); 24 | 25 | auto device_id = lhs_mat.device_id(); 26 | auto set_device_status = cuda_set_device(device_id); 27 | if (!set_device_status) { 28 | MGCPP_THROW_SYSTEM_ERROR(set_device_status.error()); 29 | } 30 | 31 | auto* thread_context = lhs_mat.context(); 32 | auto handle = thread_context->get_cublas_context(device_id); 33 | 34 | auto shape = lhs_mat.shape(); 35 | 36 | size_t m = shape[0]; 37 | size_t n = shape[1]; 38 | 39 | value_type const alpha = 1; 40 | value_type const beta = 1; 41 | 42 | auto result = device_matrix({m, n}); 43 | auto status = cublas::geam(handle, CUBLAS_OP_N, CUBLAS_OP_N, m, n, &alpha, 44 | lhs_mat.data(), m, &beta, rhs_mat.data(), m, 45 | result.data_mutable(), m); 46 | if (!status) { 47 | MGCPP_THROW_SYSTEM_ERROR(status.error()); 48 | } 49 | 50 | return result; 51 | } 52 | 53 | template 54 | decltype(auto) strict::add(dense_vector const& lhs, 55 | dense_vector const& rhs) { 56 | using allocator_type = typename LhsDenseVec::allocator_type; 57 | using value_type = typename LhsDenseVec::value_type; 58 | 59 | auto const& lhs_vec = ~lhs; 60 | auto const& rhs_vec = ~rhs; 61 | 62 | MGCPP_ASSERT(lhs_vec.shape() == rhs_vec.shape(), "vector size didn't match"); 63 | 64 | auto device_id = lhs_vec.device_id(); 65 | auto set_device_status = cuda_set_device(device_id); 66 | if (!set_device_status) { 67 | MGCPP_THROW_SYSTEM_ERROR(set_device_status.error()); 68 | } 69 | 70 | auto* thread_context = lhs_vec.context(); 71 | auto handle = thread_context->get_cublas_context(device_id); 72 | 73 | auto size = lhs_vec.size(); 74 | 75 | value_type const alpha = 1; 76 | 77 | auto result = device_vector(lhs_vec); 78 | auto status = cublas::axpy(handle, size, &alpha, rhs_vec.data(), 1, 79 | result.data_mutable(), 1); 80 | if (!status) { 81 | MGCPP_THROW_SYSTEM_ERROR(status.error()); 82 | } 83 | 84 | return result; 85 | } 86 | } // namespace mgcpp 87 | -------------------------------------------------------------------------------- /include/mgcpp/operations/fft.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_OPERATIONS_FFT_HPP_ 8 | #define _MGCPP_OPERATIONS_FFT_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace mgcpp { 16 | /// FFT direction 17 | enum class fft_direction { 18 | /// Forward FFT. 19 | forward, 20 | /// Inverse FFT. 21 | inverse 22 | }; 23 | 24 | namespace strict { 25 | /** 26 | * Performs real-to-complex forward FFT. 27 | * \param vec the vector to perform the fft on. 28 | * \returns the FFT result. 29 | */ 30 | template 31 | inline decltype(auto) rfft(dense_vector const& vec); 32 | 33 | /** 34 | * Performs complex-to-real inverse normalized FFT. 35 | * \param vec the vector to perform the fft on. 36 | * \param n performs `((vec.size() - 1) * 2)` point inverse FFT if `n` equals 37 | * -1, otherwise performs an `n`-point inverse FFT. \returns the FFT result. 38 | */ 39 | template 40 | inline decltype(auto) irfft(dense_vector> const& vec, 41 | int n = -1); 42 | 43 | /** 44 | * Performs complex-to-complex FFT. 45 | * \param vec the vector to perform the fft on. 46 | * \param direction fft_direction::forward for forward fft, 47 | * fft_direction::inverse for inverse normalized fft. \returns the FFT result. 48 | */ 49 | template 50 | inline decltype(auto) cfft(dense_vector> const& vec, 51 | fft_direction direction); 52 | 53 | /** 54 | * Performs 2D real-to-complex forward FFT. 55 | * \param mat the matrix to perform the fft on. 56 | * \returns the FFT result. 57 | */ 58 | template 59 | inline decltype(auto) rfft(dense_matrix const& mat); 60 | 61 | /** 62 | * Performs 2D complex-to-real inverse normalized FFT. 63 | * \param mat the matrix to perform the fft on. 64 | * \param n the number of rows. if n == -1, the number is deduced from the size 65 | * of `mat`. \returns the FFT result. 66 | */ 67 | template 68 | inline decltype(auto) irfft(dense_matrix> const& mat, 69 | int n = -1); 70 | 71 | /** 72 | * Performs 2D complex-to-complex FFT. 73 | * \param mat the matrix to perform the fft on. 74 | * \param direction fft_direction::forward for forward fft, 75 | * fft_direction::inverse for inverse normalized fft. \returns the FFT result. 76 | */ 77 | template 78 | inline decltype(auto) cfft(dense_matrix> const& mat, 79 | fft_direction direction); 80 | } // namespace strict 81 | } // namespace mgcpp 82 | 83 | #include 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /include/mgcpp/operations/hdmd.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_OPERATIONS_HADAMARD_HPP_ 8 | #define _MGCPP_OPERATIONS_HADAMARD_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace mgcpp { 18 | namespace strict { 19 | /** 20 | * Element-wise multiplication of two equal-sized vectors. (Hadamard Product) 21 | * \param lhs left-hand side 22 | * \param rhs right-hand side 23 | * \returns the element-wise multiplication of lhs and rhs 24 | */ 25 | template 26 | inline decltype(auto) hdmd(dense_vector const& lhs, 27 | dense_vector const& rhs); 28 | } // namespace strict 29 | } // namespace mgcpp 30 | 31 | #include 32 | #endif 33 | -------------------------------------------------------------------------------- /include/mgcpp/operations/hdmd.tpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace mgcpp { 13 | template 14 | decltype(auto) strict::hdmd(dense_vector const& lhs, 15 | dense_vector const& rhs) { 16 | using allocator_type = typename LhsDenseVec::allocator_type; 17 | 18 | auto const& lhs_vec = ~lhs; 19 | auto const& rhs_vec = ~rhs; 20 | 21 | MGCPP_ASSERT(lhs_vec.shape() == rhs_vec.shape(), 22 | "matrix dimensions didn't match"); 23 | 24 | size_t size = lhs_vec.size(); 25 | 26 | auto result = device_vector(size); 27 | auto status = 28 | mgblas_vhp(lhs_vec.data(), rhs_vec.data(), result.data_mutable(), size); 29 | if (!status) { 30 | MGCPP_THROW_SYSTEM_ERROR(status.error()); 31 | } 32 | 33 | return result; 34 | } 35 | } // namespace mgcpp 36 | -------------------------------------------------------------------------------- /include/mgcpp/operations/mean.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_OPERATIONS_MEAN_HPP_ 8 | #define _MGCPP_OPERATIONS_MEAN_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace mgcpp { 18 | namespace strict { 19 | template 20 | inline decltype(auto) mean(dense_vector const& vec); 21 | 22 | template 23 | inline decltype(auto) mean(dense_matrix const& mat); 24 | } // namespace strict 25 | } // namespace mgcpp 26 | 27 | #include 28 | #endif 29 | -------------------------------------------------------------------------------- /include/mgcpp/operations/mean.tpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace mgcpp { 13 | template 14 | decltype(auto) strict::mean(dense_vector const& vec) { 15 | using value_type = typename DenseVec::value_type; 16 | 17 | auto const& original_vec = ~vec; 18 | 19 | auto device_id = original_vec.device_id(); 20 | auto set_device_status = cuda_set_device(device_id); 21 | if (!set_device_status) { 22 | MGCPP_THROW_SYSTEM_ERROR(set_device_status.error()); 23 | } 24 | 25 | size_t size = original_vec.size(); 26 | value_type result; 27 | 28 | auto status = mgblas_vpr(original_vec.data(), &result, size); 29 | if (!status) { 30 | MGCPP_THROW_SYSTEM_ERROR(status.error()); 31 | } 32 | 33 | return result / size; 34 | } 35 | 36 | template 37 | decltype(auto) strict::mean(dense_matrix const& mat) { 38 | using value_type = typename DenseMat::value_type; 39 | 40 | auto const& original_mat = ~mat; 41 | 42 | auto device_id = original_mat.device_id(); 43 | auto set_device_status = cuda_set_device(device_id); 44 | if (!set_device_status) { 45 | MGCPP_THROW_SYSTEM_ERROR(set_device_status.error()); 46 | } 47 | 48 | auto shape = original_mat.shape(); 49 | 50 | size_t total_size = shape[0] * shape[1]; 51 | value_type result; 52 | 53 | auto status = mgblas_vpr(original_mat.data(), &result, total_size); 54 | if (!status) { 55 | MGCPP_THROW_SYSTEM_ERROR(status.error()); 56 | } 57 | 58 | return result / total_size; 59 | } 60 | } // namespace mgcpp 61 | -------------------------------------------------------------------------------- /include/mgcpp/operations/mult.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_OPERATIONS_MULTIPLICATION_HPP_ 8 | #define _MGCPP_OPERATIONS_MULTIPLICATION_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | namespace mgcpp { 19 | namespace strict { 20 | /** 21 | * Matrix-matrix multiplication. 22 | * \param lhs left-hand side matrix 23 | * \param rhs right-hand side matrix 24 | * \returns lhs * rhs 25 | */ 26 | template 27 | inline decltype(auto) mult(dense_matrix const& lhs, 28 | dense_matrix const& rhs); 29 | 30 | // template 35 | // inline device_vector 37 | // mult(dense_vector const& first, 38 | // dense_vector const& second); 39 | 40 | /** 41 | * Matrix-vector multiplication. 42 | * If matrix is size (n x m), then vector's size must be m. 43 | * The resulting vector is of size n. 44 | * \param mat left-hand side matrix 45 | * \param vec right-hand side vector 46 | * \returns mat * vec 47 | */ 48 | template 49 | inline decltype(auto) mult(dense_matrix const& mat, 50 | dense_vector const& vec); 51 | 52 | /** 53 | * Scalar-vector multiplication. 54 | * \param scalar the scalar multiplier 55 | * \param vec vector to be multiplied by the scalar 56 | * \returns scalar * vec 57 | */ 58 | template < 59 | typename DenseVec, 60 | typename ScalarType, 61 | typename VectorType, 62 | typename = typename std::enable_if::value>::type> 63 | inline decltype(auto) mult(ScalarType scalar, 64 | dense_vector const& vec); 65 | 66 | /** 67 | * Scalar-matrix multiplication. 68 | * \param scalar the scalar multiplier 69 | * \param mat matrix to be multiplied by the scalar 70 | * \returns scalar * mat 71 | */ 72 | template < 73 | typename DenseMat, 74 | typename MatrixType, 75 | typename ScalarType, 76 | typename = typename std::enable_if::value>::type> 77 | inline decltype(auto) mult(ScalarType scalar, 78 | dense_matrix const& mat); 79 | 80 | // template 81 | // void 82 | // mult_assign(gpu::matrix& first, 83 | // gpu::matrix const& second); 84 | } // namespace strict 85 | } // namespace mgcpp 86 | 87 | #include 88 | #endif 89 | -------------------------------------------------------------------------------- /include/mgcpp/operations/outer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef OUTER_HPP 2 | #define OUTER_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace mgcpp { 8 | namespace strict { 9 | template 10 | inline decltype(auto) outer(dense_vector const& lhs, 11 | dense_vector const& rhs); 12 | } 13 | } // namespace mgcpp 14 | 15 | #include 16 | #endif // OUTER_HPP 17 | -------------------------------------------------------------------------------- /include/mgcpp/operations/outer.tpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace mgcpp { 7 | 8 | template 9 | inline decltype(auto) strict::outer( 10 | dense_vector const& lhs, 11 | dense_vector const& rhs) { 12 | using allocator_type = typename LhsDenseVec::allocator_type; 13 | 14 | auto* context = (~lhs).context(); 15 | auto handle = context->get_cublas_context((~lhs).device_id()); 16 | 17 | auto shape = mgcpp::make_shape((~lhs).size(), (~rhs).size()); 18 | 19 | device_matrix result(shape); 20 | 21 | const Type alpha = static_cast(1); 22 | 23 | auto status = 24 | cublas::ger(handle, shape[0], shape[1], &alpha, (~lhs).data(), 1, 25 | (~rhs).data(), 1, result.data_mutable(), shape[0]); 26 | if (!status) { 27 | MGCPP_THROW_SYSTEM_ERROR(status.error()); 28 | } 29 | 30 | return result; 31 | } 32 | } // namespace mgcpp 33 | -------------------------------------------------------------------------------- /include/mgcpp/operations/pad.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_OPERATIONS_PAD_HPP_ 8 | #define _MGCPP_OPERATIONS_PAD_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | namespace mgcpp { 19 | /// pad_size_t::first : pad before amount 20 | /// pad_size_t::second : pad after amount 21 | using pad_size_t = std::pair; 22 | 23 | namespace strict { 24 | /** 25 | * Applies padding to a vector. 26 | * \param vec the vector to be padded. 27 | * \param pad the padding size. 28 | * \param pad_constant the value of the padding cells. If not specified, the 29 | * default padding is zero. \return the padded result 30 | */ 31 | template 32 | inline decltype(auto) pad(dense_vector const& vec, 33 | pad_size_t pad, 34 | typename value_type::type pad_constant = 35 | typename value_type::type{}); 36 | } // namespace strict 37 | } // namespace mgcpp 38 | 39 | #include 40 | #endif 41 | -------------------------------------------------------------------------------- /include/mgcpp/operations/pad.tpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace mgcpp { 12 | template 13 | inline decltype(auto) strict::pad( 14 | dense_vector const& vec, 15 | pad_size_t pad, 16 | typename value_type::type pad_constant) { 17 | using allocator_type = typename DenseVec::allocator_type; 18 | 19 | auto dvec = ~vec; 20 | 21 | auto new_size = pad.first + dvec.size() + pad.second; 22 | 23 | if (pad.first == 0) { 24 | auto orig_size = dvec.size(); 25 | dvec.resize(new_size); 26 | 27 | if (pad.second > 0) { 28 | auto fill_result = mgblas_fill(dvec.data_mutable() + orig_size, 29 | pad_constant, pad.second); 30 | if (!fill_result) { 31 | MGCPP_THROW_SYSTEM_ERROR(fill_result.error()); 32 | } 33 | } 34 | 35 | return dvec; 36 | } else { 37 | auto result = device_vector(new_size, pad_constant); 38 | 39 | auto cpy_status = 40 | cuda_memcpy(result.data_mutable() + pad.first, dvec.data(), dvec.size(), 41 | cuda_memcpy_kind::device_to_device); 42 | if (!cpy_status) { 43 | MGCPP_THROW_SYSTEM_ERROR(cpy_status.error()); 44 | } 45 | 46 | if (pad.first > 0) { 47 | auto fill_result = 48 | mgblas_fill(result.data_mutable(), pad_constant, pad.first); 49 | if (!fill_result) { 50 | MGCPP_THROW_SYSTEM_ERROR(fill_result.error()); 51 | } 52 | } 53 | 54 | if (pad.second > 0) { 55 | auto fill_result = 56 | mgblas_fill(result.data_mutable() + pad.first + dvec.size(), 57 | pad_constant, pad.second); 58 | if (!fill_result) { 59 | MGCPP_THROW_SYSTEM_ERROR(fill_result.error()); 60 | } 61 | } 62 | 63 | return result; 64 | } 65 | } 66 | } // namespace mgcpp 67 | -------------------------------------------------------------------------------- /include/mgcpp/operations/sub.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_OPERATIONS_SUBSTRACTION_HPP_ 8 | #define _MGCPP_OPERATIONS_SUBSTRACTION_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace mgcpp { 18 | namespace strict { 19 | /** 20 | * Vector Subtraction. 21 | * \param lhs the left-hand side 22 | * \param rhs the right-hand side 23 | * \returns lhs - rhs 24 | */ 25 | template 26 | inline decltype(auto) sub(dense_vector const& lhs, 27 | dense_vector const& rhs); 28 | 29 | /** 30 | * Matrix Subtraction. 31 | * \param lhs the left-hand side 32 | * \param rhs the right-hand side 33 | * \returns lhs - rhs 34 | */ 35 | template 36 | inline decltype(auto) sub(dense_matrix const& lhs, 37 | dense_matrix const& rhs); 38 | } // namespace strict 39 | } // namespace mgcpp 40 | 41 | #include 42 | #endif 43 | -------------------------------------------------------------------------------- /include/mgcpp/operations/sub.tpp: -------------------------------------------------------------------------------- 1 | // Copyright RedPortal, mujjingun 2017 - 2018. 2 | // Distributed under the Boost Software License, Version 1.0. 3 | // (See accompanying file LICENSE or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace mgcpp { 11 | template 12 | decltype(auto) strict::sub(dense_vector const& lhs, 13 | dense_vector const& rhs) { 14 | using allocator_type = typename LhsDeviceVec::allocator_type; 15 | using value_type = typename LhsDeviceVec::value_type; 16 | 17 | auto const& lhs_vec = ~lhs; 18 | auto const& rhs_vec = ~rhs; 19 | 20 | MGCPP_ASSERT(lhs_vec.shape() == rhs_vec.shape(), 21 | "vector dimensions didn't match"); 22 | 23 | auto* thread_context = lhs_vec.context(); 24 | auto device_id = lhs_vec.device_id(); 25 | auto handle = thread_context->get_cublas_context(device_id); 26 | 27 | auto size = lhs_vec.size(); 28 | 29 | value_type const alpha = -1; 30 | 31 | auto result = device_vector(lhs_vec); 32 | auto status = cublas::axpy(handle, size, &alpha, rhs_vec.data(), 1, 33 | result.data_mutable(), 1); 34 | if (!status) { 35 | MGCPP_THROW_SYSTEM_ERROR(status.error()); 36 | } 37 | 38 | return result; 39 | } 40 | 41 | template 42 | decltype(auto) strict::sub(dense_matrix const& lhs, 43 | dense_matrix const& rhs) { 44 | using allocator_type = typename LhsDenseMat::allocator_type; 45 | using value_type = typename LhsDenseMat::value_type; 46 | 47 | auto const& lhs_mat = ~lhs; 48 | auto const& rhs_mat = ~rhs; 49 | 50 | MGCPP_ASSERT(lhs_mat.shape() == rhs_mat.shape(), 51 | "matrix dimensions didn't match"); 52 | 53 | auto set_device_status = cuda_set_device(lhs_mat.device_id()); 54 | if (!set_device_status) { 55 | MGCPP_THROW_SYSTEM_ERROR(set_device_status.error()); 56 | } 57 | 58 | auto* thread_context = lhs_mat.context(); 59 | auto device_id = lhs_mat.device_id(); 60 | auto handle = thread_context->get_cublas_context(device_id); 61 | 62 | auto shape = lhs_mat.shape(); 63 | 64 | size_t m = shape[0]; 65 | size_t n = shape[1]; 66 | 67 | value_type const alpha = 1; 68 | value_type const beta = -1; 69 | 70 | auto result = device_matrix({m, n}); 71 | 72 | auto status = cublas::geam(handle, CUBLAS_OP_N, CUBLAS_OP_N, m, n, &alpha, 73 | lhs_mat.data(), m, &beta, rhs_mat.data(), m, 74 | result.data_mutable(), m); 75 | 76 | if (!status) { 77 | MGCPP_THROW_SYSTEM_ERROR(status.error()); 78 | } 79 | 80 | return result; 81 | } 82 | } // namespace mgcpp 83 | -------------------------------------------------------------------------------- /include/mgcpp/operations/sum.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_OPERATIONS_SUM_HPP_ 8 | #define _MGCPP_OPERATIONS_SUM_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace mgcpp { 18 | namespace strict { 19 | template 20 | inline decltype(auto) sum(dense_vector const& vec); 21 | 22 | template 23 | inline decltype(auto) sum(dense_matrix const& mat); 24 | } // namespace strict 25 | } // namespace mgcpp 26 | 27 | #include 28 | #endif 29 | -------------------------------------------------------------------------------- /include/mgcpp/operations/sum.tpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace mgcpp { 16 | template 17 | decltype(auto) strict::sum(dense_vector const& vec) { 18 | using value_type = typename DenseVec::value_type; 19 | using device_pointer = typename DenseVec::device_pointer; 20 | 21 | auto const& original_vec = ~vec; 22 | 23 | auto device_id = original_vec.device_id(); 24 | auto set_device_status = cuda_set_device(device_id); 25 | if (!set_device_status) { 26 | MGCPP_THROW_SYSTEM_ERROR(set_device_status.error()); 27 | } 28 | 29 | size_t size = original_vec.size(); 30 | 31 | value_type result; 32 | auto status = 33 | mgblas_vpr(original_vec.data(), pun_cast(&result), size); 34 | if (!status) { 35 | MGCPP_THROW_SYSTEM_ERROR(status.error()); 36 | } 37 | 38 | return result; 39 | } 40 | 41 | template 42 | decltype(auto) strict::sum(dense_matrix const& mat) { 43 | using value_type = typename DenseMat::value_type; 44 | using device_pointer = typename DenseMat::device_pointer; 45 | 46 | auto const& original_mat = ~mat; 47 | 48 | auto device_id = original_mat.device_id(); 49 | auto set_device_status = cuda_set_device(device_id); 50 | if (!set_device_status) { 51 | MGCPP_THROW_SYSTEM_ERROR(set_device_status.error()); 52 | } 53 | 54 | auto shape = original_mat.shape(); 55 | 56 | value_type result; 57 | auto status = 58 | mgblas_vpr(original_mat.data(), pun_cast(&result), 59 | shape[0] * shape[1]); 60 | if (!status) { 61 | MGCPP_THROW_SYSTEM_ERROR(status.error()); 62 | } 63 | 64 | return result; 65 | } 66 | } // namespace mgcpp 67 | -------------------------------------------------------------------------------- /include/mgcpp/operations/trans.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_OPERATIONS_TRANS_HPP_ 8 | #define _MGCPP_OPERATIONS_TRANS_HPP_ 9 | 10 | #include 11 | 12 | namespace mgcpp { 13 | namespace strict { 14 | template 15 | decltype(auto) trans(dense_matrix const& mat); 16 | } 17 | } // namespace mgcpp 18 | 19 | #include 20 | #endif 21 | -------------------------------------------------------------------------------- /include/mgcpp/operations/trans.tpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace mgcpp { 12 | 13 | template 14 | decltype(auto) strict::trans(dense_matrix const& mat) { 15 | using allocator_type = typename DenseMat::allocator_type; 16 | 17 | auto const& dmat = ~mat; 18 | auto* context = dmat.context(); 19 | auto handle = context->get_cublas_context(dmat.device_id()); 20 | 21 | auto shape = dmat.shape(); 22 | 23 | auto m = shape[0]; 24 | auto n = shape[1]; 25 | 26 | Type alpha = 1; 27 | Type beta = 0; 28 | 29 | // switch places 30 | auto result = device_matrix({n, m}); 31 | 32 | Type* null = nullptr; 33 | auto status = 34 | cublas::geam(handle, CUBLAS_OP_T, CUBLAS_OP_N, n, m, &alpha, dmat.data(), 35 | m, &beta, null, n, result.data_mutable(), n); 36 | 37 | if (!status) 38 | MGCPP_THROW_SYSTEM_ERROR(status.error()); 39 | 40 | return result; 41 | } 42 | } // namespace mgcpp 43 | -------------------------------------------------------------------------------- /include/mgcpp/system/assert.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_SYSTEM_ASSERT_HPP_ 8 | #define _MGCPP_SYSTEM_ASSERT_HPP_ 9 | 10 | namespace mgcpp { 11 | inline bool ASSERT_MESSAGE(char const* message) { 12 | (void)message; 13 | return false; 14 | } 15 | } // namespace mgcpp 16 | 17 | #ifndef MGCPP_ASSERT 18 | #include 19 | #define MGCPP_ASSERT(EXPR, MESSAGE) \ 20 | assert((EXPR) || mgcpp::ASSERT_MESSAGE(MESSAGE)) 21 | #endif 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/mgcpp/system/concept.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_SYSTEM_CONCEPT_HPP_ 8 | #define _MGCPP_SYSTEM_CONCEPT_HPP_ 9 | 10 | #define MGCPP_CONCEPT(...) \ 11 | typename = typename std::enable_if<(__VA_ARGS__)>::type 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /include/mgcpp/system/cublas_error.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_SYSTEM_CUBLAS_ERROR_HPP_ 8 | #define _MGCPP_SYSTEM_CUBLAS_ERROR_HPP_ 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | namespace mgcpp { 17 | typedef cublasStatus_t cublas_error_t; 18 | } 19 | 20 | std::error_code make_error_code(mgcpp::cublas_error_t err) noexcept; 21 | 22 | namespace std { 23 | template <> 24 | struct is_error_code_enum : public std::true_type {}; 25 | } // namespace std 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/mgcpp/system/cuda_error.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_SYSTEM_CUDA_ERROR_HPP_ 8 | #define _MGCPP_SYSTEM_CUDA_ERROR_HPP_ 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | namespace mgcpp { 17 | typedef cudaError_t cuda_error_t; 18 | } 19 | 20 | std::error_code make_error_code(mgcpp::cuda_error_t err) noexcept; 21 | 22 | namespace std { 23 | template <> 24 | struct is_error_code_enum : public std::true_type {}; 25 | } // namespace std 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/mgcpp/system/cufft_error.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_SYSTEM_CUFFT_ERROR_HPP_ 8 | #define _MGCPP_SYSTEM_CUFFT_ERROR_HPP_ 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | namespace mgcpp { 17 | using cufft_error_t = cufftResult; 18 | } 19 | 20 | std::error_code make_error_code(mgcpp::cufft_error_t err) noexcept; 21 | 22 | namespace std { 23 | template <> 24 | struct is_error_code_enum : public std::true_type {}; 25 | } // namespace std 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/mgcpp/system/error_code.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_SYSTEM_ERROR_CODE_ 8 | #define _MGCPP_SYSTEM_ERROR_CODE_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace mgcpp { 20 | enum class status_t { success = 0 }; 21 | 22 | std::error_condition make_error_condition(mgcpp::status_t err) noexcept; 23 | } // namespace mgcpp 24 | 25 | namespace std { 26 | template <> 27 | struct is_error_condition_enum : public std::true_type {}; 28 | } // namespace std 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/mgcpp/system/exception.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_SYSTEM_EXCEPTIONS_HPP_ 8 | #define _MGCPP_SYSTEM_EXCEPTIONS_HPP_ 9 | 10 | #include 11 | 12 | #ifndef MGCPP_ABORT_ON_ERROR 13 | #define MGCPP_ABORT_ON_ERROR true 14 | #endif 15 | 16 | #ifndef MGCPP_ERROR_MESSAGE_HANDLER 17 | #define MGCPP_ERROR_MESSAGE_HANDLER(...) fprintf(stderr, __VA_ARGS__) 18 | #endif 19 | 20 | #ifndef mgcpp_error_check 21 | #define mgcpp_error_check(EXP) \ 22 | do { \ 23 | try { \ 24 | EXP; \ 25 | } catch (std::exception const& e) { \ 26 | MGCPP_ERROR_MESSAGE_HANDLER("[mgcpp errror] %s in %s line %d\n", \ 27 | e.what(), __FILE__, __LINE__); \ 28 | if (MGCPP_ABORT_ON_ERROR) \ 29 | exit(1); \ 30 | } \ 31 | } while (false) 32 | #endif 33 | 34 | #ifdef ERROR_CHECK_EXCEPTION 35 | #define MGCPP_THROW(EXCEPTION) \ 36 | do { \ 37 | MGCPP_ERROR_MESSAGE_HANDLER("[mgcpp errror] %s in %s line %d\n", \ 38 | EXCEPTION.what(), __FILE__, __LINE__); \ 39 | throw EXCEPTION; \ 40 | } while (false) 41 | #endif 42 | 43 | #ifndef MGCPP_THROW 44 | #define MGCPP_THROW(EXCEPTION) throw EXCEPTION 45 | #endif 46 | 47 | #ifndef MGCPP_THROW_SYSTEM_ERROR 48 | #define MGCPP_THROW_SYSTEM_ERROR(ERROR) MGCPP_THROW(std::system_error(ERROR)) 49 | #endif 50 | 51 | #ifndef MGCPP_THROW_BAD_ALLOC 52 | #define MGCPP_THROW_BAD_ALLOC MGCPP_THROW(std::bad_alloc()) 53 | #endif 54 | 55 | #ifndef MGCPP_THROW_INVALID_ARGUMENT 56 | #define MGCPP_THROW_INVALID_ARGUMENT(MESSAGE) \ 57 | MGCPP_THROW(std::invalid_argument(MESSAGE)) 58 | #endif 59 | 60 | #ifndef MGCPP_THROW_LENGTH_ERROR 61 | #define MGCPP_THROW_LENGTH_ERROR(MESSAGE) \ 62 | MGCPP_THROW(std::length_error(MESSAGE)) 63 | #endif 64 | 65 | #ifndef MGCPP_THROW_OUT_OF_RANGE 66 | #define MGCPP_THROW_OUT_OF_RANGE(MESSAGE) \ 67 | MGCPP_THROW(std::out_of_range(MESSAGE)) 68 | #endif 69 | 70 | #ifndef MGCPP_THROW_RUNTIME_ERROR 71 | #define MGCPP_THROW_RUNTIME_ERROR(MESSAGE) \ 72 | MGCPP_THROW(std::runtime_error(MESSAGE)) 73 | #endif 74 | 75 | #ifndef MGCPP_THROW_OVERFLOW_ERROR 76 | #define MGCPP_THROW_OVERFLOW_ERROR(MESSAGE) \ 77 | MGCPP_THROW(std::overflow_error(MESSAGE)) 78 | #endif 79 | 80 | #ifndef MGCPP_THROW_UNDERFLOW_ERROR 81 | #define MGCPP_THROW_UNDERFLOW_ERROR(MESSAGE) \ 82 | MGCPP_THROW(std::underflow_error(MESSAGE)) 83 | #endif 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /include/mgcpp/system/mgblas_error.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_SYSTEM_MGCPP_KERNEL_ERROR_HPP_ 8 | #define _MGCPP_SYSTEM_MGCPP_KERNEL_ERROR_HPP_ 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace mgcpp { 16 | std::error_code make_error_code(mgcpp::mgblas_error_t err) noexcept; 17 | } 18 | 19 | namespace std { 20 | template <> 21 | struct is_error_code_enum : public std::true_type {}; 22 | } // namespace std 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/mgcpp/system/outcome.hpp: -------------------------------------------------------------------------------- 1 | #ifndef OUTCOME_HPP 2 | #define OUTCOME_HPP 3 | 4 | #define BOOST_SYSTEM_NO_DEPRECATED 5 | #include 6 | namespace outcome { 7 | template 8 | using result = BOOST_OUTCOME_V2_NAMESPACE::std_result; 9 | template 10 | using outcome = BOOST_OUTCOME_V2_NAMESPACE::std_outcome; 11 | using BOOST_OUTCOME_V2_NAMESPACE::success; 12 | } // namespace outcome 13 | 14 | #endif // OUTCOME_HPP 15 | -------------------------------------------------------------------------------- /include/mgcpp/system/pun_cast.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_PUN_CAST_HPP_ 8 | #define _MGCPP_PUN_CAST_HPP_ 9 | 10 | #include 11 | 12 | namespace mgcpp { 13 | template 14 | inline To pun_cast(From const* from) { 15 | union pun_t { 16 | From src; 17 | typename std::remove_pointer::type dst; 18 | }; 19 | return &(reinterpret_cast(from))->dst; 20 | } 21 | 22 | template 23 | inline To pun_cast(From* from) { 24 | union pun_t { 25 | From src; 26 | typename std::remove_pointer::type dst; 27 | }; 28 | return &(reinterpret_cast(from))->dst; 29 | } 30 | } // namespace mgcpp 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /include/mgcpp/type_traits/device_value_type.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_TYPE_TRAITS_DEVICE_VALUE_TYPE_HPP_ 8 | #define _MGCPP_TYPE_TRAITS_DEVICE_VALUE_TYPE_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace mgcpp { 18 | template 19 | struct device_value_type { 20 | using type = Type; 21 | }; 22 | 23 | template <> 24 | struct device_value_type> { 25 | using type = cuComplex; 26 | }; 27 | 28 | template <> 29 | struct device_value_type> { 30 | using type = cuDoubleComplex; 31 | }; 32 | 33 | template <> 34 | struct device_value_type { 35 | using type = __half; 36 | }; 37 | } // namespace mgcpp 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /include/mgcpp/type_traits/host_value_type.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_TYPE_TRAITS_HOST_VALUE_TYPE_HPP_ 8 | #define _MGCPP_TYPE_TRAITS_HOST_VALUE_TYPE_HPP_ 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace mgcpp { 16 | template 17 | struct value_type { 18 | using type = Type; 19 | }; 20 | 21 | template 22 | struct value_type> { 23 | using type = std::complex; 24 | }; 25 | 26 | #ifdef USE_HALF 27 | template <> 28 | struct value_type { 29 | using type = float; 30 | }; 31 | #endif 32 | 33 | } // namespace mgcpp 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /include/mgcpp/type_traits/is_scalar.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_TYPE_TRAITS_IS_SCALAR_HPP_ 8 | #define _MGCPP_TYPE_TRAITS_IS_SCALAR_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace mgcpp { 15 | template 16 | struct is_scalar { 17 | static const bool value = 18 | std::is_arithmetic::value && !std::is_same::value && 19 | !std::is_same::value && !std::is_same::value && 20 | !std::is_same::value && !std::is_same::value && 21 | !std::is_same::value; 22 | }; 23 | 24 | template 25 | struct is_scalar> : std::true_type {}; 26 | 27 | #ifdef USE_HALF 28 | template <> 29 | struct is_scalar : std::true_type {}; 30 | #endif 31 | } // namespace mgcpp 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /include/mgcpp/type_traits/is_supported_type.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_TYPE_TRAITS_IS_SUPPORTED_TYPE_HPP_ 8 | #define _MGCPP_TYPE_TRAITS_IS_SUPPORTED_TYPE_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace mgcpp { 15 | template 16 | struct is_supported_type : std::false_type {}; 17 | 18 | template <> 19 | struct is_supported_type : std::true_type {}; 20 | 21 | template <> 22 | struct is_supported_type : std::true_type {}; 23 | 24 | template <> 25 | struct is_supported_type> : std::true_type {}; 26 | 27 | template <> 28 | struct is_supported_type> : std::true_type {}; 29 | 30 | #ifdef USE_HALF 31 | template <> 32 | struct is_supported_type : std::true_type {}; 33 | #endif 34 | } // namespace mgcpp 35 | #endif 36 | -------------------------------------------------------------------------------- /include/mgcpp/type_traits/mat_mat_mult_expr.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_TYPE_TRAITS_MAT_MAT_MULT_EXPR_HPP_ 8 | #define _MGCPP_TYPE_TRAITS_MAT_MAT_MULT_EXPR_HPP_ 9 | 10 | #include 11 | #include 12 | 13 | namespace mgcpp { 14 | template 15 | struct is_mat_mat_mult_expr : std::false_type {}; 16 | 17 | template 18 | struct is_mat_mat_mult_expr> 19 | : std::true_type {}; 20 | } // namespace mgcpp 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /include/mgcpp/type_traits/shape_type.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SHAPE_TYPE_HPP 2 | #define SHAPE_TYPE_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace mgcpp { 9 | 10 | template 11 | struct has_shape { 12 | private: 13 | typedef char one; 14 | typedef struct { 15 | char array[2]; 16 | } two; 17 | 18 | template 19 | static one test(typename C::shape_type*); 20 | template 21 | static two test(...); 22 | 23 | public: 24 | static const bool value = sizeof(test(0)) == sizeof(one); 25 | }; 26 | 27 | } // namespace mgcpp 28 | #endif // SHAPE_TYPE_HPP 29 | -------------------------------------------------------------------------------- /include/mgcpp/type_traits/trans_expr.hpp: -------------------------------------------------------------------------------- 1 | // Copyright RedPortal, mujjingun 2017 - 2018. 2 | // Distributed under the Boost Software License, Version 1.0. 3 | // (See accompanying file LICENSE or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | #ifndef _MGCPP_TYPE_TRAITS_TRANS_EXPR_HPP_ 7 | #define _MGCPP_TYPE_TRAITS_TRANS_EXPR_HPP_ 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace mgcpp { 17 | template 18 | struct is_mat_trans_expr : std::false_type {}; 19 | 20 | template )> 23 | struct is_mat_trans_expr> : std::true_type {}; 24 | 25 | template 26 | struct assert_mat_trans_expr { 27 | using result = typename std::enable_if< 28 | fold_or::value>::type; 29 | }; 30 | 31 | template 32 | struct assert_mat_trans_expr_t { 33 | using result = typename std:: 34 | enable_if::value, T>::type; 35 | }; 36 | 37 | template 38 | struct assert_mat_trans_expr { 39 | using result = 40 | typename std::enable_if::value>> ::type; 41 | }; 42 | 43 | } // namespace mgcpp 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /include/mgcpp/type_traits/type_traits.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_TYPE_TRAITS_TYPE_TRAITS_HPP_ 8 | #define _MGCPP_TYPE_TRAITS_TYPE_TRAITS_HPP_ 9 | 10 | static_assert(true, "remove this file"); 11 | 12 | namespace mgcpp { 13 | template 14 | using void_t = void; 15 | 16 | } // namespace mgcpp 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /include/mgcpp/vector/dense_vector.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_VECTOR_DENSE_VECTOR_HPP_ 8 | #define _MGCPP_VECTOR_DENSE_VECTOR_HPP_ 9 | 10 | #include 11 | #include 12 | 13 | namespace mgcpp { 14 | template 15 | class dense_vector : public vector_base {}; 16 | } // namespace mgcpp 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /include/mgcpp/vector/forward.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_VECTOR_FORWARD_HPP_ 8 | #define _MGCPP_VECTOR_FORWARD_HPP_ 9 | 10 | #include 11 | 12 | namespace mgcpp { 13 | template 14 | struct vector_base; 15 | 16 | template 17 | class dense_vector; 18 | 19 | template 20 | class device_vector; 21 | } // namespace mgcpp 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/mgcpp/vector/vector_base.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_VECTOR_VECTOR_BASE_HPP_ 8 | #define _MGCPP_VECTOR_VECTOR_BASE_HPP_ 9 | 10 | #include 11 | 12 | namespace mgcpp { 13 | template 14 | struct vector_base { 15 | inline VectorType const& operator~() const noexcept; 16 | 17 | inline VectorType& operator~() noexcept; 18 | }; 19 | } // namespace mgcpp 20 | 21 | #include 22 | #endif 23 | -------------------------------------------------------------------------------- /include/mgcpp/vector/vector_base.tpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | namespace mgcpp { 10 | template 11 | VectorType const& vector_base::operator~() const noexcept { 12 | return *static_cast(this); 13 | }; 14 | 15 | template 16 | VectorType& vector_base::operator~() noexcept { 17 | return *static_cast(this); 18 | }; 19 | } // namespace mgcpp 20 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | tornado==6.3.2 2 | requests 3 | PyGithub 4 | GitPython 5 | -------------------------------------------------------------------------------- /src/cublas_error.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace mgcpp { 12 | class cublas_error_category_t : public std::error_category { 13 | public: 14 | const char* name() const noexcept override; 15 | 16 | std::string message(int ev) const override; 17 | } cublas_error_category; 18 | 19 | const char* cublas_error_category_t::name() const noexcept { 20 | return "cublas"; 21 | } 22 | 23 | std::string cublas_error_category_t::message(int ev) const { 24 | switch (static_cast(ev)) { 25 | case CUBLAS_STATUS_SUCCESS: 26 | return "CUBLAS_STATUS_SUCCESS: Operation completed successfully"; 27 | break; 28 | 29 | case CUBLAS_STATUS_NOT_INITIALIZED: 30 | return "CUABLS_STATUS_NOT_INITIALIZED: The cuBLAS library was not " 31 | "initialized."; 32 | break; 33 | 34 | case CUBLAS_STATUS_ALLOC_FAILED: 35 | return "CUBLAS_STATUS_ALLOC_FAILED: Resource allocation failed inside " 36 | "the cuBLAS"; 37 | break; 38 | 39 | case CUBLAS_STATUS_INVALID_VALUE: 40 | return "CUBLAS_STATUS_INVALID_VALUE: An unsupported value or parameter " 41 | "was passed to"; 42 | break; 43 | 44 | case CUBLAS_STATUS_ARCH_MISMATCH: 45 | return "CUBLAS_STATUS_ARCH_MISMATCH: The function requires a feature " 46 | "absent from the device architecture"; 47 | break; 48 | 49 | case CUBLAS_STATUS_MAPPING_ERROR: 50 | return "CUBLAS_STATUS_MAPPING_ERROR: An access to GPU memory space " 51 | "failed"; 52 | break; 53 | 54 | case CUBLAS_STATUS_EXECUTION_FAILED: 55 | return "CUBLAS_STATUS_EXECUTION_FAILED: The GPU Program failed to " 56 | "execute."; 57 | break; 58 | 59 | case CUBLAS_STATUS_INTERNAL_ERROR: 60 | return "BLAS_STATUS_INTERNAL_ERROR: An internal cuBLAS operation failed"; 61 | break; 62 | 63 | #if CUDART_VERSION >= 6000 64 | case CUBLAS_STATUS_NOT_SUPPORTED: 65 | return "CUBLAS_STATUS_NOT_SUPPORTED: The operation is not supported by " 66 | "cublas."; 67 | break; 68 | #endif 69 | #if CUDART_VERSION >= 6500 70 | case CUBLAS_STATUS_LICENSE_ERROR: 71 | return "CUBLAS_STATUS_LICENSE_ERROR: The cuBlas license is not valid."; 72 | break; 73 | #endif 74 | } 75 | return ""; 76 | } 77 | } // namespace mgcpp 78 | 79 | std::error_code make_error_code(mgcpp::cublas_error_t err) noexcept { 80 | return {static_cast(err), mgcpp::cublas_error_category}; 81 | } 82 | -------------------------------------------------------------------------------- /src/cuda/device.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace mgcpp { 12 | outcome::result cuda_set_device(size_t device_id) noexcept { 13 | std::error_code err_code = cudaSetDevice(static_cast(device_id)); 14 | 15 | if (err_code != status_t::success) 16 | return err_code; 17 | 18 | return outcome::success(); 19 | } 20 | } // namespace mgcpp 21 | -------------------------------------------------------------------------------- /src/cuda_error.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace mgcpp { 12 | class cuda_error_category_t : public std::error_category { 13 | public: 14 | const char* name() const noexcept override; 15 | 16 | std::string message(int ev) const override; 17 | } cuda_error_category; 18 | 19 | const char* cuda_error_category_t::name() const noexcept { 20 | return "cuda"; 21 | } 22 | 23 | std::string cuda_error_category_t::message(int ev) const { 24 | return "internal cuda error: " + 25 | std::string(cudaGetErrorString(static_cast(ev))); 26 | } 27 | } // namespace mgcpp 28 | 29 | std::error_code make_error_code(mgcpp::cuda_error_t err) noexcept { 30 | return {static_cast(err), mgcpp::cuda_error_category}; 31 | } 32 | -------------------------------------------------------------------------------- /src/cudamalloc_resource.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace mgcpp { 6 | 7 | cudamalloc_resource::cudamalloc_resource(size_t device_id) 8 | : device_memory_resource(device_id) {} 9 | 10 | cudamalloc_resource* cudamalloc_resource::instance(size_t device_id) { 11 | static std::vector> resources([] { 12 | int device_number = 0; 13 | std::error_code status = cudaGetDeviceCount(&device_number); 14 | if (status != status_t::success) { 15 | MGCPP_THROW_SYSTEM_ERROR(status); 16 | } 17 | std::vector> vec; 18 | for (size_t i = 0; i < static_cast(device_number); ++i) { 19 | vec.emplace_back(new cudamalloc_resource(i)); 20 | } 21 | return vec; 22 | }()); 23 | 24 | if (device_id >= resources.size()) { 25 | MGCPP_THROW_OUT_OF_RANGE("Invalid device id."); 26 | } 27 | return resources[device_id].get(); 28 | } 29 | 30 | void* cudamalloc_resource::do_allocate(size_t bytes) { 31 | auto set_device_stat = cuda_set_device(device_id()); 32 | if (!set_device_stat) { 33 | MGCPP_THROW_SYSTEM_ERROR(set_device_stat.error()); 34 | } 35 | 36 | auto ptr = cuda_malloc(bytes); 37 | if (!ptr) { 38 | MGCPP_THROW_SYSTEM_ERROR(ptr.error()); 39 | } 40 | _allocated_bytes += bytes; 41 | return ptr.value(); 42 | } 43 | 44 | void cudamalloc_resource::do_deallocate(void* p, size_t bytes) { 45 | (void)bytes; 46 | auto set_device_stat = cuda_set_device(device_id()); 47 | if (!set_device_stat) { 48 | MGCPP_THROW_SYSTEM_ERROR(set_device_stat.error()); 49 | } 50 | 51 | auto free_stat = cuda_free(p); 52 | if (!p) { 53 | MGCPP_THROW_SYSTEM_ERROR(free_stat.error()); 54 | } 55 | 56 | _allocated_bytes -= bytes; 57 | } 58 | 59 | bool cudamalloc_resource::do_is_equal(const memory_resource& other) const 60 | noexcept { 61 | const cudamalloc_resource* other_p = 62 | dynamic_cast(&other); 63 | // compare if it has the same device id 64 | if (other_p) { 65 | return device_id() == other_p->device_id(); 66 | } else { 67 | return false; 68 | } 69 | } 70 | 71 | size_t cudamalloc_resource::allocated_bytes() const noexcept { 72 | return _allocated_bytes; 73 | } 74 | 75 | } // namespace mgcpp 76 | -------------------------------------------------------------------------------- /src/cufft_error.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | namespace mgcpp { 7 | class cufft_error_category_t : public std::error_category { 8 | public: 9 | const char* name() const noexcept override; 10 | 11 | std::string message(int ev) const override; 12 | } cufft_error_category; 13 | 14 | const char* cufft_error_category_t::name() const noexcept { 15 | return "cufft"; 16 | } 17 | 18 | std::string cufft_error_category_t::message(int ev) const { 19 | switch (static_cast(ev)) { 20 | case CUFFT_SUCCESS: 21 | return "CUFFT_SUCCESS: The cuFFT operation was successful."; 22 | 23 | case CUFFT_INVALID_PLAN: 24 | return "CUFFT_INVALID_PLAN: cuFFT was passed an invalid plan handle."; 25 | 26 | case CUFFT_ALLOC_FAILED: 27 | return "CUFFT_ALLOC_FAILED: cuFFT failed to allocate GPU or CPU memory"; 28 | 29 | case CUFFT_INVALID_TYPE: 30 | return "CUFFT_INVALID_TYPE: No longer used."; 31 | 32 | case CUFFT_INVALID_VALUE: 33 | return "CUFFT_INVALID_VALUE: User specified an invalid pointer or " 34 | "parameter."; 35 | 36 | case CUFFT_INTERNAL_ERROR: 37 | return "CUFFT_INTERNAL_ERROR: Driver or internal cuFFT library error."; 38 | 39 | case CUFFT_EXEC_FAILED: 40 | return "CUFFT_EXEC_FAILED: Failed to execute an FFT on the GPU."; 41 | 42 | case CUFFT_SETUP_FAILED: 43 | return "CUFFT_SETUP_FAILED: The cuFFT library failed to initialize."; 44 | 45 | case CUFFT_INVALID_SIZE: 46 | return "CUFFT_INVALID_SIZE: User specified an invalid transform size."; 47 | 48 | case CUFFT_UNALIGNED_DATA: 49 | return "CUFFT_UNALIGNED_DATA: No longer used."; 50 | 51 | case CUFFT_INCOMPLETE_PARAMETER_LIST: 52 | return "CUFFT_INCOMPLETE_PARAMETER_LIST: Missing parameters in call."; 53 | 54 | case CUFFT_INVALID_DEVICE: 55 | return "CUFFT_INVALID_DEVICE: Execution of a plan was on different GPU " 56 | "than plan creation."; 57 | 58 | case CUFFT_PARSE_ERROR: 59 | return "CUFFT_PARSE_ERROR: Internal plan database error."; 60 | 61 | case CUFFT_NO_WORKSPACE: 62 | return "CUFFT_NO_WORKSPACE: No workspace has been provided prior to plan " 63 | "execution."; 64 | 65 | case CUFFT_NOT_IMPLEMENTED: 66 | return "CUFFT_NOT_IMPLEMENTED: Function does not implement functionality " 67 | "for parameters given."; 68 | 69 | case CUFFT_LICENSE_ERROR: 70 | return "CUFFT_LICENSE_ERROR: Used in previous versions."; 71 | 72 | #if CUDART_VERSION >= 8000 // added in CUDA toolkit v8.0 73 | case CUFFT_NOT_SUPPORTED: 74 | return "CUFFT_NOT_SUPPORTED: Operation is not supported for parameters " 75 | "given."; 76 | #endif 77 | } 78 | return ""; 79 | } 80 | } // namespace mgcpp 81 | 82 | std::error_code make_error_code(mgcpp::cufft_error_t err) noexcept { 83 | return {static_cast(err), mgcpp::cufft_error_category}; 84 | } 85 | -------------------------------------------------------------------------------- /src/device_memory_resource.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace mgcpp { 4 | 5 | device_memory_resource::device_memory_resource(size_t device_id) 6 | : _device_id(device_id) {} 7 | 8 | size_t device_memory_resource::device_id() const { 9 | return _device_id; 10 | } 11 | 12 | } // namespace mgcpp 13 | -------------------------------------------------------------------------------- /src/error_code.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace mgcpp { 13 | class mgcpp_error_category_t : public std::error_category { 14 | public: 15 | const char* name() const noexcept override; 16 | 17 | std::string message(int ev) const override; 18 | 19 | bool equivalent(std::error_code const& err, int condition) const 20 | noexcept override; 21 | } mgcpp_error_category; 22 | 23 | const char* mgcpp_error_category_t::name() const noexcept { 24 | return "mgcpp"; 25 | } 26 | 27 | std::string mgcpp_error_category_t::message(int ev) const { 28 | switch (static_cast(ev)) { 29 | case status_t::success: 30 | return "successfully operated"; 31 | break; 32 | } 33 | return ""; 34 | } 35 | 36 | bool mgcpp_error_category_t::equivalent(std::error_code const& err, 37 | int condition) const noexcept { 38 | switch (static_cast(condition)) { 39 | case status_t::success: 40 | if (err == cublas_error_t::CUBLAS_STATUS_SUCCESS || 41 | err == cuda_error_t::cudaSuccess || 42 | err == cufft_error_t::CUFFT_SUCCESS || err == mgblas_error_t::success) 43 | return true; 44 | else 45 | return false; 46 | break; 47 | } 48 | return false; 49 | } 50 | 51 | std::error_condition make_error_condition(mgcpp::status_t err) noexcept { 52 | return {static_cast(err), mgcpp::mgcpp_error_category}; 53 | } 54 | } // namespace mgcpp 55 | -------------------------------------------------------------------------------- /src/eval_cache.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace mgcpp { 7 | 8 | struct eval_cache { 9 | size_t total_computations = 0; 10 | size_t cache_hits = 0; 11 | bool evaluating = false; 12 | std::unordered_map cnt; 13 | std::unordered_map map; 14 | }; 15 | 16 | eval_cache& get_eval_cache() { 17 | static thread_local eval_cache cache{}; 18 | return cache; 19 | } 20 | 21 | size_t get_last_run_cache_hits() { 22 | return get_eval_cache().cache_hits; 23 | } 24 | 25 | void analyze_graph(size_t id, std::function traverse) { 26 | auto& cache = get_eval_cache(); 27 | 28 | cache.cnt[id]++; 29 | 30 | // if cnt is bigger than 1, the subexpressions won't be evaluated 31 | if (cache.cnt[id] <= 1) { 32 | traverse(); 33 | } 34 | } 35 | 36 | namespace { 37 | struct cache_lock_guard { 38 | cache_lock_guard() { 39 | auto& cache = get_eval_cache(); 40 | cache.total_computations = 0; 41 | cache.cache_hits = 0; 42 | cache.evaluating = true; 43 | } 44 | ~cache_lock_guard() { 45 | auto& cache = get_eval_cache(); 46 | cache.evaluating = false; 47 | if (!std::uncaught_exception()) { 48 | MGCPP_ASSERT(cache.cnt.empty(), 49 | "Cache counter is not empty after evaluation"); 50 | MGCPP_ASSERT(cache.map.empty(), 51 | "Cache map is not empty after evaluation"); 52 | } 53 | } 54 | }; 55 | } // namespace 56 | 57 | static_any evaluate_if_needed(size_t id, 58 | bool needs_caching, 59 | std::function traverse, 60 | std::function evaluate) { 61 | auto& cache = get_eval_cache(); 62 | 63 | // traverse the tree first to count the number of duplicate subtrees 64 | if (!cache.evaluating) { 65 | traverse(); 66 | 67 | cache_lock_guard guard{}; 68 | 69 | return evaluate_if_needed(id, needs_caching, std::move(traverse), 70 | std::move(evaluate)); 71 | } 72 | 73 | cache.total_computations++; 74 | 75 | // try to find cache 76 | auto it = cache.map.find(id); 77 | 78 | // number of instances of this node left 79 | auto left = --cache.cnt.at(id); 80 | if (left == 0) { 81 | cache.cnt.erase(id); 82 | } 83 | 84 | // If cached, return the cache 85 | if (it != cache.map.end()) { 86 | cache.cache_hits++; 87 | auto cached = it->second; 88 | 89 | // Erase the cache for memory if it is no longer needed 90 | if (left == 0) { 91 | cache.map.erase(it); 92 | } 93 | 94 | return cached; 95 | } 96 | 97 | // If the same subexpression is shared by more than 1 nodes 98 | // and this is not a terminal node, cache 99 | if (needs_caching && left >= 1) { 100 | return cache.map[id] = evaluate(); 101 | } 102 | 103 | // No need to cache if the expression is not shared 104 | return evaluate(); 105 | } 106 | 107 | } // namespace mgcpp 108 | -------------------------------------------------------------------------------- /src/expression.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace mgcpp { 5 | size_t make_id() { 6 | static std::atomic counter(0); 7 | return counter.fetch_add(1); 8 | } 9 | } // namespace mgcpp 10 | -------------------------------------------------------------------------------- /src/global_context.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | namespace mgcpp { 10 | static global_context _singl_context{}; 11 | 12 | thread_context& global_context::get_thread_context() { 13 | auto this_thread_id = std::this_thread::get_id(); 14 | auto lck = std::unique_lock(_singl_context._mtx); 15 | ++_singl_context._context_ref_cnt[this_thread_id]; 16 | return _singl_context._thread_ctx[this_thread_id]; 17 | } 18 | 19 | void global_context::reference_cnt_decr() { 20 | auto this_thread_id = std::this_thread::get_id(); 21 | auto lck = std::unique_lock(_singl_context._mtx); 22 | auto ref = --_singl_context._context_ref_cnt[this_thread_id]; 23 | 24 | if (ref <= 0) 25 | _singl_context._thread_ctx.erase(this_thread_id); 26 | } 27 | } // namespace mgcpp 28 | -------------------------------------------------------------------------------- /src/init.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | 16 | namespace mgcpp { 17 | void init(bool print_system_info) { 18 | auto cuda_status = cuda_set_device(0); 19 | if (!cuda_status) { 20 | MGCPP_THROW_SYSTEM_ERROR(cuda_status.error()); 21 | } 22 | 23 | if (print_system_info) { 24 | const int kb = 1024; 25 | const int mb = kb * kb; 26 | 27 | std::cout << "CUDA version: " << CUDART_VERSION << std::endl; 28 | 29 | int devCount; 30 | std::error_code device_count_status = cudaGetDeviceCount(&devCount); 31 | if (device_count_status != status_t::success) { 32 | MGCPP_THROW_SYSTEM_ERROR(device_count_status); 33 | } 34 | 35 | std::cout << "Found " << devCount << " CUDA devices" << '\n' << std::endl; 36 | 37 | for (int i = 0; i < devCount; ++i) { 38 | cudaDeviceProp props; 39 | std::error_code property_status = cudaGetDeviceProperties(&props, i); 40 | if (property_status != status_t::success) { 41 | MGCPP_THROW_SYSTEM_ERROR(property_status); 42 | } 43 | 44 | std::cout << "[ Device " << i << " ]\n"; 45 | std::cout << "- " << props.name << ": " << props.major << "." 46 | << props.minor << '\n'; 47 | std::cout << "- Global Memory: " << props.totalGlobalMem / mb << "mb\n"; 48 | std::cout << "- Shared Memory: " << props.sharedMemPerBlock / kb 49 | << "kb\n"; 50 | std::cout << "- Constant Memory: " << props.totalConstMem / kb << "kb\n"; 51 | std::cout << "- Block Registers: " << props.regsPerBlock << '\n'; 52 | std::cout << std::endl; 53 | } 54 | } 55 | } 56 | } // namespace mgcpp 57 | -------------------------------------------------------------------------------- /src/kernels/convert.cu: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #define BLK 64 5 | 6 | namespace mgcpp 7 | { 8 | __global__ void 9 | mgblas_HFconvert_impl(__half const* from, float* to, size_t n) 10 | { 11 | int const id = blockIdx.x * blockDim.x + threadIdx.x; 12 | 13 | if(id >= n) 14 | return; 15 | 16 | to[id] = __half2float(from[id]); 17 | } 18 | 19 | __global__ void 20 | mgblas_FHconvert_impl(float const* from, __half* to, size_t n) 21 | { 22 | int const id = blockIdx.x * blockDim.x + threadIdx.x; 23 | 24 | if(id >= n) 25 | return; 26 | 27 | to[id] = __float2half(from[id]); 28 | } 29 | 30 | mgblas_error_t 31 | mgblas_HFconvert(__half const* from, float* to, size_t n) 32 | { 33 | int grid_size = static_cast( 34 | ceil(static_cast(n)/ BLK )); 35 | mgblas_HFconvert_impl<<>>(from, to, n); 36 | 37 | return success; 38 | } 39 | 40 | mgblas_error_t 41 | mgblas_FHconvert(float const* from, __half* to, size_t n) 42 | { 43 | int grid_size = static_cast( 44 | ceil(static_cast(n)/ BLK )); 45 | mgblas_FHconvert_impl<<>>(from, to, n); 46 | 47 | return success; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/kernels/map.cu: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | #define BLK 64 11 | 12 | namespace mgcpp 13 | { 14 | #define MGCPP_DEFINE_MAP_FUNCTION(fname, cudaname) \ 15 | __global__ void \ 16 | mgblas_S ## fname ## _impl(float* x, size_t n) \ 17 | { \ 18 | int const id = blockIdx.x * blockDim.x + threadIdx.x; \ 19 | if(id < n) \ 20 | x[id] = cudaname ## f(x[id]); \ 21 | } \ 22 | mgblas_error_t \ 23 | mgblas_S ## fname (float* x, size_t n) \ 24 | { \ 25 | if (n == 0) \ 26 | return invalid_range; \ 27 | int grid_size = \ 28 | static_cast( \ 29 | ceil(static_cast(n)/ BLK)); \ 30 | mgblas_S ## fname ##_impl<<>>(x, n); \ 31 | return success; \ 32 | } \ 33 | __global__ void \ 34 | mgblas_D ## fname ## _impl(double* x, size_t n) \ 35 | { \ 36 | int const id = blockIdx.x * blockDim.x + threadIdx.x; \ 37 | if(id < n) \ 38 | x[id] = cudaname(x[id]); \ 39 | } \ 40 | mgblas_error_t \ 41 | mgblas_D ## fname (double* x, size_t n) \ 42 | { \ 43 | if (n == 0) \ 44 | return invalid_range; \ 45 | int grid_size = \ 46 | static_cast( \ 47 | ceil(static_cast(n)/ BLK)); \ 48 | mgblas_D ## fname ##_impl<<>>(x, n); \ 49 | return success; \ 50 | } 51 | 52 | MGCPP_DEFINE_MAP_FUNCTION(vab, fabs) 53 | 54 | // define trig functions 55 | MGCPP_DEFINE_MAP_FUNCTION(vsin, sin) 56 | MGCPP_DEFINE_MAP_FUNCTION(vcos, cos) 57 | MGCPP_DEFINE_MAP_FUNCTION(vtan, tan) 58 | MGCPP_DEFINE_MAP_FUNCTION(vsinh, sinh) 59 | MGCPP_DEFINE_MAP_FUNCTION(vcosh, cosh) 60 | MGCPP_DEFINE_MAP_FUNCTION(vtanh, tanh) 61 | 62 | __device__ float reluf(float f) 63 | { 64 | return fmaxf(f, 0.f); 65 | } 66 | 67 | __device__ double relu(double f) 68 | { 69 | return fmax(f, 0.); 70 | } 71 | 72 | MGCPP_DEFINE_MAP_FUNCTION(vrelu, relu) 73 | 74 | #undef MGCPP_DEFINE_MAP_FUNCTION 75 | } 76 | -------------------------------------------------------------------------------- /src/mgblas_error.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | namespace mgcpp { 11 | class mgblas_error_category_t : public std::error_category { 12 | public: 13 | const char* name() const noexcept override; 14 | 15 | std::string message(int ev) const override; 16 | } mgblas_error_category; 17 | 18 | const char* mgblas_error_category_t::name() const noexcept { 19 | return "mgblas"; 20 | } 21 | 22 | std::string mgblas_error_category_t::message(int ev) const { 23 | switch (static_cast(ev)) { 24 | case success: 25 | return "Operation was executed without problem"; 26 | break; 27 | 28 | case index_out_of_range: 29 | return "requested operation range is incorrect"; 30 | break; 31 | 32 | case invalid_range: 33 | return "operation range is invalid"; 34 | break; 35 | 36 | case memory_allocation_failure: 37 | return "failed to allocate device memory"; 38 | break; 39 | 40 | case device_to_host_memcpy_failure: 41 | return "failed to copy memory from device to host"; 42 | break; 43 | } 44 | return ""; 45 | } 46 | 47 | std::error_code make_error_code(mgcpp::mgblas_error_t err) noexcept { 48 | return {static_cast(err), mgcpp::mgblas_error_category}; 49 | } 50 | } // namespace mgcpp 51 | -------------------------------------------------------------------------------- /src/new_delete_resource.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace mgcpp { 4 | 5 | void* new_delete_resource::do_allocate(size_t bytes) { 6 | return ::operator new(bytes); 7 | } 8 | 9 | void new_delete_resource::do_deallocate(void* p, size_t bytes) { 10 | (void)bytes; 11 | return ::operator delete(p); 12 | } 13 | 14 | bool new_delete_resource::do_is_equal(const memory_resource& other) const 15 | noexcept { 16 | (void)other; 17 | return true; 18 | } 19 | 20 | new_delete_resource* new_delete_resource::instance() { 21 | static new_delete_resource resource{}; 22 | return &resource; 23 | } 24 | 25 | } // namespace mgcpp 26 | -------------------------------------------------------------------------------- /src/thread_context.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace mgcpp { 13 | cublasHandle_t thread_context::get_cublas_context(size_t device_id) { 14 | auto& handle = _cublas_handle[device_id]; 15 | 16 | if (!handle) { 17 | auto set_device_stat = cuda_set_device(device_id); 18 | if (!set_device_stat) { 19 | MGCPP_THROW_SYSTEM_ERROR(set_device_stat.error()); 20 | } 21 | 22 | cublasHandle_t new_handle; 23 | 24 | std::error_code status = cublasCreate(&new_handle); 25 | if (status != status_t::success) { 26 | MGCPP_THROW_SYSTEM_ERROR(status); 27 | } 28 | 29 | handle = cublas_handle_unique_ptr( 30 | new_handle, [device_id](cublasHandle_t handle) { 31 | auto status = cuda_set_device(device_id); 32 | if (!status) { 33 | MGCPP_THROW_SYSTEM_ERROR(status.error()); 34 | } 35 | std::error_code destroy_status = cublasDestroy(handle); 36 | 37 | if (destroy_status != status_t::success) { 38 | MGCPP_THROW_SYSTEM_ERROR(destroy_status); 39 | } 40 | }); 41 | } 42 | 43 | return handle.get(); 44 | } 45 | 46 | thread_context::thread_context(thread_context&& other) noexcept 47 | : _cublas_handle(std::move(other._cublas_handle)) {} 48 | 49 | thread_context& thread_context::operator=(thread_context&& other) noexcept { 50 | _cublas_handle = std::move(other._cublas_handle); 51 | return *this; 52 | } 53 | } // namespace mgcpp 54 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | ## All these files will be deprecated! 3 | set(TEST_SOURCE_FILES 4 | ${TEST_DIR}/main.cpp 5 | ${TEST_DIR}/test_policy.cpp 6 | ${TEST_DIR}/memory_leak_detector.cpp 7 | ${TEST_DIR}/global_context_test.cpp 8 | ${TEST_DIR}/thread_context_test.cpp 9 | ${TEST_DIR}/cuda_exception_test.cpp 10 | ${TEST_DIR}/cuda_error_test.cpp 11 | ${TEST_DIR}/cuda_memory_test.cpp 12 | ${TEST_DIR}/device_allocators_test.cpp 13 | ${TEST_DIR}/mgblas_helpers_test.cpp 14 | ${TEST_DIR}/matrix_view_test.cpp 15 | ${TEST_DIR}/device_vector_test.cpp 16 | #${TEST_DIR}/type_trait_test.cpp 17 | ${TEST_DIR}/blaslv1_operation_test.cpp 18 | ${TEST_DIR}/blaslv3_operation_test.cpp 19 | ${TEST_DIR}/blaslv1_expression_test.cpp 20 | ${TEST_DIR}/blaslv3_expression_test.cpp 21 | ${TEST_DIR}/blaslv2_expression_test.cpp 22 | ${TEST_DIR}/gradient_test.cpp 23 | ) 24 | 25 | set(TEST_SOURCE_FILES 26 | ${TEST_SOURCE_FILES} 27 | ${TEST_DIR}/test_utils.cpp) 28 | 29 | # System Test 30 | set(SYSTEM_TEST_PATH ${TEST_DIR}/system) 31 | 32 | # Allocator Test 33 | set(ALLOCATOR_TEST_PATH ${TEST_DIR}/allocators) 34 | 35 | # Adapters Test 36 | set(ADAPTERS_TEST_PATH ${TEST_DIR}/adapters) 37 | 38 | # Context Test 39 | set(CONTEXT_TEST_PATH ${TEST_DIR}/context) 40 | 41 | # CUDA Test 42 | set(CUDA_TEST_PATH ${TEST_DIR}/cuda) 43 | 44 | # CUDA LIBS Test 45 | set(CUDA_LIBS_TEST_PATH ${TEST_DIR}/cuda_libs) 46 | 47 | # Matrix Test 48 | set(MATRIX_TEST_PATH ${TEST_DIR}/matrix) 49 | set(TEST_SOURCE_FILES 50 | ${TEST_SOURCE_FILES} 51 | ${MATRIX_TEST_PATH}/device_matrix_test.cpp) 52 | 53 | # Operations Test 54 | set(OPERATIONS_TEST_PATH ${TEST_DIR}/operations) 55 | 56 | # Expressions Test 57 | set(EXPRESSIONS_TEST_PATH ${TEST_DIR}/expressions) 58 | 59 | # Vector Test 60 | set(VECTOR_TEST_PATH ${TEST_DIR}/vector) 61 | 62 | # Operations Test 63 | set(OPERATIONS_TEST_PATH ${TEST_DIR}/operations) 64 | set(TEST_SOURCE_FILES 65 | ${TEST_SOURCE_FILES} 66 | ${OPERATIONS_TEST_PATH}/fft_test.cpp) 67 | 68 | # Kernels Test 69 | set(KERNELS_TEST_PATH ${TEST_DIR}/kernels) 70 | 71 | # Type Traits Test 72 | set(TYPE_TRAITS_TEST_PATH ${TEST_DIR}/type_traits) 73 | 74 | mgcpp_display_elements("Source files for ${PROJECT_NAME} tests" 75 | "${TEST_SOURCE_FILES}") 76 | 77 | # add test target 78 | add_executable(${PROJECT_NAME}_test ${TEST_SOURCE_FILES}) 79 | 80 | target_include_directories(${PROJECT_NAME}_test 81 | PUBLIC 82 | ${PROJECT_SOURCE_DIR}/include 83 | ${GTEST_INCLUDE_DIRS}) 84 | 85 | target_link_libraries(${PROJECT_NAME}_test 86 | ${PROJECT_NAME} 87 | ${GTEST_LIBRARIES}) 88 | 89 | set(TEST_BUILD_FLAGS ${BUILD_FLAGS}) 90 | 91 | message("Test C++ flags = ${TEST_BUILD_FLAGS}") 92 | 93 | set_target_properties(${PROJECT_NAME}_test 94 | PROPERTIES COMPILE_FLAGS "${TEST_BUILD_FLAGS}" 95 | CXX_STANDARD 14 96 | CXX_STANDARD_REQUIRED ON 97 | CXX_EXTENSIONS OFF) 98 | 99 | # ctest 100 | add_test(${PROJECT_NAME}_cmake_test ${PROJECT_NAME}_test) 101 | -------------------------------------------------------------------------------- /test/blaslv2_expression_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | TEST(lv2_expr, mat_vec_mult) { 12 | using matrix = mgcpp::device_matrix; 13 | using vector = mgcpp::device_vector; 14 | 15 | matrix M = matrix::from_list( 16 | {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}}); // (4, 3) 17 | vector v({1, 2, 3}); 18 | 19 | auto mult_expr = mgcpp::ref(M) * mgcpp::ref(v); 20 | 21 | vector result; 22 | EXPECT_NO_THROW({ result = eval(mult_expr); }); 23 | 24 | auto shape = result.size(); 25 | EXPECT_EQ(shape, 4); 26 | 27 | float expected[] = {14, 32, 50, 68}; 28 | for (size_t i = 0; i < shape; ++i) { 29 | EXPECT_EQ(result.check_value(i), expected[i]) << "i: " << i; 30 | } 31 | } 32 | 33 | TEST(lv2_expr, mat_reduce_sum) { 34 | using vector = mgcpp::device_vector; 35 | vector v({1, 2, 3}); 36 | 37 | auto sum = reduce_sum(ref(v)); 38 | auto val = eval(sum); 39 | 40 | EXPECT_FLOAT_EQ(val, 6); 41 | } 42 | 43 | TEST(lv2_expr, mat_reduce_mean) { 44 | using vector = mgcpp::device_vector; 45 | vector v({1, 2, 3}); 46 | 47 | auto sum = reduce_mean(ref(v)); 48 | auto val = eval(sum); 49 | 50 | EXPECT_FLOAT_EQ(val, 2); 51 | } 52 | -------------------------------------------------------------------------------- /test/cpu_matrix.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _CPU_MATRIX_HPP_ 2 | #define _CPU_MATRIX_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | inline size_t encode_index(size_t i, size_t j, size_t m) { 9 | return i + j * m; 10 | } 11 | 12 | template 13 | class cpu_matrix { 14 | private: 15 | size_t _m; 16 | size_t _n; 17 | T* _data; 18 | 19 | public: 20 | cpu_matrix(size_t m, size_t n) : _m(m), _n(n) { 21 | _data = (T*)malloc(sizeof(T) * _m * _n); 22 | } 23 | 24 | T& operator()(size_t i, size_t j) { return _data[encode_index(i, j, _m)]; } 25 | 26 | T* data() const { return _data; } 27 | 28 | mgcpp::shape<2> shape() const { return {_m, _n}; } 29 | 30 | ~cpu_matrix() { free(_data); } 31 | }; 32 | 33 | template 34 | class cpu_vector { 35 | private: 36 | size_t _m; 37 | T* _data; 38 | 39 | public: 40 | cpu_vector(size_t m) : _m(m) { _data = (T*)malloc(sizeof(T) * _m); } 41 | 42 | T& operator()(size_t i) { return _data[i]; } 43 | 44 | T* data() const { return _data; } 45 | 46 | size_t size() const { return _m; } 47 | 48 | mgcpp::shape<1> shape() const { return {_m}; } 49 | 50 | ~cpu_vector() { free(_data); } 51 | }; 52 | 53 | namespace mgcpp { 54 | template 55 | struct adapter> : std::true_type { 56 | void operator()(cpu_matrix const& mat, 57 | Type** out_p, 58 | size_t* m, 59 | size_t* n) { 60 | *out_p = mat.data(); 61 | auto shape = mat.shape(); 62 | *m = shape[0]; 63 | *n = shape[1]; 64 | } 65 | }; 66 | 67 | template 68 | struct adapter> : std::true_type { 69 | void operator()(cpu_vector const& vec, Type** out_p, size_t* m) { 70 | *out_p = vec.data(); 71 | *m = vec.size(); 72 | } 73 | }; 74 | 75 | // template 76 | // struct adapter> : std::true_type { 77 | // void operator()(std::vector const& vec, Type** out_p, size_t* m) { 78 | // *out_p = vec.data(); 79 | // *m = vec.size(); 80 | // } 81 | // }; 82 | 83 | } // namespace mgcpp 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /test/cuda_error_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | TEST(cuda_error, cuda_error_string_function) { 15 | using mgcpp::cuda_error_t; 16 | std::error_code err_code = cuda_error_t::cudaErrorMemoryAllocation; 17 | auto result = std::string(err_code.message()); 18 | auto answer = std::string("internal cuda error: out of memory"); 19 | 20 | ASSERT_EQ(result, answer); 21 | } 22 | -------------------------------------------------------------------------------- /test/cuda_exception_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | TEST(mgcpp_exception, mgcpp_error_check) { 15 | size_t free_memory = 0; 16 | cudaMemGetInfo(&free_memory, nullptr); 17 | 18 | EXPECT_EXIT( 19 | { 20 | mgcpp_error_check(auto rst = mgcpp::cuda_malloc(free_memory * 2); 21 | if (!rst) MGCPP_THROW_SYSTEM_ERROR(rst.error())); 22 | }, 23 | ::testing::ExitedWithCode(1), ""); 24 | } 25 | -------------------------------------------------------------------------------- /test/cuda_memory_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | TEST(cuda_malloc, cuda_malloc_success) { 12 | size_t free_memory_before_malloc = 0; 13 | cudaMemGetInfo(&free_memory_before_malloc, nullptr); 14 | 15 | auto rst = mgcpp::cuda_malloc(10); 16 | EXPECT_TRUE(bool(rst)); 17 | 18 | size_t free_memory_after_malloc = 0; 19 | cudaMemGetInfo(&free_memory_after_malloc, nullptr); 20 | 21 | EXPECT_GT(free_memory_before_malloc, free_memory_after_malloc); 22 | 23 | (void)mgcpp::cuda_free(rst.value()); 24 | } 25 | 26 | TEST(cuda_malloc, cuda_malloc_failure) { 27 | size_t free_memory = 0; 28 | cudaMemGetInfo(&free_memory, nullptr); 29 | 30 | auto ptr = mgcpp::cuda_malloc(free_memory * 2); 31 | EXPECT_FALSE(ptr); 32 | } 33 | 34 | TEST(cuda_free, cuda_free_success) { 35 | size_t free_memory_before_malloc = 0; 36 | cudaMemGetInfo(&free_memory_before_malloc, nullptr); 37 | 38 | auto result = mgcpp::cuda_malloc(10); 39 | ; 40 | EXPECT_TRUE(bool(result)); 41 | 42 | size_t free_memory_after_malloc = 0; 43 | cudaMemGetInfo(&free_memory_after_malloc, nullptr); 44 | 45 | EXPECT_GT(free_memory_before_malloc, free_memory_after_malloc); 46 | 47 | auto free_result = mgcpp::cuda_free(result.value()); 48 | EXPECT_TRUE(bool(free_result)); 49 | 50 | size_t free_memory_after_free = 0; 51 | cudaMemGetInfo(&free_memory_after_free, nullptr); 52 | 53 | EXPECT_EQ(free_memory_after_free, free_memory_before_malloc); 54 | } 55 | 56 | TEST(cuda_free, cuda_free_failure) { 57 | float* ptr = (float*)10u; 58 | auto result = mgcpp::cuda_free(ptr); 59 | EXPECT_FALSE(result); 60 | } 61 | 62 | TEST(cuda_memcpy, memcpy_to_and_from_host) { 63 | size_t size = 1; 64 | auto device = mgcpp::cuda_malloc(size); 65 | float host = 7; 66 | 67 | host = 7; 68 | auto to_device_stat = mgcpp::cuda_memcpy( 69 | device.value(), &host, size, mgcpp::cuda_memcpy_kind::host_to_device); 70 | EXPECT_TRUE(bool(to_device_stat)); 71 | 72 | host = 0; 73 | auto to_host_stat = mgcpp::cuda_memcpy( 74 | &host, device.value(), size, mgcpp::cuda_memcpy_kind::device_to_host); 75 | EXPECT_TRUE(bool(to_host_stat)); 76 | 77 | EXPECT_EQ(host, 7); 78 | (void)mgcpp::cuda_free(device.value()); 79 | } 80 | 81 | TEST(cuda_memset, memset_to_zero) { 82 | size_t size = 1; 83 | auto memory = mgcpp::cuda_malloc(size); 84 | 85 | float host = 7; 86 | 87 | auto to_device_stat = mgcpp::cuda_memcpy( 88 | memory.value(), &host, size, mgcpp::cuda_memcpy_kind::host_to_device); 89 | EXPECT_TRUE(bool(to_device_stat)); 90 | 91 | auto status = mgcpp::cuda_memset_to_zero(memory.value(), size); 92 | EXPECT_TRUE(bool(status)); 93 | 94 | host = 7; 95 | auto to_host_stat = mgcpp::cuda_memcpy( 96 | &host, memory.value(), size, mgcpp::cuda_memcpy_kind::device_to_host); 97 | EXPECT_TRUE(bool(to_host_stat)); 98 | EXPECT_EQ(host, 0); 99 | 100 | (void)mgcpp::cuda_free(memory.value()); 101 | } 102 | -------------------------------------------------------------------------------- /test/device_allocators_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | TEST(default_allocator, device_allocation_and_deallocation) { 14 | auto stat = mgcpp::cuda_set_device(0); 15 | EXPECT_TRUE(bool(stat)); 16 | 17 | auto mem_info = mgcpp::cuda_mem_get_info(); 18 | size_t before_memory = mem_info.value().first; 19 | 20 | mgcpp::allocator allocator{}; 21 | 22 | float* ptr = nullptr; 23 | EXPECT_NO_THROW({ ptr = allocator.allocate_device(10); }); 24 | EXPECT_NE(ptr, nullptr); 25 | 26 | mem_info = mgcpp::cuda_mem_get_info(); 27 | size_t after_memory = mem_info.value().first; 28 | 29 | EXPECT_GT(before_memory, after_memory); 30 | 31 | EXPECT_NO_THROW({ allocator.deallocate_device(ptr, 10); }); 32 | 33 | mem_info = mgcpp::cuda_mem_get_info(); 34 | size_t final_memory = mem_info.value().first; 35 | 36 | EXPECT_EQ(before_memory, final_memory); 37 | } 38 | 39 | TEST(default_allocator, copy_to_and_from_host) { 40 | auto stat = mgcpp::cuda_set_device(0); 41 | EXPECT_TRUE(bool(stat)); 42 | 43 | mgcpp::allocator allocator{}; 44 | 45 | size_t size = 10; 46 | 47 | float* host = allocator.allocate_host(size); 48 | float* device = allocator.allocate_device(size); 49 | 50 | *host = 10; 51 | 52 | EXPECT_NO_THROW({ allocator.copy_from_host(device, host, size); }); 53 | EXPECT_NO_THROW({ allocator.copy_to_host(host, device, size); }); 54 | 55 | EXPECT_EQ(*host, 10); 56 | 57 | allocator.deallocate_host(host, size); 58 | allocator.deallocate_device(device, size); 59 | } 60 | -------------------------------------------------------------------------------- /test/fft_test.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MGfoundation/mgcpp/a14ff0d6d6a9ece200b7b7aaa14b90b5486510ac/test/fft_test.cpp -------------------------------------------------------------------------------- /test/global_context_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | #include 12 | 13 | TEST(global_context, request_context_from_same_thread) { 14 | auto* context_one = &mgcpp::global_context::get_thread_context(); 15 | auto* context_two = &mgcpp::global_context::get_thread_context(); 16 | 17 | EXPECT_EQ(context_one, context_two); 18 | 19 | mgcpp::global_context::reference_cnt_decr(); 20 | mgcpp::global_context::reference_cnt_decr(); 21 | } 22 | 23 | TEST(global_context, request_context_from_different_thread) { 24 | auto* context_one = &mgcpp::global_context::get_thread_context(); 25 | 26 | mgcpp::thread_context* context_two; 27 | auto thread = std::thread([&context_two, &context_one]() { 28 | context_two = &mgcpp::global_context::get_thread_context(); 29 | 30 | EXPECT_NE(context_one, context_two); 31 | 32 | mgcpp::global_context::reference_cnt_decr(); 33 | }); 34 | 35 | thread.join(); 36 | mgcpp::global_context::reference_cnt_decr(); 37 | } 38 | -------------------------------------------------------------------------------- /test/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "memory_leak_detector.hpp" 12 | 13 | int main(int argc, char* argv[]) { 14 | ::testing::InitGoogleTest(&argc, argv); 15 | 16 | ::testing::UnitTest::GetInstance()->listeners().Append( 17 | new mgcpp::memory_leak_detector()); 18 | 19 | mgcpp::init(true); 20 | 21 | return RUN_ALL_TESTS(); 22 | } 23 | -------------------------------------------------------------------------------- /test/memory_leak_detector.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include "memory_leak_detector.hpp" 15 | #include "test_policy.hpp" 16 | 17 | namespace mgcpp { 18 | void memory_leak_detector::OnTestStart(::testing::TestInfo const& test_info) { 19 | (void)cuda_set_device(0); 20 | 21 | if (!test_policy::get_policy().detect_memory_leak()) 22 | return; 23 | 24 | if (test_info.name() == std::string("thread_context")) 25 | return; 26 | 27 | auto device_number = test_policy::get_policy().device_num(); 28 | 29 | device_free_memory.clear(); 30 | device_free_memory.reserve(device_number); 31 | 32 | for (auto i = 0u; i < device_number; ++i) { 33 | (void)cuda_set_device(i); 34 | 35 | auto memstat = cuda_mem_get_info(); 36 | EXPECT_TRUE(bool(memstat)) 37 | << "error occurred while getting memory of device " << i << '\n' 38 | << memstat.error() << "in start of test " << test_info.name(); 39 | 40 | device_free_memory.push_back(memstat.value().first); 41 | } 42 | } 43 | 44 | void memory_leak_detector::OnTestEnd(::testing::TestInfo const& test_info) { 45 | (void)cuda_set_device(0); 46 | 47 | if (!test_policy::get_policy().detect_memory_leak()) 48 | return; 49 | 50 | if (test_info.test_case_name() == std::string("thread_context")) 51 | return; 52 | 53 | auto device_number = test_policy::get_policy().device_num(); 54 | for (auto i = 0u; i < device_number; ++i) { 55 | (void)cuda_set_device(i); 56 | 57 | auto memstat = cuda_mem_get_info(); 58 | 59 | EXPECT_TRUE(bool(memstat)) 60 | << "error while getting memory info of device " << i << '\n' 61 | << "in test " << test_info.name(); 62 | 63 | size_t result_memory = memstat.value().first; 64 | EXPECT_EQ(result_memory, device_free_memory[i]) 65 | << "memory leak detected in test " << test_info.name() << '\n' 66 | << "for device " << i << '\n'; 67 | } 68 | } 69 | } // namespace mgcpp 70 | -------------------------------------------------------------------------------- /test/memory_leak_detector.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_TEST_MEMORY_LEAK_DETECTOR_HPP_ 8 | #define _MGCPP_TEST_MEMORY_LEAK_DETECTOR_HPP_ 9 | 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace mgcpp { 18 | class memory_leak_detector : public ::testing::EmptyTestEventListener { 19 | std::vector device_free_memory; 20 | 21 | void OnTestStart(::testing::TestInfo const& test_info) override; 22 | 23 | void OnTestEnd(::testing::TestInfo const& test_info) override; 24 | }; 25 | } // namespace mgcpp 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /test/mgblas_helpers_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | TEST(mgblas_helpers, array_init) { 15 | auto stat = mgcpp::cuda_set_device(0); 16 | EXPECT_TRUE(bool(stat)); 17 | 18 | size_t size = 20; 19 | float value = 7; 20 | 21 | auto rst = mgcpp::cuda_malloc(size); 22 | auto status = mgcpp::mgblas_fill(rst.value(), value, size); 23 | EXPECT_TRUE(bool(status)) << status.error(); 24 | 25 | float* host = (float*)malloc(sizeof(float) * size); 26 | 27 | (void)mgcpp::cuda_memcpy(host, rst.value(), size, 28 | mgcpp::cuda_memcpy_kind::device_to_host); 29 | 30 | for (auto i = 0u; i < size; ++i) { 31 | EXPECT_EQ(host[i], value); 32 | } 33 | 34 | free(host); 35 | (void)mgcpp::cuda_free(rst.value()); 36 | } 37 | -------------------------------------------------------------------------------- /test/mgcpp_test.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_TEST_MGCPP_TEST_HPP_ 8 | #define _MGCPP_TEST_MGCPP_TEST_HPP_ 9 | 10 | #include 11 | 12 | #define MGCPP_TEST(FIXTURE, TEST_NAME) \ 13 | TEST_F(FIXTURE, TEST_NAME) { TEST_NAME(); } 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /test/test_policy.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include "test_policy.hpp" 12 | 13 | namespace mgcpp { 14 | test_policy& test_policy::get_policy() { 15 | static test_policy _policy; 16 | return _policy; 17 | } 18 | 19 | test_policy::test_policy() { 20 | int device_number = 0; 21 | std::error_code status = cudaGetDeviceCount(&device_number); 22 | if (status != status_t::success) 23 | MGCPP_THROW_SYSTEM_ERROR(status); 24 | 25 | _device_num = static_cast(device_number); 26 | _detect_memory_leak = true; 27 | } 28 | 29 | size_t test_policy::device_num() const noexcept { 30 | return _device_num; 31 | } 32 | 33 | bool test_policy::detect_memory_leak() const noexcept { 34 | return _detect_memory_leak; 35 | } 36 | } // namespace mgcpp 37 | -------------------------------------------------------------------------------- /test/test_policy.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_TEST_TEST_POLICY_HPP_ 8 | #define _MGCPP_TEST_TEST_POLICY_HPP_ 9 | 10 | namespace mgcpp { 11 | class test_policy { 12 | test_policy(); 13 | 14 | size_t _device_num; 15 | bool _detect_memory_leak; 16 | 17 | public: 18 | static test_policy& get_policy(); 19 | 20 | size_t device_num() const noexcept; 21 | 22 | bool detect_memory_leak() const noexcept; 23 | }; 24 | } // namespace mgcpp 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /test/test_utils.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include "test_utils.hpp" 8 | #include 9 | 10 | // https://github.com/s9w/articles/blob/master/perf%20cpp%20random.md 11 | // according to this benchmark, boost mt is the fastest 12 | // but anything fast will just be fine 13 | boost::random::mt19937 rng(MGCPP_RAND_SEED); 14 | std::normal_distribution normal(0.0, 1.0); 15 | std::uniform_real_distribution uniform(-1.0, 1.0); 16 | 17 | namespace internal { 18 | double uniform_rand() { 19 | return uniform(rng); 20 | } 21 | 22 | double normal_rand() { 23 | return normal(rng); 24 | } 25 | } // namespace internal 26 | -------------------------------------------------------------------------------- /test/test_utils.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef _MGCPP_TEST_TEST_UTILS_HPP_ 8 | #define _MGCPP_TEST_TEST_UTILS_HPP_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "cpu_matrix.hpp" 20 | 21 | #define MGCPP_RAND_SEED 1 22 | 23 | namespace internal { 24 | double uniform_rand(); 25 | double normal_rand(); 26 | } // namespace internal 27 | 28 | template 29 | struct complex_value_type; 30 | 31 | template 32 | struct complex_value_type> { 33 | using type = Type; 34 | }; 35 | 36 | template 37 | void random_fill_impl(Iter begin, Iter end) { 38 | for (Iter it = begin; it != end; ++it) 39 | *it = internal::normal_rand(); 40 | } 41 | 42 | template ::type> 45 | void random_fill_impl(Iter begin, Iter end) { 46 | using value_type = typename complex_value_type::type; 47 | for (Iter it = begin; it != end; ++it) 48 | *it = std::complex(internal::normal_rand(), 49 | internal::normal_rand()); 50 | } 51 | 52 | template 53 | void random_fill(Iter begin, Iter end) { 54 | using value_type = decltype(*begin); 55 | random_fill_impl(begin, end); 56 | } 57 | 58 | template 59 | void random_matrix(Type& mat) { 60 | using value_type = typename Type::value_type; 61 | auto shape = mat.shape(); 62 | auto size = shape[0] * shape[1]; 63 | cpu_matrix buf(shape[0], shape[1]); 64 | auto* ptr = buf.data(); 65 | random_fill(ptr, ptr + size); 66 | mat = Type(buf); 67 | } 68 | 69 | template 70 | void random_vector(Type& vec) { 71 | using value_type = typename Type::value_type; 72 | auto size = vec.size(); 73 | cpu_vector buf(size); 74 | auto* ptr = buf.data(); 75 | random_fill(ptr, ptr + size); 76 | vec = Type(buf); 77 | } 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /test/thread_context_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include "test_policy.hpp" 11 | 12 | #include 13 | 14 | TEST(thread_context, request_cublas_handle) { 15 | auto* context = &mgcpp::global_context::get_thread_context(); 16 | 17 | auto cublas_context_one = context->get_cublas_context(0); 18 | auto cublas_context_two = context->get_cublas_context(0); 19 | 20 | EXPECT_EQ(cublas_context_one, cublas_context_two); 21 | 22 | mgcpp::global_context::reference_cnt_decr(); 23 | } 24 | 25 | TEST(thread_context, request_cublas_handle_different_device) { 26 | if (mgcpp::test_policy::get_policy().device_num() >= 2) { 27 | auto* context = &mgcpp::global_context::get_thread_context(); 28 | 29 | auto cublas_context_one = context->get_cublas_context(0); 30 | auto cublas_context_two = context->get_cublas_context(1); 31 | 32 | EXPECT_NE(cublas_context_one, cublas_context_two); 33 | 34 | mgcpp::global_context::reference_cnt_decr(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test/type_trait_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright RedPortal, mujjingun 2017 - 2018. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | TEST(mat_mat_expr_trait, is_same_gpu_matrix_success) { 13 | using FirstMat = mgcpp::gpu::matrix; 14 | using SecondMat = mgcpp::gpu::matrix; 15 | bool is_same_gpu_matrix = 16 | mgcpp::is_same_gpu_matrix::value; 17 | 18 | EXPECT_TRUE(is_same_gpu_matrix); 19 | } 20 | 21 | TEST(mat_mat_expr_trait, is_same_gpu_matrix_fail) { 22 | using FirstMat = mgcpp::gpu::matrix; 23 | using SecondMat = mgcpp::gpu::matrix; 24 | 25 | bool is_same_gpu_matrix = 26 | mgcpp::is_same_gpu_matrix::value; 27 | 28 | EXPECT_FALSE(is_same_gpu_matrix); 29 | } 30 | 31 | TEST(gpu_matrix_trait, is_gpu_matrix_success) { 32 | using mat = mgcpp::gpu::matrix; 33 | 34 | bool is_gpu_matrix = mgcpp::is_gpu_matrix::value; 35 | EXPECT_TRUE(is_gpu_matrix); 36 | } 37 | 38 | TEST(gpu_matrix_trait, is_gpu_matrix_cv_success) { 39 | using mat = mgcpp::gpu::matrix; 40 | 41 | bool gpu_matrix = mgcpp::is_gpu_matrix::value; 42 | EXPECT_TRUE(gpu_matrix); 43 | 44 | bool gpu_matrix_ref = mgcpp::is_gpu_matrix::type>::value; 45 | EXPECT_TRUE(gpu_matrix_ref); 46 | 47 | bool gpu_matrix_const_ref = 48 | mgcpp::is_gpu_matrix::type>::value; 49 | EXPECT_TRUE(gpu_matrix_const_ref); 50 | } 51 | 52 | TEST(gpu_matrix_trait, is_gpu_matrix_fail) { 53 | using mat = mgcpp::cpu::matrix; 54 | 55 | bool is_gpu_matrix = mgcpp::is_gpu_matrix::value; 56 | EXPECT_FALSE(is_gpu_matrix); 57 | } 58 | --------------------------------------------------------------------------------