Главная / Обучение / Практикум / Запуск массива заданий с использованием GridWay

Запуск массива заданий с использованием GridWay.

Этот практикум демонстрирует возможность запуска массива заданий, используя метапланировщик GridWay. В качестве примера рассматривается известный алгоритм по вычислению числа π.

Предварительные действия

Прежде чем выполнять какие-либо действия необходимо получить прокси-сертификат для того чтобы получить доступ к грид-ресурсам.

  $ voms-proxy-init -voms gilda
  Enter GRID pass phrase:
  Your identity: /DC=es/DC=irisgrid/O=ucm/CN=joseluis.vazquez
  Cannot find file or dir: /home/jlvazquez/.glite/vomses
  Creating temporary proxy ................................................. Done
  Contacting  voms.ct.infn.it:15001 [/C=IT/O=INFN/OU=Host/L=Catania/CN=voms.ct.infn.it] "gilda" Done
  Creating proxy ...................................... Done
  Your proxy is valid until Tue Jun  3 08:22:47 2008

Постановка задачи

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

Интегрируемая функция

Интегрируемая функция: f(x) = 4/(1+x2). То есть искомое число π будет равно значению интеграла f(x) на интервале [0,1].

Для того чтобы вычислить этот интеграл, разобьём интервал интегрирования на несколько частей и вычислим их по отдельности.

Разбиение интервала интегрирования

Ясно, что чем больше частей, тем точнее будет вычисленное значение.

Вычисление площади

Итак, у нас есть доступ в Грид с несколькими вычислительными узлами, есть GridWay для запуска заданий.... Почему бы не использовать их для вычисления числа π, распределив вычисление каждой из частей между отдельными узлами и выполнить это одной командой.

Программная часть

Для реализации этого алгоритма выберем язык программирования С. Создайте текстовый файл с именем pi.c и скопируйте в него следующий текст:

#include <stdio.h>
#include <string.h>

int main (int argc, char** args)
{
  int task_id;
  int total_tasks;
  long long int n;
  long long int i;
  double l_sum, x, h;

  task_id = atoi(args[1]);
  total_tasks = atoi(args[2]);
  n = atoll(args[3]);

  fprintf(stderr, "task_id=%d total_tasks=%d n=%lld\n", task_id, total_tasks, n);

  h = 1.0/n;
  l_sum = 0.0;
  for (i = task_id; i < n; i += total_tasks)
  {
    x = (i + 0.5)*h;
    l_sum += 4.0/(1.0 + x*x);
  }
  l_sum *= h;
  printf("%0.12g\n", l_sum);
  return 0;
}

Затем скомпилируйте его при помощи команды

  $ gcc -O3 pi.c -o pi

Важное замечание: в зависимости от архитектуры удалённых узлов (32 или 64 разрядная) необходимо добавить соответствующий флаг -m32 или -m64.

После компиляции вы получите исполняемый файл pi. Эта программа принимает три параметра:

Описание задания

Для того чтобы использовать GridWay для выполнения задания, необходимо подготовить файл описания задания. В нашем случае он будет называться pi.jt. Создайте файл с таким именем и скопируйте в него следующий текст:

  EXECUTABLE  = pi
  ARGUMENTS   = ${TASK_ID} ${TOTAL_TASKS} 100000
  STDOUT_FILE = stdout_file.${TASK_ID}
  STDERR_FILE = stderr_file.${TASK_ID}
  RANK        = CPU_MHZ

Важное замечание: если исполняемый файл скомпилирован для определённой архитектуры (скажем для определённости для 32-разрядной), а есть вероятность того что в Грид присутствуют узлы с 64-разрядной архитектурой, то в файл описания задания необходимо добавить ограничение для использования только 32-разрядных узлов.

  REQUIREMENTS = ARCH="x86"

Запуск задания

Теперь необходимо запустить задание. Это выполняется командой:

  $ gwsubmit -v -t pi.jt -n 4
  ARRAY ID: 1

  TASK JOB
  0    15
  1    16
  2    17
  3    18

Для того чтобы ожидать завершения всех заданий используется команда gwwait. Аргумент, передаваемый этой команде - это идентификатор, присвоенный всему массиву заданий. Он выдаётся в качестве выходных данных команды gwsubmit, если при запуске указана опция -v. Это значение можно также получить при помощи команды gwps.

Команда gwwait блокирует консоль и возвращает упраление только когда завершатся все задания из массива.

   $ gwwait -v -A 1
   0   : 0
   1   : 0
   2   : 0
   3   : 0

Если команда была вызвана с опцией -v, то для каждого задания массива выводится код завершения (обычно код=0 означает успешное завершение).

Получение и обработка результатов

При завершении каждое из заданий создаёт файл с выходными данными. В нашем случае в текущей директории будут созданы файлы:

   stdout_file.0
   stdout_file.1
   stdout_file.2
   stdout_file.3

Всё что нам остаётся сделать - просуммировать результаты из каждого файла. Проще всего это выполнить, используя скрипт для awk.

   $ awk 'BEGIN {sum=0} {sum+=$1} END {printf "Pi is %0.12g\n", sum}' stdout_file.*
   Pi is 3.1415926536

Не очень высокая точность, не правда ли? Вы можете запустить задание ещё раз, увеличив интервал разбиения, скажем до 10 000 000 000. Как вы думаете, надо ли увеличивать количество заданий? На что это повлияет? Какой компромиссный вариант следует выбрать ?

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

    #!/bin/sh

  AID=`gwsubmit -v -t pi.jt -n 4 | head -1 | awk '{print $3}'`

  if [ $? -ne 0 ]
  then
      echo "Submission failed!"
      exit 1
  fi

  gwwait -v -A $AID

  if [ $? -eq 0 ]
  then
      awk 'BEGIN {sum=0} {sum+=$1} END {printf "Pi is %0.12g\n", sum}' stdout_file.*
  else
      echo "Some tasks failed!"
  fi

Дополнительная информация

Для получения дополнительной информации посетите сайт документации по GridWay .


egee@pnpi.nw.ru

©2004-2010 ПИЯФ РАН им. Б.П.Константинова

СтатистикаСтатистика сайта