在集群上分布 Haskell
Distributing Haskell on a cluster
我有一段处理文件的代码,
processFiles :: [FilePath] -> (FilePath -> IO ()) -> IO ()
此函数生成一个执行 IO 操作的异步进程。此 IO 操作必须通过作业调度系统(例如 Slurm)提交给集群。
因为我必须使用作业调度系统,所以无法使用cloudHaskell 来分发闭包。相反,该程序编写了一个包含所需计算的新 Main.hs,即与 main 依赖的所有模块一起复制到集群节点,然后使用 "runhaskell Main.hs [opts]"。然后异步进程应该定期询问作业调度系统(使用 threadDelay)作业是否完成。
有没有办法避免创建新的 Main?我可以序列化 IO 操作并以某种方式在节点中执行它吗?
是的。有一个神奇的图书馆,叫做packman
。它允许您将任何 haskell 事物转换为数据(只要其中没有 IORef
或相关事物。)这里是您需要的事物:
trySerialize :: a -> IO (Serialized a)
deserialize :: Serialized a -> IO a
instance Typeable a => Binary (Serialized a)
是的,正是这些类型。你可以用trySerialize
打包你的IO
动作,用Binary
把它传送到任何地方,然后deserialize
把IO动作拿出来,准备使用。
packman
的注意事项是:
- 它将事物存储为 thunk。这可能是您想要的,以便节点可以进行评估。
- 就是说,如果你的 thunk 很大,
Binary
可能也会很大。评估 thunk 可以解决这个问题。
- 就像我说的,可变引用是禁忌。需要注意的一件事是,他们在您不知情的情况下 inside thunks。
除此之外,这似乎是您想要的!
我有一段处理文件的代码,
processFiles :: [FilePath] -> (FilePath -> IO ()) -> IO ()
此函数生成一个执行 IO 操作的异步进程。此 IO 操作必须通过作业调度系统(例如 Slurm)提交给集群。
因为我必须使用作业调度系统,所以无法使用cloudHaskell 来分发闭包。相反,该程序编写了一个包含所需计算的新 Main.hs,即与 main 依赖的所有模块一起复制到集群节点,然后使用 "runhaskell Main.hs [opts]"。然后异步进程应该定期询问作业调度系统(使用 threadDelay)作业是否完成。
有没有办法避免创建新的 Main?我可以序列化 IO 操作并以某种方式在节点中执行它吗?
是的。有一个神奇的图书馆,叫做packman
。它允许您将任何 haskell 事物转换为数据(只要其中没有 IORef
或相关事物。)这里是您需要的事物:
trySerialize :: a -> IO (Serialized a)
deserialize :: Serialized a -> IO a
instance Typeable a => Binary (Serialized a)
是的,正是这些类型。你可以用trySerialize
打包你的IO
动作,用Binary
把它传送到任何地方,然后deserialize
把IO动作拿出来,准备使用。
packman
的注意事项是:
- 它将事物存储为 thunk。这可能是您想要的,以便节点可以进行评估。
- 就是说,如果你的 thunk 很大,
Binary
可能也会很大。评估 thunk 可以解决这个问题。 - 就像我说的,可变引用是禁忌。需要注意的一件事是,他们在您不知情的情况下 inside thunks。
- 就是说,如果你的 thunk 很大,
除此之外,这似乎是您想要的!