Làm thế nào để có được ma trận phức tạp thưa thớt từ mã của tôi đến PETSc một cách hiệu quả


8

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 ABN , 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 AB 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 đó zAx=λBxABNN×NABzABzlà 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 ở đó.N<1500N

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ế, MatSetValuesdò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_ENTRIESnhư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 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?ABzABMatCreateSeqAIJWithArrays

Đây có phải là cách hiệu quả nhất để làm điều đó? Do ma trận 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ả AB đề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ọiABzABzAxBxAxBxMatCreateSeqAIJWithArrays, do đó, có thể nhanh hơn để thực hiện tất cả điều này trong PETSc sau khi ma trận B được chuyển qua.AB

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 MatSetValuesnà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

Câu trả lời:


7

Điều quan trọng là preallocate chính xác. Đây gần như chắc chắn là lý do tại sao lắp ráp của bạn chậm. Nếu bạn đang bắt đầu với một đại diện ma trận dày đặc, chỉ cần quét qua nó một lần để đếm số lượng khác không trên mỗi hàng, sau đó gọi MatSeqAIJSetPreallocation(). Xem Câu hỏi thường gặp này . Tùy chọn MAT_IGNORE_ZERO_ENTRIESnày thực sự được sử dụng khi có một số độ thưa thớt nhẹ trong các khối dày đặc khác thay vì xây dựng toàn bộ ma trận trong một cuộc gọi từ một ma trận dày đặc. Vì lý do này, nó không tự động thực hiện phân chia dựa trên độ thưa thớt của một khối đó.

Tạo một ma trận trung gian dày đặc không thể mở rộng bộ nhớ, vì vậy cuối cùng bạn sẽ muốn tránh nó. MatSetValues()thực sự có nghĩa là được sử dụng cho các khối dày đặc logic trong một ma trận thưa thớt. Bạn thường gọi một lần trên mỗi hàng (hoặc nhóm hàng, điển hình của phương thức FD) hoặc một lần cho mỗi phần tử (điển hình của phương thức FEM). Nếu bạn đang dịch một ma trận thưa thớt lắp ráp hiện có, chỉ cần gọi MatSetValues()một lần mỗi hàng. Nếu bạn muốn bỏ qua ma trận trung gian (hiệu suất tốt hơn và bộ nhớ thấp hơn), chỉ cần gọi MatSetValues()một lần cho mỗi phần tử.

Lưu ý rằng bạn có thể gọi PETSc trực tiếp từ Fortran, mặc dù có người dùng của mọi phương ngữ Fortran giữa Fortran 77 cơ bản và các phiên bản mới nhất. Các giao diện sẽ trông khá thô đối với bạn như một người áp dụng các tính năng mới nhất. Đề xuất các cách duy trì để cải thiện hỗ trợ cho các phương ngữ mới nhất sẽ được đánh giá cao.


Cảm ơn câu trả lời tuyệt vời. Tôi có thể thấy bây giờ ý tưởng đằng sau MatSetValues(). Để dịch một ma trận hiện có, không phải là nhanh hơn chỉ gọi MatCreateSeqAIJWithArraysmột lần thay vì gọi MatSeqAIJSetPreallocationvà sau đó MatSetValuescho mỗi hàng?
Ondřej Čertík

Tôi sẽ cung cấp thông tin phản hồi về các gói Fortran. Cho đến bây giờ, đây là cách nhanh nhất để tôi có thể viết trình điều khiển mà tôi cần bằng C và chỉ tự mình bọc trình điều khiển này.
Ondřej Čertík

1
Chắc chắn, nhưng điều đó đòi hỏi bạn phải bắt đầu với một ma trận CSR được lắp ráp bằng cách sử dụng cùng một quy ước. Nếu bạn sử dụng một số định dạng khác, chỉ cần đóng gói một hàng tại một thời điểm. Nếu bạn preallocate, thời gian dành cho MatSetValues()sẽ rất nhỏ so với việc tính toán các mục và giải quyết hệ thống. Ngoài ra, việc lắp ráp bằng cách sử dụng MatSetValues[Blocked][Local]()ngăn mã của bạn phụ thuộc vào một định dạng ma trận cụ thể, cho phép bạn chọn các định dạng lưu trữ trong thời gian chạy.
Jed Brown
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.