В моей недавней работе с Gibbs sampling
, я очень хорошо использовал RVar
, который, на мой взгляд, обеспечивает почти идеальный интерфейс для генерации случайных чисел. К сожалению, я не смог использовать Repa из-за невозможности использования монадических действий на картах.
Пока ясно, что монадические карты не могут быть распараллелены вообще, мне кажется, что RVar
может быть по крайней мере одним примером монады, где эффекты можно безопасно распараллелить (по крайней мере, в принципе, я не очень хорошо знаком с внутренней обработкой RVar
). А именно, я хочу написать что-то вроде следующего,
drawClass :: Sample -> RVar Class
drawClass = ...
drawClasses :: Array U DIM1 Sample -> RVar (Array U DIM1 Class)
drawClasses samples = A.mapM drawClass samples
где A.mapM
будет выглядеть примерно так:
mapM :: ParallelMonad m => (a -> m b) -> Array r sh a -> m (Array r sh b)
Хотя ясно, как это будет работать, в решающей степени зависит реализация RVar
и ее базового RandomSource
, в принципе можно было бы подумать, что это будет связано с привлечением нового случайного семени для каждого потока, порожденного и продолжающегося, как обычно.
Интуитивно кажется, что эта же идея может быть обобщена на некоторые другие монады.
Итак, мой вопрос: можно ли построить класс ParallelMonad
из монад, для которых эффекты можно безопасно распараллелить (предположительно, заселенными, по крайней мере, RVar
)?
Как это выглядит? Какие другие монады могут обитать в этом классе? Попросили ли вы других рассмотреть возможность того, как это может работать в Repa?
Наконец, если это понятие параллельных монадических действий не может быть обобщено, кто-нибудь видит хороший способ сделать эту работу в конкретном случае RVar
(где это было бы очень полезно)? Отказ RVar
для parallelism - очень сложный компромисс.