diff --git a/src/ftorch.f90 b/src/ftorch.f90 index 7c31681..859d02a 100644 --- a/src/ftorch.f90 +++ b/src/ftorch.f90 @@ -55,26 +55,32 @@ module ftorch 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 @@ -83,26 +89,32 @@ module ftorch 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 @@ -728,6 +740,60 @@ subroutine torch_tensor_from_array_int8_4d(tensor, data_in, layout, & 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, & + c_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, intent(in) :: layout(5) !! Control order of indices + integer(c_int), intent(in) :: c_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) :: c_tensor_shape(5) !! Shape of the tensor + integer(c_int), parameter :: c_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 :: 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 (c_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 + + c_tensor_shape = shape(data_in) + + strides(layout(1)) = 1 + do i = 2, ndims + strides(layout(i)) = strides(layout(i - 1)) * c_tensor_shape(layout(i - 1)) + end do + + tensor%p = torch_from_blob_c(c_loc(data_in), ndims, c_tensor_shape, & + strides, c_dtype, c_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, & c_device_type, device_index, requires_grad) @@ -944,6 +1010,60 @@ subroutine torch_tensor_from_array_int16_4d(tensor, data_in, layout, & 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, & + c_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, intent(in) :: layout(5) !! Control order of indices + integer(c_int), intent(in) :: c_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) :: c_tensor_shape(5) !! Shape of the tensor + integer(c_int), parameter :: c_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 :: 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 (c_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 + + c_tensor_shape = shape(data_in) + + strides(layout(1)) = 1 + do i = 2, ndims + strides(layout(i)) = strides(layout(i - 1)) * c_tensor_shape(layout(i - 1)) + end do + + tensor%p = torch_from_blob_c(c_loc(data_in), ndims, c_tensor_shape, & + strides, c_dtype, c_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, & c_device_type, device_index, requires_grad) @@ -1160,6 +1280,60 @@ subroutine torch_tensor_from_array_int32_4d(tensor, data_in, layout, & 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, & + c_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, intent(in) :: layout(5) !! Control order of indices + integer(c_int), intent(in) :: c_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) :: c_tensor_shape(5) !! Shape of the tensor + integer(c_int), parameter :: c_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 :: 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 (c_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 + + c_tensor_shape = shape(data_in) + + strides(layout(1)) = 1 + do i = 2, ndims + strides(layout(i)) = strides(layout(i - 1)) * c_tensor_shape(layout(i - 1)) + end do + + tensor%p = torch_from_blob_c(c_loc(data_in), ndims, c_tensor_shape, & + strides, c_dtype, c_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, & c_device_type, device_index, requires_grad) @@ -1376,6 +1550,60 @@ subroutine torch_tensor_from_array_int64_4d(tensor, data_in, layout, & 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, & + c_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, intent(in) :: layout(5) !! Control order of indices + integer(c_int), intent(in) :: c_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) :: c_tensor_shape(5) !! Shape of the tensor + integer(c_int), parameter :: c_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 :: 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 (c_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 + + c_tensor_shape = shape(data_in) + + strides(layout(1)) = 1 + do i = 2, ndims + strides(layout(i)) = strides(layout(i - 1)) * c_tensor_shape(layout(i - 1)) + end do + + tensor%p = torch_from_blob_c(c_loc(data_in), ndims, c_tensor_shape, & + strides, c_dtype, c_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, & c_device_type, device_index, requires_grad) @@ -1592,6 +1820,60 @@ subroutine torch_tensor_from_array_real32_4d(tensor, data_in, layout, & 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, & + c_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, intent(in) :: layout(5) !! Control order of indices + integer(c_int), intent(in) :: c_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) :: c_tensor_shape(5) !! Shape of the tensor + integer(c_int), parameter :: c_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 :: 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 (c_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 + + c_tensor_shape = shape(data_in) + + strides(layout(1)) = 1 + do i = 2, ndims + strides(layout(i)) = strides(layout(i - 1)) * c_tensor_shape(layout(i - 1)) + end do + + tensor%p = torch_from_blob_c(c_loc(data_in), ndims, c_tensor_shape, & + strides, c_dtype, c_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, & c_device_type, device_index, requires_grad) @@ -1808,6 +2090,60 @@ subroutine torch_tensor_from_array_real64_4d(tensor, data_in, layout, & 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, & + c_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, intent(in) :: layout(5) !! Control order of indices + integer(c_int), intent(in) :: c_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) :: c_tensor_shape(5) !! Shape of the tensor + integer(c_int), parameter :: c_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 :: 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 (c_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 + + c_tensor_shape = shape(data_in) + + strides(layout(1)) = 1 + do i = 2, ndims + strides(layout(i)) = strides(layout(i - 1)) * c_tensor_shape(layout(i - 1)) + end do + + tensor%p = torch_from_blob_c(c_loc(data_in), ndims, c_tensor_shape, & + strides, c_dtype, c_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) @@ -1929,6 +2265,36 @@ subroutine torch_tensor_to_array_int8_4d(tensor, data_out, sizes) 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 :: c_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, c_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 @@ -2049,6 +2415,36 @@ subroutine torch_tensor_to_array_int16_4d(tensor, data_out, sizes) 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 :: c_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, c_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 @@ -2169,6 +2565,36 @@ subroutine torch_tensor_to_array_int32_4d(tensor, data_out, sizes) 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 :: c_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, c_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 @@ -2289,6 +2715,36 @@ subroutine torch_tensor_to_array_int64_4d(tensor, data_out, sizes) 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 :: c_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, c_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 @@ -2409,6 +2865,36 @@ subroutine torch_tensor_to_array_real32_4d(tensor, data_out, sizes) 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 :: c_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, c_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 @@ -2529,5 +3015,35 @@ subroutine torch_tensor_to_array_real64_4d(tensor, data_out, sizes) 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 :: c_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, c_dtype) + call c_f_pointer(cptr, data_out, my_shape) + + end subroutine torch_tensor_to_array_real64_5d + end module ftorch diff --git a/src/ftorch.fypp b/src/ftorch.fypp index bc922b3..e31de27 100644 --- a/src/ftorch.fypp +++ b/src/ftorch.fypp @@ -5,7 +5,7 @@ $:'' if RANK == 0 else '(' + ':' + ',:' * (RANK - 1) + ')' #:set C_PRECISIONS = ['c_int8_t', 'c_int16_t', 'c_int32_t', 'c_int64_t', 'c_float', 'c_double'] #:set C_PRECISIONS = dict(zip(PRECISIONS, C_PRECISIONS)) #:set ENUMS = dict(zip(PRECISIONS, ['torch_kInt8', 'torch_kInt16', 'torch_kInt32', 'torch_kInt64', 'torch_kFloat32', 'torch_kFloat64'])) -#:set RANKS = range(1, 5) +#:set RANKS = range(1, 6) #:def enum_from_prec(PRECISION) $:ENUMS[PRECISION] #:enddef enum_from_prec