установить количество потоков в пакете R, который использует Fortran и PpenMP - PullRequest
0 голосов
/ 01 февраля 2019

Я пишу простой пакет R, который использует Fortran и OpenMP.Это мой модуль fortran:

module im_f_module
   use omp_lib
   implicit none
   contains

subroutine fill_matrix(N,K,A,ncores) bind(C, name="fill_")
   use, intrinsic                                         :: iso_c_binding, only : c_double, c_int
   integer(c_int), intent(in)                             :: N,K, ncores
   real(c_double), DIMENSION(N, K), intent(out)           :: A
   integer                                                :: nn, kk, thread_num
   ! Specify number of threads to use:
    !$ call omp_set_num_threads(ncores)
    !$omp parallel private(thread_num)
    !$omp parallel do
    do nn=1,N
       do kk=1,K
          !$ thread_num = omp_get_thread_num()
          A(nn,kk) = thread_num
       end do
       !print *, A(nn, :)
    end do
    !$omp end parallel do
end subroutine fill_matrix



end module im_f_module

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

fill_my_matrix(N = 2, K = 2, ncores = 4)

Должно иметь 4 разных значения.Увы, он только один:

     [,1] [,2]
[1,]    0    0
[2,]    0    0

Я предполагаю, что !$ call omp_set_num_threads(ncores) не устанавливает количество потоков равным 4. Как это исправить?

Если это полезно, весь код моего пакета доступен в этом репозитории github

1 Ответ

0 голосов
/ 03 февраля 2019

Мне удалось заставить это работать с помощью пакета OpenMPController.Если есть лучший способ сделать это, я хотел бы изучить это.Сейчас я просто изменил свою функцию R следующим образом:

#'@export
#'@useDynLib fortranMatrix, .registration = TRUE
fill_my_matrix <- function(N=10, K=5, nthreads=4) {
  (OpenMPController::omp_set_num_threads(nthreads))
  A <- .Fortran("fill",
                N = as.integer(N),
                K = as.integer(K),
                A = matrix(1982,nrow = N, ncol = K),
                nthreads = as.integer(nthreads))
  return(A$A)
}

И вот что я получаю, когда я ее называю:

> fill_my_matrix(N = 6, K = 6, nthreads = 6)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    0    0    0    0    0    0
[2,]    1    1    1    1    1    1
[3,]    2    2    2    2    2    2
[4,]    3    3    3    3    3    3
[5,]    4    4    4    4    4    4
[6,]    5    5    5    5    5    5
...