Repository navigation
[AutoTVM]Core functionality for Graph tuner - #2184
Conversation
c4fe94e to
64eaa46
Compare
|
@yzhliu Do we have a time line for layout_transform op? |
028c984 to
d2b9380
Compare
6ba6936 to
deaaaf4
Compare
|
@tqchen @merrymercy @eqy @masahi @yzhliu All tasks are done and this PR is ready to be reviewed. |
|
I want to try this on my box, @kevinthesun can you tell me how long should I expect tuning would take roughly? Say, I want to tune vgg16 or resnet50 on a single desktop. Assuming kernel level tuning is done. |
|
@masahi The graph-tuner itself would be fairly fast (the time I tried resnet it took less than a minute, probably seconds, on a server cpu). When I say "itself", it means the performance for each layer has already tuned (and recorded) by tensor-level AutoTVM. But I think there exists some bug in current Relay's AlterOpLayout https://discuss.tvm.ai/t/relay-alter-op-layout-pass-regression/1870 though. @kevinthesun Correct me if I'm wrong. |
|
In tune_relay_x86.py, I can see that we first tune each layer individually using standard AutoTVM workflow. At this stage, I assume the tuned layout is fixed (all conv ops are NCHW16c or NCHW8c depending on vector length). But for graph tuning, we also need timing record for NCHW64c, NCHW32c ... right? Does tune_graph(...) itself launch tensor level tuning jobs, in addition to solving a combinatorial problem? I have a good idea of how long tune_kernels(...) would take, but not for tune_graph(...). If my understanding is correct, tune_graph should take a very long time if I start from scratch. |
|
@masahi All tensor level jobs are done by autotvm. In this tutorial, all combinations defined in search space are covered. |
43137bd to
f88cba9
Compare
| from tvm.relay import testing | ||
| from tvm.autotvm.tuner import XGBTuner, GATuner, RandomTuner, GridSearchTuner | ||
| from tvm.autotvm.graph_tuner import DPTuner, PBQPTuner | ||
| from tvm.autotvm.graph_tuner.utils import relay_get_conv2d_NCHWc_AVX_workload, infer_conv2d_layout_shape_avx |
There was a problem hiding this comment.
It seems relay_get_conv2d_NCHWc_AVX_workload -> get_conv2d_NCHWc_AVX_workload
| cfg = get_config() | ||
| cfg.add_flop(-1) | ||
| data = args[0] | ||
| out = topi.nn.layout_transform(*args) |
There was a problem hiding this comment.
There is no topi.nn.layout_transform. We have topi.layout_transform instead, here.
But I still get the following error. Maybe the API changed recently?
TypeError: layout_transform() takes 3 positional arguments but 6 were given
There was a problem hiding this comment.
yes top.nn.layout_transform was changed recently.
|
@kevinthesun do you mean the tuning for non standard layouts such as NCHW64c, NCHW32c is supposed to happen during I ran this tutorial yesterday with resnet 18, but the log indicates there are only 12 tasks. It doesn't seem it is trying many layouts exhaustively. |
|
@masahi This progress graph shows there are 12 conv2d workloads to be tuned. For each workload, there should be a bunch of different schedules tried. You can check the resulting log file to see different config for each workload. |
|
Ah, I looked at the autotvm template definition for x86 conv, and realized that different layouts are tuned through |
Yes, that was also a confusing part of the organization to me as well :). I think this currently means that we do not really have a way to just tune one specific layout. |
f067487 to
a729da7
Compare
|
@yzhliu The failing tests are not related to this PR, and I can successfully pass on my local machine. |
|
@tqchen test_rank_zero and test_rank_zero_bound_checkers are failing, which should be unrelated to this PR. I can reproduce the failing tests locally while running all python unit tests. However, if I only run test_codegen_llvm.py, those two tests can pass. Do you have any insight about this kind of behavior? |
| RULE_OUT_NODE_NAMES = ["Tuple", "TupleGetItem", "batch_flatten", "transpose", "reshape", | ||
| "multibox_prior", "multibox_transform_loc", "where", | ||
| "non_max_suppression", "strided_slice"] | ||
| INVALID_LAYOUT_TIME = 1000000000.0 |
| """ | ||
| self._node_list = [] | ||
| self._layout_transform_dict = {} | ||
| self._layout_transform_matrix_dict = {} |
There was a problem hiding this comment.
would layout_transform_perf_records and layout_transform_interlayer_cost be better name?
| node_dict : dictionary from tvm.relay.Expr to int | ||
| Dictionary to record node index | ||
|
|
||
| node_list : list of dictionary |
There was a problem hiding this comment.
could you elaborate what's in the dictionary?
| # Only replace the first input tensor | ||
| input_workload = input_node["workloads"][0] | ||
| first_tensor = input_workload[1] | ||
| dtype = first_tensor[-1] |
There was a problem hiding this comment.
suggest to add comment describe the content of these lists, the index looks confusing, (and makes me panic about out-of-bound)
There was a problem hiding this comment.
Added explanations in docstring of expr2graph
| dtype = first_tensor[-1] | ||
| new_shape = tuple([val.value for val in node_entry["types"][0].shape]) | ||
| actual_workload = (input_workload[0],) + \ | ||
| ((new_shape + (dtype,)),) + input_workload[2:] |
There was a problem hiding this comment.
The elemwise-like node shape might not be necessarily the same as input nodes. For example, a pooling following a conv2d, befoer going into an elemwise node.
| if key not in out: | ||
| raise RuntimeError("%s not in output dictionary." % str(key)) | ||
| if not os.path.isfile(log_file): | ||
| raise RuntimeError("No log file with name %s exists." % log_file) |
There was a problem hiding this comment.
can we assert some results instead of just ensure there's an output? e.g., assert out[key] == xxx, or assert max(out) == xxx
| for op_name, node in zip(op_name_list, node_list): | ||
| if op_name != node["op"]: | ||
| raise RuntimeError("Node operator mismatch: expecting %s but got %s" | ||
| % (str(op_name), str(node["op"]))) |
| out = has_multiple_inputs(node_list, node_idx, input_names) | ||
| if out != expected_result: | ||
| raise RuntimeError("Output mismatch: expecting checking %s to be %s but got %s." | ||
| % (node_list[node_idx]["op"], str(expected_result), str(out))) |
There was a problem hiding this comment.
assert out == expected_result, "Output mismatch ..."
| input_names = ["data"] | ||
| out = get_direct_ancestor(node_list, visited_dict, target_ops, 5, input_names) | ||
| if len(out) != 2 or out != [2, 0]: | ||
| raise RuntimeError("Output mismatch: expecting [2, 0] but got %s." % str(out)) |
| expected_out = [records[3][0].config, records[1][0].config, records[2][0].config] | ||
| if expected_out != out: | ||
| raise RuntimeError("Output mismatch: expecting %s but got %s" | ||
| % (str(expected_out), str(out))) |
|
@yzhliu comments addressed. |
yzhliu
left a comment
There was a problem hiding this comment.
The overall looks good to me. While any idea how could we address the ci failure?
|
Thanks! |
* Add graph tuning * Add tests * Fix tests * Fix pylint * Small fix for docstring * Minor fix * Support fetching workload from relay expr * Simplify benchmark layout transformation * Add relay support * Fix infer layout func name * Refactor internal data representation * Fix issues * Add PBQP solver * Fix layout transform check * Add PBQPTuner test * Fix lint * Update tutorial * Fix tutorial * Fix lint * Add relay test * Remove nnvm since nnvm graph can be converted to relay function * Modify benchmark layout wrt new layout_transform api * Fix lint * Update docstring for DP tuner * Refactor traverse graph * Support graph tuning for multiple target operators * Fix fetching workloads * Add x86 depthwise_conv2d infer_layout * Fix x86 depthwise_conv2d autotvm * Fix PBQP tuner * Fix DP tuner * Generate dummy layout transform record * Update tutorial * Modify layout records name * Add ASF header * Add ASF header for testing files * Fix test * Fix topi fetching * Some refactors * Fix lint * Fix tutorial * Rename test files * Fix doc typo * Add test case note link
* Add graph tuning * Add tests * Fix tests * Fix pylint * Small fix for docstring * Minor fix * Support fetching workload from relay expr * Simplify benchmark layout transformation * Add relay support * Fix infer layout func name * Refactor internal data representation * Fix issues * Add PBQP solver * Fix layout transform check * Add PBQPTuner test * Fix lint * Update tutorial * Fix tutorial * Fix lint * Add relay test * Remove nnvm since nnvm graph can be converted to relay function * Modify benchmark layout wrt new layout_transform api * Fix lint * Update docstring for DP tuner * Refactor traverse graph * Support graph tuning for multiple target operators * Fix fetching workloads * Add x86 depthwise_conv2d infer_layout * Fix x86 depthwise_conv2d autotvm * Fix PBQP tuner * Fix DP tuner * Generate dummy layout transform record * Update tutorial * Modify layout records name * Add ASF header * Add ASF header for testing files * Fix test * Fix topi fetching * Some refactors * Fix lint * Fix tutorial * Rename test files * Fix doc typo * Add test case note link
This is the core function for graph tuner: #1585
Tasks yet to be done:
We can start reviewing for core parts. @tqchen @merrymercy @eqy @yzhliu @masahi