When you call a function with an invalid type of array, you sometimes receive no error, but get an unexpected result by broadcasting.
When you use CUDA with an illegal type of array, it causes memory corruption, and you get a serious error.
These bugs are hard to fix.
Chainer can check preconditions of each function, and helps to prevent such problems.
These conditions may help a user to understand specification of functions.

Each implementation of Function has a method for type check, check_type_forward().
This function is called just before the forward() method of the Function class.
You can override this method to check the condition on types and shapes of arguments.

in_types is an instance of TypeInfoTuple, which is a sub-class of tuple.
To get type information about the first argument, use in_types[0].
If the function gets multiple arguments, we recommend to use new variables for readability:

x_type,y_type=in_types

In this case, x_type represents the type of the first argument, and y_type represents the second one.

We describe usage of in_types with an example.
When you want to check if the number of dimension of x_type equals to 2, write this code:

utils.type_check.expect(x_type.ndim==2)

When this condition is true, nothing happens.
Otherwise this code throws an exception, and the user gets a message like this:

How does it show an error message like "in_types[0].ndim==2"?
If x_type is an object containing ndim member variable, we cannot show such an error message because this equation is evaluated as a boolean value by Python interpreter.

Actually x_type is a Expr objects, and doesn’t have a ndim member variable itself.
Expr represents a syntax tree.
x_type.ndim makes a Expr object representing (getattr,x_type,'ndim').
x_type.ndim==2 makes an object like (eq,(getattr,x_type,'ndim'),2).
expect() gets a Expr object and evaluates it.
When it is True, it causes no error and shows nothing.
Otherwise, this method shows a readable error message.

Why do we need to wrap the function numpy.sum with utils.type_check.Variable?
x_type.shape is not a tuple but an object of Expr as we have seen before.
Therefore, numpy.sum(x_type.shape) fails.
We need to evaluate this function lazily.

How to write a more complicated condition that can’t be written with these operators?
You can evaluate Expr and get its result value with eval() method.
Then check the condition and show warning message by hand:

x_shape=x_type.shape.eval()# get actual shape (int tuple)ifnotmore_complicated_condition(x_shape):expect_msg='Shape is expected to be ...'actual_msg='Shape is ...'raiseutils.type_check.InvalidType(expect_msg,actual_msg)

Please write a readable error message.
This code generates the following error message:

in_types.size() returns a Expr object representing the number of arguments.
You can check it in the same way.

And then, get each type:

x_type,y_type=in_types

Don’t get each value before checking in_types.size().
When the number of argument is illegal, type_check.expect might output unuseful error messages.
For example, this code doesn’t work when the size of in_types is 0: