قرار است برنامه ای که با زبان C++ نوشته شده را کامپایل و اجرا کنیم این برنامه از MPI استفاده می کند و عملیات ضرب 2 ماتریس را انجام می دهد که برای راحتی و اطمینان از نتیجه ماتریس های تولید شده درایه هایی با مقدار 1 دارند.

این برنامه را می توانید بر روی یک سیستم و یا بصورت توزیع شده روی چند سیستم اجرا کنید که چگونگی این کار در ادامه توضیح داده خواهد شد.

*این آموزش برای سیستم عامل لینوکس و توزیع دبیان (Linux Debian) آماده شده است!

دانشگاه فردوسی ، دانشگاه امام رضا ، دکتر سوادی ، MPI ، توزیع شده ، موازی ، تمرین ، ضرب ماتریس ، Matrix Multiplication with MPI

1.پیش نیاز ها


1-در ابتدا شما به یک سیستم عامل لینوکس احتیاج دارید (این مثال بر روی توزیع های Debian 8 , Ubuntu 16.0.4 , Mint 18 تست شده است)، این آموزش بر اساس Mint 18 و VMware نوشته شده است.
اگر لینوکس ندارید می توانید با دریافت و استفاده از نرم افزار های مجازی سازی مانند (VMware Workstation , VirtualBox , ...) استفاده کنید و با ایجاد یک ماشین مجازی و دریافت فایل ISO لینوکس بر روی آن لینوکس نصب و اجرا کنید.


2-بعد از اجرای لینوکس دستورات زیر را برای نصب پیش نیاز های لازم در ترمینال لینوکس وارد کنید.
*توجه کنید که یا با اجرا su و زدن پسورد به حالت سوپر یوزر بروید (در ubuntu دستور su بصورت پیشفرض نصب نیست!) و دستورات را بدون sudo بزنید و یا هر دستور را با sudo اجرا کنید.

sudo apt-get install openssh-server
sudo apt-get install gcc
sudo apt-get install g++
sudo apt-get install mpi-default-dev

3-باید یک یوزر (mpiuser) برای راحت تر کار کردن با mpi بسازیم، برای این کار دستور زیر را اجرا کنید و پسوردی برای آن قرار دهید که فراموش نکنید! (مابقی مقادیر خواسته شده مهم نیست).

sudo adduser mpiuser

وقتی یوزر را ساختید با دستور زیر یوزر فعال خود در ترمینال را به mpiuser تغییر دهید.

su mpiuser

خب وقتی پسورد را زدید و یوزر شما تغییر کرد دستور زیر را بزنید و به آدرس اصلی این یوزر بروید.

cd /home/mpiuser/

4-فایل های مربوط به ضرب ماتریس ها را دریافت کنید: دریافت MPI-Matrix.zip : حجم: 42.7 کیلوبایت

از حالت فشرده خارج کنید و فایل Matrix را به آدرس زیر منتقل کنید (توجه کنید که باید با دسترسی root یا یوزر mpiuser این کار را انجام یدهید!)
/home/mpiuser/
خب حالا در ترمینال به آدرس Matrix بروید،می توانید با cd Matrix یا دستور زیر به این آدرس بروید:
cd /home/mpiuser/Matrix/

2.کد و کامپایل

حالا باید بریم سراغ کامپایل برنامه، برنامه MPI هم نحوه کامپایل متفاوتی دارد و هم نحوه اجرای آن فرق دارد.

فایل هایی که در شاخه Matrix قرار دادید شامل فایل های کامپایل شده نیز هستند ولی اگر می خواهید خودتان مجدد کامپایل بگیرید و یا تغییراتی در کد بدهید و کامپایل بگیرید می توانید از دستورات زیر استفاده کنید:

*دقت کنید که مسیر ترمینال شما باید در شاخه Matrix باشد و بهتر است یا یوزر mpiuser باشد.

mpic++ mpi.cpp -o mpi
mpic++ generate.cpp -o generate

خب برای استفاده باید با فایل generate ماتریس ایجاد کنیم، برای این کار دستور زیر را در ترمینال بزنید تا ماتریس های مربعی a و b را با ابعاد وارد شده (500) ایجاد کند.

./generate 500

3.اجرا تک سیستمی

برای اجرای تک سیستمی درصورت درست انجام دادن مراحل قبل دستور زیر را وارد کنید، عدد 4 در دستور زیر تعداد هسته ها را برای استفاده مشخص می کند.
mpirun -n 4 ./mpi

خروجی این دستور به صورت زیر خواهد بود

Reading a.dat containing 500 * 500 items...
Reading b.dat containing 500 * 500 items...
Sending data to 4 clients
0: Calculating a * b (size=125)...
3: Calculating a * b (size=125)...
1: Calculating a * b (size=125)...
2: Calculating a * b (size=125)...

4.اجرای توزیع شده

برای اجرای توزیع شده کمی تنظیمات و سیستم های دیگر مورد نیاز است که در شبکه ای در دسترس باشند.
شما می توانید همین تنظیمات را در سیستمی دیگر بر روی یک لینوکس یا ماشین مجازی لینوکسی ایجاد کنید و یا از همین ماشینی که ساختید کلون clone بگیرید و در سیستمی دیگر، روی ماشین مجازی اجرا کنید، که ساده ترین حالت است.
باید توجه داشته باشید که چند نکته زیر حتما بین دو سیستم رعایت شده باشد و درست کار کند:
1.در سیستم های دیگر هم یوزری با همین نام mpiuser وجود داشته باشد.
2.هردو سیستم همدیگر را در شبکه ببنند و ping هم را داشته باشند.
3.آدرس قرارگیری فایل ها در هردو سیستم به یک صورت باشد(/home/mpiuser/Matrix/).
4.بتوانید با یوزر mpiuser به یکدیگر ssh بزنید.

خب اگر سیستم دوم را هم با شرایط گفته شده حاضر کردید باید در سیستم اصلی یا master در همان آدرس گفته شده (/home/mpiuser/Matrix/) باشد و با یوزر mpiuser سپس دستور زیر را بزنید و فایل hostfile که آدرس سیستم های دیگر است slave ها را در آن بصورت هر ip در یک خط بنویسید.
nano hostfile
داخل hostfile باید بصورت زیر باشد:
127.0.0.1
192.168.1.5
192.168.1.8:2
خط اول سیستم خودتان یا master است و خط دوم ip یکی از سیستم های slave و خط سوم هم یکی دیگر از سیستم های slave که در انتهای آن تعداد هسته ای که اجازه استفاده داریم مشخص شده.
برای اجرا توزیع شده همان دو خط اول کافیست و بقیه برای استفاده وسیع تر است.
بعد از تنظیم فایل hostfile اگر مراحل گفته شده درست انجام شده باشد با اجرا دستور زیر در ترمینال ماتریسی که تولید کرده بودیم بین سیستم های تعریف شده در hostfile تقسیم می شود.
mpirun --hostfile hostfile ./mpi

خروجی این دستور به صورت زیر خواهد بود

Reading a.dat containing 500 * 500 items...
Reading b.dat containing 500 * 500 items...
Sending data to 8 clients
1: Calculating a * b (size=62)...
2: Calculating a * b (size=62)...
6: Calculating a * b (size=62)...
5: Calculating a * b (size=62)...
0: Calculating a * b (size=62)...
7: Calculating a * b (size=62)...
4: Calculating a * b (size=62)...
3: Calculating a * b (size=62)...
*توجه داشته باشید که mpi برای هرکدام از سیستم های تعریف شده، به آنها با یوزری که دستور را اجرا کردید(mpiuser) یک ssh می زند که یعنی اگر فینگر پرینت سیستم master را بر روی دیگر سیستم ها کپی نکرده باشید برای هر slave از شما در حین اجرا، پسورد آن سیستم را نیز برای اتصال می گیرد.
 وقتی کد را اجرا کردید سیستم مانیتور را اگر اجرا کنید master به این صورت است که در قسمت network در حال ارسال ماتریس است و


در سیستم slave هم سیستم مانیتور را اجرا کنید تا بالارفتن استفاده از cpu و دریافت ماتریس در افزایش استفاده از network ببینید، اگر در شبکه ای بدون استفاده دیگر باشید خواهید دید که نمودار ارسال master با نمودار دریافت slave شبیه هم هستند.


5.منابع و مطالعه بیشتر

با تشکر از mtoloo.blog.ir برای تولید کد این پروژه و راهنمایی های ایشون.

لیست منابع و سایت ها برای مطالعه بیشتر: