Skip to content

Protect torch_tensor_from_array from abuse #417

@Mikolaj-A-Kowalski

Description

@Mikolaj-A-Kowalski

I think there are two potentially dangerous things that can be done with the from_array tensor constructors. Perhaps we should try to think about some protections or at least we should probably discuss these failure modes more explicitly in the documentation?

Passing non-contiguous arrays is allowed

Currently there is nothing that protects against doing the following (e.g. in the SimpleNet example)

   ...
   ! Set up Fortran data structures
   real(wp), dimension(10), target :: in_data
   real(wp), dimension(10), target :: out_data
   real(wp), dimension(10), target :: expected
   ...

   ! Create Torch input/output tensors from the above arrays
   call torch_tensor_from_array(in_tensors(1), in_data(1:10:2), torch_kCPU)
   call torch_tensor_from_array(out_tensors(1), out_data(1:10:2), torch_kCPU)
   ...

which (unless I am forgetting something) is valid Fortran and something a user may do at some point. The problem is that the result is not what is expected since the torch_tensor_from_array implicitly assumes that the input array is contiguous. As the result in this example the in_data(1:5) will be used instead of the odd indices.

Perhaps we should add is_contiguous check inside torch_tensor_from_array and throw an error if it isn't?

Passing a temporary array

Since the data_in dummy argument is declared intent(in) the following is allowed:

   call torch_tensor_from_array(in_tensors(1), in_data*2, torch_kCPU)

as in we can provide result of an expression as an argument, which I think will make a tensor point to a temporary. This problem is technically mentioned in the docs (temporary array has no target attribute which the docs say is required), but I feel like this is easy to miss (e.g. some of the usage like that sneaked into the unit tests) and we should think of some automatic protection against it.

I think there are two legal ways of doing that:

  1. (preferred) Make the data_in an intent(in) pointer. I believe in that case a target actual argument should still bind. Also maybe adding contiguous attribute will help to move the check from the 1st problem from runtime to compile-time (need to check) [EDIT: Seems to work on the first glance. The only problem is that the error message is not very informative. Just: `"There is no specific subroutine..." :-/
  2. We can make the data_in intent(inout) and just be careful not to modify it by accident. It should prevent accidental usage with temporary arrays (or at least reduce a chance of that happening)

Last but not least I am not sure how it will all work for backwards compatibility :-/

Metadata

Metadata

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions