Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.fds-net.ru/showflat.php?Number=9281292&src=arc&showlite=
Дата изменения: Unknown
Дата индексирования: Wed Apr 13 00:36:22 2016
Кодировка: Windows-1251
[fortran] вопрос знатокам - Public forum of MSU united student networks
Root | Google | Yandex | Mail.ru | Kommersant | Afisha | LAN Support
  
Technical >> Development (Archive)

Страницы: 1
springy
Energizer

Рег.: 10.01.2004
Сообщений: 366
Рейтинг: 29
  [fortran] вопрос знатокам
      13.02.2010 13:43
 

Я хочу написать функцию, которая на вход получает массив и размерности, выделяет память allocate-ом, и возвращает массив. Причем функция должна уметь выделять память для массивов разного ранга. По существу мне нужна просто обертка для allocate, которая будет еще кое-что делать.

В Fortran 2003 есть возможность передавать allocatable объекты как параметры. Но проблема в том, что мне приходится указывать число размерностей массива в интерфейсе функции, поэтому она работает только для массивов определеного ранга.

Код, приведенный ниже, не компилируется, так как subroutine memory на вход принимает массив ранга 1, а я ему даю массив ранга 3.

Можно ли как-нибудь все-таки такую функцию реализовать? Писать отдельно функции для массивов ранга 1, 2, 3 и т.д. как-то не хочется...

Спасибо!

code:
module memory_allocator contains subroutine memory(array, length) implicit none real(8), allocatable, intent(out), dimension(:) :: array integer, intent(in) :: length integer :: ierr print *, "memory: before: ", allocated(array) allocate(array(length), stat=ierr) if (ierr /= 0) then print *, "error allocating memory: ierr=", ierr end if print *, "memory: after: ", allocated(array) end subroutine memory subroutine freem(array) implicit none real(8), allocatable, dimension(:) :: array print *, "freem: before: ", allocated(array) deallocate(array) print *, "freem: after: ", allocated(array) end subroutine freem end module memory_allocator program alloc use memory_allocator implicit none integer, parameter :: n = 3 real(8), allocatable, dimension(:,:,:) :: foo integer :: i, j, k print *, "main: before memory: ", allocated(foo) call memory(foo, n*n*n) print *, "main: after memory: ", allocated(foo) do i = 1,n do j = 1,n do k = 1, n foo(i, j, k) = real(i*j*k) end do end do end do print *, foo print *, "main: before freem: ", allocated(foo) call freem(foo) print *, "main: after freem: ", allocated(foo) end program alloc


code:
gfortran -o alloc alloc.f90 -std=f2003 alloc.f90:46.14: call memory(foo, n*n*n) 1 Error: Rank mismatch in argument 'array' at (1) (1 and 3) alloc.f90:60.13: call freem(foo) 1 Error: Rank mismatch in argument 'array' at (1) (1 and 3)


epsilon
enthusiast

Рег.: 01.04.2007
Сообщений: 376
Рейтинг: 411
  Re: [fortran] вопрос знатокам [re: springy]
      13.02.2010 17:23
 

как вариант, можно хранить массив ранга 1 и по мере необходимости работать с ним как с 3-х мерным, воспользовавшись фичей 2003 фортрана 'pointer rank remapping' (правда gfortran (4.4.1) и ifort (11.1.038) ее не поддерживают).

code:
program alloc use memory_allocator implicit none integer, parameter :: n = 3 real(8), dimension(:), allocatable, target :: foo real(8), dimension(:,:,:), pointer :: foo3d integer :: i, j, k print *, "main: before memory: ", allocated(foo) call memory(foo, n*n*n) foo3d(1:n,1:n,1:n) => foo print *, "main: after memory: ", allocated(foo) forall (i=1:n, j=1:n, k=1:n) foo3d(i, j, k) = real(i*j*k,kind=8) print *, foo print *, "main: before freem: ", allocated(foo) call freem(foo) print *, "main: after freem: ", allocated(foo) end program alloc


Forest
Carpal Tunnel

Рег.: 29.08.2002
Сообщений: 11597
Рейтинг: 795
  Re: [fortran] вопрос знатокам [re: springy]
      13.02.2010 22:41
 


 
В ответ на:

Но проблема в том, что мне приходится указывать число размерностей массива в интерфейсе функции, поэтому она работает только для массивов определеного ранга.



А что мешает передать размерность массивом?

springy
Energizer

Рег.: 10.01.2004
Сообщений: 366
Рейтинг: 29
  Re: [fortran] вопрос знатокам [re: Forest]
      14.02.2010 00:42
 

Ну вот а как это сделать?..
Я так понимаю, что этот массив должен быть описан как deferred shape, т.е. a(:,...,:), потому что он allocatable. Т.е. про него известен только ранг, а как его передать параметром?

Forest
Carpal Tunnel

Рег.: 29.08.2002
Сообщений: 11597
Рейтинг: 795
  Re: [fortran] вопрос знатокам [re: springy]
      17.02.2010 18:26
 

Самый простой вариант передать все явно: ранг, массив размерностей размера ранг (это если все размерности начинаются с 1 и того же числа - если надо использовать отрезки - немного сложнее) и сам массив.
Что-то вроде такого:
 
code:
subroutine memory(array, length, range) implicit none integer, intent(in) :: range, length(range) ...


springy
Energizer

Рег.: 10.01.2004
Сообщений: 366
Рейтинг: 29
  Re: [fortran] вопрос знатокам [re: Forest]
      17.02.2010 22:28
 

Я не понимаю, array в этом случае как описать?

Вот так не получится, потому что allocatable массив array должен быть описан как deferred shape
 
code:
subroutine memory(array, dims) integer, intent(in) :: dims(:) real(8), intent(inout), allocatable :: array(dims)


 
code:
alloc.f90:7.47: real(8), allocatable, intent(out) :: array(dims) 1 Error: Expression at (1) must be scalar alloc.f90:4.25: subroutine memory(array, dims) 1 Error: Allocatable array 'array' at (1) must have a deferred shape


Forest
Carpal Tunnel

Рег.: 29.08.2002
Сообщений: 11597
Рейтинг: 795
  Re: [fortran] вопрос знатокам [re: springy]
      18.02.2010 20:56
 

Действительно, с рангом массива сложнее - сконструировать не проблема, но вот описать такой параметр?..
Так сразу непонятно как.
Имхо это одна из недоделок фортрана, но мб и можно извернуться через символьные константы (описывая ими сечения, но у меня не получилось, а мб и нельзя).

Как вариант - можно действительно все делать одномерными массивами (как тут уже и советовали).
Тогда в минимальном варианте надо будет лишь написать свой метод доступа к ячейке (но он будет конечно не такой же универсальный, как и в стандарте, но мб и хватит), ну или написать фабрику.

Но конечно все это не очень удобно, и в этом основной минус фортрана - как только хочется что-нибудь сделать красиво - язык не пускает :(

Страницы: 1

Technical >> Development (Archive)

Дополнительная информация
1 зарегистрированных и 0 анонимных пользователей просматривают этот форум.

Модераторы:  DarkGray 

Печать темы

Права
      Вы можете создавать новые темы
      Вы можете отвечать на сообщения
      HTML отключен
      UBBCode включен

Рейтинг:
Просмотров темы:

Переход в