Skip to content

Multithreading

Eli Belash edited this page Sep 10, 2019 · 15 revisions

Tensorflow.NET is thread-safe, our multithreading model is thread-wide Session and Graph; meaning tf.get_default_graph/session() are unique to the thread they are executed in.

We chose this model because a dominant portion of our api does not accept Graph as a parameter, instead it accesses tf.get_default_graph() to initialize an Operation in it.
This allows cleaner and similar code to Python and still having complete isolation between threads.

Due to lack of documentation in Tensorflow regarding their c_api, we don't know which of their API is threadsafe therefore some issues such as access violation or other types of memory corruption might occur. Let us know about it and we'll work to get it fixed. In most cases wrapping code with lock (Locks.ProcessWide) solves the problem.

Capabilities

  • Initialize sessions, graphs and operations in completely isolation from other threads.
  • Call your_session.run(...) parallely and in separate threads regardless to the defaults in the executing thread.

Limitations

  • When writing a model, it has to be done in the same thread unless yourgraph.as_default() is called in a different thread.
    For example : You can't start a model and then continue it in a Task unless you call graph.as_default() and session.as_default() before doing so.
  • Tensorflow's c_api for the most part is thread-safe, calls of status.Check() sometimes to be inside a process-wide lock, for example:
    lock (Locks.ProcessWide) 
    { 
        var status = new Status(); 
        c_api.someapicall(); 
        status.Check(true); 
    }
  • Lack of support for TPL. Task.Run(...) because TaskScheduler can't assure the tasks will be run in different threads, Only way to use Task with Tensorflow.NET is to initiate tasks like this:
    Task.Factory.StartNew(() => { ... }, TaskCreationOptions.LongRunning);
    If a Graph or Session were created in thread x, in order to use them in thread y the developer must call Session.as_default() and Graph.as_default() first before using it.
Clone this wiki locally