I have a closed source non-threadsafe C++ shared lib that provides one function f :: ByteString -> ByteString. The run-time of this function can be something between one second and a couple of hours.
I am looking for a way to distribute the calculation to multiple cores/servers (SIMD).
In a nutshell, I'm looking for a framework that provides a function
g :: Strategy b -> (a -> b) -> a -> b
to lift a function that can only be called sequentially into a function that behaves like any other pure function in Haskell.
For instance, I want to be able to write:
parMap rwhnf f args -- will not work
Since f calls a C function in a non-thread-safe lib via FFI, this will not work. Hence, I could replace the function f with a function g that holds a job queue and dispatches the tasks to N separate processes. The processes could run locally or distributed:
parMap rwhnf g args -- should works
Potential frameworks I already looked into are
MPI: Client (Haskell) <-- MPI --> Broker (C++) <-- MPI --> Worker (C++) <--> Lib (C++)
ZeroMQ: Client (Haskell) <-- ZeroMQ --> Broker (C++) <-- ZeroMQ --> Worker (C++) <--> Lib (C++)
Cloud Haskell: Client (Haskell) <-- CloudHaskell --> Worker (Haskell) <-- FFI --> Lib (C++)
Gearman
Erlang: Client (Haskell) <-- Erlang --> Broker (Erlang) <-- Erlang C Node --> Worker (C++)
Each approach has advantages and disadvantages.
MPI will create a lot of security issues and is a pretty heavy-weight solution.
ZeroMQ is a nice solution but would require that I write the broker/load balancer etc. all by myself (especially getting the reliability right is not trivial).
CloudHaskell doesn't look very mature.
Gearman doesn't run on Windows and has no Haskell bindings. I know about java-gearman-service but it is much less mature than the C daemon and has some other issues (e.g. no doc, shuts down if there is no incoming flow of tasks for some time, etc.).
Similar to 1 and requires the use of a third language.
Thanks!