!| Main module for FTorch containing types and procedures. ! Generated from `ftorch.fypp` using the [fypp Fortran preprocessor](https://fypp.readthedocs.io/en/stable/index.html). ! ! * License ! FTorch is released under an MIT license. ! See the [LICENSE](https://github.com/Cambridge-ICCS/FTorch/blob/main/LICENSE) ! file for details. module ftorch use, intrinsic :: iso_c_binding, only: c_int, c_int8_t, c_int16_t, c_int32_t, c_int64_t, & c_float, c_double, c_char, c_ptr, c_null_ptr, c_f_pointer use, intrinsic :: iso_fortran_env, only: int8, int16, int32, int64, real32, real64 implicit none integer, parameter :: ftorch_int = int32 ! set integer size for FTorch library !> Type for holding a torch neural net (nn.Module). type torch_model type(c_ptr) :: p = c_null_ptr !! pointer to the neural net in memory end type torch_model !> Type for holding a Torch tensor. type torch_tensor type(c_ptr) :: p = c_null_ptr !! pointer to the tensor in memory contains procedure :: get_rank procedure :: get_shape end type torch_tensor !| Enumerator for Torch data types ! From c_torch.h (torch_data_t) ! Note that 0 `torch_kUInt8` and 5 `torch_kFloat16` are not sypported in Fortran enum, bind(c) enumerator :: torch_kUInt8 = 0 ! not supported in Fortran enumerator :: torch_kInt8 = 1 enumerator :: torch_kInt16 = 2 enumerator :: torch_kInt32 = 3 enumerator :: torch_kInt64 = 4 enumerator :: torch_kFloat16 = 5 ! not supported in Fortran enumerator :: torch_kFloat32 = 6 enumerator :: torch_kFloat64 = 7 end enum !| Enumerator for Torch devices ! From c_torch.h (torch_device_t) enum, bind(c) enumerator :: torch_kCPU = 0 enumerator :: torch_kCUDA = 1 end enum !> Interface for directing `torch_tensor_from_array` to possible input types and ranks interface torch_tensor_from_array module procedure torch_tensor_from_array_int8_1d module procedure torch_tensor_from_array_int8_2d module procedure torch_tensor_from_array_int8_3d module procedure torch_tensor_from_array_int8_4d module procedure torch_tensor_from_array_int8_5d module procedure torch_tensor_from_array_int16_1d module procedure torch_tensor_from_array_int16_2d module procedure torch_tensor_from_array_int16_3d module procedure torch_tensor_from_array_int16_4d module procedure torch_tensor_from_array_int16_5d module procedure torch_tensor_from_array_int32_1d module procedure torch_tensor_from_array_int32_2d module procedure torch_tensor_from_array_int32_3d module procedure torch_tensor_from_array_int32_4d module procedure torch_tensor_from_array_int32_5d module procedure torch_tensor_from_array_int64_1d module procedure torch_tensor_from_array_int64_2d module procedure torch_tensor_from_array_int64_3d module procedure torch_tensor_from_array_int64_4d module procedure torch_tensor_from_array_int64_5d module procedure torch_tensor_from_array_real32_1d module procedure torch_tensor_from_array_real32_2d module procedure torch_tensor_from_array_real32_3d module procedure torch_tensor_from_array_real32_4d module procedure torch_tensor_from_array_real32_5d module procedure torch_tensor_from_array_real64_1d module procedure torch_tensor_from_array_real64_2d module procedure torch_tensor_from_array_real64_3d module procedure torch_tensor_from_array_real64_4d module procedure torch_tensor_from_array_real64_5d end interface !> Interface for directing `torch_tensor_to_array` to possible input types and ranks interface torch_tensor_to_array module procedure torch_tensor_to_array_int8_1d module procedure torch_tensor_to_array_int8_2d module procedure torch_tensor_to_array_int8_3d module procedure torch_tensor_to_array_int8_4d module procedure torch_tensor_to_array_int8_5d module procedure torch_tensor_to_array_int16_1d module procedure torch_tensor_to_array_int16_2d module procedure torch_tensor_to_array_int16_3d module procedure torch_tensor_to_array_int16_4d module procedure torch_tensor_to_array_int16_5d module procedure torch_tensor_to_array_int32_1d module procedure torch_tensor_to_array_int32_2d module procedure torch_tensor_to_array_int32_3d module procedure torch_tensor_to_array_int32_4d module procedure torch_tensor_to_array_int32_5d module procedure torch_tensor_to_array_int64_1d module procedure torch_tensor_to_array_int64_2d module procedure torch_tensor_to_array_int64_3d module procedure torch_tensor_to_array_int64_4d module procedure torch_tensor_to_array_int64_5d module procedure torch_tensor_to_array_real32_1d module procedure torch_tensor_to_array_real32_2d module procedure torch_tensor_to_array_real32_3d module procedure torch_tensor_to_array_real32_4d module procedure torch_tensor_to_array_real32_5d module procedure torch_tensor_to_array_real64_1d module procedure torch_tensor_to_array_real64_2d module procedure torch_tensor_to_array_real64_3d module procedure torch_tensor_to_array_real64_4d module procedure torch_tensor_to_array_real64_5d end interface !> Interface for deleting generic torch objects interface torch_delete module procedure torch_model_delete module procedure torch_tensor_delete module procedure torch_tensor_array_delete end interface interface function torch_from_blob_c(data, ndims, tensor_shape, strides, dtype, & device_type, device_index, & requires_grad) result(tensor_p) & bind(c, name = 'torch_from_blob') use, intrinsic :: iso_c_binding, only : c_bool, c_int, c_int64_t, c_ptr implicit none ! Arguments type(c_ptr), value, intent(in) :: data integer(c_int), value, intent(in) :: ndims integer(c_int64_t), intent(in) :: tensor_shape(*) integer(c_int64_t), intent(in) :: strides(*) integer(c_int), value, intent(in) :: dtype integer(c_int), value, intent(in) :: device_type integer(c_int), value, intent(in) :: device_index logical(c_bool), value, intent(in) :: requires_grad type(c_ptr) :: tensor_p end function torch_from_blob_c end interface interface assignment (=) module procedure torch_tensor_assign end interface interface operator (+) module procedure torch_tensor_add end interface interface operator (-) module procedure torch_tensor_subtract end interface interface operator (*) module procedure torch_tensor_multiply module procedure torch_tensor_premultiply_int8 module procedure torch_tensor_postmultiply_int8 module procedure torch_tensor_premultiply_int16 module procedure torch_tensor_postmultiply_int16 module procedure torch_tensor_premultiply_int32 module procedure torch_tensor_postmultiply_int32 module procedure torch_tensor_premultiply_int64 module procedure torch_tensor_postmultiply_int64 module procedure torch_tensor_premultiply_real32 module procedure torch_tensor_postmultiply_real32 module procedure torch_tensor_premultiply_real64 module procedure torch_tensor_postmultiply_real64 end interface interface operator (/) module procedure torch_tensor_divide module procedure torch_tensor_postdivide_int8 module procedure torch_tensor_postdivide_int16 module procedure torch_tensor_postdivide_int32 module procedure torch_tensor_postdivide_int64 module procedure torch_tensor_postdivide_real32 module procedure torch_tensor_postdivide_real64 end interface interface operator (**) module procedure torch_tensor_power_int8 module procedure torch_tensor_power_int16 module procedure torch_tensor_power_int32 module procedure torch_tensor_power_int64 module procedure torch_tensor_power_real32 module procedure torch_tensor_power_real64 end interface interface function torch_to_blob_c(tensor, dtype) result(data) & bind(c, name = 'torch_to_blob') use, intrinsic :: iso_c_binding, only : c_int, c_ptr implicit none type(c_ptr), value, intent(in) :: tensor integer(c_int), value, intent(in) :: dtype type(c_ptr) :: data end function torch_to_blob_c end interface contains !> Returns a tensor filled with the scalar value 0. subroutine torch_tensor_zeros(tensor, ndims, tensor_shape, dtype, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_int, c_int64_t type(torch_tensor), intent(out) :: tensor !! Returned tensor integer(c_int), intent(in) :: ndims !! Number of dimensions of the tensor integer(c_int64_t), intent(in) :: tensor_shape(*) !! Shape of the tensor integer(c_int), intent(in) :: dtype !! Data type of the tensor integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical(c_bool), optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor integer(c_int) :: device_index_value !! device index used logical(c_bool) :: requires_grad_value !! Whether gradients need to be computed for the created tensor interface function torch_zeros_c(ndims, tensor_shape, dtype, & device_type, device_index, requires_grad) result(tensor) & bind(c, name = 'torch_zeros') use, intrinsic :: iso_c_binding, only : c_bool, c_int, c_int64_t, c_ptr implicit none integer(c_int), value, intent(in) :: ndims integer(c_int64_t), intent(in) :: tensor_shape(*) integer(c_int), value, intent(in) :: dtype integer(c_int), value, intent(in) :: device_type integer(c_int), value, intent(in) :: device_index logical(c_bool), value, intent(in) :: requires_grad type(c_ptr) :: tensor end function torch_zeros_c end interface ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = logical(.false., c_bool) else requires_grad_value = requires_grad end if tensor%p = torch_zeros_c(ndims, tensor_shape, dtype, device_type, & device_index_value, requires_grad_value) end subroutine torch_tensor_zeros !> Returns a tensor filled with the scalar value 1. subroutine torch_tensor_ones(tensor, ndims, tensor_shape, dtype, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_int, c_int64_t type(torch_tensor), intent(out) :: tensor !! Returned tensor integer(c_int), intent(in) :: ndims !! Number of dimensions of the tensor integer(c_int64_t), intent(in) :: tensor_shape(*) !! Shape of the tensor integer(c_int), intent(in) :: dtype !! Data type of the tensor integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical(c_bool), optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor integer(c_int) :: device_index_value !! device index used logical(c_bool) :: requires_grad_value !! Whether gradients need to be computed for the created tensor interface function torch_ones_c(ndims, tensor_shape, dtype, & device_type, device_index, requires_grad) result(tensor) & bind(c, name = 'torch_ones') use, intrinsic :: iso_c_binding, only : c_bool, c_int, c_int64_t, c_ptr implicit none integer(c_int), value, intent(in) :: ndims integer(c_int64_t), intent(in) :: tensor_shape(*) integer(c_int), value, intent(in) :: dtype integer(c_int), value, intent(in) :: device_type integer(c_int), value, intent(in) :: device_index logical(c_bool), value, intent(in) :: requires_grad type(c_ptr) :: tensor end function torch_ones_c end interface ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = logical(.false., c_bool) else requires_grad_value = requires_grad end if tensor%p = torch_ones_c(ndims, tensor_shape, dtype, device_type, & device_index_value, requires_grad_value) end subroutine torch_tensor_ones ! Torch Tensor API !| Exposes the given data as a tensor without taking ownership of the original data. ! This routine will take an (i, j, k) array and return an (k, j, i) tensor. subroutine torch_tensor_from_blob(tensor, data, ndims, tensor_shape, layout, dtype, & device_type, device_index, & requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_int, c_int64_t, c_ptr type(torch_tensor), intent(out) :: tensor !! Returned tensor type(c_ptr), intent(in) :: data !! Pointer to data integer(c_int), intent(in) :: ndims !! Number of dimensions of the tensor integer(c_int64_t), intent(in) :: tensor_shape(*) !! Shape of the tensor integer(c_int), intent(in) :: layout(*) !! Layout for strides for accessing data integer(c_int), intent(in) :: dtype !! Data type of the tensor integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical(c_bool), optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor integer(c_int) :: i !! loop index integer(c_int64_t) :: strides(ndims) !! Strides for accessing data integer(c_int) :: device_index_value !! device index used logical(c_bool) :: requires_grad_value !! Whether gradients need to be computed for the created tensor if (.not. present(requires_grad)) then requires_grad_value = logical(.false., c_bool) else requires_grad_value = requires_grad end if strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif tensor%p = torch_from_blob_c(data, ndims, tensor_shape, strides, dtype, & device_type, device_index_value, & requires_grad_value) end subroutine torch_tensor_from_blob !> Prints the contents of a tensor. subroutine torch_tensor_print(tensor) type(torch_tensor), intent(in) :: tensor !! Input tensor interface subroutine torch_tensor_print_c(tensor) & bind(c, name = 'torch_tensor_print') use, intrinsic :: iso_c_binding, only : c_ptr implicit none type(c_ptr), value, intent(in) :: tensor end subroutine torch_tensor_print_c end interface call torch_tensor_print_c(tensor%p) end subroutine torch_tensor_print !> Determines the device index of a tensor. function torch_tensor_get_device_index(tensor) result(device_index) use, intrinsic :: iso_c_binding, only : c_int type(torch_tensor), intent(in) :: tensor !! Input tensor integer(c_int) :: device_index !! Device index of tensor interface function torch_tensor_get_device_index_c(tensor) result(device_index) & bind(c, name = 'torch_tensor_get_device_index') use, intrinsic :: iso_c_binding, only : c_int, c_ptr implicit none type(c_ptr), value, intent(in) :: tensor integer(c_int) :: device_index end function torch_tensor_get_device_index_c end interface device_index = torch_tensor_get_device_index_c(tensor%p) end function torch_tensor_get_device_index !> Determines the rank of a tensor. function get_rank(self) result(rank) class(torch_tensor), intent(in) :: self integer(kind=int32) :: rank !! rank of tensor interface function torch_tensor_get_rank_c(tensor) result(rank) & bind(c, name = 'torch_tensor_get_rank') use, intrinsic :: iso_c_binding, only : c_int, c_ptr implicit none type(c_ptr), value, intent(in) :: tensor integer(c_int) :: rank end function torch_tensor_get_rank_c end interface rank = torch_tensor_get_rank_c(self%p) end function get_rank !> Determines the shape of a tensor. function get_shape(self) result(sizes) use, intrinsic :: iso_c_binding, only : c_int, c_long, c_long_long, c_ptr class(torch_tensor), intent(in) :: self #ifdef UNIX integer(kind=c_long), pointer :: sizes(:) !! Pointer to tensor data #else integer(kind=c_long_long), pointer :: sizes(:) !! Pointer to tensor data #endif integer(kind=int32) :: ndims(1) type(c_ptr) :: cptr interface function torch_tensor_get_sizes_c(tensor) result(sizes) & bind(c, name = 'torch_tensor_get_sizes') use, intrinsic :: iso_c_binding, only : c_int, c_long, c_ptr implicit none type(c_ptr), value, intent(in) :: tensor type(c_ptr) :: sizes end function torch_tensor_get_sizes_c end interface ndims(1) = self%get_rank() cptr = torch_tensor_get_sizes_c(self%p) call c_f_pointer(cptr, sizes, ndims) end function get_shape !> Deallocates an array of tensors. subroutine torch_tensor_array_delete(tensor_array) type(torch_tensor), dimension(:), intent(inout) :: tensor_array integer(ftorch_int) :: i ! use bounds rather than (1, N) because it's safer do i = lbound(tensor_array, dim=1), ubound(tensor_array, dim=1) call torch_tensor_delete(tensor_array(i)) end do end subroutine torch_tensor_array_delete !> Deallocates a tensor. subroutine torch_tensor_delete(tensor) type(torch_tensor), intent(inout) :: tensor interface subroutine torch_tensor_delete_c(tensor) & bind(c, name = 'torch_tensor_delete') use, intrinsic :: iso_c_binding, only : c_ptr implicit none type(c_ptr), value, intent(in) :: tensor end subroutine torch_tensor_delete_c end interface call torch_tensor_delete_c(tensor%p) end subroutine torch_tensor_delete !> Overloads assignment operator for tensors. subroutine torch_tensor_assign(output, input) type(torch_tensor), intent(out) :: output type(torch_tensor), intent(in) :: input interface function torch_tensor_assign_c(input_c) result(output_c) & bind(c, name = 'torch_tensor_assign') use, intrinsic :: iso_c_binding, only : c_ptr implicit none type(c_ptr), value, intent(in) :: input_c type(c_ptr) :: output_c end function torch_tensor_assign_c end interface output%p = torch_tensor_assign_c(input%p) end subroutine torch_tensor_assign !> Overloads addition operator for two tensors. function torch_tensor_add(tensor1, tensor2) result(output) type(torch_tensor), intent(in) :: tensor1 type(torch_tensor), intent(in) :: tensor2 type(torch_tensor) :: output interface function torch_tensor_add_c(tensor1_c, tensor2_c) result(output_c) & bind(c, name = 'torch_tensor_add') use, intrinsic :: iso_c_binding, only : c_ptr implicit none type(c_ptr), value, intent(in) :: tensor1_c type(c_ptr), value, intent(in) :: tensor2_c type(c_ptr) :: output_c end function torch_tensor_add_c end interface output%p = torch_tensor_add_c(tensor1%p, tensor2%p) end function torch_tensor_add !> Overloads subtraction operator for two tensors. function torch_tensor_subtract(tensor1, tensor2) result(output) type(torch_tensor), intent(in) :: tensor1 type(torch_tensor), intent(in) :: tensor2 type(torch_tensor) :: output interface function torch_tensor_subtract_c(tensor1_c, tensor2_c) result(output_c) & bind(c, name = 'torch_tensor_subtract') use, intrinsic :: iso_c_binding, only : c_ptr implicit none type(c_ptr), value, intent(in) :: tensor1_c type(c_ptr), value, intent(in) :: tensor2_c type(c_ptr) :: output_c end function torch_tensor_subtract_c end interface output%p = torch_tensor_subtract_c(tensor1%p, tensor2%p) end function torch_tensor_subtract !> Overloads multiplication operator for two tensors. function torch_tensor_multiply(tensor1, tensor2) result(output) type(torch_tensor), intent(in) :: tensor1 type(torch_tensor), intent(in) :: tensor2 type(torch_tensor) :: output interface function torch_tensor_multiply_c(tensor1_c, tensor2_c) result(output_c) & bind(c, name = 'torch_tensor_multiply') use, intrinsic :: iso_c_binding, only : c_ptr implicit none type(c_ptr), value, intent(in) :: tensor1_c type(c_ptr), value, intent(in) :: tensor2_c type(c_ptr) :: output_c end function torch_tensor_multiply_c end interface output%p = torch_tensor_multiply_c(tensor1%p, tensor2%p) end function torch_tensor_multiply !> Overloads multiplication operator for a scalar of type int8 and a tensor. function torch_tensor_premultiply_int8(scalar, tensor) result(output) integer(kind=int8), intent(in) :: scalar type(torch_tensor), intent(in) :: tensor type(torch_tensor) :: output interface function torch_tensor_premultiply_c(scalar_c, tensor_c) result(output_c) & bind(c, name = 'torch_tensor_premultiply') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : int8 implicit none integer(kind=int8), value, intent(in) :: scalar_c type(c_ptr), value, intent(in) :: tensor_c type(c_ptr) :: output_c end function torch_tensor_premultiply_c end interface output%p = torch_tensor_premultiply_c(scalar, tensor%p) end function torch_tensor_premultiply_int8 !> Overloads multiplication operator for a scalar of type int16 and a tensor. function torch_tensor_premultiply_int16(scalar, tensor) result(output) integer(kind=int16), intent(in) :: scalar type(torch_tensor), intent(in) :: tensor type(torch_tensor) :: output interface function torch_tensor_premultiply_c(scalar_c, tensor_c) result(output_c) & bind(c, name = 'torch_tensor_premultiply') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : int16 implicit none integer(kind=int16), value, intent(in) :: scalar_c type(c_ptr), value, intent(in) :: tensor_c type(c_ptr) :: output_c end function torch_tensor_premultiply_c end interface output%p = torch_tensor_premultiply_c(scalar, tensor%p) end function torch_tensor_premultiply_int16 !> Overloads multiplication operator for a scalar of type int32 and a tensor. function torch_tensor_premultiply_int32(scalar, tensor) result(output) integer(kind=int32), intent(in) :: scalar type(torch_tensor), intent(in) :: tensor type(torch_tensor) :: output interface function torch_tensor_premultiply_c(scalar_c, tensor_c) result(output_c) & bind(c, name = 'torch_tensor_premultiply') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : int32 implicit none integer(kind=int32), value, intent(in) :: scalar_c type(c_ptr), value, intent(in) :: tensor_c type(c_ptr) :: output_c end function torch_tensor_premultiply_c end interface output%p = torch_tensor_premultiply_c(scalar, tensor%p) end function torch_tensor_premultiply_int32 !> Overloads multiplication operator for a scalar of type int64 and a tensor. function torch_tensor_premultiply_int64(scalar, tensor) result(output) integer(kind=int64), intent(in) :: scalar type(torch_tensor), intent(in) :: tensor type(torch_tensor) :: output interface function torch_tensor_premultiply_c(scalar_c, tensor_c) result(output_c) & bind(c, name = 'torch_tensor_premultiply') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : int64 implicit none integer(kind=int64), value, intent(in) :: scalar_c type(c_ptr), value, intent(in) :: tensor_c type(c_ptr) :: output_c end function torch_tensor_premultiply_c end interface output%p = torch_tensor_premultiply_c(scalar, tensor%p) end function torch_tensor_premultiply_int64 !> Overloads multiplication operator for a scalar of type real32 and a tensor. function torch_tensor_premultiply_real32(scalar, tensor) result(output) real(kind=real32), intent(in) :: scalar type(torch_tensor), intent(in) :: tensor type(torch_tensor) :: output interface function torch_tensor_premultiply_c(scalar_c, tensor_c) result(output_c) & bind(c, name = 'torch_tensor_premultiply') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : real32 implicit none real(kind=real32), value, intent(in) :: scalar_c type(c_ptr), value, intent(in) :: tensor_c type(c_ptr) :: output_c end function torch_tensor_premultiply_c end interface output%p = torch_tensor_premultiply_c(scalar, tensor%p) end function torch_tensor_premultiply_real32 !> Overloads multiplication operator for a scalar of type real64 and a tensor. function torch_tensor_premultiply_real64(scalar, tensor) result(output) real(kind=real64), intent(in) :: scalar type(torch_tensor), intent(in) :: tensor type(torch_tensor) :: output interface function torch_tensor_premultiply_c(scalar_c, tensor_c) result(output_c) & bind(c, name = 'torch_tensor_premultiply') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : real64 implicit none real(kind=real64), value, intent(in) :: scalar_c type(c_ptr), value, intent(in) :: tensor_c type(c_ptr) :: output_c end function torch_tensor_premultiply_c end interface output%p = torch_tensor_premultiply_c(scalar, tensor%p) end function torch_tensor_premultiply_real64 !> Overloads multiplication operator for a tensor and a scalar of type int8. function torch_tensor_postmultiply_int8(tensor, scalar) result(output) type(torch_tensor), intent(in) :: tensor integer(kind=int8), intent(in) :: scalar type(torch_tensor) :: output interface function torch_tensor_postmultiply_c(tensor_c, scalar_c) & result(output_c) bind(c, name = 'torch_tensor_postmultiply') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : int8 implicit none type(c_ptr), value, intent(in) :: tensor_c integer(kind=int8), value, intent(in) :: scalar_c type(c_ptr) :: output_c end function torch_tensor_postmultiply_c end interface output%p = torch_tensor_postmultiply_c(tensor%p, scalar) end function torch_tensor_postmultiply_int8 !> Overloads multiplication operator for a tensor and a scalar of type int16. function torch_tensor_postmultiply_int16(tensor, scalar) result(output) type(torch_tensor), intent(in) :: tensor integer(kind=int16), intent(in) :: scalar type(torch_tensor) :: output interface function torch_tensor_postmultiply_c(tensor_c, scalar_c) & result(output_c) bind(c, name = 'torch_tensor_postmultiply') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : int16 implicit none type(c_ptr), value, intent(in) :: tensor_c integer(kind=int16), value, intent(in) :: scalar_c type(c_ptr) :: output_c end function torch_tensor_postmultiply_c end interface output%p = torch_tensor_postmultiply_c(tensor%p, scalar) end function torch_tensor_postmultiply_int16 !> Overloads multiplication operator for a tensor and a scalar of type int32. function torch_tensor_postmultiply_int32(tensor, scalar) result(output) type(torch_tensor), intent(in) :: tensor integer(kind=int32), intent(in) :: scalar type(torch_tensor) :: output interface function torch_tensor_postmultiply_c(tensor_c, scalar_c) & result(output_c) bind(c, name = 'torch_tensor_postmultiply') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : int32 implicit none type(c_ptr), value, intent(in) :: tensor_c integer(kind=int32), value, intent(in) :: scalar_c type(c_ptr) :: output_c end function torch_tensor_postmultiply_c end interface output%p = torch_tensor_postmultiply_c(tensor%p, scalar) end function torch_tensor_postmultiply_int32 !> Overloads multiplication operator for a tensor and a scalar of type int64. function torch_tensor_postmultiply_int64(tensor, scalar) result(output) type(torch_tensor), intent(in) :: tensor integer(kind=int64), intent(in) :: scalar type(torch_tensor) :: output interface function torch_tensor_postmultiply_c(tensor_c, scalar_c) & result(output_c) bind(c, name = 'torch_tensor_postmultiply') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : int64 implicit none type(c_ptr), value, intent(in) :: tensor_c integer(kind=int64), value, intent(in) :: scalar_c type(c_ptr) :: output_c end function torch_tensor_postmultiply_c end interface output%p = torch_tensor_postmultiply_c(tensor%p, scalar) end function torch_tensor_postmultiply_int64 !> Overloads multiplication operator for a tensor and a scalar of type real32. function torch_tensor_postmultiply_real32(tensor, scalar) result(output) type(torch_tensor), intent(in) :: tensor real(kind=real32), intent(in) :: scalar type(torch_tensor) :: output interface function torch_tensor_postmultiply_c(tensor_c, scalar_c) & result(output_c) bind(c, name = 'torch_tensor_postmultiply') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : real32 implicit none type(c_ptr), value, intent(in) :: tensor_c real(kind=real32), value, intent(in) :: scalar_c type(c_ptr) :: output_c end function torch_tensor_postmultiply_c end interface output%p = torch_tensor_postmultiply_c(tensor%p, scalar) end function torch_tensor_postmultiply_real32 !> Overloads multiplication operator for a tensor and a scalar of type real64. function torch_tensor_postmultiply_real64(tensor, scalar) result(output) type(torch_tensor), intent(in) :: tensor real(kind=real64), intent(in) :: scalar type(torch_tensor) :: output interface function torch_tensor_postmultiply_c(tensor_c, scalar_c) & result(output_c) bind(c, name = 'torch_tensor_postmultiply') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : real64 implicit none type(c_ptr), value, intent(in) :: tensor_c real(kind=real64), value, intent(in) :: scalar_c type(c_ptr) :: output_c end function torch_tensor_postmultiply_c end interface output%p = torch_tensor_postmultiply_c(tensor%p, scalar) end function torch_tensor_postmultiply_real64 !> Overloads division operator for two tensors. function torch_tensor_divide(tensor1, tensor2) result(output) type(torch_tensor), intent(in) :: tensor1 type(torch_tensor), intent(in) :: tensor2 type(torch_tensor) :: output interface function torch_tensor_divide_c(tensor1_c, tensor2_c) result(output_c) & bind(c, name = 'torch_tensor_divide') use, intrinsic :: iso_c_binding, only : c_ptr implicit none type(c_ptr), value, intent(in) :: tensor1_c type(c_ptr), value, intent(in) :: tensor2_c type(c_ptr) :: output_c end function torch_tensor_divide_c end interface output%p = torch_tensor_divide_c(tensor1%p, tensor2%p) end function torch_tensor_divide !> Overloads division operator for a tensor and a scalar of type int8. function torch_tensor_postdivide_int8(tensor, scalar) result(output) type(torch_tensor), intent(in) :: tensor integer(kind=int8), intent(in) :: scalar type(torch_tensor) :: output interface function torch_tensor_postdivide_c(tensor_c, scalar_c) & result(output_c) bind(c, name = 'torch_tensor_postdivide') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : int8 implicit none type(c_ptr), value, intent(in) :: tensor_c integer(kind=int8), value, intent(in) :: scalar_c type(c_ptr) :: output_c end function torch_tensor_postdivide_c end interface output%p = torch_tensor_postdivide_c(tensor%p, scalar) end function torch_tensor_postdivide_int8 !> Overloads division operator for a tensor and a scalar of type int16. function torch_tensor_postdivide_int16(tensor, scalar) result(output) type(torch_tensor), intent(in) :: tensor integer(kind=int16), intent(in) :: scalar type(torch_tensor) :: output interface function torch_tensor_postdivide_c(tensor_c, scalar_c) & result(output_c) bind(c, name = 'torch_tensor_postdivide') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : int16 implicit none type(c_ptr), value, intent(in) :: tensor_c integer(kind=int16), value, intent(in) :: scalar_c type(c_ptr) :: output_c end function torch_tensor_postdivide_c end interface output%p = torch_tensor_postdivide_c(tensor%p, scalar) end function torch_tensor_postdivide_int16 !> Overloads division operator for a tensor and a scalar of type int32. function torch_tensor_postdivide_int32(tensor, scalar) result(output) type(torch_tensor), intent(in) :: tensor integer(kind=int32), intent(in) :: scalar type(torch_tensor) :: output interface function torch_tensor_postdivide_c(tensor_c, scalar_c) & result(output_c) bind(c, name = 'torch_tensor_postdivide') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : int32 implicit none type(c_ptr), value, intent(in) :: tensor_c integer(kind=int32), value, intent(in) :: scalar_c type(c_ptr) :: output_c end function torch_tensor_postdivide_c end interface output%p = torch_tensor_postdivide_c(tensor%p, scalar) end function torch_tensor_postdivide_int32 !> Overloads division operator for a tensor and a scalar of type int64. function torch_tensor_postdivide_int64(tensor, scalar) result(output) type(torch_tensor), intent(in) :: tensor integer(kind=int64), intent(in) :: scalar type(torch_tensor) :: output interface function torch_tensor_postdivide_c(tensor_c, scalar_c) & result(output_c) bind(c, name = 'torch_tensor_postdivide') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : int64 implicit none type(c_ptr), value, intent(in) :: tensor_c integer(kind=int64), value, intent(in) :: scalar_c type(c_ptr) :: output_c end function torch_tensor_postdivide_c end interface output%p = torch_tensor_postdivide_c(tensor%p, scalar) end function torch_tensor_postdivide_int64 !> Overloads division operator for a tensor and a scalar of type real32. function torch_tensor_postdivide_real32(tensor, scalar) result(output) type(torch_tensor), intent(in) :: tensor real(kind=real32), intent(in) :: scalar type(torch_tensor) :: output interface function torch_tensor_postdivide_c(tensor_c, scalar_c) & result(output_c) bind(c, name = 'torch_tensor_postdivide') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : real32 implicit none type(c_ptr), value, intent(in) :: tensor_c real(kind=real32), value, intent(in) :: scalar_c type(c_ptr) :: output_c end function torch_tensor_postdivide_c end interface output%p = torch_tensor_postdivide_c(tensor%p, scalar) end function torch_tensor_postdivide_real32 !> Overloads division operator for a tensor and a scalar of type real64. function torch_tensor_postdivide_real64(tensor, scalar) result(output) type(torch_tensor), intent(in) :: tensor real(kind=real64), intent(in) :: scalar type(torch_tensor) :: output interface function torch_tensor_postdivide_c(tensor_c, scalar_c) & result(output_c) bind(c, name = 'torch_tensor_postdivide') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : real64 implicit none type(c_ptr), value, intent(in) :: tensor_c real(kind=real64), value, intent(in) :: scalar_c type(c_ptr) :: output_c end function torch_tensor_postdivide_c end interface output%p = torch_tensor_postdivide_c(tensor%p, scalar) end function torch_tensor_postdivide_real64 !> Overloads exponentiation operator for a tensor and a scalar of type `int8` function torch_tensor_power_int8(tensor, power) result(output) type(torch_tensor), intent(in) :: tensor integer(kind=int8), intent(in) :: power type(torch_tensor) :: output interface function torch_tensor_power_c(tensor_c, power_c) result(output_c) & bind(c, name = 'torch_tensor_power') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : int8 implicit none type(c_ptr), value, intent(in) :: tensor_c integer(kind=int8), value, intent(in) :: power_c type(c_ptr) :: output_c end function torch_tensor_power_c end interface output%p = torch_tensor_power_c(tensor%p, power) end function torch_tensor_power_int8 !> Overloads exponentiation operator for a tensor and a scalar of type `int16` function torch_tensor_power_int16(tensor, power) result(output) type(torch_tensor), intent(in) :: tensor integer(kind=int16), intent(in) :: power type(torch_tensor) :: output interface function torch_tensor_power_c(tensor_c, power_c) result(output_c) & bind(c, name = 'torch_tensor_power') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : int16 implicit none type(c_ptr), value, intent(in) :: tensor_c integer(kind=int16), value, intent(in) :: power_c type(c_ptr) :: output_c end function torch_tensor_power_c end interface output%p = torch_tensor_power_c(tensor%p, power) end function torch_tensor_power_int16 !> Overloads exponentiation operator for a tensor and a scalar of type `int32` function torch_tensor_power_int32(tensor, power) result(output) type(torch_tensor), intent(in) :: tensor integer(kind=int32), intent(in) :: power type(torch_tensor) :: output interface function torch_tensor_power_c(tensor_c, power_c) result(output_c) & bind(c, name = 'torch_tensor_power') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : int32 implicit none type(c_ptr), value, intent(in) :: tensor_c integer(kind=int32), value, intent(in) :: power_c type(c_ptr) :: output_c end function torch_tensor_power_c end interface output%p = torch_tensor_power_c(tensor%p, power) end function torch_tensor_power_int32 !> Overloads exponentiation operator for a tensor and a scalar of type `int64` function torch_tensor_power_int64(tensor, power) result(output) type(torch_tensor), intent(in) :: tensor integer(kind=int64), intent(in) :: power type(torch_tensor) :: output interface function torch_tensor_power_c(tensor_c, power_c) result(output_c) & bind(c, name = 'torch_tensor_power') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : int64 implicit none type(c_ptr), value, intent(in) :: tensor_c integer(kind=int64), value, intent(in) :: power_c type(c_ptr) :: output_c end function torch_tensor_power_c end interface output%p = torch_tensor_power_c(tensor%p, power) end function torch_tensor_power_int64 !> Overloads exponentiation operator for a tensor and a scalar of type `real32` function torch_tensor_power_real32(tensor, power) result(output) type(torch_tensor), intent(in) :: tensor real(kind=real32), intent(in) :: power type(torch_tensor) :: output interface function torch_tensor_power_c(tensor_c, power_c) result(output_c) & bind(c, name = 'torch_tensor_power') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : real32 implicit none type(c_ptr), value, intent(in) :: tensor_c real(kind=real32), value, intent(in) :: power_c type(c_ptr) :: output_c end function torch_tensor_power_c end interface output%p = torch_tensor_power_c(tensor%p, power) end function torch_tensor_power_real32 !> Overloads exponentiation operator for a tensor and a scalar of type `real64` function torch_tensor_power_real64(tensor, power) result(output) type(torch_tensor), intent(in) :: tensor real(kind=real64), intent(in) :: power type(torch_tensor) :: output interface function torch_tensor_power_c(tensor_c, power_c) result(output_c) & bind(c, name = 'torch_tensor_power') use, intrinsic :: iso_c_binding, only : c_ptr use, intrinsic :: iso_fortran_env, only : real64 implicit none type(c_ptr), value, intent(in) :: tensor_c real(kind=real64), value, intent(in) :: power_c type(c_ptr) :: output_c end function torch_tensor_power_c end interface output%p = torch_tensor_power_c(tensor%p, power) end function torch_tensor_power_real64 ! Torch Model API !> Loads a TorchScript nn.module (pre-trained PyTorch model saved with TorchScript) subroutine torch_model_load(model, filename, device_type, device_index, & requires_grad, is_training) use, intrinsic :: iso_c_binding, only : c_bool, c_int, c_null_char type(torch_model), intent(out) :: model !! Returned deserialized model character(*), intent(in) :: filename !! Filename of saved TorchScript model integer(c_int), optional, intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor logical, optional, intent(in) :: is_training !! Whether gradients need to be computed for the created tensor integer(c_int) :: device_type_value integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor logical :: is_training_value !! Whether the model is being trained, rather than evaluated interface function torch_jit_load_c(filename, device_type, device_index, & requires_grad, is_training) result(model) & bind(c, name = 'torch_jit_load') use, intrinsic :: iso_c_binding, only : c_bool, c_char, c_int, c_ptr implicit none character(c_char), intent(in) :: filename(*) integer(c_int), value, intent(in) :: device_type integer(c_int), value, intent(in) :: device_index logical(c_bool), value, intent(in) :: requires_grad logical(c_bool), value, intent(in) :: is_training type(c_ptr) :: model end function torch_jit_load_c end interface ! Process optional arguments if (present(device_type)) then device_type_value = device_type else device_type_value = torch_kCPU endif if (present(device_index)) then device_index_value = device_index else if (device_type_value == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if if (.not. present(is_training)) then is_training_value = .false. else is_training_value = is_training end if ! Need to append c_null_char at end of filename model%p = torch_jit_load_c(trim(adjustl(filename))//c_null_char, & device_type_value, device_index_value, & logical(requires_grad_value, c_bool), & logical(is_training_value, c_bool)) end subroutine torch_model_load !> Performs a forward pass of the model with the input tensors subroutine torch_model_forward(model, input_tensors, output_tensors, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_ptr, c_int, c_loc type(torch_model), intent(in) :: model !! Model type(torch_tensor), intent(in), dimension(:) :: input_tensors !! Array of Input tensors type(torch_tensor), intent(in), dimension(:) :: output_tensors !! Returned output tensors logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor integer(ftorch_int) :: i integer(c_int) :: n_inputs integer(c_int) :: n_outputs type(c_ptr), dimension(size(input_tensors)), target :: input_ptrs type(c_ptr), dimension(size(output_tensors)), target :: output_ptrs interface subroutine torch_jit_model_forward_c(model, input_tensors, n_inputs, & output_tensors, n_outputs, requires_grad) & bind(c, name = 'torch_jit_module_forward') use, intrinsic :: iso_c_binding, only : c_bool, c_ptr, c_int implicit none type(c_ptr), value, intent(in) :: model type(c_ptr), value, intent(in) :: input_tensors integer(c_int), value, intent(in) :: n_inputs type(c_ptr), value, intent(in) :: output_tensors integer(c_int), value, intent(in) :: n_outputs logical(c_bool), value, intent(in) :: requires_grad end subroutine torch_jit_model_forward_c end interface n_inputs = size(input_tensors) n_outputs = size(output_tensors) if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if ! Assign array of pointers to the input tensors do i = 1, n_inputs input_ptrs(i) = input_tensors(i)%p end do ! Assign array of pointers to the output tensors do i = 1, n_outputs output_ptrs(i) = output_tensors(i)%p end do call torch_jit_model_forward_c(model%p, c_loc(input_ptrs), n_inputs, & c_loc(output_ptrs), n_outputs, & logical(requires_grad_value, c_bool)) end subroutine torch_model_forward !> Deallocates a TorchScript model subroutine torch_model_delete(model) type(torch_model), intent(in) :: model !! Torch Model to deallocate interface subroutine torch_jit_model_delete_c(model) & bind(c, name = 'torch_jit_module_delete') use, intrinsic :: iso_c_binding, only : c_ptr implicit none type(c_ptr), value, intent(in) :: model end subroutine torch_jit_model_delete_c end interface call torch_jit_model_delete_c(model%p) end subroutine torch_model_delete !> Return a Torch tensor pointing to data_in array of rank 1 containing data of type `int8` subroutine torch_tensor_from_array_int8_1d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int8 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int8), intent(in), target :: data_in(:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(1) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(1) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt8 !! Data type integer(c_int64_t) :: strides(1) !! Strides for accessing data integer(c_int), parameter :: ndims = 1 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int8_1d !> Return a Torch tensor pointing to data_in array of rank 2 containing data of type `int8` subroutine torch_tensor_from_array_int8_2d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int8 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int8), intent(in), target :: data_in(:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(2) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(2) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt8 !! Data type integer(c_int64_t) :: strides(2) !! Strides for accessing data integer(c_int), parameter :: ndims = 2 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int8_2d !> Return a Torch tensor pointing to data_in array of rank 3 containing data of type `int8` subroutine torch_tensor_from_array_int8_3d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int8 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int8), intent(in), target :: data_in(:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(3) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(3) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt8 !! Data type integer(c_int64_t) :: strides(3) !! Strides for accessing data integer(c_int), parameter :: ndims = 3 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int8_3d !> Return a Torch tensor pointing to data_in array of rank 4 containing data of type `int8` subroutine torch_tensor_from_array_int8_4d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int8 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int8), intent(in), target :: data_in(:,:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(4) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(4) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt8 !! Data type integer(c_int64_t) :: strides(4) !! Strides for accessing data integer(c_int), parameter :: ndims = 4 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int8_4d !> Return a Torch tensor pointing to data_in array of rank 5 containing data of type `int8` subroutine torch_tensor_from_array_int8_5d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int8 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int8), intent(in), target :: data_in(:,:,:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(5) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(5) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt8 !! Data type integer(c_int64_t) :: strides(5) !! Strides for accessing data integer(c_int), parameter :: ndims = 5 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int8_5d !> Return a Torch tensor pointing to data_in array of rank 1 containing data of type `int16` subroutine torch_tensor_from_array_int16_1d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int16 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int16), intent(in), target :: data_in(:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(1) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(1) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt16 !! Data type integer(c_int64_t) :: strides(1) !! Strides for accessing data integer(c_int), parameter :: ndims = 1 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int16_1d !> Return a Torch tensor pointing to data_in array of rank 2 containing data of type `int16` subroutine torch_tensor_from_array_int16_2d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int16 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int16), intent(in), target :: data_in(:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(2) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(2) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt16 !! Data type integer(c_int64_t) :: strides(2) !! Strides for accessing data integer(c_int), parameter :: ndims = 2 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int16_2d !> Return a Torch tensor pointing to data_in array of rank 3 containing data of type `int16` subroutine torch_tensor_from_array_int16_3d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int16 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int16), intent(in), target :: data_in(:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(3) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(3) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt16 !! Data type integer(c_int64_t) :: strides(3) !! Strides for accessing data integer(c_int), parameter :: ndims = 3 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int16_3d !> Return a Torch tensor pointing to data_in array of rank 4 containing data of type `int16` subroutine torch_tensor_from_array_int16_4d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int16 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int16), intent(in), target :: data_in(:,:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(4) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(4) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt16 !! Data type integer(c_int64_t) :: strides(4) !! Strides for accessing data integer(c_int), parameter :: ndims = 4 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int16_4d !> Return a Torch tensor pointing to data_in array of rank 5 containing data of type `int16` subroutine torch_tensor_from_array_int16_5d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int16 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int16), intent(in), target :: data_in(:,:,:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(5) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(5) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt16 !! Data type integer(c_int64_t) :: strides(5) !! Strides for accessing data integer(c_int), parameter :: ndims = 5 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int16_5d !> Return a Torch tensor pointing to data_in array of rank 1 containing data of type `int32` subroutine torch_tensor_from_array_int32_1d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int32 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int32), intent(in), target :: data_in(:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(1) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(1) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt32 !! Data type integer(c_int64_t) :: strides(1) !! Strides for accessing data integer(c_int), parameter :: ndims = 1 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int32_1d !> Return a Torch tensor pointing to data_in array of rank 2 containing data of type `int32` subroutine torch_tensor_from_array_int32_2d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int32 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int32), intent(in), target :: data_in(:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(2) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(2) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt32 !! Data type integer(c_int64_t) :: strides(2) !! Strides for accessing data integer(c_int), parameter :: ndims = 2 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int32_2d !> Return a Torch tensor pointing to data_in array of rank 3 containing data of type `int32` subroutine torch_tensor_from_array_int32_3d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int32 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int32), intent(in), target :: data_in(:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(3) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(3) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt32 !! Data type integer(c_int64_t) :: strides(3) !! Strides for accessing data integer(c_int), parameter :: ndims = 3 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int32_3d !> Return a Torch tensor pointing to data_in array of rank 4 containing data of type `int32` subroutine torch_tensor_from_array_int32_4d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int32 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int32), intent(in), target :: data_in(:,:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(4) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(4) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt32 !! Data type integer(c_int64_t) :: strides(4) !! Strides for accessing data integer(c_int), parameter :: ndims = 4 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int32_4d !> Return a Torch tensor pointing to data_in array of rank 5 containing data of type `int32` subroutine torch_tensor_from_array_int32_5d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int32 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int32), intent(in), target :: data_in(:,:,:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(5) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(5) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt32 !! Data type integer(c_int64_t) :: strides(5) !! Strides for accessing data integer(c_int), parameter :: ndims = 5 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int32_5d !> Return a Torch tensor pointing to data_in array of rank 1 containing data of type `int64` subroutine torch_tensor_from_array_int64_1d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int64 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int64), intent(in), target :: data_in(:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(1) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(1) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt64 !! Data type integer(c_int64_t) :: strides(1) !! Strides for accessing data integer(c_int), parameter :: ndims = 1 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int64_1d !> Return a Torch tensor pointing to data_in array of rank 2 containing data of type `int64` subroutine torch_tensor_from_array_int64_2d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int64 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int64), intent(in), target :: data_in(:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(2) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(2) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt64 !! Data type integer(c_int64_t) :: strides(2) !! Strides for accessing data integer(c_int), parameter :: ndims = 2 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int64_2d !> Return a Torch tensor pointing to data_in array of rank 3 containing data of type `int64` subroutine torch_tensor_from_array_int64_3d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int64 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int64), intent(in), target :: data_in(:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(3) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(3) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt64 !! Data type integer(c_int64_t) :: strides(3) !! Strides for accessing data integer(c_int), parameter :: ndims = 3 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int64_3d !> Return a Torch tensor pointing to data_in array of rank 4 containing data of type `int64` subroutine torch_tensor_from_array_int64_4d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int64 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int64), intent(in), target :: data_in(:,:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(4) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(4) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt64 !! Data type integer(c_int64_t) :: strides(4) !! Strides for accessing data integer(c_int), parameter :: ndims = 4 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int64_4d !> Return a Torch tensor pointing to data_in array of rank 5 containing data of type `int64` subroutine torch_tensor_from_array_int64_5d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int64 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs integer(kind=int64), intent(in), target :: data_in(:,:,:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(5) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(5) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kInt64 !! Data type integer(c_int64_t) :: strides(5) !! Strides for accessing data integer(c_int), parameter :: ndims = 5 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_int64_5d !> Return a Torch tensor pointing to data_in array of rank 1 containing data of type `real32` subroutine torch_tensor_from_array_real32_1d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real32 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs real(kind=real32), intent(in), target :: data_in(:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(1) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(1) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kFloat32 !! Data type integer(c_int64_t) :: strides(1) !! Strides for accessing data integer(c_int), parameter :: ndims = 1 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_real32_1d !> Return a Torch tensor pointing to data_in array of rank 2 containing data of type `real32` subroutine torch_tensor_from_array_real32_2d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real32 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs real(kind=real32), intent(in), target :: data_in(:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(2) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(2) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kFloat32 !! Data type integer(c_int64_t) :: strides(2) !! Strides for accessing data integer(c_int), parameter :: ndims = 2 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_real32_2d !> Return a Torch tensor pointing to data_in array of rank 3 containing data of type `real32` subroutine torch_tensor_from_array_real32_3d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real32 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs real(kind=real32), intent(in), target :: data_in(:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(3) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(3) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kFloat32 !! Data type integer(c_int64_t) :: strides(3) !! Strides for accessing data integer(c_int), parameter :: ndims = 3 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_real32_3d !> Return a Torch tensor pointing to data_in array of rank 4 containing data of type `real32` subroutine torch_tensor_from_array_real32_4d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real32 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs real(kind=real32), intent(in), target :: data_in(:,:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(4) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(4) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kFloat32 !! Data type integer(c_int64_t) :: strides(4) !! Strides for accessing data integer(c_int), parameter :: ndims = 4 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_real32_4d !> Return a Torch tensor pointing to data_in array of rank 5 containing data of type `real32` subroutine torch_tensor_from_array_real32_5d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real32 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs real(kind=real32), intent(in), target :: data_in(:,:,:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(5) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(5) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kFloat32 !! Data type integer(c_int64_t) :: strides(5) !! Strides for accessing data integer(c_int), parameter :: ndims = 5 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_real32_5d !> Return a Torch tensor pointing to data_in array of rank 1 containing data of type `real64` subroutine torch_tensor_from_array_real64_1d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real64 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs real(kind=real64), intent(in), target :: data_in(:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(1) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(1) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kFloat64 !! Data type integer(c_int64_t) :: strides(1) !! Strides for accessing data integer(c_int), parameter :: ndims = 1 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_real64_1d !> Return a Torch tensor pointing to data_in array of rank 2 containing data of type `real64` subroutine torch_tensor_from_array_real64_2d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real64 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs real(kind=real64), intent(in), target :: data_in(:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(2) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(2) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kFloat64 !! Data type integer(c_int64_t) :: strides(2) !! Strides for accessing data integer(c_int), parameter :: ndims = 2 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_real64_2d !> Return a Torch tensor pointing to data_in array of rank 3 containing data of type `real64` subroutine torch_tensor_from_array_real64_3d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real64 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs real(kind=real64), intent(in), target :: data_in(:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(3) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(3) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kFloat64 !! Data type integer(c_int64_t) :: strides(3) !! Strides for accessing data integer(c_int), parameter :: ndims = 3 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_real64_3d !> Return a Torch tensor pointing to data_in array of rank 4 containing data of type `real64` subroutine torch_tensor_from_array_real64_4d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real64 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs real(kind=real64), intent(in), target :: data_in(:,:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(4) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(4) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kFloat64 !! Data type integer(c_int64_t) :: strides(4) !! Strides for accessing data integer(c_int), parameter :: ndims = 4 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_real64_4d !> Return a Torch tensor pointing to data_in array of rank 5 containing data of type `real64` subroutine torch_tensor_from_array_real64_5d(tensor, data_in, layout, & device_type, device_index, requires_grad) use, intrinsic :: iso_c_binding, only : c_bool, c_float, c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real64 ! output tensor type(torch_tensor), intent(out) :: tensor !! Returned tensor ! inputs real(kind=real64), intent(in), target :: data_in(:,:,:,:,:) !! Input data that tensor will point at integer(ftorch_int), intent(in) :: layout(5) !! Control order of indices integer(c_int), intent(in) :: device_type !! Device type the tensor will live on (`torch_kCPU` or `torch_kCUDA`) integer(c_int), optional, intent(in) :: device_index !! device index to use for `torch_kCUDA` case logical, optional, intent(in) :: requires_grad !! Whether gradients need to be computed for the created tensor ! local data integer(c_int64_t) :: tensor_shape(5) !! Shape of the tensor integer(c_int), parameter :: dtype = torch_kFloat64 !! Data type integer(c_int64_t) :: strides(5) !! Strides for accessing data integer(c_int), parameter :: ndims = 5 !! Number of dimension of input data integer(ftorch_int) :: i integer(c_int) :: device_index_value logical :: requires_grad_value !! Whether gradients need to be computed for the created tensor ! Process optional arguments if (present(device_index)) then device_index_value = device_index else if (device_type == torch_kCPU) then device_index_value = -1 else device_index_value = 0 endif if (.not. present(requires_grad)) then requires_grad_value = .false. else requires_grad_value = requires_grad end if tensor_shape = shape(data_in) strides(layout(1)) = 1 do i = 2, ndims strides(layout(i)) = strides(layout(i - 1)) * tensor_shape(layout(i - 1)) end do tensor%p = torch_from_blob_c(c_loc(data_in), ndims, tensor_shape, & strides, dtype, device_type, & device_index_value, & logical(requires_grad_value, c_bool)) end subroutine torch_tensor_from_array_real64_5d !> Return the array data associated with a Torch tensor of rank 1 and data type `int8` subroutine torch_tensor_to_array_int8_1d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int8, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int8), pointer, intent(out) :: data_out(:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(1) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt8 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 1(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 1(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int8_1d !> Return the array data associated with a Torch tensor of rank 2 and data type `int8` subroutine torch_tensor_to_array_int8_2d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int8, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int8), pointer, intent(out) :: data_out(:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(2) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt8 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 2(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 2(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int8_2d !> Return the array data associated with a Torch tensor of rank 3 and data type `int8` subroutine torch_tensor_to_array_int8_3d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int8, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int8), pointer, intent(out) :: data_out(:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(3) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt8 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 3(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 3(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int8_3d !> Return the array data associated with a Torch tensor of rank 4 and data type `int8` subroutine torch_tensor_to_array_int8_4d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int8, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int8), pointer, intent(out) :: data_out(:,:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(4) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt8 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 4(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 4(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int8_4d !> Return the array data associated with a Torch tensor of rank 5 and data type `int8` subroutine torch_tensor_to_array_int8_5d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int8, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int8), pointer, intent(out) :: data_out(:,:,:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(5) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt8 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 5(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 5(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int8_5d !> Return the array data associated with a Torch tensor of rank 1 and data type `int16` subroutine torch_tensor_to_array_int16_1d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int16, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int16), pointer, intent(out) :: data_out(:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(1) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt16 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 1(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 1(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int16_1d !> Return the array data associated with a Torch tensor of rank 2 and data type `int16` subroutine torch_tensor_to_array_int16_2d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int16, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int16), pointer, intent(out) :: data_out(:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(2) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt16 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 2(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 2(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int16_2d !> Return the array data associated with a Torch tensor of rank 3 and data type `int16` subroutine torch_tensor_to_array_int16_3d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int16, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int16), pointer, intent(out) :: data_out(:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(3) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt16 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 3(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 3(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int16_3d !> Return the array data associated with a Torch tensor of rank 4 and data type `int16` subroutine torch_tensor_to_array_int16_4d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int16, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int16), pointer, intent(out) :: data_out(:,:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(4) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt16 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 4(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 4(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int16_4d !> Return the array data associated with a Torch tensor of rank 5 and data type `int16` subroutine torch_tensor_to_array_int16_5d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int16, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int16), pointer, intent(out) :: data_out(:,:,:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(5) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt16 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 5(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 5(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int16_5d !> Return the array data associated with a Torch tensor of rank 1 and data type `int32` subroutine torch_tensor_to_array_int32_1d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int32, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int32), pointer, intent(out) :: data_out(:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(1) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt32 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 1(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 1(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int32_1d !> Return the array data associated with a Torch tensor of rank 2 and data type `int32` subroutine torch_tensor_to_array_int32_2d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int32, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int32), pointer, intent(out) :: data_out(:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(2) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt32 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 2(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 2(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int32_2d !> Return the array data associated with a Torch tensor of rank 3 and data type `int32` subroutine torch_tensor_to_array_int32_3d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int32, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int32), pointer, intent(out) :: data_out(:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(3) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt32 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 3(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 3(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int32_3d !> Return the array data associated with a Torch tensor of rank 4 and data type `int32` subroutine torch_tensor_to_array_int32_4d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int32, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int32), pointer, intent(out) :: data_out(:,:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(4) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt32 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 4(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 4(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int32_4d !> Return the array data associated with a Torch tensor of rank 5 and data type `int32` subroutine torch_tensor_to_array_int32_5d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int32, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int32), pointer, intent(out) :: data_out(:,:,:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(5) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt32 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 5(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 5(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int32_5d !> Return the array data associated with a Torch tensor of rank 1 and data type `int64` subroutine torch_tensor_to_array_int64_1d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int64, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int64), pointer, intent(out) :: data_out(:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(1) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt64 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 1(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 1(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int64_1d !> Return the array data associated with a Torch tensor of rank 2 and data type `int64` subroutine torch_tensor_to_array_int64_2d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int64, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int64), pointer, intent(out) :: data_out(:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(2) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt64 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 2(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 2(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int64_2d !> Return the array data associated with a Torch tensor of rank 3 and data type `int64` subroutine torch_tensor_to_array_int64_3d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int64, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int64), pointer, intent(out) :: data_out(:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(3) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt64 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 3(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 3(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int64_3d !> Return the array data associated with a Torch tensor of rank 4 and data type `int64` subroutine torch_tensor_to_array_int64_4d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int64, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int64), pointer, intent(out) :: data_out(:,:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(4) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt64 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 4(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 4(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int64_4d !> Return the array data associated with a Torch tensor of rank 5 and data type `int64` subroutine torch_tensor_to_array_int64_5d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : int64, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor integer(kind=int64), pointer, intent(out) :: data_out(:,:,:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(5) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kInt64 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 5(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 5(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_int64_5d !> Return the array data associated with a Torch tensor of rank 1 and data type `real32` subroutine torch_tensor_to_array_real32_1d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real32, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor real(kind=real32), pointer, intent(out) :: data_out(:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(1) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kFloat32 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 1(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 1(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_real32_1d !> Return the array data associated with a Torch tensor of rank 2 and data type `real32` subroutine torch_tensor_to_array_real32_2d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real32, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor real(kind=real32), pointer, intent(out) :: data_out(:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(2) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kFloat32 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 2(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 2(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_real32_2d !> Return the array data associated with a Torch tensor of rank 3 and data type `real32` subroutine torch_tensor_to_array_real32_3d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real32, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor real(kind=real32), pointer, intent(out) :: data_out(:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(3) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kFloat32 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 3(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 3(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_real32_3d !> Return the array data associated with a Torch tensor of rank 4 and data type `real32` subroutine torch_tensor_to_array_real32_4d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real32, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor real(kind=real32), pointer, intent(out) :: data_out(:,:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(4) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kFloat32 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 4(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 4(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_real32_4d !> Return the array data associated with a Torch tensor of rank 5 and data type `real32` subroutine torch_tensor_to_array_real32_5d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real32, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor real(kind=real32), pointer, intent(out) :: data_out(:,:,:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(5) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kFloat32 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 5(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 5(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_real32_5d !> Return the array data associated with a Torch tensor of rank 1 and data type `real64` subroutine torch_tensor_to_array_real64_1d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real64, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor real(kind=real64), pointer, intent(out) :: data_out(:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(1) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kFloat64 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 1(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 1(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_real64_1d !> Return the array data associated with a Torch tensor of rank 2 and data type `real64` subroutine torch_tensor_to_array_real64_2d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real64, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor real(kind=real64), pointer, intent(out) :: data_out(:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(2) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kFloat64 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 2(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 2(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_real64_2d !> Return the array data associated with a Torch tensor of rank 3 and data type `real64` subroutine torch_tensor_to_array_real64_3d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real64, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor real(kind=real64), pointer, intent(out) :: data_out(:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(3) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kFloat64 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 3(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 3(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_real64_3d !> Return the array data associated with a Torch tensor of rank 4 and data type `real64` subroutine torch_tensor_to_array_real64_4d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real64, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor real(kind=real64), pointer, intent(out) :: data_out(:,:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(4) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kFloat64 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 4(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 4(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_real64_4d !> Return the array data associated with a Torch tensor of rank 5 and data type `real64` subroutine torch_tensor_to_array_real64_5d(tensor, data_out, sizes) use, intrinsic :: iso_c_binding, only : c_int, c_int64_t, c_loc use, intrinsic :: iso_fortran_env, only : real64, int64 type(torch_tensor), intent(in) :: tensor !! Returned tensor real(kind=real64), pointer, intent(out) :: data_out(:,:,:,:,:) !! Pointer to tensor data integer, optional, intent(in) :: sizes(5) !! Number of entries for each rank integer(kind=int64), allocatable :: my_shape(:) !! Number of entries for each rank ! Local data integer(c_int), parameter :: dtype = torch_kFloat64 !! Data type type(c_ptr) :: cptr my_shape = tensor%get_shape() if (present(sizes)) then if (.not. all(my_shape == sizes)) then write(*,*) 'Error :: sizes argument does not match shape of tensor' write(*,'(A, 5(I0, " "), A)') 'sizes :: [ ', sizes(:), ']' write(*,'(A, 5(I0, " "), A)') 'tensor shape :: [ ', my_shape(:), ']' stop 1 end if end if ! Have the data_out array point to the Tensor data cptr = torch_to_blob_c(tensor%p, dtype) call c_f_pointer(cptr, data_out, my_shape) end subroutine torch_tensor_to_array_real64_5d end module ftorch