\subsection{Компоновка} \index{OpenCL компоновщик}% \index{oclh_lr@\texttt{oclh\_lr}}% Изолированная компоновка (линковка) осуществляется утилитой \verb|oclh_lr|. \subsubsection{Синопсис} \begin{CodeParWithCC}{\\\{\}} oclh_lr [--dev-idxs=\underline{\smash{\textit{#}}},\underline{\smash{\textit{#}}},... | --dev-name=\underline{\smash{\textit{mask}}}] [--verbatim-output-name] [-o \underline{\smash{\textit{outfile}}}] [LINKER_OPTIONS] \underline{\smash{\textit{infile}}}... \end{CodeParWithCC} \subsubsection{Описание} При вызове \verb|oclh_lr| осуществляется компоновка (линковка) объектных файлов \verbIU{infile}\verb|...| для всех доступных в системе устройств GPGPU. При этом необходимо понимать, что могут быть скомпонованы только объекты скомпилированные для одной архитектуры GPGPU, а архитектуры ускорителей могут отличаться даже у одного производителя. При попытке скомпоновать объект скомпилированный для архитектуры отличной от архитектуры устройства будет выдана ошибка \verb|-42| OpenCL API:\\* \centerline{\Verb|oclerr: clCreateProgramWithBinary returned error -42 - CL\_INVALID\_BINARY|}\\* В связи с изложенным рекомендуется запускать компоновщик только для одного устройства или модели устройств используя ключ \verb|--dev-idxs=|\verbIU{\#}\verb|,|\verbIU{\#}\verb|,...| или \verb|--dev-name=|\verbIU{mask}. Если указан ключ \verb|--dev-idxs=|% \verbIU{\#}\verb|,|\verbIU{\#}\verb|,...|, то будет осуществлена компоновка только для устройств с индексами \verbIU{\#}\Verb|,|\verbIU{\#}\Verb|,...| (подробнее~см.~п.\ref{subsubsec:lr_args}). Если указан ключ \verb|--dev-name=|% \verbIU{mask}, то будет осуществлена компоновка только для устройств, модель которых соответствует маске \verbIU{mask} (подробнее~см.~п.\ref{subsubsec:lr_args}). Во время работы \verb|oclh_lr| ведётся подробный диагностический журнал в файле \verb|oclh_lr.log|, куда сохраняется избыточная информация обо всех доступных устройствах GPGPU, используемых платформах и созданных для компоновки контекстах. Формат файла-журнала описан в п.\ref{subsec:logformat}. Журнал компоновки программы ведётся в отдельных файлах \verbIU{outfile}\verb|-|\verbI{модель\_устройства\_GPGPU}\verb|-link.log|. Результат работы компоновщика -- исполняемый файл-объект или библиотека сохраняется в файле \verbIU{outfile}\verb|-|\verbI{модель\_устройства\_GPGPU}\verb|.clexe| или \verbIU{outfile}\verb|-|\verbI{модель\_устройства\_GPGPU}\verb|.clso|, соответственно. Если указан ключ \verb|--verbatim-output-name|, то результат будет сохранен в файле \verbIU{outfile}. Иногда возникает ситуация, когда библиотека OpenCL производителя устройства выдала в качестве результата несколько двоичных файлов, в таком случае все двоичные файлы будут сохранены, но к именам файлов будет добавлен постфикс \verb|.|\verbI{N}, где \verbI{N}~--~десятичное число обозначающее порядковый номер (начиная с ноля) двоичного блока сформированного компилятором производителя устройства GPGPU. Если ключ \verb|-o| не указан, то \verbIU{outfile} в названии файла будет заменён на подстроку вида \verb|program_0x|\verbI{HHHH}. В случае если модель устройства GPGPU средствами OpenCL определить не удалось, тогда \verbI{модель\_устройства\_GPGPU} будет заменена на подстроку вида \verb|dev_0x|\verbI{HHHH}. В приведённых подстановках \verbI{HHHH} это шестнадцатеричное представление последних двух байт адресов программы и устройства GPGPU, соответственно. Так как для одного запуска адрес программы и устройства GPGPU уникален, с большой вероятностью два последних байта также уникальны, поэтому могут быть использованы как подстрока для поиска связанных записей в файле основного журнала \verb|oclh_lr.log|. Имя файла основного журнала \verb|oclh_lr.log| и пути сохранения файлов могут быть изменены при сборке библиотеки OpenCL helpers в заголовочном файле\\* \indent\indent\verb|src/inc/oclh_settings.h|\\* Данное имя и пути сохранения журналов и результатов компоновки определены в макросах\\* \indent\indent\verb|#define _GHM_LOG_PATH "."|\\* \indent\indent\verb|#define _GHM_OCLH_LINKER_LOG_FILENAME "oclh_lr.log"| \subsubsection{Аргументы} \label{subsubsec:lr_args} {\NmCnvDescript\verb|--dev-idxs=|\verbIU{\#}\Verb|,|\verbIU{\#}\verb|,...|\\* числа \verbIU{\#}\verb|,|\verbIU{\#}\verb|,...|, указанные без пробелов через запятую после ключа \verb|--dev-idxs=| это порядковые номера (индексы) устройств GPGPU в системе, для которых будет осуществлена компоновка. Индексы начинаются с ноля. Узнать индекс конкретного устройства можно из файла-журнала, в начальной секции которого в описании устройства самая первая строка имеет вид\par {\hspace{2\leftskip}\verbI{YYYY}\verb|-|\verbI{MM}\verb|-|\verbI{DD}% \verb| |\verbI{hh}\verb|:|\verbI{mm}\verb|:|\verbI{ss}% \verb| ws_0x|\verbI{HHHH}\verb| dev_0x|\verbI{HHHH}% \verb+ | Device index: +\verbI{N}},\par \noindent где \verbI{N}~--~индекс данного устройства.\par} {\NmCnvDescript\verb|--dev-name=|\verbIU{mask}\\* строка \verbIU{mask}, указанная после ключа \verb|--dev-name=| это маска, которая указывает для каких моделей устройств, присутствующих в системе будет осуществлена компоновка. Символами подстановки являются:\par \hspace{2\leftskip}\verb|?| -- замещает один любой символ;\par \hspace{2\leftskip}\verb|*| -- замещает любое количество любых символов.\par \noindent При отсутствии символов подстановки \verbIU{mask} рассматривается как точное наименование модели устройства. Узнать модель конкретного устройства можно из файла-журнала, в начальной секции которого в описании устройств присутствует строка вида\par {\hspace{2\leftskip}\verbI{YYYY}\verb|-|\verbI{MM}\verb|-|\verbI{DD}% \verb| |\verbI{hh}\verb|:|\verbI{mm}\verb|:|\verbI{ss}% \verb| ws_0x|\verbI{HHHH}\verb| dev_0x|\verbI{HHHH}% \verb+ | Device name: +\verbI{модель}}\par \noindent где \verbI{модель}~--~и есть строка, которая проверяется на соответствие маске \verbIU{mask}.\par} {\NmCnvDescript\verb|--verbatim-output-name|\\* данный ключ предписывает компоновщику не добавлять к имени выходного файла модель устройства и расширение, а использовать его именно так как указано. Однако, в случае если результатом работы компоновщика является не один двоичный блок, то к имени будет добавлен постфикс \verb|.|\verbI{N}, где \verbI{N}~--~десятичное число обозначающее порядковый номер (начиная с ноля) двоичного блока сформированного компоновщиком производителя устройства GPGPU.\par} {\NmCnvDescript\verb|-o |\verbIU{outfile}\\* строка \verbIU{outfile}~--~имя выходного файла. Если не задан ключ \verb|--verbatim-output-name|, то \verbIU{outfile} используется как префикс имени файла \verbIU{outfile}\verb|-|% \verbI{модель\_устройства\_GPGPU}\verb|.clexe| или \verbIU{outfile}\verb|-|% \verbI{модель\_устройства\_GPGPU}\verb|.clso|, содержащего двоичный блок кода сформированный в результате компоновки. В случае, если ключ \verb|--verbatim-output-name| указан, то \verbIU{outfile} используется <<как есть>>, за исключением случаев, когда в результате компоновки сформированы несколько двоичных блоков~--~в таком случае все двоичные блоки будут сохранены с именами файлов \verbIU{outfile}\verb|.|\verbI{N}, где \verbI{N}~--~порядковый номер двоичного блока начиная с ноля. Кроме того строка \verbIU{outfile} будет использована как префикс в имени файла-журнала компоновки.\par \begin{ImpNote} Пробельные символы в начале и в конце строки \verbIU{outfile} будут удалены. Пробельные символы внутри строки \verbIU{outfile} будут заменены на знак подчёркивания~<<\verb|_|>>~(underscore). \end{ImpNote} } {\NmCnvDescript\verb|LINKER_OPTIONS|\\* аргументы компоновщика. В неизменённом виде и с сохранением последовательности передаются компоновщику производителя. Сами аргументы компоновщика описаны в спецификациях OpenCL, кроме того, компоновщик производителя может поддерживать дополнительные аргументы не отражённые в спецификациях OpenCL.\par} {\NmCnvDescript\verbIU{infile}\verb|...|\\* список разделённый пробелами с именами файлов содержащих скомпилированные объекты OpenCL. Имя файла не может начинаться с символа~<<\verb|-|>>.\par}