1. Update akg submodule 2. Refactor akg_kernel_build, akg_ascend_kernel_build, akg_gpu_kernel_build 3. Add akg_kernel_json_decoder to support converting kernel_json to AnfNode. 4. Add GraphKernel Cost Model. (mindspore/_extends/graph_kernel) 5. Add some GraphKernel passes to GpuSession, move these passes to backend/optimizer/graph_kernel. 6. Add global id for ir files. 7. Fix bug in ConstInputToAttr.pull/5783/head
parent
c415e8ceda
commit
37a48f6aac
@ -1 +1 @@
|
|||||||
Subproject commit 3bb6264188d0b1d6ff776a35a571bc7190df0800
|
Subproject commit d237aa7d8e9d3fb709bda9f30205b02129bc2b59
|
@ -0,0 +1,17 @@
|
|||||||
|
# Copyright 2020 Huawei Technologies Co., Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
# ============================================================================
|
||||||
|
"""init"""
|
||||||
|
from .splitter import split_with_json
|
||||||
|
from .expander import get_op_expander
|
@ -0,0 +1,58 @@
|
|||||||
|
# Copyright 2020 Huawei Technologies Co., Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
# ============================================================================
|
||||||
|
"""generate json desc for graph kernel ops"""
|
||||||
|
import json
|
||||||
|
import json.decoder as jd
|
||||||
|
import traceback
|
||||||
|
from mindspore import log as logger
|
||||||
|
import mindspore._extends.graph_kernel.expanders as expanders
|
||||||
|
|
||||||
|
|
||||||
|
def get_op_expander(json_str: str):
|
||||||
|
"""get op expander by json info"""
|
||||||
|
try:
|
||||||
|
kernel_info = json.loads(json_str)
|
||||||
|
expand_info = kernel_info['expand_info']
|
||||||
|
|
||||||
|
if 'name' not in expand_info:
|
||||||
|
logger.error("expand info have no op name")
|
||||||
|
return None
|
||||||
|
if 'process' not in expand_info:
|
||||||
|
logger.error("expand info have no processor info")
|
||||||
|
return None
|
||||||
|
|
||||||
|
processor = expand_info['process']
|
||||||
|
op_name = str(expand_info['name']).lower()
|
||||||
|
expand_op_func_name = 'expand_' + op_name
|
||||||
|
if not hasattr(expanders, expand_op_func_name):
|
||||||
|
logger.error("Generator do not support op: {}".format(op_name))
|
||||||
|
return None
|
||||||
|
expand_op_func = getattr(expanders, expand_op_func_name)
|
||||||
|
# generate graph desc.
|
||||||
|
graph = expand_op_func(expand_info)
|
||||||
|
if graph is None:
|
||||||
|
logger.error("Failed to generate graph of: {}".format(op_name))
|
||||||
|
return None
|
||||||
|
|
||||||
|
graph.set_processor(processor)
|
||||||
|
|
||||||
|
# dump graph to json desc.
|
||||||
|
desc = graph.dump()
|
||||||
|
return json.dumps(desc)
|
||||||
|
|
||||||
|
except jd.JSONDecodeError:
|
||||||
|
logger.error("Failed to generate graph kernel op")
|
||||||
|
logger.error(traceback.format_exc())
|
||||||
|
return None
|
@ -0,0 +1,20 @@
|
|||||||
|
# Copyright 2020 Huawei Technologies Co., Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
# ============================================================================
|
||||||
|
"""expanders init"""
|
||||||
|
|
||||||
|
from .gelu import expand_gelu
|
||||||
|
from .layernorm import expand_layernorm
|
||||||
|
from .softmax import expand_softmax
|
||||||
|
from .square import expand_square
|
@ -0,0 +1,68 @@
|
|||||||
|
# Copyright 2020 Huawei Technologies Co., Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
# ===========================================================================
|
||||||
|
"""generate json desc for gelu"""
|
||||||
|
from mindspore._extends.graph_kernel.model import model_builder as builder
|
||||||
|
|
||||||
|
CSVALUE = 0.044715
|
||||||
|
CSVALUE_A = 1.5957691 # 2*np.sqrt(2/np.pi)
|
||||||
|
|
||||||
|
|
||||||
|
def expand_gelu(expand_info):
|
||||||
|
"""Gelu expander"""
|
||||||
|
|
||||||
|
# get op info.
|
||||||
|
input_desc = expand_info['input_desc'][0]
|
||||||
|
graph_builder = builder.GraphBuilder()
|
||||||
|
|
||||||
|
# generate a graph.
|
||||||
|
with graph_builder.graph_scope('main') as graph_scope:
|
||||||
|
# create tensor input.
|
||||||
|
input_x = graph_builder.tensor(input_desc['shape'], input_desc['data_type'], input_desc['format'])
|
||||||
|
dtype = input_x.dtype
|
||||||
|
if dtype == 'float16':
|
||||||
|
input_x = graph_builder.emit('Cast', [input_x], attrs={'dst_type': 'float32'})
|
||||||
|
|
||||||
|
# cal tanh.
|
||||||
|
mul_0 = graph_builder.emit('Mul', [input_x, input_x])
|
||||||
|
pow_0 = graph_builder.emit('Mul', [mul_0, input_x])
|
||||||
|
const_csvalue = graph_builder.value(pow_0.dtype, CSVALUE, input_desc['format'])
|
||||||
|
mul_1 = graph_builder.emit('Mul', [pow_0, const_csvalue])
|
||||||
|
tanh_res = graph_builder.emit('TensorAdd', [input_x, mul_1])
|
||||||
|
|
||||||
|
const_csvalue_a = graph_builder.value(tanh_res.dtype, CSVALUE_A, input_desc['format'])
|
||||||
|
mul_0 = graph_builder.emit('Mul', [tanh_res, const_csvalue_a])
|
||||||
|
|
||||||
|
const_zero = graph_builder.value(mul_0.dtype, 0.0, input_desc['format'])
|
||||||
|
mul_0_min = graph_builder.emit('Minimum', [mul_0, const_zero])
|
||||||
|
right_mul = graph_builder.emit('Exp', [mul_0_min])
|
||||||
|
|
||||||
|
mul_0_abs = graph_builder.emit('Abs', [mul_0])
|
||||||
|
const_neg_one = graph_builder.value(mul_0_abs.dtype, -1.0, input_desc['format'])
|
||||||
|
mul_0_abs_neg = graph_builder.emit('Mul', [mul_0_abs, const_neg_one])
|
||||||
|
|
||||||
|
mul_0_abs_neg_exp = graph_builder.emit('Exp', [mul_0_abs_neg])
|
||||||
|
|
||||||
|
const_one = graph_builder.value(mul_0_abs_neg_exp.dtype, 1.0, input_desc['format'])
|
||||||
|
mul_0_abs_neg_exp_add = graph_builder.emit('TensorAdd', [mul_0_abs_neg_exp, const_one])
|
||||||
|
left_mul = graph_builder.emit('RealDiv', [input_x, mul_0_abs_neg_exp_add])
|
||||||
|
|
||||||
|
result = graph_builder.emit('Mul', [left_mul, right_mul])
|
||||||
|
if dtype == 'float16':
|
||||||
|
result = graph_builder.emit('Cast', [result], attrs={'dst_type': 'float16'})
|
||||||
|
# set graph output.
|
||||||
|
graph_scope.set_output(result)
|
||||||
|
|
||||||
|
graph = graph_builder.get()[0]
|
||||||
|
return graph
|
@ -0,0 +1,87 @@
|
|||||||
|
# Copyright 2020 Huawei Technologies Co., Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
# ===========================================================================
|
||||||
|
"""generate json desc for LayerNorm"""
|
||||||
|
from mindspore._extends.graph_kernel.model import model_builder as builder
|
||||||
|
|
||||||
|
|
||||||
|
def expand_layernorm(expand_info):
|
||||||
|
"""LayerNorm expander"""
|
||||||
|
|
||||||
|
# get op info.
|
||||||
|
input_desc_0 = expand_info['input_desc'][0]
|
||||||
|
input_desc_1 = expand_info['input_desc'][1]
|
||||||
|
input_desc_2 = expand_info['input_desc'][2]
|
||||||
|
attrs = expand_info['attr']
|
||||||
|
begin_norm_axis = None
|
||||||
|
epsilon = None
|
||||||
|
for item in attrs:
|
||||||
|
if 'begin_norm_axis' in item:
|
||||||
|
begin_norm_axis = item['begin_norm_axis']
|
||||||
|
if 'epsilon' in item:
|
||||||
|
epsilon = item['epsilon']
|
||||||
|
graph_builder = builder.GraphBuilder()
|
||||||
|
|
||||||
|
# generate a graph.
|
||||||
|
with graph_builder.graph_scope('main') as graph_scope:
|
||||||
|
# create tensor input.
|
||||||
|
input_x = graph_builder.tensor(input_desc_0['shape'], input_desc_0['data_type'], input_desc_0['format'])
|
||||||
|
input_gamma = graph_builder.tensor(input_desc_1['shape'], input_desc_1['data_type'], input_desc_1['format'])
|
||||||
|
input_beta = graph_builder.tensor(input_desc_2['shape'], input_desc_2['data_type'], input_desc_2['format'])
|
||||||
|
|
||||||
|
# Calculate the scaling ratio of the average
|
||||||
|
shape_x = input_desc_0['shape']
|
||||||
|
if begin_norm_axis < 0:
|
||||||
|
begin_norm_axis += len(shape_x)
|
||||||
|
reduce_axis = ()
|
||||||
|
for i, _ in enumerate(shape_x):
|
||||||
|
if i > begin_norm_axis or i == begin_norm_axis:
|
||||||
|
reduce_axis = reduce_axis + (i,)
|
||||||
|
|
||||||
|
reduce_elts = 1.0
|
||||||
|
for i in reduce_axis:
|
||||||
|
reduce_elts *= shape_x[i]
|
||||||
|
mean_cof = 1.0 / reduce_elts
|
||||||
|
mean_cof_v = graph_builder.value(input_x.dtype, mean_cof, input_x.data_format)
|
||||||
|
|
||||||
|
# Calculate mean
|
||||||
|
mean_red = graph_builder.emit('ReduceSum', [input_x], attrs={'reduce_axis': reduce_axis, 'keep_dims': True})
|
||||||
|
mean = graph_builder.emit('Mul', [mean_red, mean_cof_v])
|
||||||
|
|
||||||
|
# Calculate variance
|
||||||
|
variance_sub = graph_builder.emit('Sub', [input_x, mean])
|
||||||
|
variance_mul = graph_builder.emit('Mul', [variance_sub, variance_sub])
|
||||||
|
variance_red = graph_builder.emit('ReduceSum', [variance_mul],
|
||||||
|
attrs={'reduce_axis': reduce_axis, 'keep_dims': True})
|
||||||
|
variance = graph_builder.emit('Mul', [variance_red, mean_cof_v])
|
||||||
|
|
||||||
|
# Calculate normalize
|
||||||
|
normalize_sub = graph_builder.emit('Sub', [input_x, mean])
|
||||||
|
epsilon_v = graph_builder.value(input_x.dtype, epsilon, input_x.data_format)
|
||||||
|
normalize_add = graph_builder.emit('TensorAdd', [variance, epsilon_v])
|
||||||
|
normalize_log = graph_builder.emit('Log', [normalize_add])
|
||||||
|
input_y = graph_builder.value(input_x.dtype, -0.5, input_x.data_format)
|
||||||
|
normalize_log_mul = graph_builder.emit('Mul', [normalize_log, input_y])
|
||||||
|
normalize_exp = graph_builder.emit('Exp', [normalize_log_mul])
|
||||||
|
normalize_mul = graph_builder.emit('Mul', [normalize_sub, normalize_exp])
|
||||||
|
|
||||||
|
# Calculate scale and translate
|
||||||
|
scale_mul = graph_builder.emit('Mul', [input_gamma, normalize_mul])
|
||||||
|
res = graph_builder.emit('TensorAdd', [scale_mul, input_beta])
|
||||||
|
|
||||||
|
# set graph output.
|
||||||
|
graph_scope.set_output(res, mean, variance)
|
||||||
|
|
||||||
|
graph = graph_builder.get()[0]
|
||||||
|
return graph
|
@ -0,0 +1,51 @@
|
|||||||
|
# Copyright 2020 Huawei Technologies Co., Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
# ===========================================================================
|
||||||
|
"""generate json desc for softmax"""
|
||||||
|
from mindspore._extends.graph_kernel.model import model_builder as builder
|
||||||
|
|
||||||
|
|
||||||
|
def expand_softmax(expand_info):
|
||||||
|
"""Softmax expander"""
|
||||||
|
|
||||||
|
# get op info.
|
||||||
|
input_desc = expand_info['input_desc'][0]
|
||||||
|
attrs = expand_info['attr']
|
||||||
|
axis = None
|
||||||
|
for item in attrs:
|
||||||
|
if 'axis' in item:
|
||||||
|
axis = item['axis']
|
||||||
|
graph_builder = builder.GraphBuilder()
|
||||||
|
|
||||||
|
# generate a graph.
|
||||||
|
with graph_builder.graph_scope('main') as graph_scope:
|
||||||
|
# create tensor input.
|
||||||
|
input_x = graph_builder.tensor(input_desc['shape'], input_desc['data_type'], input_desc['format'])
|
||||||
|
# cal softmax.
|
||||||
|
|
||||||
|
if input_x.dtype == 'float32':
|
||||||
|
input_x_cast = graph_builder.emit('Cast', [input_x], attrs={'dst_type': 'float16'})
|
||||||
|
max_x = graph_builder.emit('ReduceMax', [input_x_cast], attrs={'reduce_axis': axis, 'keep_dims': True})
|
||||||
|
max_x = graph_builder.emit('Cast', [max_x], attrs={'dst_type': 'float32'})
|
||||||
|
else:
|
||||||
|
max_x = graph_builder.emit('ReduceMax', [input_x], attrs={'reduce_axis': axis, 'keep_dims': True})
|
||||||
|
data_sub = graph_builder.emit('Sub', [input_x, max_x])
|
||||||
|
data_exp = graph_builder.emit('Exp', [data_sub])
|
||||||
|
data_expsum = graph_builder.emit('ReduceSum', [data_exp], attrs={'reduce_axis': axis, 'keep_dims': True})
|
||||||
|
result = graph_builder.emit('RealDiv', [data_exp, data_expsum])
|
||||||
|
# set graph output.
|
||||||
|
graph_scope.set_output(result)
|
||||||
|
|
||||||
|
graph = graph_builder.get()[0]
|
||||||
|
return graph
|
@ -0,0 +1,36 @@
|
|||||||
|
# Copyright 2020 Huawei Technologies Co., Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
# ===========================================================================
|
||||||
|
"""generate json desc for square"""
|
||||||
|
from mindspore._extends.graph_kernel.model import model_builder as builder
|
||||||
|
|
||||||
|
|
||||||
|
def expand_square(expand_info):
|
||||||
|
"""Square expander"""
|
||||||
|
|
||||||
|
# get op info.
|
||||||
|
input_desc = expand_info['input_desc'][0]
|
||||||
|
graph_builder = builder.GraphBuilder()
|
||||||
|
|
||||||
|
# generate a graph.
|
||||||
|
with graph_builder.graph_scope('main') as graph_scope:
|
||||||
|
# create tensor input.
|
||||||
|
input_x = graph_builder.tensor(input_desc['shape'], input_desc['data_type'], input_desc['format'])
|
||||||
|
# create op.
|
||||||
|
result = graph_builder.emit('Mul', [input_x, input_x])
|
||||||
|
# set graph output.
|
||||||
|
graph_scope.set_output(result)
|
||||||
|
|
||||||
|
graph = graph_builder.get()[0]
|
||||||
|
return graph
|
@ -0,0 +1,18 @@
|
|||||||
|
# Copyright 2020 Huawei Technologies Co., Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
# ===========================================================================
|
||||||
|
"""GraphKernel cost model init"""
|
||||||
|
|
||||||
|
from .graph_split import split
|
||||||
|
from .model_builder import GraphBuilder, load_composite
|
@ -0,0 +1,153 @@
|
|||||||
|
# Copyright 2020 Huawei Technologies Co., Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
# ===========================================================================
|
||||||
|
"""Cost model splitter"""
|
||||||
|
|
||||||
|
from .model import PrimLib, Graph
|
||||||
|
|
||||||
|
|
||||||
|
class GraphSplitByPattern:
|
||||||
|
"""Graph split by pattern"""
|
||||||
|
|
||||||
|
def __init__(self, graph):
|
||||||
|
self.graph = graph
|
||||||
|
self.groups = []
|
||||||
|
self.op_group = {}
|
||||||
|
for op in self.graph.ops:
|
||||||
|
g = [op]
|
||||||
|
self.groups.append(g)
|
||||||
|
self.op_group[op] = g
|
||||||
|
self.ids = {}
|
||||||
|
for i, op in enumerate(graph.ops):
|
||||||
|
self.ids[op] = i
|
||||||
|
self.doms = self.post_dom(graph.ops)
|
||||||
|
_, outputs = graph.deduce_parameters()
|
||||||
|
self.outputs = set(outputs)
|
||||||
|
|
||||||
|
def post_dom(self, ops):
|
||||||
|
"""Post dom"""
|
||||||
|
doms, i_doms = {}, {}
|
||||||
|
for i in range(len(ops) - 1, -1, -1):
|
||||||
|
op = ops[i]
|
||||||
|
doms[op] = {op}
|
||||||
|
i_dom = None
|
||||||
|
if op.output.to_ops:
|
||||||
|
suc_dom = set(doms[op.output.to_ops[0]])
|
||||||
|
for to in op.output.to_ops[1:]:
|
||||||
|
suc_dom.intersection_update(doms[to])
|
||||||
|
doms[op].update(suc_dom)
|
||||||
|
for dom in suc_dom:
|
||||||
|
if i_dom is None or self.ids[dom] < self.ids[i_dom]:
|
||||||
|
i_dom = dom
|
||||||
|
i_doms[op] = i_dom
|
||||||
|
return i_doms
|
||||||
|
|
||||||
|
def get_pattern(self, op, i):
|
||||||
|
"""Get pattern"""
|
||||||
|
pattern = PrimLib.UNKNOWN
|
||||||
|
_, elem_relation = PrimLib.input_relation(op, i)
|
||||||
|
for pat in elem_relation:
|
||||||
|
if pat and pat > pattern:
|
||||||
|
pattern = pat
|
||||||
|
return pattern
|
||||||
|
|
||||||
|
def fuse(self, check_fun):
|
||||||
|
"""Fuse ops"""
|
||||||
|
def _get_path(op, dom):
|
||||||
|
path_ops, visited = [], set()
|
||||||
|
|
||||||
|
def _get_path_depth(p):
|
||||||
|
visited.add(p)
|
||||||
|
if self.op_group[p][0] == p:
|
||||||
|
path_ops.append(p)
|
||||||
|
for to in p.output.to_ops:
|
||||||
|
if to != dom and to not in visited:
|
||||||
|
_get_path_depth(to)
|
||||||
|
_get_path_depth(op)
|
||||||
|
return path_ops
|
||||||
|
changed = True
|
||||||
|
while changed:
|
||||||
|
for group in self.groups:
|
||||||
|
op = group[0]
|
||||||
|
dom = self.doms[op]
|
||||||
|
if dom is None or op.output in self.outputs:
|
||||||
|
continue
|
||||||
|
ops = _get_path(op, dom)
|
||||||
|
if check_fun(op, dom, ops):
|
||||||
|
dom_group = self.op_group[dom]
|
||||||
|
fused = []
|
||||||
|
for fop in ops:
|
||||||
|
f_group = self.op_group[fop]
|
||||||
|
for p in f_group:
|
||||||
|
self.op_group[p] = dom_group
|
||||||
|
fused.append(f_group)
|
||||||
|
dom_group += f_group
|
||||||
|
for g in fused:
|
||||||
|
self.groups.remove(g)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
changed = False
|
||||||
|
|
||||||
|
def to_subgraphs(self):
|
||||||
|
"""Transform op groups to subgraphs"""
|
||||||
|
subgraphs = []
|
||||||
|
for i, group in enumerate(self.groups):
|
||||||
|
group.sort(key=lambda op: self.ids[op])
|
||||||
|
subgraphs.append(Graph('{}_{}'.format(self.graph.name, i), group))
|
||||||
|
return subgraphs
|
||||||
|
|
||||||
|
def split(self):
|
||||||
|
"""Split graph"""
|
||||||
|
def _buddy(op, dom, path_ops):
|
||||||
|
"""Fuse buddy together"""
|
||||||
|
# pylint: disable=unused-argument
|
||||||
|
group = self.op_group[op]
|
||||||
|
for p in group:
|
||||||
|
# p is buddy
|
||||||
|
if p.output.buddy is not None and p.output.buddy.members[0].op not in group:
|
||||||
|
return True
|
||||||
|
# p's output is buddy
|
||||||
|
for to in p.output.to_ops:
|
||||||
|
if to.output.buddy is not None and to not in group:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _injective(pattern, limit):
|
||||||
|
def _checker(op, dom, path_ops):
|
||||||
|
# pylint: disable=unused-argument
|
||||||
|
for p in op.output.to_ops:
|
||||||
|
if p not in self.op_group[dom]:
|
||||||
|
return False
|
||||||
|
if PrimLib.iter_type(op) in (PrimLib.ELEMWISE, PrimLib.BROADCAST):
|
||||||
|
for i, t in enumerate(dom.inputs):
|
||||||
|
if t == op.output:
|
||||||
|
return self.get_pattern(dom, i) == pattern and len(self.op_group[op]) < limit
|
||||||
|
return False
|
||||||
|
return _checker
|
||||||
|
|
||||||
|
def _diamond(op, dom, path_ops):
|
||||||
|
if PrimLib.iter_type(op) not in (PrimLib.ELEMWISE, PrimLib.BROADCAST) or \
|
||||||
|
PrimLib.iter_type(dom) in (PrimLib.UNKNOWN, PrimLib.TRANSFORM):
|
||||||
|
return False
|
||||||
|
return len(path_ops) == 1 and op.output not in dom.inputs
|
||||||
|
self.fuse(_buddy)
|
||||||
|
self.fuse(_injective(PrimLib.ELEMWISE, 100))
|
||||||
|
self.fuse(_injective(PrimLib.BROADCAST, 6))
|
||||||
|
self.fuse(_injective(PrimLib.REDUCE, 6))
|
||||||
|
self.fuse(_diamond)
|
||||||
|
return self.to_subgraphs()
|
||||||
|
|
||||||
|
|
||||||
|
def split(graph):
|
||||||
|
return GraphSplitByPattern(graph).split()
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,36 @@
|
|||||||
|
# Copyright 2020 Huawei Technologies Co., Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
# ============================================================================
|
||||||
|
"""GraphKernel splitter"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import json.decoder as jd
|
||||||
|
import traceback
|
||||||
|
from mindspore import log as logger
|
||||||
|
from . import model
|
||||||
|
|
||||||
|
|
||||||
|
def split_with_json(json_str: str):
|
||||||
|
"""Call costmodel to split GraphKernel"""
|
||||||
|
try:
|
||||||
|
graph_desc = json.loads(json_str)
|
||||||
|
comp = model.load_composite(graph_desc)
|
||||||
|
graph_split = model.split(comp.graph)
|
||||||
|
is_multi_graph = len(graph_split) > 1
|
||||||
|
graph_list = list(map(comp.dump, graph_split))
|
||||||
|
result = {"multi_graph": is_multi_graph, "graph_desc": graph_list}
|
||||||
|
return json.dumps(result)
|
||||||
|
except jd.JSONDecodeError:
|
||||||
|
logger.error(traceback.format_exc())
|
||||||
|
return None
|
@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Copyright 2020 Huawei Technologies Co., Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
# ============================================================================
|
||||||
|
PYTHONPATH="$(pwd)/..:${PYTHONPATH}"
|
||||||
|
export PYTHONPATH
|
@ -0,0 +1,142 @@
|
|||||||
|
# Copyright 2020 Huawei Technologies Co., Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
# ===========================================================================
|
||||||
|
"""graph kernel split"""
|
||||||
|
import json
|
||||||
|
import getopt
|
||||||
|
import sys
|
||||||
|
import model
|
||||||
|
|
||||||
|
|
||||||
|
def print_usage():
|
||||||
|
print('Usage: graph_kernel_split.py [OPTION] <JSON_FILE>')
|
||||||
|
print('Options:')
|
||||||
|
print(' -s <config/auto>\tsplit graph with config')
|
||||||
|
print(' -e \t\testimate graph')
|
||||||
|
print(' -i \t\tnaive estimate')
|
||||||
|
print(' -o <prefix>\toutput split graphs')
|
||||||
|
print(' -v \t\tverbose mode')
|
||||||
|
print(' -h \t\tprint this help')
|
||||||
|
print('Report bugs to xiong.gao@huawei.com')
|
||||||
|
|
||||||
|
|
||||||
|
class Option:
|
||||||
|
"""Options"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.split = None
|
||||||
|
self.estimate = False
|
||||||
|
self.estimate_naive = False
|
||||||
|
self.output = None
|
||||||
|
self.verbose = False
|
||||||
|
self.help = False
|
||||||
|
|
||||||
|
def parse(self, options):
|
||||||
|
"""parse options"""
|
||||||
|
for name, val in options:
|
||||||
|
if name == '-h':
|
||||||
|
self.help = True
|
||||||
|
elif name == '-v':
|
||||||
|
self.verbose = True
|
||||||
|
elif name == '-o':
|
||||||
|
self.output = val
|
||||||
|
elif name == '-e':
|
||||||
|
self.estimate = True
|
||||||
|
elif name == '-s':
|
||||||
|
self.split = val
|
||||||
|
elif name == '-i':
|
||||||
|
self.estimate_naive = True
|
||||||
|
|
||||||
|
|
||||||
|
opt = Option()
|
||||||
|
|
||||||
|
|
||||||
|
def estimate(graph_in, parts_in, naive):
|
||||||
|
"""estimate graphs costs"""
|
||||||
|
def _print_cost(name, c):
|
||||||
|
print("%s\tdma_ratio=%f, saturation=%f, mix_saturation=%f, type=%s" %
|
||||||
|
(name, c.dma_ratio(), c.saturation(), c.mix_saturation(), c.cost_type()))
|
||||||
|
main_cost, _ = model.estimate(graph_in, naive)
|
||||||
|
split_cost, sub_costs = model.estimate(parts_in, naive) if parts_in else (None, None)
|
||||||
|
_print_cost("MainGraph:", main_cost)
|
||||||
|
if parts_in:
|
||||||
|
_print_cost("Subgraphs:", split_cost)
|
||||||
|
if opt.verbose:
|
||||||
|
for i, sub_cost in enumerate(sub_costs):
|
||||||
|
_print_cost(" |_%d:\t" % (i), sub_cost)
|
||||||
|
|
||||||
|
|
||||||
|
def split_graph(graph_in, config):
|
||||||
|
"""split graph"""
|
||||||
|
if config == 'auto':
|
||||||
|
return model.split(graph_in)
|
||||||
|
subgraphs = []
|
||||||
|
all_tensors = []
|
||||||
|
subgraph_idx = 0
|
||||||
|
config_parts = config.split('|')
|
||||||
|
for part in config_parts:
|
||||||
|
tensor_names = part.split(',')
|
||||||
|
graph_name = "%s_%d" % (graph_in.name, subgraph_idx)
|
||||||
|
g = graph_in.extract_subgraph(graph_name, tensor_names)
|
||||||
|
assert len(g.ops) == len(tensor_names)
|
||||||
|
subgraphs.append(g)
|
||||||
|
all_tensors += tensor_names
|
||||||
|
subgraph_idx += 1
|
||||||
|
if len(all_tensors) < len(graph_in.ops):
|
||||||
|
graph_name = "%s_%d" % (graph_in.name, subgraph_idx)
|
||||||
|
g = graph_in.extract_subgraph(graph_name, all_tensors, True)
|
||||||
|
subgraphs.append(g)
|
||||||
|
return subgraphs
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
opts, args = getopt.getopt(sys.argv[1:], 'heivo:s:')
|
||||||
|
opt.parse(opts)
|
||||||
|
if len(args) != 1 or opt.help:
|
||||||
|
print_usage()
|
||||||
|
sys.exit(0)
|
||||||
|
in_file = args[0]
|
||||||
|
with open(in_file, 'r') as f:
|
||||||
|
desc = json.loads(f.read())
|
||||||
|
comp = model.load_composite(desc)
|
||||||
|
graph = comp.graph
|
||||||
|
parts = []
|
||||||
|
# 1. split sub-graphs
|
||||||
|
if opt.split is not None:
|
||||||
|
parts = split_graph(graph, opt.split)
|
||||||
|
if opt.verbose:
|
||||||
|
print('----------- main graph --------------')
|
||||||
|
print(graph)
|
||||||
|
for i, _ in enumerate(parts):
|
||||||
|
print('---------------- sub graph %d ---------------' % (i))
|
||||||
|
print(parts[i])
|
||||||
|
# 2. estimate cost
|
||||||
|
if opt.estimate:
|
||||||
|
print('------------- cost --------------')
|
||||||
|
estimate(graph, parts, False)
|
||||||
|
if opt.estimate_naive:
|
||||||
|
print('------------- naive cost --------------')
|
||||||
|
estimate(graph, parts, True)
|
||||||
|
# 3. output parts
|
||||||
|
if opt.output is not None:
|
||||||
|
for graph_part in parts:
|
||||||
|
desc = comp.dump(graph_part)
|
||||||
|
s_desc = json.dumps(desc)
|
||||||
|
fname = "%s_%s.json" % (opt.output, graph_part.name)
|
||||||
|
with open(fname, 'w', encoding='utf-8') as of:
|
||||||
|
of.write(s_desc)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -0,0 +1,53 @@
|
|||||||
|
# Copyright 2020 Huawei Technologies Co., Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
# ===========================================================================
|
||||||
|
"""test split"""
|
||||||
|
import model
|
||||||
|
|
||||||
|
|
||||||
|
def graph_1():
|
||||||
|
gb = model.GraphBuilder()
|
||||||
|
with gb.graph_scope("main"):
|
||||||
|
a = gb.tensor([1024, 16], "float32", name="a")
|
||||||
|
b = gb.emit("Abs", a, 'b')
|
||||||
|
c = gb.emit("Abs", b, 'c')
|
||||||
|
d = gb.emit("Abs", c, 'd')
|
||||||
|
gb.emit("TensorAdd", [b, d], "e")
|
||||||
|
return gb.get()[0]
|
||||||
|
|
||||||
|
|
||||||
|
def graph_2():
|
||||||
|
gb = model.GraphBuilder()
|
||||||
|
with gb.graph_scope("main"):
|
||||||
|
a = gb.tensor([1024, 16], "float32", name="a")
|
||||||
|
b = gb.emit("Abs", a, 'b')
|
||||||
|
c = gb.emit("Abs", b, 'c')
|
||||||
|
d = gb.emit("ReduceSum", c, 'd', attrs={'reduce_axis': (1,)})
|
||||||
|
gb.emit("Sqrt", d, 'e')
|
||||||
|
return gb.get()[0]
|
||||||
|
|
||||||
|
|
||||||
|
def test_split_by_pattern():
|
||||||
|
def _test(graph):
|
||||||
|
print("***************** main graph ***************")
|
||||||
|
print(graph)
|
||||||
|
subgraphs = model.split(graph)
|
||||||
|
for i, g in enumerate(subgraphs):
|
||||||
|
print('------------- subgraph {} --------------'.format(i))
|
||||||
|
print(g)
|
||||||
|
_test(graph_2())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_split_by_pattern()
|
File diff suppressed because it is too large
Load Diff
@ -1,76 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_AKG_AKGKERNELBUILD_H_
|
|
||||||
#define MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_AKG_AKGKERNELBUILD_H_
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
#include <map>
|
|
||||||
#include <utility>
|
|
||||||
#include "backend/kernel_compiler/kernel.h"
|
|
||||||
#include "ir/dtype.h"
|
|
||||||
#include "ir/primitive.h"
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
#include "backend/kernel_compiler/common_utils.h"
|
|
||||||
#include "backend/kernel_compiler/oplib/oplib.h"
|
|
||||||
|
|
||||||
namespace mindspore {
|
|
||||||
namespace kernel {
|
|
||||||
class AkgKernelBuild {
|
|
||||||
public:
|
|
||||||
AkgKernelBuild() {
|
|
||||||
input_tensor_idx_ = {};
|
|
||||||
output_tensor_idx_ = 0;
|
|
||||||
}
|
|
||||||
~AkgKernelBuild() = default;
|
|
||||||
|
|
||||||
KernelPackPtr BuildByJson(const AnfNodePtr &anf_node, std::vector<size_t> *const input_size,
|
|
||||||
std::vector<size_t> *const output_size);
|
|
||||||
static std::string GetProcessor(const AnfNodePtr &anf_node);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool CreateInputDescJson(const AnfNodePtr &anf_node, nlohmann::json *const inputs_json);
|
|
||||||
bool CreateOutputDescJson(const AnfNodePtr &anf_node, nlohmann::json *const outputs_json);
|
|
||||||
bool CreateAttrDescJson(const AnfNodePtr &anf_node, const std::string &op_name,
|
|
||||||
const std::shared_ptr<OpInfo> &op_info, nlohmann::json *const attrs_json);
|
|
||||||
KernelPackPtr OpBuild(const std::string &node_json, const AnfNodePtr &anf_node);
|
|
||||||
int GetOpCntInc();
|
|
||||||
size_t GetInputTensorIdxInc(const AnfNodePtr &anf_node, size_t input_idx);
|
|
||||||
size_t GetOutputTensorIdxInc();
|
|
||||||
bool GenerateSingleKernelJson(const AnfNodePtr &anf_node, const std::string &op_name,
|
|
||||||
nlohmann::json *const node_json);
|
|
||||||
|
|
||||||
static int op_cnt_;
|
|
||||||
// lock for variable fusionOpCnt in singleton mode
|
|
||||||
static std::mutex op_cnt_mtx_;
|
|
||||||
std::string json_name_;
|
|
||||||
std::string json_info_;
|
|
||||||
std::unordered_map<AnfNodePtr, size_t> input_tensor_idx_;
|
|
||||||
size_t output_tensor_idx_;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool GetIOSize(const nlohmann::json &node_json, std::vector<size_t> *const input_size,
|
|
||||||
std::vector<size_t> *const output_size);
|
|
||||||
void SetTensorName(const std::string &tag, const std::string &new_name, const std::pair<size_t, size_t> &position,
|
|
||||||
nlohmann::json *const node_json);
|
|
||||||
std::string GetTensorName(const nlohmann::json &node_json, const std::string &tag,
|
|
||||||
const std::pair<size_t, size_t> &position);
|
|
||||||
} // namespace kernel
|
|
||||||
} // namespace mindspore
|
|
||||||
|
|
||||||
#endif // MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_AKG_AKGKERNELBUILD_H_
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_AKG_AKG_KERNEL_JSON_DECODER_H_
|
||||||
|
#define MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_AKG_AKG_KERNEL_JSON_DECODER_H_
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include "ir/scalar.h"
|
||||||
|
#include "ir/anf.h"
|
||||||
|
#include "ir/func_graph.h"
|
||||||
|
|
||||||
|
namespace mindspore {
|
||||||
|
namespace kernel {
|
||||||
|
class AkgKernelJsonDecoder {
|
||||||
|
public:
|
||||||
|
AkgKernelJsonDecoder() { nodes_map_.clear(); }
|
||||||
|
~AkgKernelJsonDecoder() = default;
|
||||||
|
|
||||||
|
FuncGraphPtr DecodeFusedNodes(const nlohmann::json &kernel_json);
|
||||||
|
FuncGraphPtr DecodeFusedNodes(const std::string &kernel_json_str);
|
||||||
|
bool DecodeSplitNodes(const nlohmann::json &kernel_json, const std::map<std::string, AnfNodePtr> &address_node_map,
|
||||||
|
AnfNodePtrList *res_graphs);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ScalarPtr DecodeScalar(const nlohmann::json &scalar_json);
|
||||||
|
ValueNodePtr DecodeValueNode(const nlohmann::json &value_json, const FuncGraphPtr &func_graph);
|
||||||
|
ParameterPtr DecodeParameter(const nlohmann::json ¶meter_json, const FuncGraphPtr &func_graph);
|
||||||
|
CNodePtr DecodeCNode(const nlohmann::json &cnode_json, const FuncGraphPtr &func_graph, const std::string &processor);
|
||||||
|
std::map<std::string, AnfNodePtr> nodes_map_{};
|
||||||
|
};
|
||||||
|
} // namespace kernel
|
||||||
|
} // namespace mindspore
|
||||||
|
#endif // MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_AKG_AKG_KERNEL_JSON_DECODER_H_
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue