Configuration Settings and Compiling Modes

Configuration

The config module contains several attributes that modify Theano’s behavior. Many of theseattributes are examined during the import of the theano module and several are assumed to beread-only.

As a rule, the attributes in the config module should not be modified inside the user code.

Theano’s code comes with default values for these attributes, but you canoverride them from your .theanorc file, and override those values in turn bythe THEANO_FLAGS environment variable.

The order of precedence is:

  • an assignment to theano.config.
  • an assignment in THEANO_FLAGS
  • an assignment in the .theanorc file (or the file indicated in THEANORC) You can display the current/effective configuration at any time by printingtheano.config. For example, to see a list of all active configurationvariables, type this from the command-line:
  1. python -c 'import theano; print(theano.config)' | less

For more detail, see Configuration in the library.

Exercise

Consider the logistic regression:

  1. import numpy
  2. import theano
  3. import theano.tensor as T
  4. rng = numpy.random
  5.  
  6. N = 400
  7. feats = 784
  8. D = (rng.randn(N, feats).astype(theano.config.floatX),
  9. rng.randint(size=N,low=0, high=2).astype(theano.config.floatX))
  10. training_steps = 10000
  11.  
  12. # Declare Theano symbolic variables
  13. x = T.matrix("x")
  14. y = T.vector("y")
  15. w = theano.shared(rng.randn(feats).astype(theano.config.floatX), name="w")
  16. b = theano.shared(numpy.asarray(0., dtype=theano.config.floatX), name="b")
  17. x.tag.test_value = D[0]
  18. y.tag.test_value = D[1]
  19.  
  20. # Construct Theano expression graph
  21. p_1 = 1 / (1 + T.exp(-T.dot(x, w)-b)) # Probability of having a one
  22. prediction = p_1 > 0.5 # The prediction that is done: 0 or 1
  23. xent = -y*T.log(p_1) - (1-y)*T.log(1-p_1) # Cross-entropy
  24. cost = xent.mean() + 0.01*(w**2).sum() # The cost to optimize
  25. gw,gb = T.grad(cost, [w,b])
  26.  
  27. # Compile expressions to functions
  28. train = theano.function(
  29. inputs=[x,y],
  30. outputs=[prediction, xent],
  31. updates=[(w, w-0.01*gw), (b, b-0.01*gb)],
  32. name = "train")
  33. predict = theano.function(inputs=[x], outputs=prediction,
  34. name = "predict")
  35.  
  36. if any([x.op.__class__.__name__ in ['Gemv', 'CGemv', 'Gemm', 'CGemm'] for x in
  37. train.maker.fgraph.toposort()]):
  38. print('Used the cpu')
  39. elif any([x.op.__class__.__name__ in ['GpuGemm', 'GpuGemv'] for x in
  40. train.maker.fgraph.toposort()]):
  41. print('Used the gpu')
  42. else:
  43. print('ERROR, not able to tell if theano used the cpu or the gpu')
  44. print(train.maker.fgraph.toposort())
  45.  
  46. for i in range(training_steps):
  47. pred, err = train(D[0], D[1])
  48.  
  49. print("target values for D")
  50. print(D[1])
  51.  
  52. print("prediction on D")
  53. print(predict(D[0]))

Modify and execute this example to run on CPU (the default) with floatX=float32 andtime the execution using the command line time python file.py. Save your codeas it will be useful later on.

Note

  • Apply the Theano flag floatX=float32 (through theano.config.floatX) in your code.
  • Cast inputs before storing them into a shared variable.
  • Circumvent the automatic cast of int32 with float32 to float64:
    • Insert manual cast in your code or use [u]int{8,16}.
    • Insert manual cast around the mean operator (this involves division by length, which is an int64).
    • Note that a new casting mechanism is being developed.

Solution


Mode

Every time theano.function is called,the symbolic relationships between the input and output Theano _variables_are optimized and compiled. The way this compilation occursis controlled by the value of the mode parameter.

Theano defines the following modes by name:

  • 'FAST_COMPILE': Apply just a few graph optimizations and only use Python implementations. So GPU is disabled.

  • 'FAST_RUN': Apply all optimizations and use C implementations where possible.

    • 'DebugMode': Verify the correctness of all optimizations, and compare C and Python
    • implementations. This mode can take much longer than the other modes, but can identifyseveral kinds of problems.
  • 'NanGuardMode': Same optimization as FAST_RUN, but check if a node generate nans.

The default mode is typically FAST_RUN, but it can be controlled viathe configuration variable config.mode,which can be overridden by passing the keyword argument totheano.function.

short nameFull constructorWhat does it do?
FAST_COMPILEcompile.mode.Mode(linker='py', optimizer='fast_compile')Python implementations only, quick and cheap graph transformations
FAST_RUNcompile.mode.Mode(linker='cvm', optimizer='fast_run')C implementations where available, all available graph transformations.
DebugModecompile.debugmode.DebugMode()Both implementations where available, all available graph transformations.

Note

For debugging purpose, there also exists a MonitorMode (which has noshort name). It can be used to step through the execution of a function:see the debugging FAQ for details.

Linkers

A mode is composed of 2 things: an optimizer and a linker. Some modes,like NanGuardMode and DebugMode, add logic around the optimizer andlinker. NanGuardMode and DebugMode use their own linker.

You can select which linker to use with the Theano flag config.linker.Here is a table to compare the different linkers.

linkergc [1]Raise error by opOverheadDefinition
cvmyesyes“++”As c|py, but the runtime algo to execute the code is in c
cvm_nogcnoyes“+”As cvm, but without gc
c|py [2]yesyes“+++”Try C code. If none exists for an op, use Python
c|py_nogcnoyes“++”As c|py, but without gc
cnoyes“+”Use only C code (if none available for an op, raise an error)
pyyesyes“+++”Use only Python code
NanGuardModenono“++++”Check if nodes generate NaN
DebugModenoyesVERY HIGHMake many checks on what Theano computes
[1]Garbage collection of intermediate results during computation.Otherwise, their memory space used by the ops is kept betweenTheano function calls, in order not toreallocate memory, and lower the overhead (make it faster…).
[2]Default

For more detail, see Mode in the library.

Using DebugMode

While normally you should use the FAST_RUN or FAST_COMPILE mode,it is useful at first (especially when you are defining new kinds ofexpressions or new optimizations) to run your code using the DebugMode(available via mode='DebugMode). The DebugMode is designed torun several self-checks and assertions that can help diagnosepossible programming errors leading to incorrect output. Note thatDebugMode is much slower than FAST_RUN or FAST_COMPILE souse it only during development (not when you launch 1000 processes on acluster!).

DebugMode is used as follows:

  1. x = T.dvector('x')
  2.  
  3. f = theano.function([x], 10 * x, mode='DebugMode')
  4.  
  5. f([5])
  6. f([0])
  7. f([7])

If any problem is detected, DebugMode will raise an exception according towhat went wrong, either at call time (f(5)) or compile time (f = theano.function(x, 10 * x, mode='DebugMode')). These exceptionsshould not be ignored; talk to your local Theano guru or email theusers list if you cannot make the exception go away.

Some kinds of errors can only be detected for certain input value combinations.In the example above, there is no way to guarantee that a future call to, sayf(-1), won’t cause a problem. DebugMode is not a silver bullet.

If you instantiate DebugMode using the constructor (see DebugMode)rather than the keyword DebugMode you can configure its behaviour viaconstructor arguments. The keyword version of DebugMode (which you get by using mode='DebugMode')is quite strict.

For more detail, see DebugMode in the library.

ProfileMode

Note

ProfileMode is deprecated. Use config.profile instead.