реклама на сайте
подробности

 
Личные инструменты

Распределённый запуск задач в локальной сети

Материал из ELECTRONIX.ru Wiki

Перейти к: навигация, поиск

Содержание

Описание проблемы

При проведении функциональной верификации разрабатываемой HDL-модели на соответствие спецификации необходимо построить множество тестовых векторов, число которых для сложных устройств достигает нескольких миллионов и время «прогона» этих тестов составляет десятки часов. При этом все тесты необходимо перепроверять после любого изменения исходной HDL-модели, т. к. теоретически изменения в моделе могут «вылезти» в любом месте. При этом если все тесты запускать на одном компьютере, то о результате можно будет узнать только через несколько дней, а то и недель. В свою очередь множество тестовых наборов независимы друг от друга, т. е. могут быть запущены параллельно, а так как в локальной сети компании есть множество рабочих станций, то стоит задача автоматизировать запуск нескольких десятков различных тестовых наборов. Предлагается решение данной задачи с помощью bash-скриптов на рабочих станциях под UNIX.

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

Предлагаемый подход

Для работы требуется список используемых хостов в локальной сети, который задаётся в файле hostlist и список выполняемых тестов (testslist, который может формироваться автоматически). Запуск начинаестся с программы multirun, которая выполняет каждые 15 с запуск прокрамы status. Программа status с помощью jobspy получает список задействованных хостов, который сравнивает со списком разрешонных для использования хостов (hostlist), создавая список свободных машин (hostfree). Если находятся свободные машины в сети, то производится запуск очередной задачи из списка на удалёноой машине с помощью скрипта onerun. Перед запуском с помощью existfile проводится проверка, что передаваемый тест существует и заданы все исходные данные, необходимые для запуска моделирования, в противном случае текущий тест пропускается. Программа onerun с помощью SSH запускает на удалённом хосте скрипт sr, затем после его выполнения копирует результаты моделирования обратно на головную машину. Программа sr, запускаясь на удалённом хосте, выполняет настройки необходимых переменных среды, после чего запускает моделирование.

Порядок работы

Нужно запустить сервер JOBSPY_DAEMON (демон) на головной машине для мониторинга выполнения моделирования. Для этого нужно добавить переменную среды

setenv JOBSPY_DAEMON <port>@<host>

например, в CSH

setenv JOBSPY_DAEMON 6001@comp01

или в BASH

export JOBSPY_DAEMON=6001@comp01

и старовать демон JOBSPY_DAEMON

jobspy -startd &

Графический интерфейс демона запускается командой

jobspy -gui
!

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

Для запуска моделирования на удалённых машинах необходимо, чтобы был настроен доступ без пароля по SSH. Если не настроен безпарольный доступ, то запускаем скрипт keygen. Этот скрипт формирует файл публичного пароля подключается на хост указанный в hostlist и копирует паблик ключ, вы должны ввести пароль пользователя первый раз, далее подключение будет происходить без запроса пароля.

Генерируем файлы тестов

В файле status указываем путь к тестам и остальные параметры, указанные в срипте

Запускаем multirun

Идем пить чай :)

!

Рекомендую запускать скрипт на удаленной машине, которую не выключают все время моделирования и запускать демона там же (при закрытии консоли, с которой запущен демон происходит его отключение, запущенные сеансы моделирования теряют с ним связь и отключаются, графический интерфейс). Эту проблему можно решисть с помощью программы screen

Особенности работы

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

  • поместите файлы с тестовыми векторами в дирректорию, где храняться предыдущие вектора (можете в новую папку)
  • добавьте список новых тестов в конец файла list_test

Идем пить чай :)

Или если нужно запустить заново все тесты (нашли какой-то баг, исправили и желаете перезапустить) и вы не выгружали скрипт, то УДАЛЯЕМ файл numrun, в котором хранится номер тегущего запуска

Идем пить чай :)

Если вы сформировали новый перечень тестов и не желаете сами вписывать список тестов то

  1. открываем файл numrun и вписываем число всех тестов в дирректории
  2. удаляем файл list_test ждем 15 сек
  3. в новом сформировавщемся файле удалем все ненужные тесты
  4. удаляем файл numrun

Идем пить чай :)

Алгоритм запуска моделирования

1) Создать файл listtest со списком тестов, если он не создан

1.2) Прочитать текущий номер теста из файла numtest

2) Проверить наличие файла <имя теста>.map

  • если нет проверяем наличие файла <имя теста>.gen и наличия в нем строки 2 в которой должен быть <имя теста>.map (наличие которого нужно проверить)
  • если нет <имя теста>.gen, то проверяем <путь к тестам>/general.map
  • если нет general.map, то ОШИБКА запуска файла, нужно перейти к следующему

3) Проверяем наличие файла <имя теста>.gen, если есть, то запоминаем первую строку как входные параметры для vsim.

4) проводим запуск vsim и сохраняем в файле numtest номер запуска++

vsim "<имя теста>.gen[строка 1]" \
     -Geeprom=[<имя теста>.map|<имя теста>.gen[строка 2]|general.map] \
     -Gtst=<имя теста>.vec \
     ....


Описание скриптов

Для работы небоходимо 5 скриптов для удаленного моделирования и 1 файл (hostlist) со списком доступных для запуска хостов:

  • multirun - зарускает моделирование через каждые 15 секунд (время можно задать в скрипте)
  • status - проверяет наличие свободных хостов и, если есть свободные, запускает existfile
  • existfile - проверяет наличие файлов с тестами и формирует строку запуска для ModelSim
  • onerun - делает коннект на удаленный хост и запускает ModelSim с заданными в existfile параметрами, после выполнения моделирования результат (*.wlf и transcript) копирует в заданную дирректорию на головную машину
  • sr - скрипт, который запускается на удаленной машине, он настраивает локальные переменные и запускает ModelSim
  • hostlist - файл, в котором задаётся список доступных удалённых хостов

Содержание файлов

Формат файла hostlist:

В каждой строке задаётся имя хоста (или IP) и число допустимых на нем запусков.

remhost1 X1
  ...
remhostN XN
!

Если в файле использовать IP, а не имя хоста, то точки в адресе нужно маскировать '\'. Но задание хостов по IP-адресам не проверено.

Число допустимых запусков задаётся для эффективного использования многоядерных машин. Например, если на хосте 8 ядер, то на этом хосте можно одновременно моделировать до 7 тестов без потери в прозводительности.

Пример hostlist-файла:

comp05 6
comp-1 1
comp-2 1
comp-3 1
comp-4 3
comp-5 1

Файл multirun

Файл: multirun
#!/bin/bash
delay=15
echo REFRESH $delay sec
watch -n ${delay} -d \.\/status \> tran

Файл status

Файл: status
1   #!/bin/bash
2   #  Скрипт формирует список всех тестов и сохраняет в testlist
3   #  Ищет свободные хосты из списка hostlist и
4   #  запускает тесты из файа testlist по порядку с номера указанного в файле numtest
5   #  пока не выполнит все тесты
6   #  Если файла нету то запускает с 0-го теста на свободном хосте
7  
8   #  В файле нужно задать следующие параметры:
9   #  path_test= "/net/comp01/home/guest/PROJECT/tb/vec"   -- удаленный путь к папке с тестовыми векторами
10  #  path_wave= $PROJECT/tb/script/result                 -- путь на машине с которой ведеться запуск
11  #                                                             -- для сохранения результата моделирования
12  #  path_scr="/net/comp01/home/guest/PROJECT/tb/script"  -- удаленный путь к папке где лежат скрипты для запуска
13 
14  function existfile () #{i,host,vlist}
15  {
16  path_test="$PROJECT/tb/vec"
17  pth=${3}
18  testname=${pth#${path_test}}
19  lll=`basename ${pth}`
20  lll=${pth%${lll}}
21  genfile=""
22  mapfile=""
23  cmdfile=$pth.vec
24  runflag=0
25      if [ -f  ${pth}.map ]
26      then
27          mapfile=${pth}.map
28          runflag=1
29          if [ -f ${pth}.gen ]
30          then
31              genfile=`cat ${pth}.gen | sed -e '2d'`
32          fi
33      else
34          if [ -f ${pth}.gen ]
35          then
36              mapfile=`cat ${pth}.gen | sed -e '1d'`
37              genfile=`cat ${pth}.gen | sed -e '2d'`
38              if [ -z $mapfile ]
39              then
40                  if [ -f ${lll}eeprom.map ]
41                  then
42                      mapfile=${lll}eeprom.map
43                      runflag=1
44                  fi
45              fi
46          else
47              if [ -f ${lll}eeprom.map ]
48              then
49                  mapfile=${lll}eeprom.map
50                  runflag=1
51              fi
52          fi
53      fi
54 
55      if [ $runflag = 1 ]
56      then
57  gvsim="${genfile} \
58     -ginitfile=${mapfile} \
59     -gcommand_file_name=${cmdfile}"
60 
61  echo ${2} ${1} $gvsim $testname
62  ./onerun ${2} ${1} $testname "${gvsim}" &
63      else
64          echo ERROR PARAMETR
65      fi
66  }
67 
68  path_test="/net/comp01/home/guest/PROJECT/tb/vec"
69  path_wave=$PROJECT/tb/script/result                # directory for save result modeling
70   name_wlf=wave_vector                              # name wlf file on remote computer
71   path_scr="/net/comp01/home/guest/PROJECT/tb/script"
72 
73  # ищем все файлы с расшиернием *.vec  в заданной дирректории если нету файла list_test
74  # и записываем все найденные тесты в файл list_test
75 
76  if [ ! -f ./list_test ]
77  then
78  find ${path_test} -name "*.vec" | sed 's/\.vec//g' > list_test
79  echo FIND ALL TEST IN $path_test
80  else
81  echo "LOAD TEST LIST FROM /list_test"
82  fi
83  vec_list=(`cat ./list_test`)
84 
85  # используя демон находим хосты занятые в данные момент
86  jobspy jobs | awk '{ printf $7 "\n" }' | sed -e '1,2d' > ./hostwork
87  
88  if [ -f ./numtest ]
89  then
90      Ns=`cat numtest  | awk '{ printf $1 "\n" }'`      # number start test
91  else
92      Ns=0
93  fi
94  Ne=`cat ./list_test | wc -l`
95  hosts=`cat hostlist | awk '{ printf $1 "\n" }'`
96  hostsnumruns=(`cat hostlist | awk '{ printf $2 "\n" }'`)
97  hostwork=`cat hostwork`
98 
99  if [ -f ./hostfree ]
100 then
101 rm -f ./hostfree
102 fi
103
104 if [ -f ./numtest ]
105 then
106 rm -f ./numtest
107 fi
108
109 # проверяем файл со списком хостов вычеркиваем из него уже заняте хосты и если есть еще тесты то запускаем
110 # на свободных хостах
111 # формируем номер текущего теста и сохраняем в файл numtest
112
113 i=0
114 for namehost in $hosts
115 do
116     numruns=0
117     res=0
118     for nameworkhost in $hostwork
119     do
120     if [ $namehost == $nameworkhost ]
121     then
122     numruns=`expr $numruns + 1`
123     fi
124     done
125     res=`expr ${hostsnumruns[$i]} - $numruns`
126     if [ $res -gt 0 ]
127     then
128         echo $namehost $res >> ./hostfree
129     fi
130     i=`expr $i + 1`   
131 done
132
133
134 hostfree=`cat hostfree | awk '{ printf $1 "\n" }'`
135 hostfreenumruns=(`cat hostfree | awk '{ printf $2 "\n" }'`)
136 j=0
137 for name in $hostfree
138 do
139     numruns=${hostfreenumruns[$j]}
140     while [ $numruns -gt 0 ]
141     do
142     if [ `expr $Ne - $Ns` -gt 0 ]
143     then
144         echo conect to ${name}
145             ./existfile $Ns  ${name} ${vec_list[${Ns}]} &  
146         #run check existfile test vectors
147 #            existfile $Ns ${name} ${vec_list[${Ns}]}     #run check function existfile test vectors       
148         Ns=`expr $Ns + 1`                   
149     fi
150         numruns=`expr  $numruns - 1`   
151     done
152     j=`expr  $j + 1`
153 done
154 echo $Ns > ./numtest

Файл existfile

Файл: existfile
1  #!/bin/bash
2  # Проверяет условие наличия файла тестовых векторов и запускает одно моделирование
3 
4  # Указываем путь к папке с тестовыми векторами на машине,
5  # с которой запускаються тесты
6 
7  # В файл передается три параметра
8  # $1 - имя хоста для удаленного запуска
9  # $2 - номер запуска
10 # $3 - полный путь к файлу с тестовыми векторами
11
12 path_test="$PROJECT/tb/vec"
13 pth=$3 
14 testname=${pth#${path_test}}
15 lll=`basename ${pth}`
16 lll=${pth%${lll}}
17 genfile=""
18 mapfile=""
19 cmdfile=${pth}.vec
20 runflag=0
21 # формируем строку с парметреми моделирования genfile
22 # строку содержащую путь к файлу с описанием СППЗУ *.map
23 # строку содержащую путь к файлу содержамему тестовы выектора *.vec
24 # список файлов формируется исходя из сущесвуеющих файлов {name}.vec
25 # если в дирректории с файлом тестового вектора есть файл *.map с таким же именени
26 # и запускаем моделирование с генериками по умолчанию
27
28     if [ -f  ${pth}.map ]
29     then
30     mapfile=${pth}.map
31     runflag=1
32     if [ -f ${pth}.gen ]
33     then
34             genfile=`cat ${pth}.gen | sed -e '2d'`       
35         # если есть файл генериков то первая строка этого файла и будет параметрами запуска
36         # если она пустая или файла нету то значения моделирования по умолчанию
37     fi
38     else
39     if [ -f ${pth}.gen ]   
40     then
41         mapfile=`cat ${pth}.gen | sed -e '1d'`
42         genfile=`cat ${pth}.gen | sed -e '2d'`
43         if [ -z $mapfile ]
44         then
45             if [ -f ${lll}eeprom.map ]
46         then
47             mapfile=${lll}eeprom.map
48             runflag=1
49         fi
50         fi   
51
52     else
53         if [ -f ${lll}eeprom.map ]
54         then
55         mapfile=${lll}eeprom.map
56         runflag=1
57         fi
58     fi
59     # если {name}.map файла нету то если есть {name}.gen файл
60     # то его вторая строка должна содержать имя {others_name}.map
61     # файла для инициализации СППЗУ, если она вторя строка пустая то проверяем файл по умолчению
62     # eeprom.map в дирректории с тестами если он есть то инициализируем СППЗУ из него и запускаем
63     # моделирование. Если не однин из вариантов не выполняется то запуск не производится
64     fi   
65
66     if [ $runflag = 1 ]
67     then
68 gvsim="${genfile} \
69    -ginitfile=${mapfile} \
70    -gcommand_file_name=${cmdfile}"
71
72 # запускаем моделирование
73
74 echo $2 $1 $gvsim $testname
75 ./onerun $2 $1 $testname "${gvsim}" &
76     else
77     echo ERROR PARAMETR
78     fi

Файл onerun

Файл: onerun
1  #!/bin/bash
2  # В файл передаем четыре параметра  $1 $2 $3 $4
3  # host numrun pathsaveresult  generic
4  # $1 имя хоста для удаленного запуска
5  # $2 номер запуска
6  # $3 путь к файлу с тестовыми векторами
7  # $4 параметры запуска ModelSim
8 
9  path_wlf=$PROJECT/tb/script/result           # directory for save result modeling wave diagram
10 name_wlf=vector                      # name wlf file on remote computer   
11 username=guest                               # username on remote host
12 path_scr="/net/comp01/home/guest/PROJECT/tb/script"
13 user_host=comp01
14 user_name=guest
15
16 # Подключаемся к удаленному хосту и запускаем скрипт
17 ssh ${username}@$1 ${path_scr}/sr ${2} \"${4}\"
18
19 # Формирем имя папки для хохранения результатов моделирования
20 # от $3 сначала строки отнимаем путь к папке с векторами
21 # остаются только название теста и подтеста
22
23 save_path=`echo ${3} | sed 's/\/net\/comp01\/home\/guest\/PROJECT\/tb\/vec\///g'`
24
25 echo COPY FROM ${name} TO ${path_wlf}/$save_path/${name_wlf}_$2.wlf
26
27 # создем папку для сохранения запуска в дирректории $path_wlf а внутри дирректории соответсвующие
28 # запускаемым тестам
29 # копируем в эту папку файл .wlf и transcript с удаленного хоста в эту дирректорию
30 mkdir -p  $path_wlf/$save_path
31 cp --reply yes /net/$1/home/guest/PROJECT_run/run$2/vsim.wlf ${path_wlf}/$save_path/${name_wlf}_$2.wlf
32 cp --reply yes /net/$1/home/guest/PROJECT_run/run$2/transcript ${path_wlf}/$save_path/transcript_$2
33 cp --reply yes /net/$1/home/guest/PROJECT_run/run$2/PROJECT_tb.ucdb ${path_wlf}/$save_path/djin18_tb_$2.ucdb

Файл sr

Файл: sr
#!/bin/sh
hname=`hostname`
echo Run QuestaSim on $hname
export JOBSPY_DAEMON=6001@comp01
export LM_LICENSE_FILE=/lic/lic.dat
export MODEL_TECH=/opt/modelsim/modeltech/
export PATH=$MODEL_TECH/bin:$PATH
export PROJECT="/net/comp01/home/guest/PROJECT"
export vector=${PROJECT}/tb/vec

echo sr run  ${2}

mkdir -p ./PROJECT
cd ./PROJECT
mkdir -p run${1}
cd ./run${1}
vlib ~/PROJECT/run${1}/PROJECT
vmap PROJECT ~/PROJECT/run${1}/PROJECT
#${PROJECT}/tb/script/check "${2}"

LIB_NAME=PROJECT_NAME
PRJ=${PROJECT}
PRJ_LIB=${PRJ}
SRC_VHD=${PRJ_LIB}/vhd
SRC_TB=${PRJ_LIB}/tb

echo run check "${2}"
time vsim -do "do ${SRC_TB}/script/compile_cfg.tcl" -c
testname="PROJECT_tb"
time vsim ${2} \
-t "ps" \
-do "do ${SRC_TB}/script/check.tcl; \
time \"run -all\"; \
coverage save -onexit ${testname}.ucdb; \
exit -f;" \
${LIB_NAME}.${testname} -coverage -novopt -c

echo "OK = [examine /PROJECT_tb/rd/ok]"

Обратная связь

По всем вопросам подержки, доработки и модификации скрипта обращаться

@Mail.ru


Страница сгенерированна за 0.27366 секунд с 6
ELECTRONIX ©2004-2016