Skip to content

Conversation

@KJlaccHoeUM9l
Copy link
Contributor

PR has added the ability to skip copying data when creating input NDArray tensors if the source input is in DLTensor format.

However, when adding this functionality, memory alignment was not checked, as it was done for GraphExecutor.
In view of this, runtime errors (Segmentation fault (core dumped)) are possible, because TVM uses aligned memory.

This PR adds this check.

@tmoreau89
Copy link
Contributor

CC @tkonolige @mbs-octoml

* If AbilityOfZeroCopyForDLTensor is true a NDArray is created
* using the memory allocated by an external source.
* Responsibility for memory retaining lies with the external source.
* Otherwise new NDArray is created, the data is copied from the DLTensor.
Copy link
Contributor

Choose a reason for hiding this comment

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

This says data will be copied but the \brief says data will not be copied. Which is it? My reading of the code below is that data will be copied if AbilityOfZeroCopyForDLTensor is false.

I don't think we should change the semantics of this function. How about we just raise an error if the AbilityOfZeroCopyForDLTensor is false?

Copy link
Contributor

Choose a reason for hiding this comment

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

No, we do not raise the error due to the following reason. If you see in detail it is development of 'set_input' method of VirtualMachine. This method can be separated on two parts: one considers input as NDArray, another one does input as DLTensor. In both cases it trys to do zero copy if can, otherwise real copy is used. It has been implemented for NDArray (it automatically does not have problem with alignment) and after we have developed it for DLTensor but not checked alignment in previous PR. If we cannot use zero copy we still should use usual copy to avoid method failure. There are no 'set_input' and 'set_input_zero_copy' methods for VM. I discussed it on previous PR, it is design of VM. It means that 'set_input' should work stably in both cases with and without copying

Copy link
Contributor

Choose a reason for hiding this comment

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

What you are proposing here is a change to the semantics of FromExternalDLTensor. Because this is a public and important API I suggest you do not change it and instead put the logic into set_input.

If NDArray needs its underlying DLTensor to be aligned, then we should also add a check to FromExternalDLTensor to make sure that the underlying data is aligned.

@tqchen maybe you can provide some feedback here.

Copy link
Member

Choose a reason for hiding this comment

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

I agree that FromExternalDLTensor in this case should check alignment,

@KJlaccHoeUM9l KJlaccHoeUM9l changed the title [VM] Memory alignment check for set_input_zero_copy [VM] Memory alignment check for set_input in Virtual Machine May 24, 2022
@vvchernov
Copy link
Contributor

Hello @tkonolige and @tqchen! I've updated public API, now its functionality should be more correct

@tkonolige
Copy link
Contributor

@vvchernov I see that you are still changing the semantics of FromExternalDLTensor. FromExternalDLTensor(DLTensor* dl_tensor, const Device& dst_dev) will copy if alignment is wrong, but FromExternalDLTensor(const DLTensor& dl_tensor) will throw an error if the alignment is wrong. I think this is pretty confusing as they both have the same name. Can you make FromExternalDLTensor(DLTensor* dl_tensor, const Device& dst_dev) fail if alignment is wrong and instead move the copying logic into the VM.

@vvchernov
Copy link
Contributor

Hello @tkonolige! I've skipped FromExternalDLTensor(DLTensor* dl_tensor, const Device& dst_dev) method from NDArray class and replaced its logic to VirtualMachine where it is really used.

Copy link
Contributor

@tkonolige tkonolige left a comment

Choose a reason for hiding this comment

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

Thanks @KJlaccHoeUM9l!

@vvchernov
Copy link
Contributor

Hello @tkonolige! CI tests were passed successfully. Could you approve it?

@tkonolige
Copy link
Contributor

@vvchernov I have approved it :). Unfortunately I am not a committer. You'll need someone who is to approve it.

Copy link
Contributor

@tmoreau89 tmoreau89 left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for the review @tkonolige

@tmoreau89 tmoreau89 merged commit 2a2d910 into apache:main May 27, 2022
@KJlaccHoeUM9l KJlaccHoeUM9l deleted the agladyshev/dev branch December 20, 2022 11:28
Lunderberg added a commit to Lunderberg/tvm that referenced this pull request May 4, 2023
Prior to this commit, any use of `tvm.nd.from_dlpack` to create a
strided `NDArray`, or a `NDArray` whose alignment was less than
`tvm::runtime::kAllocAlignment` would raise an error.  As a result,
views into larger arrays, which are unlikely to be aligned and
compact, could only be shared when copied into an aligned and compact
buffer.

This commit moves the compact/aligned check from the `NDArray` class
into the generated TIR code as part of DLTensor unpacking.  These
checks were initially introduced in
apache#11391, to avoid segfaults caused by
use of non-aligned buffers in code intended for aligned buffers.  The
new checks will provide the same safeguard as the alignment is checked
prior to use, but allows the alignment requirement to be relaxed on a
per-buffer basis.

This approach also removes a potential bug resulting from compile-time
configuration of `tvm::runtime::kAllocAlignment`, first introduced in
apache#13307.  Since TVM supports
cross-compiling, the installation of TVM used to compile a kernel may
assume a larger value of `kAllocAlignment` than is provided by the
runtime installation of TVM.  By validating the alignment within the
generated kernel, rather than as part of the runtime, this potential
inconsistency would be caught.
Lunderberg added a commit to Lunderberg/tvm that referenced this pull request May 8, 2023
Prior to this commit, any use of `tvm.nd.from_dlpack` to create a
strided `NDArray`, or a `NDArray` whose alignment was less than
`tvm::runtime::kAllocAlignment` would raise an error.  As a result,
views into larger arrays, which are unlikely to be aligned and
compact, could only be shared when copied into an aligned and compact
buffer.

This commit moves the compact/aligned check from the `NDArray` class
into the generated TIR code as part of DLTensor unpacking.  These
checks were initially introduced in
apache#11391, to avoid segfaults caused by
use of non-aligned buffers in code intended for aligned buffers.  The
new checks will provide the same safeguard as the alignment is checked
prior to use, but allows the alignment requirement to be relaxed on a
per-buffer basis.

This approach also removes a potential bug resulting from compile-time
configuration of `tvm::runtime::kAllocAlignment`, first introduced in
apache#13307.  Since TVM supports
cross-compiling, the installation of TVM used to compile a kernel may
assume a larger value of `kAllocAlignment` than is provided by the
runtime installation of TVM.  By validating the alignment within the
generated kernel, rather than as part of the runtime, this potential
inconsistency would be caught.
Lunderberg added a commit to Lunderberg/tvm that referenced this pull request Jun 5, 2023
Prior to this commit, any use of `tvm.nd.from_dlpack` to create a
strided `NDArray`, or a `NDArray` whose alignment was less than
`tvm::runtime::kAllocAlignment` would raise an error.  As a result,
views into larger arrays, which are unlikely to be aligned and
compact, could only be shared when copied into an aligned and compact
buffer.

This commit moves the compact/aligned check from the `NDArray` class
into the generated TIR code as part of DLTensor unpacking.  These
checks were initially introduced in
apache#11391, to avoid segfaults caused by
use of non-aligned buffers in code intended for aligned buffers.  The
new checks will provide the same safeguard as the alignment is checked
prior to use, but allows the alignment requirement to be relaxed on a
per-buffer basis.

This approach also removes a potential bug resulting from compile-time
configuration of `tvm::runtime::kAllocAlignment`, first introduced in
apache#13307.  Since TVM supports
cross-compiling, the installation of TVM used to compile a kernel may
assume a larger value of `kAllocAlignment` than is provided by the
runtime installation of TVM.  By validating the alignment within the
generated kernel, rather than as part of the runtime, this potential
inconsistency would be caught.
Lunderberg added a commit to Lunderberg/tvm that referenced this pull request Jun 12, 2023
Prior to this commit, any use of `tvm.nd.from_dlpack` to create a
strided `NDArray`, or a `NDArray` whose alignment was less than
`tvm::runtime::kAllocAlignment` would raise an error.  As a result,
views into larger arrays, which are unlikely to be aligned and
compact, could only be shared when copied into an aligned and compact
buffer.

This commit moves the compact/aligned check from the `NDArray` class
into the generated TIR code as part of DLTensor unpacking.  These
checks were initially introduced in
apache#11391, to avoid segfaults caused by
use of non-aligned buffers in code intended for aligned buffers.  The
new checks will provide the same safeguard as the alignment is checked
prior to use, but allows the alignment requirement to be relaxed on a
per-buffer basis.

This approach also removes a potential bug resulting from compile-time
configuration of `tvm::runtime::kAllocAlignment`, first introduced in
apache#13307.  Since TVM supports
cross-compiling, the installation of TVM used to compile a kernel may
assume a larger value of `kAllocAlignment` than is provided by the
runtime installation of TVM.  By validating the alignment within the
generated kernel, rather than as part of the runtime, this potential
inconsistency would be caught.
Lunderberg added a commit to Lunderberg/tvm that referenced this pull request Jul 5, 2023
Prior to this commit, any use of `tvm.nd.from_dlpack` to create a
strided `NDArray`, or a `NDArray` whose alignment was less than
`tvm::runtime::kAllocAlignment` would raise an error.  As a result,
views into larger arrays, which are unlikely to be aligned and
compact, could only be shared when copied into an aligned and compact
buffer.

This commit moves the compact/aligned check from the `NDArray` class
into the generated TIR code as part of DLTensor unpacking.  These
checks were initially introduced in
apache#11391, to avoid segfaults caused by
use of non-aligned buffers in code intended for aligned buffers.  The
new checks will provide the same safeguard as the alignment is checked
prior to use, but allows the alignment requirement to be relaxed on a
per-buffer basis.

This approach also removes a potential bug resulting from compile-time
configuration of `tvm::runtime::kAllocAlignment`, first introduced in
apache#13307.  Since TVM supports
cross-compiling, the installation of TVM used to compile a kernel may
assume a larger value of `kAllocAlignment` than is provided by the
runtime installation of TVM.  By validating the alignment within the
generated kernel, rather than as part of the runtime, this potential
inconsistency would be caught.

This check is also restricted to targets whose `void*` opaque pointer
can be interpreted as a pointer to the data array.  (e.g. No such
check applies on Vulkan, as the `void*` is a pointer to a struct that
contains additional bookkeeping.)
Lunderberg added a commit to Lunderberg/tvm that referenced this pull request May 23, 2024
Prior to this commit, any use of `tvm.nd.from_dlpack` to create a
strided `NDArray`, or a `NDArray` whose alignment was less than
`tvm::runtime::kAllocAlignment` would raise an error.  As a result,
views into larger arrays, which are unlikely to be aligned and
compact, could only be shared when copied into an aligned and compact
buffer.

This commit moves the compact/aligned check from the `NDArray` class
into the generated TIR code as part of DLTensor unpacking.  These
checks were initially introduced in
apache#11391, to avoid segfaults caused by
use of non-aligned buffers in code intended for aligned buffers.  The
new checks will provide the same safeguard as the alignment is checked
prior to use, but allows the alignment requirement to be relaxed on a
per-buffer basis.

This approach also removes a potential bug resulting from compile-time
configuration of `tvm::runtime::kAllocAlignment`, first introduced in
apache#13307.  Since TVM supports
cross-compiling, the installation of TVM used to compile a kernel may
assume a larger value of `kAllocAlignment` than is provided by the
runtime installation of TVM.  By validating the alignment within the
generated kernel, rather than as part of the runtime, this potential
inconsistency would be caught.

This check is also restricted to targets whose `void*` opaque pointer
can be interpreted as a pointer to the data array.  (e.g. No such
check applies on Vulkan, as the `void*` is a pointer to a struct that
contains additional bookkeeping.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants