Cách hiệu quả nhất để có được một ma trận thưa thớt phức tạp từ mã Fortran của tôi sang PETSc là gì? Tôi hiểu rằng đây là vấn đề phụ thuộc, vì vậy tôi đã cố gắng cung cấp càng nhiều chi tiết có liên quan càng tốt dưới đây.
Tôi đã chơi với lễ eigenvalue giải [1] cho các vấn đề của các loại , kích thước của ma trận A và B là N , và khá nhiều mọi thời đại là chi tiêu giải quyết N × N tuyến tính phức tạp hệ thống với M0 bên tay phải. N là lớn (số hàm cơ sở FE, trong 3D), M0 nhỏ (trong trường hợp của tôi, tôi quan tâm đến M0 ~ 20). Ma trận A và B là thực, đối xứng và thưa thớt, và vấn đề phức tạp cần giải quyết là z A - B , trong đó zlà một số phức. Tác giả của FEAST dường như đề xuất rằng độ chính xác của giải pháp cho hệ thống tuyến tính này không nhất thiết phải rất cao để có được giá trị riêng và hàm riêng, vì vậy một số bộ giải nhanh có thể là một giải pháp tuyệt vời cho vấn đề này.
Cho đến nay tôi chỉ sử dụng Lapack cho hệ thống phức tạp và nó hoạt động rất tốt cho trên máy tính của tôi. Đối với N lớn hơn , tôi chưa biết bộ giải tốt nhất là gì, vì vậy tôi muốn chỉ sử dụng PETSc và chơi với các bộ giải lặp ở đó.
Tôi đã viết một trình điều khiển C đơn giản và gọi nó từ Fortran, xem [2] cho tất cả các mã, nhưng vấn đề chỉ nằm ở phần này (cập nhật: Tôi đã đặt ở đây tất cả các dòng để tạo ma trận, như tôi vừa nhận ra rằng điều này có liên quan):
ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr);
ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr);
ierr = MatSetFromOptions(A);CHKERRQ(ierr);
ierr = MatSetOption(A,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr);
ierr = MatSetUp(A);CHKERRQ(ierr);
for (i=0; i<n; i++) col[i] = i;
ierr = MatSetValues(A,n,col,n,col,A_,INSERT_VALUES);CHKERRQ(ierr);
Điều này cực kỳ chậm (tức là đối với N ~ 1500, việc này có thể mất 2 giây, trong khi thực sự giải quyết được ngay lập tức), trên thực tế, MatSetValues
dòng này chiếm khá nhiều 100% thời gian cho toàn bộ phép tính eigenvalue ... Ma trận A_ là một Ma trận 2D xuất phát từ Fortran. Tôi đã cố gắng vô hiệu hóa MAT_IGNORE_ZERO_ENTRIES
nhưng nó không tạo ra sự khác biệt nào. Vì vậy, tôi nghĩ rằng vấn đề đơn giản là ngay cả đối với N vừa phải như 1500, tôi cần sử dụng một số định dạng ma trận thưa thớt, điều đó có đúng không?
Vì vậy, tôi đã triển khai định dạng CSR trong mã Fortran của mình cho ma trận và B (hoặc cho z A - B ) và bây giờ tôi đang cố gắng tìm ra cách cung cấp hiệu quả cho PETSc. Bây giờ, tôi chỉ muốn có được một cái gì đó hoạt động tuần tự, đó là nhịp đập của Lapack. Tôi có nên sử dụng chức năng cho việc này?MatCreateSeqAIJWithArrays
Đây có phải là cách hiệu quả nhất để làm điều đó? Do ma trận và B không thay đổi, chỉ có số phức z thay đổi trong thuật toán FEAST và trong phép tính FE, tôi nghĩ rằng cả A và B đều có cùng cấu trúc thưa thớt, có lẽ người ta có thể cải thiện mọi thứ hơn nữa bằng cách khai thác Cấu trúc thưa thớt và sau đó chỉ cần nhanh chóng đánh giá z A x - B x trong mỗi lần lặp FEAST ( A x , B x là các mảng giá trị của định dạng CSR), tôi có thể thực hiện điều này một cách dễ dàng trong Fortran, nhưng có thể nó luôn chậm để gọiMatCreateSeqAIJWithArrays
, do đó, có thể nhanh hơn để thực hiện tất cả điều này trong PETSc sau khi ma trận và B được chuyển qua.
Tôi muốn biết liệu cách tiếp cận CSR này cho vấn đề này là chính xác hay liệu tôi đang làm sai (rõ ràng cách tiếp cận ban đầu của tôi với phương pháp MatSetValues
này là không tối ưu). Cảm ơn cho bất kỳ lời khuyên.
[1] http://www.ecs.umass.edu/~polizzi/feast/
[2] https://github.com/certik/hfsolver/pull/14
[3] http://www.mcs.anl.gov/petsc/petsc-3.1/docs/manualpages/Mat/MatCreateSeqAIJWithArrays.html
MatSetValues()
. Để dịch một ma trận hiện có, không phải là nhanh hơn chỉ gọiMatCreateSeqAIJWithArrays
một lần thay vì gọiMatSeqAIJSetPreallocation
và sau đóMatSetValues
cho mỗi hàng?