Adakah rekomendasi untuk kerangka kerja pengujian unit yang kompatibel dengan kode / pustaka yang menggunakan MPI?

13

Biasanya, saya menulis kode seri, dan ketika saya melakukannya, saya menulis unit test dengan beberapa kerangka pengujian gaya xUnit (MATLAB xUnit, PyUnit / nose, atau kerangka pengujian C ++ Google).

Berdasarkan pencarian Google sepintas, saya belum melihat banyak tentang bagaimana praktisi menguji kode yang menggunakan MPI. Apakah ada praktik terbaik untuk itu?

Dibandingkan dengan Strategi untuk pengujian unit dan pengembangan berbasis tes , saya mencari jawaban yang berkaitan dengan perangkat lunak apa yang harus saya gunakan untuk kerangka pengujian (jika ada - jawabannya bisa "menggulung kode Anda sendiri", di mana contoh kasus kode pengujian khusus akan sangat membantu).

Sebagian besar dari apa yang saya cari untuk diuji adalah evaluasi fungsi sisi kanan dan rutinitas perakitan matriks Jacobian untuk stepper waktu yang akan mengintegrasikan PDE semi-diskritisasi. Saya akan menggunakan PETSc, jadi jika ada sesuatu yang spesifik PETSc, itu akan membantu selain kerangka pengujian yang lebih umum.

Suntingan Klarifikasi:

Contoh akan di ${PETSC_DIR}/src/ts/examples/tutorials/ex2.c, di mana saya ingin menguji sesuatu seperti RHSFunction(evaluasi fungsi sisi kanan) danRHSJacobian (evaluasi matriks Jacobian). Saya akan menguji terhadap nilai-nilai yang diketahui untuk sisi kanan rakitan dan matriks Jacobian rakitan; Saya bisa mendapatkan nilai-nilai ini secara analitik untuk beberapa contoh masalah sederhana. Fungsi-fungsi ini adalah fungsi spesifik aplikasi yang tidak akan menjalankan fungsi level aplikasi lainnya, tetapi mereka bisa memanggil MPI jika perakitan vektor atau matriks dilakukan dalam fungsi tersebut (seperti dalam contoh PETSc yang ditautkan di atas). Jika saya menulis fungsi yang hanya menghitung porsi vektor atau matriks lokal ke prosesor, saya ingin menguji terhadap global, versi rakitan jika memungkinkan karena, karena baru mengenal pemrograman paralel, lebih intuitif bagi saya untuk memikirkan vektor global dan global matriks. Pengujian ini akan dijalankan pada ukuran masalah kecil dan sejumlah kecil prosesor.

Saya dapat memikirkan beberapa strategi untuk melakukan ini:

  • Strategi yang mungkin tidak akan berfungsi dengan baik, berdasarkan pencarian Google yang telah saya lakukan pada topik ini, akan membangun output yang diketahui, menemukan kesalahan relatif / absolut secara paralel, dan kemudian melakukan perbandingan naif. Output mungkin akan kacau - siapa pun yang telah menulis program "Halo, dunia" dengan MPI tahu mengapa - yang membatasi utilitas melakukan pengujian unit. ( Ini adalah dorongan untuk mengajukan pertanyaan. ) Tampaknya juga ada beberapa kericuhan potensial dalam menyebut kerangka kerja unit-testing.
  • Tulis output ke file (dalam PETSc, misalnya, menggunakan VecViewdan MatView), dan bandingkan dengan output yang diketahui dengan sesuatu seperti ndiffatau numdiff. Perasaan saya dengan metode ini dari pengalaman sebelumnya melakukan pengujian unit dengan perbandingan file adalah bahwa itu akan rewel, dan itu akan memerlukan beberapa penyaringan. Metode ini sepertinya akan sangat baik untuk pengujian regresi, karena saya bisa mengganti utilitas di atas dengan yang sederhana diff, dan tidak perlu khawatir tentang mencocokkan format teks. Saya telah mengumpulkan bahwa strategi ini kurang lebih seperti yang disarankan WolfgangBangerth dan andybauer. PETSc juga tampaknya menggunakan pendekatan serupa untuk beberapa pengujian yang dilakukannya.
  • Gunakan kerangka kerja pengujian unit, kumpulkan semuanya ke dalam prosesor dengan MPI peringkat 0, dan mintalah untuk melakukan pengujian unit hanya jika peringkat prosesor adalah 0. Saya bisa melakukan sesuatu yang mirip dengan norma-norma (mungkin bahkan lebih mudah seperti itu), meskipun untungnya adalah bahwa setiap kesalahan yang dikembalikan akan memberi tahu saya bahwa saya memiliki masalah dalam perhitungan saya, tetapi bukan elemen mana yang salah. Maka saya tidak perlu khawatir tentang output pengujian unit yang kacau; Saya hanya perlu khawatir tentang memanggil kerangka pengujian unit dengan benar. PETSc tampaknya menggunakan perbandingan norm-wise dalam program contohnya ketika solusi yang tepat tersedia, tetapi ia tidak menggunakan kerangka pengujian unit saat membuat perbandingan tersebut (juga tidak harus, tentu saja).
Geoff Oxberry
sumber
Saya hanya terbiasa dengan suite pengujian internal, jadi saya tidak bisa merekomendasikan apa pun. Yang sedang berkata, apakah tidak ada suite pengujian ini yang memungkinkan Anda menentukan cara menjalankan executable yang Anda buat? Jika ya, sepele untuk membuat tes yang berfungsi untuk program MPI.
Bill Barth
Mereka harus. Dalam bahasa yang dikompilasi, itu hanya sebuah executable, jadi seharusnya tidak ada masalah untuk menggunakannya mpiexec, dan termasuk panggilan seperti PETScInitialize/ PETScFinalizedalam kode setup / teardown. (Mungkin, jika saya tidak menggunakan PETSc, saya akan mengganti panggilan itu dengan analog dari MPI_Init/ MPI_Finalize, tergantung pada perpustakaan yang saya gunakan.) Kerangka pengujian Google adalah rilis berbasis sumber, jadi kompilasi bersama dengan kode I menulis juga tidak akan menjadi masalah.
Geoff Oxberry
Deskripsi masalah Anda memberi tahu saya bahwa Anda tertarik menggunakan kerangka kerja unit-testing untuk menjalankan tes integrasi / regresi. Tidak ada yang salah dengan itu, tetapi Anda mungkin ingin lebih memperjelas pertanyaan Anda. Saya pikir jika Anda bertanya kepada pakar pengujian unit bagaimana menulis tes unit untuk kode ilmiah Anda, mereka akan meminta Anda untuk menulis tes dengan cara modular. Artinya, sebagian besar tes Anda tidak akan memiliki panggilan MPI yang tepat di dalamnya.
Aron Ahmadia
Biarkan saya lebih konkret. Sesuatu yang ingin saya uji pada masalah kecil dengan sejumlah kecil prosesor (katakanlah, 1-4) adalah apakah matriks Jacobian yang saya buat benar-benar menghasilkan Jacobian global yang tepat. Saya juga ingin menguji fungsi sisi kanan saya terhadap sisi kanan global yang diketahui. Setiap pengujian semacam itu harus tetap hanya menjalankan fungsi tunggal dalam aplikasi (misalnya, dalam PETSc, pengujian RHSFunctiondan RHSJacobiandalam ${PETSC_DIR}/src/ts/examples/tutorials/ex.2) secara terpisah.
Geoff Oxberry
Saya tidak berpikir kerangka kerja saat ini ada yang akan membantu Anda melakukan apa yang Anda inginkan. Kami telah berhasil bertengkar untuk melakukan beberapa hal bagi kami di PyClaw, (dan Lisandro telah menggunakannya dalam mpi4py dan petsc4py). Sudahkah Anda melihat kerangka pengujian di mpich?
Aron Ahmadia

Jawaban:

8

Saya pengguna senang GoogleTest dengan kode C ++ MPI di lingkungan build CMake / CTest:

  • CMake secara otomatis menginstal / menghubungkan googletest dari svn!
  • menambahkan tes adalah one-liner!
  • menulis tes itu mudah! (dan google mock sangat kuat!)
  • CTest dapat mengirimkan parameter baris perintah ke pengujian Anda, dan mengekspor data ke CDash!

Begini Cara kerjanya. Sekumpulan unit-test yang membutuhkan mpi ditulis ke dalam beberapa my_mpi_test.cppfile yang terlihat seperti ini:

#include <gtest/gtest.h>
#include <boost/mpi.h>

/// Most testing libraries allow to define main yourself to override initialization.
int main(int argc, char* argv[]) {
    ::testing::InitGoogleTest(&argc, argv);  /// Set gtest environment
    mpi::environment env(argc, argv);  /// Set mpi environment
    return RUN_ALL_TESTS();  /// Execute all gtest tests
}

TEST(test_batch_name, test_name) {  /// Then you can create tests as usual,
  using namespace mpi;
  communicator world;  /// and use MPI inside your tests.
  /* ... test stuff here ... */
}

CMakeLists.txt yang menambahkan tes ini adalah:

add_mpi_test(my_mpi 2)  # Uses 2 MPI processes

di mana add_mpi_testmembungkus CMake di add_testdalam CMakeLists.txt root saya:

function(add_mpi_test name no_mpi_proc)
  include_directories(${MY_TESTING_INCLUDES})
      # My test are all called name_test.cpp
      add_executable(${name} ${name}_test.cpp)
      add_dependencies(${name} googletest)
  # Make sure to link MPI here too:
  target_link_libraries(${name} ${MY_TESTING_LIBS})
  set(test_parameters ${MPIEXEC_NUMPROC_FLAG} ${no_mpi_proc} "./${name}")
      add_test(NAME ${name} COMMAND ${MPIEXEC} ${test_parameters})
endfunction(add_mpi_test)

Bagian terakhir ini tidak perlu tetapi memungkinkan Anda untuk dengan mudah menambahkan tes mpi dalam satu baris. Kemudian Anda dapat memutuskan apakah Anda ingin melakukan hard-code angka proses MPI untuk setiap tes atau membacanya melalui parameter baris perintah ke ctest.

gnzlbg
sumber
4

Ada beberapa paket perangkat lunak berkemampuan MPI yang menggunakan set alat CMake untuk pengujian. Yang bisa saya pikirkan adalah Trilinos, VTK dan ParaView. Saya akan berpikir bahwa Anda tidak ingin berasumsi bahwa executable perlu diluncurkan dengan mpirun dan / atau mpiexec. CMake memiliki dukungan untuk menentukan cara meluncurkan executable yang tepat bersama dengan opsi yang berbeda seperti jumlah maksimum proses untuk digunakan dan pra-dan pasca-bendera, jika diperlukan.

Anda mungkin ingin melihat bagian Situs HPC pada dasbor ParaView tempat pengujian dijalankan pada berbagai superkomputer NERSC dan Argonne. Dikubur di sana juga sebagian besar pengaturan yang harus Anda tentukan untuk membuatnya bekerja pada mesin-mesin itu.

Sebagai referensi, dasbor Trilinos memiliki beragam paket yang terdaftar dan bagi saya agak mengesankan di organisasinya.

Pengungkapan penuh: Saya seorang karyawan Kitware dan CMake adalah salah satu proyek sumber terbuka yang terlibat dengan Kitware.

andybauer
sumber
Terima kasih atas jawabannya! Saya telah melihat CTest, dan belum menemukan dokumentasi apa pun selain dari deskripsi seperti halaman manual di situs web KitWare. Bisakah Anda merekomendasikan tutorial yang tersedia secara bebas?
Geoff Oxberry
Ada banyak informasi tentang wiki CMake . Ada banyak tutorial untuk CMake, CTest dan CPack di sana. Saya menemukan sebagian besar jawaban saya untuk aplikasi tersebut di Stack Overflow .
andybauer
andybauer - Terima kasih atas jawabannya. Apakah Anda keberatan mengedit jawaban Anda dan mengungkapkan afiliasi Anda dengan KitWare?
Aron Ahmadia
3

Kami hanya menggulung kode kami sendiri. II - pada dasarnya, kami memberi tahu kerangka kerja untuk melakukan tes menggunakan mpirun -np .... Kami sebelumnya hanya menggunakan skema pengujian berbasis Makefile (kompilasi, tautkan, jalankan pengujian, lalu bandingkan hasilnya dengan yang sebelumnya telah disimpan) dan Anda dapat menemukannya di sini:

dan untuk konteks, target non-MPI ada di sini:

Kami menulis ulang hal-hal menggunakan CMake / CTest, dengan perkembangan saat ini di sini:

Wolfgang Bangerth
sumber
Wolfgang, terima kasih atas jawabannya! PETSc tampaknya melakukan hal serupa.
Geoff Oxberry