You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Paddle/doc/design/python_api.md

2.9 KiB

Design Doc: Python API

The top level user API in Python should be as same as API in paddle.v2 after refactoring Paddle from a layer based framework to an operator based framework. There are many new classes in CPP in [compile time] for describing neural networks, such as Variable, Operator, Block. The issue about current design is how to give a proper way to wrap the C++ API to paddle.v2 API and writing layers in Python.

This implementation of Python API includes two steps.

  1. Implement the Python API using current C++ runtime concepts.
  2. Replace the implementation by using compile-time concepts when they are completed.

The implementation of the first step is a temporary implementation. We should design our Python API concepts based on compile-time concepts. We just use runtime classes to implement it for now.

Python Class and compile-time protobuf

As we design our Python API concepts based on compile-time, we try to map our Python classes to every compile-time result, i.e., the protobuf messages. They are:

Python Class Compile-time protobuf
Block BlockDesc
Operator OpDesc
Variable VarDesc

Block

class Block(objects):
	def __init__(self, parent=None):
		self.vars_ = map<string, Variable>()
		self.ops_ = vector<Operator>()
		if parent is None:
			self.global_vars = map<string, Variable>()
			self.parent=None
		else:
			self.parent = parent
			self.global_vars = None
	
	def create_global_vars(...):
		if self.parent is not None:
			return self.parent.create_global_vars(...)
		else:
			return self.global_vars.new()

Operator

class Operator(object):
	def __init__(self, type, inputs, outputs, attrs):
		# create OpDesc in Python
		op_desc = ...
		self.cpp_op_desc_ptr = cpp.to_cpp_op_desc(op_desc)
		cpp.infer_shapes(self.cpp_op_desc_ptr, inputs, outputs)
		outputs.op = self

	def type(self):
		return self.cpp_op_desc_ptr.type()

Variable

class Variable(object):
    def __init__(self, shape, dtype="float32", name=None, block=None):
        if name is None:
            if prefix is not None:
                name = unique_name_generator(prefix)
            else:
                name = unique_name_generator("unknown")
        self.name = name
        self.block = block
        self.cpp_var_desc_ptr = ...
        self.op = None

    def shape(self):
        cpp_shape = self.cpp_var_desc_ptr.shape()
        return [None if elem < 0 else elem for elem in cpp_shape]

Parameter

class Parameter(Variable):
    def __init__(self, trainable, initialize_attrs, optimize_attrs):
        pass

Layer Functions