Лабораторные работы по информатике

Практикум по физике Лабораторные работы по информатике Microsoft Visio Алгоритмические основы машинной графики AutoCAD
Практикум по механике и молекулярной физике
ОПРЕДЕЛЕНИЕ МОМЕНТА ИНЕРЦИИ
МАТЕМАТИЧЕСКИЙ МАЯТНИК
Физический маятник
ОПРЕДЕЛЕНИЕ МОДУЛЯ ЮНГА
ПОПЕРЕЧНЫЕ КОЛЕБАНИЯ СТРУНЫ
ОПРЕДЕЛЕНИЕ КОЭФФИЦИЕНТА ВЯЗКОСТИ
ОПРЕДЕЛЕНИЕ КОЭФФИЦИЕНТА ПОВЕРХНОСТНОГО НАТЯЖЕНИЯ
ОПРЕДЕЛЕНИЕ ВЛАЖНОСТИ ВОЗДУХА
ОПРЕДЕЛЕНИЕ АДИАБАТИЧЕСКОЙ ПОСТОЯННОЙ ВОЗДУХА
Вынужденные колебания линейного осциллятора
Лабораторные работы по информатике
Определение параметров n-мерных коммутационных структур
Преобразование последовательного алгоритма в параллельный
Представление алгоритмов в виде граф–схем.

Построение матрицы логической несовместимости операторов

Построение множеств взаимно независимых операторов
Определение ранних и поздних сроков окончания выполнения операторов
Запуск параллельных программ на кластере
Microsoft Visio
Спецификация требований к информационной системе
Основы работы в редакторе деловой графики Microsoft Visio 2010.
Лабораторная работа №3
Лабораторная работа №4
Функциональное моделирование
Диаграмма классов
Алгоритмические основы машинной графики

Анимация и морфинг

Отсечение прямоугольным окном
Построение проекции трехмерного объекта
Создание простых объектов
Основные навыки работы с объектами
Привязка объектов
Редактирование формы произвольных кривых
Приемы работы с контурами объектов
Создание цветных изображений
Обмен изображениями с другими программами
Ввод и редактирование текста
СИСТЕМА АВТОМАТИЗИРОВАННОГО ПРОЕКТИРОВАНИЯ AutoCAD
Основы работы с использованием системы AutoCAD
Команды рисования
Нанесение надписей
Команды редактирования
Проставление размеров на чертеже
Работа с блоками чертежа
 

Лабораторная работа №7. Запуск параллельных программ на кластере

Цель работы – практическая реализация и отладка простейших параллельных программ "Hello world" и вычисления числа π на кластере. Работа с очередью заданий на кластере с помощью планировщика IBM Tivoli LoadLeveler.

Теоретическая часть

Кластером обычно называют параллельную или распределенную систему, состоящую из набора взаимосвязанных целостных компьютеров, которые используются как единый, унифицированный вычислительный ресурс. Кластеры, имеющие преимущества в сравнении с более традиционными системами, применяют для решения задач повышенной сложности.

На кластере в МГТУ им. Н.Э.Баумана установлена ОС Linux – RHEL. Удаленное управление ОС можно выполнять с помощью протокола SSH (англ. Secure Shell — «безопасная оболочка») — сетевой протокол сеансового уровня, позволяющий производить удалённое управление операционной системой и туннелирование TCP-соединений (например, для передачи файлов). SSH допускает выбор различных алгоритмов шифрования, что позволяет не только реализовать удаленную работу, но и передавать файлы по шифрованному каналу. SSH-клиенты и SSH-серверы доступны для большинства сетевых операционных систем. Рассмотрим возможные способы подключения по SSH:

Linux

SSH-клиент и используемая им библиотека SSL входят в комплект поставки большинства Linux-дистрибутивов. При необходимости установка из исходных кодов возможна без прав суперпользователя (аналог пользователя с административными правами в Windows) в домашнюю директорию /home/username. Исчерпывающую информацию по настройке и применению команд ssh и scp можно получить, обратившись к встроенной справке:

$> man ssh

$> man scp

Windows

Существует несколько реализаций SSH для Windows. Одним из ssh-клиентов является PuTTY (см. тж. PuTTY Portable). При его настройке (раздел «Session») в поле «Host Name» нужно указать интернет-адрес системы, к которой вы хотите подключиться, а переключатель «Connection type» выставить в положение «SSH». Чтобы не вводить при каждом подключении имя пользователя, с которым вы зарегистрированы в системе (например, myname), его можно указать через символ '@' в том же поле «Host Name» (например, myname@<интернет-адрес>).

Для копирования файлов с локальной машины на удаленную (в данном случае кластер) можно использовать программу WinSCP (см. тж. WinSCP Portable), которая предоставляет удобный графический интерфейс. При работе в терминале будет полезна утилита pscp, входящая в пакет PuTTY. Синтаксис аргументов ее командной строки аналогичен таковому у Linux-команды scp.

Кроме того, можно установить Linux-подобное окружение Cygwin, в котором уже имеются программы ssh, scp

Если вы применяете Linux из виртуальной машины типа VirtualBox, то часто можете непосредственно воспользоваться всеми преимуществами Linux-окружения: встроенными ssh, scp, и X-сервером. (Однако этот механизм может не сработать, если ваш провайдер предоставляет интернет-доступ через VPN-подключение; в таком случае необходимо отредактировать таблицы маршрутизации и/или указать в конфигурационных файлах адреса локальных DNS-серверов, но подобная настройка выходит за пределы рассматриваемых здесь вопросов.)

На компьютерах в лаборатории ИУ-6 установлена ОС Ubuntu 8. Далее рассмотрим подключение к кластеру с использованием данной ОС. Вход в систему произвести для пользователя student (пароль: student). Терминал для ввода команд можно открыть из графической оболочки в меню Applications (Приложения), раздел Accessories (Стандартные в русифицированной версии) или сочетанием клавиш Ctrl+Alt+F1 (выход из консоли — Ctrl+Alt+F7). В данном случае проще работать через графическую оболочку. В ОС доступны несколько терминалов, необходимо будет открыть два. Один будет использоваться для удаленной работы с Linux RHEL, другой – с локальной ОС (понадобится при копировании файлов на кластер).

Подключение к кластеру по ssh

student@805-21:~$ ssh username@195.19.33.110

где 195.19.33.110 ip адрес кластера.

Логин и пароль для доступа к кластеру необходимо получить у преподавателя перед началом лабораторной. Username здесь и далее следует заменить на Ваше имя пользователя! Если логин введен верно, то через несколько секунд последует запрос пароля:

username@195.19.33.110's password:

Если авторизация успешна, то появится строка с указанием текущей директории и времени и именем пользователя:

  [11:55 username@mgmt ~]$

где ~ означает домашнюю директорию home.

Для запуска программ нужно, чтобы пользователь находился в группе loadl. Это можно проверить командой :

[11:55 username@mgmt ~]$groups username

Отклик системы содержит имя пользователя и имя группы(должно быть loadl).

С точки зрения конечного пользователя файловая система вычислительного кластера состоит из двух частей:

/home — домашние директории, предназначенные для хранения пользовательских данных, разработки и компиляции программ, постобработки результатов расчетов; узлы ввода-вывода не имеют доступа к этой части файловой системы

/gpfs — высокопроизводительная часть файловой системы, к которой имеют непосредственный доступ узлы ввода-вывода; служит для хранения временных файлов, необходимых для счета (исполняемых файлов и данных)

В ОС Linux для переходов по каталогу используется команда cd. Для обозначения корня ОС используется символ '/', текущая директория - './', предыдущая директория - '../'.

 

Создание папки для проекта в домашней директории.

cd $HOME

mkdir projectname

  В папке projectname будут хранится все файлы, используемые в лабораторной работе. Для просмотра содержимого папки используется команда ls.

 [11:55 username@mgmt ~]$ls

ответ:

1aba7 code1 Dragovich hello mbox PRJ7

  bin common EXAMPLES laba7 Popov test

Справку по команде всегда можно получить командой man.

 man ls

Просмотр текстовых файлов можно осуществить встроенным текстовым редактором nano. Нихжняя строка содержит описание доступных команд.

nano filename

4. Копирование файлов

Файлы hello.c и hello.job создать на локальной машине с помощью текстового редактора, скопировав текст файлов из данного методического указания (см. ниже). Необходимо сохранить в созданной папке (см. п.3) файлы с кодом программ и заданий для IBM LoadLeveler. Для этого на локальной машине необходимо выполнить команду scp.

 student@805-21:~$scp hello.c username@195.19.33.110:projectname/

 student@805-21:~$scp hello.job username@195.19.33.110:projectname/

Файл задания hello.job выглядит следующим образом:

#!/bin/bash

#Название задания (может включать в себя любую комбинацию букв и цифр

#@job_name = hello

#Тип задания: может быть последовательный или параллельный.

#Выберем параллельный тип задания

#@job_type = MPICH

#@class = small_mpi

#@group = loadl

#STDIN для задания – имя файла или /dev/null по умолчанию

#@ input = /dev/null

#STDOUT для задания (выходные данные)

#По умолчанию: /dev/null

#@ output = /gpfs/home/iu6/username/projectname/hello.$(user).$(jobid).stdout

#STDERR для задания (вывод ошибок)

#@ error = /gpfs/home/iu6/username/projectname/hello.$(user).$(jobid).stderr

#@ initialdir = /gpfs/home/iu6/username/projectname/

#notification - Specifies when the user specified in the notify_user keyword is sent mail.

#Syntax: notification = always|error|start|never|complete

#@ notification = complete

#node – Минимальное и максимальное число узлов, необходимое шагу задания.

#Syntax: node = [min][,max]

#@ node = 32

#@ tasks_per_node = 2

#node_usage – Показывает разделяет ли данный шаг задания узлы с другими шагами.

#Syntax: node_usage = shared | not_shared

#@ node_usage = shared

#Необходимо выражение queue, помещающее шаг задания в очередь

#@ queue

echo "-------------------------------------------------------"

echo LOADL_STEP_ID = $LOADL_STEP_ID

echo HOSTNAME: `hostname`

echo "-------------------------------------------------------"

mpdboot -r ssh -n `cat $LOADL_HOSTFILE|sort|uniq|wc -l` -f $LOADL_HOSTFILE

mpirun -r ssh -machinefile $LOADL_HOSTFILE -n $LOADL_TOTAL_TASKS ./hello.c.exe 100000

mpdallexit

Замените в файле задания пути для выходного файла и файла ошибок для Вашего пользователя и названия папки проекта! Файл должен быть сохранен в кодировке UTF-8 (Обратить на это внимание при редактировании файла в текстовом редакторе ОС Windows). Можно изменить файл уже после копирования в ОС кластера с помощью текстового редактора nano.

Ниже следует текст MPI-программы hello.c, которая выводит на экран приветствия от каждого процесса.

/* hello.c */

#include <stdio.h>

/* Необходимо подключить для MPI_* функций */

#include "mpi.h"

int main(int argc, char **argv) {

 int rank;

 char host[150];

  int namelen;

 /* Инициализация MPI. Тут передаются специфические для командной строки mpich аргументы */

 MPI_Init(&argc, &argv);

 /* Получение номера процесса. Номер rank сохраняется в переменную 'rank' */

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

 /* Узнаем на котором компьютере запущено. Сохраним имя в 'host' */

 MPI_Get_processor_name(host,&namelen);

  printf("Hello world (Rank: %d / Host: %s)\n", rank, host);

  fflush(stdout);

 /* Заключение: Закрываем соединения к остальным дочерним процессам, очистка памяти

 * где была расположена библиотека MPI и т д */

 MPI_Finalize();

 return 0;

}

5. Компиляция программы

mpicc -o hello.c.exe hello.c

или

mpicc -o hello.c.exe hello6.c -lm

6. Постановка программы в очередь

 /gpfs/LoadL/bin/llsubmit ./hello.job

или

 llsubmit hello.job

При успешной постановке в очередь последует отклик с номером Вашего задания:

llsubmit: The job "mgmt.nodes.489" has been submitted.

Для запуска задач на кластере служит команда mpirun. Но в интерактивном режиме она используется очень редко и только привилегированными группами пользователей. На многопользовательских системах одновременно несколько пользователей, обладающих разными приоритетами (студенты, аспиранты, сотрудники, …), отправляют на счет задачи, предъявляющие различные требования к вычислительным ресурсам (число процессоров, максимальное время счета, …). Т.е., как правило, проходит некоторое время между отправкой задачи и ее постановкой на счет. Именно поэтому использование mpirun в интерактивном режиме с frontend-серверов пользователями системы невозможно. Для управления заданиями применяется специальная программа, называемая планировщиком задач, или диспетчером очереди, которая внутри себя и вызывает mpirun. На кластере установлен планировщих задач IBM Tivoli LoadLeveler. Чтобы поставить задание в очередь, необходимо подготовить специальный командный файл, в котором будет указан путь к исполняемому файлу и запрашиваемые программой ресурсы.

Полный список и подробное описание команд планировщика можно найти в официальной документации, здесь же мы приведем только самые необходимые:

llsubmit — постановка задания в очередь

llq — просмотр очереди заданий

llcancel — удаление задания из очереди

llhold — приостановка/продолжение продвижения задания в очереди

llmodify — изменение параметров задания

llprio — изменение приоритета задания

llclass — информация о классах заданий

llstatus — информация о машине

Краткую справку о ключах командной строки можно получить, использовав параметр -H, например:

llsubmit -H

7. Просмотр результатов работы программы

Во-первых, проверим очередь заданий, чтобы убедиться, что задание запущено:

 llq

Отклик:

Id  Owner Submitted ST PRI Class Running On

------------ ---------- ----------- -- --- ------------ -----------

mgmt.490.0 barsic 10/1 11:57 R 50 small_mpi  n1107 

mgmt.456.0 barsic 9/21 17:04 H 50 small 

2 job step(s) in queue, 0 waiting, 0 pending, 1 running, 1 held, 0 preempted

В выведенной таблице выводится следующая информация: 

Id

Идентификатор задания: имя_машины.номер_задания.номер_шага

Owner

Идентификатор пользователя, от имени которого запускается задание

Submitted

Дата и время постановки задания в очередь, причем дата записана в североамериканском формате (т.е. 10/6 соответствует 6-му октября)

ST

Состояние задания (здесь приведены не все возможные значения):

R — задание выполняется в данный момент («Running»)

ST — задание запускается в данный момент («Starting»)

P — задание переведено в процессе запуска («Pending»)

I — задание ожидает своей очереди на запуск («Idle»)

H — прохождение задания приостановлено пользователем («User Hold»)

NQ — задание не готово к запуску («Not Queued»)

C — задание завершено («Completed»)

PRI

Приоритет задания

Class

Класс задания

Running On

Имя машины, на которой работает задание; пусто, если задание еще не запущено

Если необходимо удалить задание из череди, воспользуйтесь командой

llcancel mgmt.490.0

или

llcancel 490

После удаления задания из очереди все задания пользователя будут заблокированы (статус H=held). Для продолжения работы использовать команду llhold для всех заданий пользователя:

llhold -r -u username

или для конкретного задания:

llhold -r mgmt.490.0

Далее необходимо проверить содержимое файлов *.stdout и *.stderr с помощью редактора nano. Содержимое при успешном выполнении будет следующим:

-------------------------------------------------------

LOADL_STEP_ID = mgmt.nodes.497.0

HOSTNAME: n2313.nodes

-------------------------------------------------------

Hello world (Rank: 0 / Host: n2313)

Hello world (Rank: 1 / Host: n2313)

Hello world (Rank: 20 / Host: n1112)

Hello world (Rank: 21 / Host: n1112)

Hello world (Rank: 30 / Host: n3207)

Hello world (Rank: 31 / Host: n3207)

и т. д.

Файл ошибок не будет содержать записей.

Используя навыки работы с кластером, полученные при работе с программой hello необходимо запустить программу вычисления числа π.

Программа вычисляет число π с помощью нахождения значений интеграла:

 Интеграл представляется как сумма n интервалов. Апроксимация интеграла на каждом интервале:

(1/n)*4/(1+x*x)

  Главный процесс (порядок 0) запрашивает у пользователя число интервалов и затем должен передать это число остальным процессам. Каждый процесс затем вычисляет n-ый интервал (x = -1/2+rank/n, -1/2+rank/n+size/n,...). В результате, суммы вычисленные каждым процессом суммируются вместе.

Код программы (*.с файл):

#include <stdio.h>

#include <math.h>

#include "mpi.h"

double Func1(double a) {

 return (4.0 / (1.0 + a*a));

}

int main(int argc, char *argv[]) {

 int done = 0, n, myid, numprocs, i;

  double PI25DT = 3.141592653589793238462643;

 double mypi, pi, h, sum, x;

 double startwtime, endwtime;

 int namelen;

 char processor_name[MPI_MAX_PROCESSOR_NAME];

 

 MPI_Init(&argc,&argv);

 MPI_Comm_size(MPI_COMM_WORLD,&numprocs);

 MPI_Comm_rank(MPI_COMM_WORLD,&myid);

 MPI_Get_processor_name(processor_name,&namelen);

 

  fprintf(stderr,"Process %d on %s\n", myid, processor_name);

  fflush(stderr);

 n = 0;

 while (!done)

 {

  if (myid == 0)

 {

 printf("Enter the number of intervals: (0 quits) ");fflush(stdout);

 n = 6;

 startwtime = MPI_Wtime();

 }

 MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);

  if (n == 0)

 done = 1;

 else

 {

 h = 1.0 / (double) n;

 sum = 0.0;

 for (i = myid + 1; i <= n; i += numprocs)

 {

 x = h * ((double)i - 0.5);

 sum += Func1(x);

 }

 mypi = h * sum;

 

 MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);

 if (myid == 0)

 {

 printf("pi is approximately %.16f, Error is %.16f\n", pi, fabs(pi - PI25DT));

fflush(stdout);

 endwtime = MPI_Wtime();

 printf("wall clock time = %f\n", endwtime-startwtime);

fflush(stdout);

 }

 }

 }

 MPI_Finalize();

return 0;

}

Для запуска программы на кластере необходимо создать фал задания. Взяв за основу файл задания hello.job нужно ввести в него необходимые изменения:

название проекта: #@job_name = pi

выходные файлы *.stdout и *.stderr должны иметь другое название (заменить hello на pi)

для выполнения программы будет достаточно 6 узлов, по одному заданию на каждый:

#@node = 6

#@tasks_per_node = 1

количество повторений запуска программы равно 1 вместо 100000, как было для hello (исправить параметр для функции mpirun).

Успешное выполнение файла записывает в *.stderr номера участвующих процессов, а в *.stdout — время выполнения и значение числа π.

Process 0 on n1102

Process 62 on n3312

и т. д.

-------------------------------------------------------

LOADL_STEP_ID = mgmt.nodes.503.0

HOSTNAME: n1102.nodes

-------------------------------------------------------

pi is approximately 3.1416009869231232, Error is 0.0000083333333301

wall clock time = 3.091967

pi is approximately 3.1416009869231232, Error is 0.0000083333333301

wall clock time = 0.002079

и т. д.

В этом алгоритме нет большого количества передач сообщений. Поэтому время соединений незначительно и у нас практически линейное увеличение скорости (при 6 процессах на 6 разных машинах увеличение в среднем около 5.8).

Иногда кластер выдаёт следующие ошибки в stdout:

-------------------------------------------------------

LOADL_STEP_ID = mgmt.nodes.128.0

HOSTNAME: n1103.nodes

-------------------------------------------------------

mpdboot_n1103.nodes (handle_mpd_output 703): Failed to establish a socket connection with n2307.nodes:40557 : (111, 'Connection refused')

mpdboot_n1103.nodes (handle_mpd_output 720): failed to connect to mpd on n2307.nodes

WARNING: Can't read mpd.hosts for list of hosts, start only on current

mpiexec: unable to start all procs; may have invalid machine names

remaining specified hosts:

172.22.12.12 (n1212.nodes)

172.22.22.13 (n2213.nodes)

mpdallexit: cannot connect to local mpd (/tmp/mpd2.console_stud101); possible causes:

1. no mpd is running on this host

2. an mpd is running but was started without a "console" (-n option)

Чаще всего это означает, что необходимо уменьшить число используемых узлов #@node и заданий, выполняемых каждым узлом #@tasks_per_node.

Попробуйте изменить значения в файле задания *.job слудующим образом:

#@node = 1

#@tasks_per_node = 4

Вопросы для самопроверки

Какой командой можно получить исполняемый код параллельной программы?

Как запустить параллельную программу на кластере?

Для чего необходим файл задания IBM LoadLeverer?

Где находятся результаты работы программы?

Как посмотреть статус запущенного задания?

Задание на лабораторную работу

Необходимо скомпилировать и запустить на кластере две параллельных программы "Hello world" и вычисления числа π. Продемонстрировать результат работы программ преподавателю и получить отметку о выполнении работы.

Оформить отчет о проделанной работе.

Содержание отчета

Цель работы.

Ответы на вопросы для самопроверки.

Схемы алгоритмов запуска заданий, самих задач и их описание.

Распечатки файлов вывода, полученных в результате работы программы.

Анализ полученных результатов.

Лабораторная работа №8. Написание программ с использованием библиотеки MPI

Цель работы – изучение структуры MPI-программ и практическая реализация программ.

Теоретическая часть

Основная схема программы MPI подчиняется следующим общим шагам:

Инициализация для коммуникаций

Коммуникации распределения данных по процессам

Выход "чистым" способом из системы передачи сообщений по завершении коммуникаций

MPI имеет свыше 125 функций. Тем не менее, начинающий программист обычно может иметь дело только с шестью функциями, которые перечислены ниже:

Инициализация для коммуникаций

MPI_Init инициализирует окружение MPI

MPI_Comm_size возвращает число процессов

MPI_Comm_rank возвращает номер текущего процесса (ранг = номер по-порядку)

Коммуникации распределения данных по процессами

MPI_Send отправляет сообщение

MPI_Recv получает сообщение

Выход из системы передачи сообщений

MPI_Finalize

Сообщения MPI состоят из двух основных частей: отправляемые/получаемые данные, и сопроводительная информация (записи на конверте /оболочке/), которая помогает отправить данные по определенному маршруту. Обычно существуют три вызываемых параметра в вызовах передачи сообщений MPI, которые описывают данные и три других параметра, которые определяют маршрут:

Сообщение = данные (3 параметра) + оболочка (3 параметра)

Данные определяют информацию, которая будет отослана или получена. Оболочка (конверт) используется в маршрутизации сообщения к получателю и связывает вызовы отправки с вызовами получения.

Коммуникаторы гарантируют уникальные пространства сообщений. В соединении с группами процессов их можно использовать, чтобы ограничить коммуникацию к подмножеству процессов.

Для C, общий формат фактических вызовов, используемых MPI, имеет вид

rc = MPI_Xxxxx(parameter, ... )

Заметим, что регистр здесь важен. Например, MPI должно быть заглавным, так же как и первая буква после подчеркивания. Все последующие символы должны быть в нижнем регистре. Переменная rc --- есть некий код возврата, имеющий целый тип. В случае успеха, он устанавливается в MPI_SUCCESS.

Программа на C должна включать файл "mpi.h". Он содержит определения для констант и функций MPI. В приложении 8.5 приводятся тексты программ на языке Си с использованием библиотеки MPI. Получите у преподавателя номер образца задачи, которую Вам надо выполнить на кластере и выполнить требуемое задание.

Вопросы для самопроверки

Какую структуру имеет простая MPI-программа?

Какие основные функции реализует библотека MPI?

Как организовать передачу сообщений между процессами?

Для чего используются коммуникаторы?

Задание на лабораторную работу

Необходимо разработать MPI-программы в соответствии с таблицей вариантов заданий (Таблица 8.1):

Передачи сообщений с буферизацией;

С использованием таймера;

С определением структуры проходящего сообщения;

С анализом тупиковых ситуаций при обмене;

Определяющую базовые характеристики коммуникационной сети: латентность;

Определяющую базовые характеристики коммуникационной сети: максимально достижимую пропускную способность и длину сообщений, на которой она достигается;

Приёма-передачи сообщений без блокировки;

Реализацию отложенных запросов на взаимодействие;

Или другую на свой выбор, использующую функциональные возможности библиотеки MPI.

 Таблица 8.1

№ варианта

№ примеров, необходимых к реализации

№ варианта

№ примеров, необходимых к реализации

1

2

3

4

5

6

7

8

13, 18

1, 20

2, 16

3, 11

12

14

19

4,17

9

10

11

12

13

14

15

16

15

9

7

4, 6

5, 17

6, 11

1, 8

2, 10

Продемонстрировать работающую программу преподавателю и получить отметку о ее выполнении.

Оформить отчет о проделанной работе.

Содержание отчета

Цель работы.

Ответы на вопросы для самопроверки.

Схемы алгоритмов и их описание.

Распечатки файлов вывода, полученных в результате работы программы.

Анализ полученных результатов.

Лабораторные работы