<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 3.7 檢測Eigen庫 **NOTE**:*此示例代碼可以在 https://github.com/dev-cafe/cmake-cookbook/tree/v1.0/chapter-03/recipe-07 中找到,包含一個C++的示例。該示例在CMake 3.9版(或更高版本)中是有效的,并且已經在GNU/Linux、macOS和Windows上進行過測試。https://github.com/dev-cafe/cmake-cookbook/tree/v1.0/chapter-03/recipe-06 中也有一個適用于CMake 3.5的C++示例。* BLAS庫為矩陣和向量操作提供了標準化接口。不過,這個接口用Fortran語言書寫。雖然已經展示了如何使用C++直接使用這些庫,但在現代C++程序中,希望有更高級的接口。 純頭文件實現的Eigen庫,使用模板編程來提供接口。矩陣和向量的計算,會在編譯時進行數據類型檢查,以確保兼容所有維度的矩陣。密集和稀疏矩陣的運算,也可使用表達式模板高效的進行實現,如:矩陣-矩陣乘積,線性系統求解器和特征值問題。從3.3版開始,Eigen可以鏈接到BLAS和LAPACK庫中,這可以將某些操作實現進行卸載,使庫的實現更加靈活,從而獲得更多的性能收益。 本示例將展示如何查找Eigen庫,使用OpenMP并行化,并將部分工作轉移到BLAS庫。 本示例中會實現,矩陣-向量乘法和[LU分解]([https://zh.wikipedia.org/wiki/LU%E5%88%86%E8%A7%A3](https://zh.wikipedia.org/wiki/LU分解)),可以選擇卸載BLAS和LAPACK庫中的一些實現。這個示例中,只考慮將在BLAS庫中卸載。 ## 準備工作 本例中,我們編譯一個程序,該程序會從命令行獲取的隨機方陣和維向量。然后我們將用LU分解來解線性方程組**Ax=b**。以下是源代碼(` linear-algebra.cpp `): ```c++ #include <chrono> #include <cmath> #include <cstdlib> #include <iomanip> #include <iostream> #include <vector> #include <Eigen/Dense> int main(int argc, char **argv) { if (argc != 2) { std::cout << "Usage: ./linear-algebra dim" << std::endl; return EXIT_FAILURE; } std::chrono::time_point<std::chrono::system_clock> start, end; std::chrono::duration<double> elapsed_seconds; std::time_t end_time; std::cout << "Number of threads used by Eigen: " << Eigen::nbThreads() << std::endl; // Allocate matrices and right-hand side vector start = std::chrono::system_clock::now(); int dim = std::atoi(argv[1]); Eigen::MatrixXd A = Eigen::MatrixXd::Random(dim, dim); Eigen::VectorXd b = Eigen::VectorXd::Random(dim); end = std::chrono::system_clock::now(); // Report times elapsed_seconds = end - start; end_time = std::chrono::system_clock::to_time_t(end); std::cout << "matrices allocated and initialized " << std::put_time(std::localtime(&end_time), "%a %b %d %Y %r\n") << "elapsed time: " << elapsed_seconds.count() << "s\n"; start = std::chrono::system_clock::now(); // Save matrix and RHS Eigen::MatrixXd A1 = A; Eigen::VectorXd b1 = b; end = std::chrono::system_clock::now(); end_time = std::chrono::system_clock::to_time_t(end); std::cout << "Scaling done, A and b saved " << std::put_time(std::localtime(&end_time), "%a %b %d %Y %r\n") << "elapsed time: " << elapsed_seconds.count() << "s\n"; start = std::chrono::system_clock::now(); Eigen::VectorXd x = A.lu().solve(b); end = std::chrono::system_clock::now(); // Report times elapsed_seconds = end - start; end_time = std::chrono::system_clock::to_time_t(end); double relative_error = (A * x - b).norm() / b.norm(); std::cout << "Linear system solver done " << std::put_time(std::localtime(&end_time), "%a %b %d %Y %r\n") << "elapsed time: " << elapsed_seconds.count() << "s\n"; std::cout << "relative error is " << relative_error << std::endl; return 0; } ``` 矩陣-向量乘法和LU分解是在Eigen庫中實現的,但是可以選擇BLAS和LAPACK庫中的實現。在這個示例中,我們只考慮BLAS庫中的實現。 ## 具體實施 這個示例中,我們將用到Eigen和BLAS庫,以及OpenMP。使用OpenMP將Eigen并行化,并從BLAS庫中卸載部分線性代數實現: 1. 首先聲明CMake最低版本、項目名稱和使用C++11語言標準: ```cmake cmake_minimum_required(VERSION 3.9 FATAL_ERROR) project(recipe-07 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_STANDARD_REQUIRED ON) ``` 2. 因為Eigen可以使用共享內存的方式,所以可以使用OpenMP并行處理計算密集型操作: ```cmake find_package(OpenMP REQUIRED) ``` 3. 調用`find_package`來搜索Eigen(將在下一小節中討論): ```cmake find_package(Eigen3 3.3 REQUIRED CONFIG) ``` 4. 如果找到Eigen,我們將打印狀態信息。注意,使用的是`Eigen3::Eigen`,這是一個`IMPORT`目標,可通過提供的CMake腳本找到這個目標: ```cmake if(TARGET Eigen3::Eigen) message(STATUS "Eigen3 v${EIGEN3_VERSION_STRING} found in ${EIGEN3_INCLUDE_DIR}") endif() ``` 5. 接下來,將源文件聲明為可執行目標: ```cmake add_executable(linear-algebra linear-algebra.cpp) ``` 6. 然后,找到BLAS。注意,現在不需要依賴項: ```cmake find_package(BLAS) ``` 7. 如果找到BLAS,我們可為可執行目標,設置相應的宏定義和鏈接庫: ```cmake if(BLAS_FOUND) message(STATUS "Eigen will use some subroutines from BLAS.") message(STATUS "See: http://eigen.tuxfamily.org/dox-devel/TopicUsingBlasLapack.html") target_compile_definitions(linear-algebra PRIVATE EIGEN_USE_BLAS ) target_link_libraries(linear-algebra PUBLIC ${BLAS_LIBRARIES} ) else() message(STATUS "BLAS not found. Using Eigen own functions") endif() ``` 8. 最后,我們鏈接到`Eigen3::Eigen`和`OpenMP::OpenMP_CXX`目標。這就可以設置所有必要的編譯標示和鏈接標志: ```cmake target_link_libraries(linear-algebra PUBLIC Eigen3::Eigen OpenMP::OpenMP_CXX ) ``` 9. 開始配置: ```shell $ mkdir -p build $ cd build $ cmake .. -- ... -- Found OpenMP_CXX: -fopenmp (found version "4.5") -- Found OpenMP: TRUE (found version "4.5") -- Eigen3 v3.3.4 found in /usr/include/eigen3 -- ... -- Found BLAS: /usr/lib/libblas.so -- Eigen will use some subroutines from BLAS. -- See: http://eigen.tuxfamily.org/dox-devel/TopicUsingBlasLapack.html ``` 10. 最后,編譯并測試代碼。注意,可執行文件使用四個線程運行: ```shell $ cmake --build . $ ./linear-algebra 1000 Number of threads used by Eigen: 4 matrices allocated and initialized Sun Jun 17 2018 11:04:20 AM elapsed time: 0.0492328s Scaling done, A and b saved Sun Jun 17 2018 11:04:20 AM elapsed time: 0.0492328s Linear system solver done Sun Jun 17 2018 11:04:20 AM elapsed time: 0.483142s relative error is 4.21946e-13 ``` ## 工作原理 Eigen支持CMake查找,這樣配置項目就會變得很容易。從3.3版開始,Eigen提供了CMake模塊,這些模塊將導出相應的目標`Eigen3::Eigen`。 `find_package`可以通過選項傳遞,屆時CMake將不會使用`FindEigen3.cmake`模塊,而是通過特定的`Eigen3Config.cmake`,`Eigen3ConfigVersion.cmake`和`Eigen3Targets.cmake`提供Eigen3安裝的標準位置(`<installation-prefix>/share/eigen3/cmake`)。這種包定位模式稱為“Config”模式,比` Find<package>.cmake `方式更加通用。有關“模塊”模式和“配置”模式的更多信息,可參考官方文檔 https://cmake.org/cmake/help/v3.5/command/find_package.html 。 雖然Eigen3、BLAS和OpenMP聲明為` PUBLIC`依賴項,但`EIGEN_USE_BLAS`編譯定義聲明為`PRIVATE`。可以在單獨的庫目標中匯集庫依賴項,而不是直接鏈接可執行文件。使用`PUBLIC/PRIVATE`關鍵字,可以根據庫目標的依賴關系調整相應標志和定義。 ## 更多信息 CMake將在預定義的位置層次結構中查找配置模塊。首先是`CMAKE_PREFIX_PATH`,` <package>_DIR`是接下來的搜索路徑。因此,如果Eigen3安裝在非標準位置,可以使用這兩個選項來告訴CMake在哪里查找它: 1. 通過將Eigen3的安裝前綴傳遞給`CMAKE_PREFIX_PATH`: ```shell $ cmake -D CMAKE_PREFIX_PATH=<installation-prefix> .. ``` 2. 通過傳遞配置文件的位置作為`Eigen3_DIR`: ```shell $ cmake -D Eigen3_DIR=<installation-prefix>/share/eigen3/cmake .. ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看