\subsection{Третий этап -- тестирование и решение возникших проблем}

Поскольку работа ведётся с исходным кодом фортран-программ, множество возможных вариантов входных программ слишком велико, чтобы предусмотреть абсолютно все ситуации на этапе реализации. Из-за этого было необходимо произвести тщательное тестирование, чтобы выявить основные случаи некорректного поведения системы SAPFOR.

Было проведено тщательное тестирование добавленного функционала на предмет корректности. Оно проводилось как на небольших модельных примерах, так и на больших примерах практически используемых программ. Суммарно за всё тестирование было обнаружено порядка тридцати различных примеров некорректного поведения добавленного режима. Далее описаны наиболее содержательных из найденных ошибок и то, как они были исправлены.

Первая из них касалась обработки приватных массивов. При распределении данных в DVM-системе запрещается распределять массивы, которые являются приватными хотябы для одного цикла. Поэтому в системе SAPFOR такие массивы не отображаются на циклы при построении схемы распределения данных. При распараллеливании на общую память DVM система допускает использование одного массива в качестве приватного и неприватного для разных циклов. Поэтому для режима распараллеливания на общую память было добавлено отображение на цикл всех неприватных для него массивов (в частности, это нужно для заполнения клаузы TIE). Из-за этого пришлось внести правки в проход LOOP\_ANALYZER\_NODIST.

Ещё одна проблема связана с обработкой передаваемых в процедуры секций массивов. Дело в том, что в DVM-системе запрещено использование в разных циклах пересекающихся по памяти различных секций массивов. Рассмотрим следующий пример:

\begin{lstlisting}[style=FORT,caption={пример, вызывающий ошибку выполнения.}]
program p
    ...
    integer:: A(100)
    call foo(A)

!DVM$ REGION
!DVM$ PARALLEL (i), TIE(A(i))
    do i = 1, 100
        A(i) = ...
    endo
!DVM$ END REGION
end

subroutine foo(A)
    integer:: A(50)

!DVM$ REGION
!DVM$ PARALLEL (i), TIE(A(i))
    do i = 1, 50
        A(i) = ...
    endo
!DVM$ END REGION
end
\end{lstlisting}

В нём нём есть два параллельных цикла (строки 8 и 19). Один из них использует полный массив A (который объявлен на строке 3). Другой же использует секцию массива A, которая содержит его первые 50 элементов (объявление на строке 15). Запуск этого примера приводит к ошибке выполнения системы DVM. При этом если бы в подпрограмме \texttt{foo} было объявлено, что массив имеет размер 100 (то есть фактически передавался бы массив целиком), то ошибки бы не было.

В случае аналогичного распараллеливания с распределением, ошибок выполнения DVM не возникает. Из-за этого в цепь проходов распараллеливания на общую память был добавлен новый проход, который получил название SELECT\_ARRAY\_DIM\_CONF. Он запускается после анализа циклов и фильтрует параллельные циклы так, чтобы в них не было пересечений по памяти используемых массивов. При обнаружение конфликтной группы циклов, выбирается один из них, который будет распараллелен, а другие к распараллеливанию не допускаются.

Таким образом схема проходов нового режима получила окончательный вид, представленный на Рис. \ref{fig:deps-final}:

% \pagebreak
\begin{figure}[h]
\centering
\includegraphics[scale=0.5]{src/assets/pass_deps_nodist_1.png}
\caption{итоговая схема работы проходов при распределении на общую память.}

\label{fig:deps-final}
\end{figure}