-
Notifications
You must be signed in to change notification settings - Fork 529
Multithreading
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.
- 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.
- 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 callgraph.as_default()
andsession.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(...)
becauseTaskScheduler
can't assure the tasks will be run in different threads, Only way to use Task withTensorflow.NET
is to initiate tasks like this:You must create the session and graph only inside thatTask.Factory.StartNew(() => { ... }, TaskCreationOptions.LongRunning);
Action
passed to theTask
factory. In order to use the graph and session created inside the task on an outside code/different thread, callsess.as_default()
andgraph.as_default()
first. - If a
Graph
orSession
were created inthread x
, in order to use them inthread y
the developer must callSession.as_default()
andGraph.as_default()
first before using it.
Call tf.enforce_singlethreading()
in the begginging of your notebook.
It was created specially for specific cases like Jupyter notebook where different threads can call your code chunks.
This will cause the library to always behave as if it is run on a single thread but does not use any locking calls.
Simply put to words: makes the library forcefully singlethreaded but unsafe multithreaded calls.