Thông thường, tôi viết mã nối tiếp và khi tôi làm, tôi viết các bài kiểm tra đơn vị với một số khung kiểm tra kiểu xUnit (MATLAB xUnit, PyUnit / mũi hoặc khung kiểm tra C ++ của Google).
Dựa trên một tìm kiếm đáng chú ý của Google, tôi chưa thấy nhiều về cách kiểm tra mã đơn vị học viên sử dụng MPI. Có thực hành tốt nhất cho điều đó?
So với Chiến lược để thử nghiệm đơn vị và phát triển dựa trên thử nghiệm , tôi đang tìm câu trả lời liên quan đến phần mềm nào tôi nên sử dụng cho khung thử nghiệm (nếu có tồn tại - câu trả lời rất có thể là "cuộn mã của riêng bạn", trong đó ví dụ trường hợp của mã thử nghiệm tùy chỉnh sẽ hữu ích).
Hầu hết những gì tôi muốn kiểm tra là các đánh giá chức năng bên tay phải và các thói quen lắp ráp ma trận Jacobian cho các bước thời gian sẽ được tích hợp các PDE bán rời rạc. Tôi sẽ sử dụng PETSc, vì vậy nếu có bất cứ thứ gì cụ thể về PETSc, điều đó sẽ hữu ích ngoài các khung kiểm tra tổng quát hơn.
Chỉnh sửa làm rõ:
Một ví dụ sẽ là ${PETSC_DIR}/src/ts/examples/tutorials/ex2.c
, nơi tôi muốn kiểm tra một cái gì đó như RHSFunction
(đánh giá chức năng bên tay phải) vàRHSJacobian
(một đánh giá ma trận Jacobian). Tôi sẽ thử nghiệm các giá trị đã biết cho ma trận Jacobian bên phải và lắp ráp; Tôi có thể có được các giá trị này một cách phân tích cho một số trường hợp vấn đề đơn giản. Các hàm này là các hàm dành riêng cho ứng dụng sẽ không thực hiện bất kỳ hàm cấp ứng dụng nào khác, nhưng chúng có thể gọi MPI nếu việc lắp ráp vectơ hoặc ma trận được thực hiện trong hàm (như trong ví dụ PETSc được liên kết ở trên). Nếu tôi viết các hàm chỉ tính các phần của vectơ hoặc ma trận cục bộ cho bộ xử lý, tôi sẽ muốn kiểm tra phiên bản lắp ráp toàn cầu nếu có thể bởi vì, mới đối với lập trình song song, tôi sẽ nghĩ trực quan hơn về vectơ toàn cầu và toàn cầu ma trận. Các thử nghiệm này sẽ được chạy trên các kích cỡ vấn đề nhỏ và số lượng nhỏ bộ xử lý.
Tôi có thể nghĩ ra một vài chiến lược để làm điều này:
- Một chiến lược có thể sẽ không hoạt động tốt, dựa trên các tìm kiếm của Google mà tôi đã thực hiện về chủ đề này, sẽ là xây dựng một đầu ra đã biết, tìm ra lỗi tương đối / tuyệt đối song song và sau đó thực hiện các so sánh ngây thơ. Đầu ra có thể sẽ bị cắt xén - bất kỳ ai đã viết chương trình "Xin chào, thế giới" với MPI đều biết tại sao - điều này hạn chế tiện ích khi thực hiện kiểm tra đơn vị. ( Đây là động lực để đặt câu hỏi. ) Dường như cũng có một số khó khăn tiềm tàng trong việc gọi khung kiểm tra đơn vị.
- Viết đầu ra vào tệp (ví dụ như trong PETSc, bằng cách sử dụng
VecView
vàMatView
) và so sánh với đầu ra đã biết với một cái gì đó nhưndiff
hoặcnumdiff
. Cảm giác ruột của tôi với phương pháp này từ kinh nghiệm trước đây khi thực hiện kiểm tra đơn vị với so sánh tệp là nó sẽ rất khó và nó sẽ yêu cầu một số bộ lọc. Tuy nhiên, phương pháp này có vẻ như là tuyệt vời để kiểm tra hồi quy, bởi vì tôi có thể thay thế các tiện ích ở trên bằng một đơn giảndiff
và không phải lo lắng về việc khớp các định dạng văn bản. Tôi đã tập hợp rằng chiến lược này ít nhiều là những gì WolfgangBangerth và andybauer đang đề xuất. PETSc cũng xuất hiện để sử dụng một cách tiếp cận tương tự cho một số thử nghiệm mà nó thực hiện. - Sử dụng khung kiểm tra đơn vị, thu thập mọi thứ vào bộ xử lý với MPI xếp hạng 0 và yêu cầu nó chỉ thực hiện kiểm tra đơn vị nếu xếp hạng bộ xử lý là 0. Tôi có thể làm điều gì đó tương tự với các chỉ tiêu (có thể dễ dàng hơn như vậy), mặc dù việc đánh đổi là bất kỳ lỗi nào được trả về sẽ cho tôi biết rằng tôi có vấn đề trong tính toán của mình, nhưng không phải là yếu tố nào bị lỗi. Sau đó, tôi không cần phải lo lắng về bất kỳ đầu ra thử nghiệm đơn vị nào bị cắt xén; Tôi chỉ cần lo lắng về việc gọi khung kiểm tra đơn vị chính xác. PETSc dường như sử dụng các so sánh thông thường trong các chương trình ví dụ của mình khi có các giải pháp chính xác, nhưng nó không sử dụng khung kiểm tra đơn vị khi thực hiện các so sánh đó (cũng không nhất thiết phải như vậy).
mpiexec
để chạy nó và bao gồm các cuộc gọi như PETScInitialize
/ PETScFinalize
trong mã thiết lập / mã xé. (Có lẽ, nếu tôi không sử dụng PETSc, tôi sẽ thay thế các cuộc gọi đó bằng các tương tự MPI_Init
/ MPI_Finalize
, tùy thuộc vào các thư viện tôi đang sử dụng.) Khung thử nghiệm của Google là một bản phát hành dựa trên nguồn, do đó biên dịch nó cùng với mã I viết cũng không phải là một vấn đề.
RHSFunction
và RHSJacobian
trong ${PETSC_DIR}/src/ts/examples/tutorials/ex.2
) một cách riêng lẻ .