Кто-нибудь имеет опыт использования расширений C для Mathematica (LibraryLink или MathLink - в настоящее время я использую LibraryLink) с удаленными параллельными ядрами?
Вкратце: как я могу прозрачно использовать определенную библиотекой функцию (см. CreateLibrary и LibraryFunctionLoad ) как в параллельных, так и в непараллельных оценках, когда подчиненные ядра работают на удаленном компьютере
Я ищу некоторые шаги настройки, которые позволят мне иметь функцию libraryFun
(написанную на C), которую можно вызывать либо как libraryFun[args]
, либо параллельно ( и of *). 1015 * и то же самое с ParallelTable[]
), когда суб-ядра работают на удаленном компьютере.
Удаленное выполнение основного ядра также может быть лучше , если у меня также не было проблем с этим .
Обновление
Тем временем я добился определенного прогресса. Я опишу это здесь.
Во-первых, ParallelEvaluate
оценит выражение во всех параллельных ядрах. Если исходные файлы для расширения C скопированы на удаленный компьютер, мы можем скомпилировать их там следующим образом:
ParallelNeeds["CCompilerDriver`"]
k1 = First@Kernels[]
ParallelEvaluate[SetDirectory["/path/to/source/files"]]
ParallelEvaluate[CreateLibrary["sourefile", "myLibrary"]]
Это нужно сделать только один раз. Я предполагаю, что библиотека уже скомпилирована на главном компьютере с ядром.
После этого во всех последующих сеансах мы можем использовать FindLibrary
на основной и удаленной машинах для загрузки библиотеки.
LibraryFunctionLoad[myFun = FindLibrary["myLibrary"], "fun", ...]
ParallelEvaluate[myFun = LibraryFunctionLoad[FindLibrary["myLibrary"], "fun", ...]]
И тут возникает проблема. Из-за разных путей myFun
будет иметь разные значения в основном и в параллельных ядрах.
Таким образом, вопрос: Как обеспечить , чтобы значение myFun
не было случайно синхронизировано между основным и параллельным ядрами?
Я покажу в отдельных примерах, как это может произойти случайно:
In[1]:= LaunchKernels[2]
Out[1]= {KernelObject[1, "local"], KernelObject[2, "local"]}
Установить значение x
в основном ядре:
In[2]:= x = 1
Out[2]= 1
Обратите внимание, что оно получает то же значение и в удаленных ядрах:
In[3]:= ParallelEvaluate[x]
Out[3]= {1, 1}
Установите другое значение для x
в параллельных ядрах и убедитесь, что они его хранят:
In[4]:= ParallelEvaluate[x = 2]
Out[4]= {2, 2}
In[5]:= {x, ParallelEvaluate[x]}
Out[5]= {1, {2, 2}}
Теперь "невинно" используйте Parallelize
на чем-то, содержащем x
:
In[6]:= Parallelize[Table[x, {10}]]
Out[6]= {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
И посмотрите, как значение x
было повторно синхронизировано между основным и подчиненным ядром.
In[7]:= {x, ParallelEvaluate[x]}
Out[7]= {1, {1, 1}}
Новый вопрос: Как я могу предотвратить автоматическую синхронизацию определенного символа между основным и субядрами?