Skip to content
This repository was archived by the owner on Nov 17, 2023. It is now read-only.

move exec.reshape to backend#10882

Merged
eric-haibin-lin merged 8 commits into
apache:masterfrom
ZiyueHuang:backend_reshape
May 24, 2018
Merged

move exec.reshape to backend#10882
eric-haibin-lin merged 8 commits into
apache:masterfrom
ZiyueHuang:backend_reshape

Conversation

@ZiyueHuang
Copy link
Copy Markdown
Member

Description

move exec.reshape to backend

cc @reminisce @eric-haibin-lin @piiswrong

Checklist

Essentials

Please feel free to remove inapplicable items for your PR.

  • The PR title starts with [MXNET-$JIRA_ID], where $JIRA_ID refers to the relevant JIRA issue created (except PRs with tiny changes)
  • Changes are complete (i.e. I finished coding on this PR)
  • All changes have test coverage:
  • Unit tests are added for small changes to verify correctness (e.g. adding a new operator)
  • Nightly tests are added for complicated/long-running ones (e.g. changing distributed kvstore)
  • Build tests will be added for build configuration changes (e.g. adding a new build option with NCCL)
  • Code is well-documented:
  • For user-facing API changes, API doc string has been updated.
  • For new C++ functions in header files, their functionalities and arguments are documented.
  • For new examples, README.md is added to explain the what the example does, the source of the dataset, expected performance on test set and reference to the original paper if applicable
  • Check the API doc at http://mxnet-ci-doc.s3-accelerate.dualstack.amazonaws.com/PR-$PR_ID/$BUILD_ID/index.html
  • To the my best knowledge, examples are either not affected by this change, or have been fixed to be compatible with this change

Changes

  • Feature1, tests, (and when applicable, API doc)
  • Feature2, tests, (and when applicable, API doc)

Comments

  • If this change is a backward incompatible change, why must this change be made.
  • Interesting edge cases to note here

@ZiyueHuang ZiyueHuang requested a review from szha as a code owner May 10, 2018 06:09
Comment thread src/c_api/c_api_executor.cc Outdated
API_END();
}

int MXExecutorReshapeEX(SymbolHandle symbol_handle,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: MXExecutorReshapeEX -> MXExecutorReshapeEx

@eric-haibin-lin eric-haibin-lin self-assigned this May 10, 2018
Copy link
Copy Markdown
Contributor

@piiswrong piiswrong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there existing test covering reshape?

Comment thread include/mxnet/c_api.h Outdated
*! \brief Return a new executor with the same symbol and shared memory,
* but different input/output shapes.
*/
MXNET_DLL int MXExecutorReshapeEx(SymbolHandle symbol_handle,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why Ex? is there a MXExecutorReshape already?

Copy link
Copy Markdown
Contributor

@reminisce reminisce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please write unit tests for this. It should cover expected behaviors of sizing down and sizing up.

Comment thread src/c_api/c_api_executor.cc Outdated
for (uint32_t nid : idx.input_nodes()) {
std::string name = idx[nid].source->attrs.name;
const TShape& new_shape = shape_vec[idx.entry_id(nid, 0)];
if (idx.mutable_input_nodes().count(nid) == 0) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you consolidate the implementation for args and aux? There is a big chunk of duplicate code.

Comment thread src/c_api/c_api_executor.cc Outdated
if (idx.mutable_input_nodes().count(nid) == 0) {
NDArray* arr = static_cast<NDArray*>(*arg);
NDArray* darr = static_cast<NDArray*>(*grad);
if (new_shape == arr->shape()) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please simplify this. There is no need to have a do nothing block.

Comment thread src/c_api/c_api_executor.cc Outdated
<< "is more efficient than the reverse."
<< "If you really want to up size, set allow_up_sizing=True "
<< "to enable allocation of new arrays.";
NDArray* empty_arr = new NDArray(new_shape, arr->ctx(), false, arr->dtype());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a memory leak. Please use arr.ReshapeAndAlloc(new_shape).

Comment thread src/c_api/c_api_executor.cc Outdated
<< "is more efficient than the reverse."
<< "If you really want to up size, set allow_up_sizing=True "
<< "to enable allocation of new arrays.";
NDArray* empty_arr = new NDArray(new_shape, arr->ctx(), false, arr->dtype());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. ReshapeAndAlloc.

@ZiyueHuang
Copy link
Copy Markdown
Member Author

Comment thread python/mxnet/executor.py Outdated
provided_arg_shape_data.extend(v)
provided_arg_shape_idx.append(len(provided_arg_shape_data))

args_handle, args = self._symbol._get_ndarray_inputs(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can get all the arg/aux/grad arrays from the executor in backend? Is it necessary to prepare them here and pass to the backend again?

@ZiyueHuang
Copy link
Copy Markdown
Member Author

Could you please review again? I realized that Reshape is more appropriate to be a member function of Executor so that it can access the internal arguments of the executor. Also I think ReshapeAndAlloc should not be used, since the original executor should work fine after reshape.

Comment thread src/executor/graph_executor.cc Outdated
auto it = arg_grad_map_.find(name);
if (partial_shaping || provided_arg_shapes.count(name) || new_shape == arr.shape()) {
if (new_shape.Size() > arr.shape().Size()) {
CHECK(allow_up_sizing) << name << up_sizing_msg.str();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need better error message

Comment thread src/executor/graph_executor.cc Outdated
size_t grad_top = 0;

std::ostringstream up_sizing_msg, unspecified_msg;
up_sizing_msg << ": Arg of new shape which is larger than original."
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<< is expensive. Normal execution doesn't need to construct these long strings.

Copy link
Copy Markdown
Contributor

@reminisce reminisce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the existing unit tests have not covered checking whether the reshaped executor and the original executor share NDArrays depending on the new shape sizes. Could you add test cases covering that check? For checking whether two NDArrays are the same in Python, you can use function same_array

symbol.outputs = g.outputs;
const nnvm::IndexedGraph& idx = g.indexed_graph();
nnvm::ShapeVector arg_shapes(idx.input_nodes().size(), TShape());
for (size_t i = 0; i < num_forward_inputs_; ++i) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call in_args->reserve(num_args) first outside loop? Same for aux_states and arg_grads.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

Comment thread src/executor/graph_executor.cc Outdated
if (partial_shaping || provided_arg_shapes.count(name) || new_shape == arr.shape()) {
if (new_shape.Size() > arr.shape().Size()) {
CHECK(allow_up_sizing) << name << up_sizing_msg.str();
in_args->push_back(NDArray(new_shape, arr.ctx(), false, arr.dtype()));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use in_args->emplace_back(new_shape, arr.ctx(), false, arr.dtype()) to avoid constructing temporary copy of NDArray. Same for all the other push_back(ndarray).

Comment thread src/executor/graph_executor.cc Outdated
arg_grads->push_back(darr.Reshape(new_shape));
grad_req_types.push_back(grad_store_.at(grad_top++).first);
} else {
arg_grads->push_back(NDArray());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use arg_grads->emplace_back().

Comment thread src/c_api/c_api_executor.cc Outdated
*aux_states = &(ret->ret_handles[nd_idx]);
nd_idx = ret->ret_handles.size();
}
API_END();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete out here if an exception is thrown?

Comment thread src/c_api/c_api_executor.cc Outdated
TShape(provided_arg_shape_data+provided_arg_shape_idx[i],
provided_arg_shape_data+provided_arg_shape_idx[i+1]));
CHECK(p.second) << "Duplicate shapes are provided for argument "
<< provided_arg_shape_names[i] << " in simple_bind";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it always simple_bind?

@ZiyueHuang
Copy link
Copy Markdown
Member Author

unittest for checking

whether the reshaped executor and the original executor share NDArrays depending on the new shape sizes

is added in test_executor.py @reminisce

@ZiyueHuang
Copy link
Copy Markdown
Member Author

ping @reminisce @piiswrong

@szha
Copy link
Copy Markdown
Member

szha commented May 21, 2018

ping @piiswrong

@szha szha removed their request for review May 21, 2018 21:47
@piiswrong
Copy link
Copy Markdown
Contributor

LGTM. Any concerns? @reminisce @eric-haibin-lin

@eric-haibin-lin eric-haibin-lin merged commit 704d218 into apache:master May 24, 2018
jinhuang415 pushed a commit to jinhuang415/incubator-mxnet that referenced this pull request May 29, 2018
* move exec.reshape to backend

* fix lint

* fix lint

* fix Symbol._get_ndarray_inputs

* update

* update

* move Reshape as a member function of Executor

* address comments
rahul003 pushed a commit to rahul003/mxnet that referenced this pull request Jun 4, 2018
* move exec.reshape to backend

* fix lint

* fix lint

* fix Symbol._get_ndarray_inputs

* update

* update

* move Reshape as a member function of Executor

* address comments
zheng-da pushed a commit to zheng-da/incubator-mxnet that referenced this pull request Jun 28, 2018
* move exec.reshape to backend

* fix lint

* fix lint

* fix Symbol._get_ndarray_inputs

* update

* update

* move Reshape as a member function of Executor

* address comments
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants