def visit_sum(self, op: d5.ops.Sum, network: ReferenceNetwork): inputs = [] for i in range(0, len(op.input)): inputs.append(network.variables[op.input[i]]) network.gradients[op.input[i]] = np.zeros_like( network.variables[op.input[i]]) Y_shape = np.copy(inputs[0]) for i in range(1, len(inputs)): Y_shape = Y_shape + inputs[i] network.variables[op.o_sum] = Y_shape input_desc = [desc_from_tensor(i) for i in inputs] output_desc = [desc_from_tensor(Y_shape)] attributes = {} attributes[ 'DTYPE'] = 'float' if inputs[0].dtype == np.float32 else 'double' opdesc = d5.compile_custom_cppop('Sum' + str(self.sum_counter), SumCPPOp, input_desc, output_desc, additional_definitions=attributes) sumlayer = d5ref.custom_op(opdesc) self.sum_counter += 1 self.add_node(op, network, sumlayer, self.sum_counter) self.add_edges(op, network, self.sum_counter)
def visit_globalaveragepool(self, op: d5.ops.GlobalAveragePool, network: ReferenceNetwork): X = network.variables[op.i_X] out_shape = [X.shape[0], X.shape[1]] for i in range(len(X.shape) - 2): out_shape = out_shape + [1] Y_shape = np.zeros(out_shape, dtype=X.dtype) network.variables[op.o_Y] = Y_shape network.gradients[op.i_X] = np.zeros_like(X) input_desc = [desc_from_tensor(X)] output_desc = [desc_from_tensor(Y_shape)] attributes = {} attributes['DTYPE'] = 'float' if X.dtype == np.float32 else 'double' opdesc = d5.compile_custom_cppop('GlobalAveragePool' + str(self.globalaveragepool_counter), GlobalAveragePoolCPPOp, input_desc, output_desc, additional_definitions=attributes) globalaveragepoollayer = d5ref.custom_op(opdesc) self.globalaveragepool_counter += 1 self.add_node(op, network, globalaveragepoollayer, self.globalaveragepool_counter) self.add_edges(op, network, self.globalaveragepool_counter)
def visit_gemm(self, op: d5.ops.Gemm, network: ReferenceNetwork): A = network.variables[op.i_A] B = network.variables[op.i_B] C = network.variables[op.i_C] transposeA = 0 if op.transA is None else op.transA.get_value() transposeB = 0 if op.transB is None else op.transB.get_value() alpha = 1.0 if op.alpha is None else op.alpha.get_value() beta = 1.0 if op.beta is None else op.beta.get_value() A_transposed = A.T if transposeA != 0 else A B_transposed = B.T if transposeB != 0 else B Y_shape = np.zeros((np.dot(A_transposed, B_transposed)).shape, dtype=A.dtype) network.variables[op.o_Y] = Y_shape network.gradients[op.i_A] = np.zeros_like(A) network.gradients[op.i_B] = np.zeros_like(B) network.gradients[op.i_C] = np.zeros_like(C) input_desc = [desc_from_tensor(i) for i in [A, B, C]] output_desc = [desc_from_tensor(Y_shape)] attributes = {} attributes['DTYPE'] = 'float' if A.dtype == np.float32 else 'double' attributes['ALPHA'] = alpha attributes['BETA'] = beta attributes['TRANSA'] = transposeA attributes['TRANSB'] = transposeB opdesc = d5.compile_custom_cppop('Gemm' + str(self.gemm_counter), GemmCPPOp, input_desc, output_desc, additional_definitions=attributes) gemmlayer = d5ref.custom_op(opdesc) self.gemm_counter += 1 self.add_node(op, network, gemmlayer, self.gemm_counter) self.add_edges(op, network, self.gemm_counter)
def visit_maxpool(self, op: d5.ops.MaxPool, network: ReferenceNetwork): X = network.variables[op.i_X] auto_pad = 'NOTSET' if op.auto_pad is None else op.auto_pad.get_value() kernel_shape = op.kernel_shape.get_value() temp_pads = [] temp_strides = [] for i in range(0, len(kernel_shape)): temp_pads.append(0) temp_pads.append(0) temp_strides.append(1) pads = temp_pads if op.pads is None else op.pads.get_value() storage_order = 0 #if op.storage_order is None else op.storage_order.get_value() strides = temp_strides if op.strides is None else op.strides.get_value( ) if auto_pad != 'NOTSET': out_shape = get_output_shape_pool(auto_pad, X.shape[2:], kernel_shape, strides) else: input_spatial_shape = X.shape[2:] out_shape = [0] * len(input_spatial_shape) for i in range(len(input_spatial_shape)): out_shape[i] = int(np.ceil(float( input_spatial_shape[i] - \ (kernel_shape[i] - 1) + \ pads[i] + \ pads[i + len(kernel_shape)] ) / \ float( strides[i] ) ) ) Y_shape = np.zeros([X.shape[0], X.shape[1]] + list(out_shape), dtype=X.dtype) network.variables[op.o_Y] = Y_shape network.gradients[op.i_X] = np.zeros_like(X) input_desc = [desc_from_tensor(X)] output_desc = [desc_from_tensor(Y_shape)] attributes = {} attributes['DTYPE'] = 'float' if X.dtype == np.float32 else 'double' attributes['AUTO_PAD'] = auto_pad attributes['KERNEL_SHAPE'] = ", ".join(str(e) for e in kernel_shape) attributes['PADS'] = ", ".join(str(e) for e in pads) attributes['STORAGE_ORDER'] = storage_order attributes['STRIDES'] = ", ".join(str(e) for e in strides) opdesc = d5.compile_custom_cppop('MaxPool' + str(self.maxpool_counter), MaxPoolCPPOp, input_desc, output_desc, additional_definitions=attributes) maxpoollayer = d5ref.custom_op(opdesc) self.maxpool_counter += 1 self.add_node(op, network, maxpoollayer, self.maxpool_counter) self.add_edges(op, network, self.maxpool_counter)
def visit_batchnormalization(self, op: d5.ops.BatchNormalization, network: ReferenceNetwork): X = network.variables[op.i_X] scale = network.variables[op.i_scale] B = network.variables[op.i_B] mean = network.variables[op.i_mean] var = network.variables[op.i_var] #mean_out = np.zeros(mean.shape, dtype=mean.dtype) #var_out = np.zeros(var.shape, dtype=var.dtype) #mean_out2 = np.zeros(mean.shape, dtype=mean.dtype) #var_out2 = np.zeros(var.shape, dtype=var.dtype) epsilon = 1e-5 if op.epsilon is None else op.epsilon.get_value() momentum = 0.9 if op.momentum is None else op.momentum.get_value() spatial = 1 if op.spatial is None else op.spatial.get_value() Y_shape = np.zeros(X.shape, dtype=X.dtype) network.variables[op.o_Y] = Y_shape network.gradients[op.i_scale] = np.zeros_like(scale) network.gradients[op.i_B] = np.zeros_like(B) network.gradients[op.i_mean] = np.zeros_like(mean) network.gradients[op.i_var] = np.zeros_like(var) input_desc = [ desc_from_tensor(X), desc_from_tensor(scale), desc_from_tensor(B), desc_from_tensor(mean), desc_from_tensor(var) ] output_desc = [ desc_from_tensor(Y_shape) #desc_from_tensor(mean_out), #desc_from_tensor(var_out), #desc_from_tensor(mean_out2), #desc_from_tensor(var_out2) ] attributes = {} attributes['DTYPE'] = 'float' if X.dtype == np.float32 else 'double' attributes['EPSILON'] = epsilon attributes['MOMENTUM'] = momentum attributes['SPATIAL'] = spatial opdesc = d5.compile_custom_cppop('BatchNormalization_Inference' + str(self.batchnormalization_counter), BatchNormalizationInferenceCPPOp, input_desc, output_desc, additional_definitions=attributes) batchnormlayer_inference = d5ref.custom_op(opdesc) self.batchnormalization_counter += 1 self.add_node(op, network, batchnormlayer_inference, self.batchnormalization_counter) self.add_edges(op, network, self.batchnormalization_counter)
def visit_reshape(self, op: d5.ops.Reshape, network: ReferenceNetwork): data = network.variables[op.i_data] shape = network.variables[op.i_shape] #compute output shape output_shape = np.ndarray(shape.shape, dtype=np.int64) for i in range(0, shape.size): if shape[i] == 0: output_shape[i] = data.shape[i] elif shape[i] == -1: input_size = data.size temp = 1 for j in range(0, i): if shape[j] == 0: temp *= data.shape[j] else: temp *= shape[j] for j in range(i + 1, shape.size): if shape[j] == 0: temp *= data.shape[j] else: temp *= shape[j] output_shape[i] = input_size / temp else: output_shape[i] = shape[i] Y_shape = np.zeros(output_shape, dtype=data.dtype) network.variables[op.o_reshaped] = Y_shape network.gradients[op.i_data] = np.zeros_like(data) network.gradients[op.i_shape] = np.zeros_like(shape) input_desc = [desc_from_tensor(data), desc_from_tensor(shape)] output_desc = [desc_from_tensor(Y_shape)] attributes = {} attributes['DTYPE'] = 'float' if data.dtype == np.float32 else 'double' opdesc = d5.compile_custom_cppop('Reshape' + str(self.reshape_counter), ReshapeCPPOp, input_desc, output_desc, additional_definitions=attributes) reshapelayer = d5ref.custom_op(opdesc) self.reshape_counter += 1 self.add_node(op, network, reshapelayer, self.reshape_counter) self.add_edges(op, network, self.reshape_counter)
def visit_relu(self, op: d5.ops.Relu, network: ReferenceNetwork): X = network.variables[op.i_X] Y_shape = np.zeros(X.shape, dtype=X.dtype) network.variables[op.o_Y] = Y_shape network.gradients[op.i_X] = np.zeros_like(X) input_desc = [desc_from_tensor(X)] output_desc = [desc_from_tensor(Y_shape)] attributes = {} attributes['DTYPE'] = 'float' if X.dtype == np.float32 else 'double' opdesc = d5.compile_custom_cppop('Relu' + str(self.relu_counter), ReluCPPOp, input_desc, output_desc, additional_definitions=attributes) relulayer = d5ref.custom_op(opdesc) self.relu_counter += 1 self.add_node(op, network, relulayer, self.relu_counter) self.add_edges(op, network, self.relu_counter)
def visit_add(self, op: d5.ops.Add, network: ReferenceNetwork): A = network.variables[op.i_A] B = network.variables[op.i_B] C = np.zeros((A + B).shape, dtype=A.dtype) network.variables[op.o_C] = C network.gradients[op.i_A] = np.zeros_like(A) network.gradients[op.i_B] = np.zeros_like(B) input_desc = [desc_from_tensor(A), desc_from_tensor(B)] output_desc = [desc_from_tensor(C)] attributes = {} attributes['DTYPE'] = 'float' if A.dtype == np.float32 else 'double' opdesc = d5.compile_custom_cppop('Add' + str(self.add_counter), AddCPPOp, input_desc, output_desc, additional_definitions=attributes) addlayer = d5ref.custom_op(opdesc) self.add_counter += 1 self.add_node(op, network, addlayer, self.add_counter) self.add_edges(op, network, self.add_counter)
def visit_matmul(self, op: d5.ops.MatMul, network: ReferenceNetwork): A = network.variables[op.i_A] B = network.variables[op.i_B] Y_shape = np.zeros((np.dot(A, B)).shape, dtype=A.dtype) network.variables[op.o_Y] = Y_shape network.gradients[op.i_A] = np.zeros_like(A) network.gradients[op.i_B] = np.zeros_like(B) input_desc = [desc_from_tensor(i) for i in [A, B]] output_desc = [desc_from_tensor(Y_shape)] attributes = {} attributes['DTYPE'] = 'float' if A.dtype == np.float32 else 'double' opdesc = d5.compile_custom_cppop('Matmul' + str(self.matmul_counter), MatMulCPPOp, input_desc, output_desc, additional_definitions=attributes) matmullayer = d5ref.custom_op(opdesc) self.matmul_counter += 1 self.add_node(op, network, matmullayer, self.matmul_counter) self.add_edges(op, network, self.matmul_counter)
def visit_softmax(self, op: d5.ops.Softmax, network: ReferenceNetwork): softmax_input = network.variables[op.i_input] axis = 1 if op.axis is None else op.axis.get_value() Y_shape = np.zeros(softmax_input.shape, dtype=softmax_input.dtype) network.variables[op.o_output] = Y_shape network.gradients[op.i_input] = np.zeros_like(softmax_input) input_desc = [desc_from_tensor(softmax_input)] output_desc = [desc_from_tensor(Y_shape)] attributes = {} attributes[ 'DTYPE'] = 'float' if softmax_input.dtype == np.float32 else 'double' attributes['AXIS'] = axis opdesc = d5.compile_custom_cppop('Softmax' + str(self.softmax_counter), SoftmaxCPPOp, input_desc, output_desc, additional_definitions=attributes) softmaxlayer = d5ref.custom_op(opdesc) self.softmax_counter += 1 self.add_node(op, network, softmaxlayer, self.softmax_counter) self.add_edges(op, network, self.softmax_counter)
def visit_conv(self, op: d5.ops.Conv, network: ReferenceNetwork): X = network.variables[op.i_X] W = network.variables[op.i_W] if op.i_B is None: temp_B = np.zeros(W.shape[0], dtype=W.dtype) B = temp_B if op.i_B is None else network.variables[op.i_B] input_tensor = [X, W] else: B = network.variables[op.i_B] input_tensor = [X, W, B] network.gradients[op.i_B] = np.zeros_like(B) #optional input #temp_B = np.zeros(W.shape[0], dtype=W.dtype) #B = temp_B if len(op.input) < 3 else self.tensors[op.input[2]] auto_pad = 'NOTSET' if op.auto_pad is None else op.auto_pad.get_value() kernel_shape = W.shape[ 2:] if op.kernel_shape is None else op.kernel_shape.get_value() #default values if not specified temp_dilations = [] temp_pads = [] temp_strides = [] for i in range(0, len(kernel_shape)): temp_dilations.append(1) temp_pads.append(0) temp_pads.append(0) temp_strides.append(1) dilations = temp_dilations if op.dilations is None else op.dilations.get_value( ) group = 1 if op.group is None else op.group.get_value() pads = temp_pads if op.pads is None else op.pads.get_value() strides = temp_strides if op.strides is None else op.strides.get_value( ) if auto_pad != 'NOTSET': out_shape = get_output_shape_conv(auto_pad, X.shape[2:], kernel_shape, dilations, strides) else: input_spatial_shape = X.shape[2:] out_shape = [0] * len(input_spatial_shape) for i in range(len(input_spatial_shape)): out_shape[i] = int( np.floor( float( input_spatial_shape[i] + \ pads[i] + \ pads[i + len(kernel_shape)] - \ (dilations[i] * (kernel_shape[i] - 1) + 1) ) / \ float( strides[i] ) ) + 1 ) Y_shape = np.zeros([X.shape[0], W.shape[0]] + list(out_shape), dtype=X.dtype) network.variables[op.o_Y] = Y_shape network.gradients[op.i_X] = np.zeros_like(X) network.gradients[op.i_W] = np.zeros_like(W) input_desc = [desc_from_tensor(i) for i in input_tensor] output_desc = [desc_from_tensor(Y_shape)] attributes = {} attributes['DTYPE'] = 'float' if X.dtype == np.float32 else 'double' attributes['AUTO_PAD'] = auto_pad attributes['DILATIONS'] = ", ".join(str(e) for e in dilations) attributes['GROUP'] = group attributes['KERNEL_SHAPE'] = ", ".join(str(e) for e in kernel_shape) attributes['PADS'] = ", ".join(str(e) for e in pads) attributes['STRIDES'] = ", ".join(str(e) for e in strides) opdesc = d5.compile_custom_cppop('Conv' + str(self.conv_counter), ConvCPPOp, input_desc, output_desc, additional_definitions=attributes) convlayer = d5ref.custom_op(opdesc) self.conv_counter += 1 self.add_node(op, network, convlayer, self.conv_counter) self.add_edges(op, network, self.conv_counter)