共享库在使用R中的并行foreach时未被识别。

huangapple go评论99阅读模式
英文:

Shared library is not recognized when using parallel foreach in R

问题

你在我的R代码中使用了一个用C语言编写的共享库。我使用dyn.load命令加载了编译后的共享库。我打算在一个并行的foreach循环中调用一个共享库函数。以下是我的代码:

  1. library(foreach)
  2. library(doParallel)
  3. totalCores = detectCores()
  4. cluster <- makeCluster(totalCores[1]-1)
  5. registerDoParallel(cluster)
  6. dyn.load("package.so")
  7. run <- function(i) {
  8. row <- data[i,]
  9. res <- .Call("c_function", as.double(row))
  10. return(res)
  11. }
  12. result <- foreach(i=1:nrow(data), .combine = rbind) %dopar% {
  13. run(i)
  14. }

我得到了以下错误:

  1. Error in { :
  2. task 1 failed - "C symbol name "c_function" not in load table"

尽管我已经加载了共享库,但似乎在并行任务中无法识别c_function。当然,如果我在foreach循环中让dyn.load命令,问题就解决了:

  1. result <- foreach(i=1:nrow(data), .combine = rbind) %dopar% {
  2. dyn.load("package.so")
  3. run(i)
  4. }

但我不确定这是否是最佳实践,因为在每次迭代中都会加载共享库(package.so),这可能效率不高。有什么想法吗?

编辑:

关于r2even的答案,我测试了以下代码:

  1. foreach(i=1:50,.packages='rootSolve') %dopar% {
  2. print(is.loaded("c_function"))
  3. }

我的电脑有10个CPU核心(20个线程),所以在执行此代码时,totalCores变量的值是20。以下是结果:

  1. [[1]]
  2. [1] TRUE
  3. [[2]]
  4. [1] TRUE
  5. [[3]]
  6. [1] TRUE
  7. [[4]]
  8. [1] TRUE
  9. [[5]]
  10. [1] TRUE
  11. [[6]]
  12. [1] TRUE
  13. [[7]]
  14. [1] TRUE
  15. [[8]]
  16. [1] TRUE
  17. [[9]]
  18. [1] TRUE
  19. [[10]]
  20. [1] TRUE
  21. [[11]]
  22. [1] FALSE
  23. [[12]]
  24. [1] FALSE
  25. [[13]]
  26. [1] FALSE
  27. [[14]]
  28. [1] FALSE
  29. [[15]]
  30. [1] FALSE
  31. [[16]]
  32. [1] FALSE
  33. [[17]]
  34. [1] FALSE
  35. [[18]]
  36. [1] FALSE
  37. [[19]]
  38. [1] FALSE
  39. [[20]]
  40. [1] TRUE
  41. [[21]]
  42. [1] TRUE
  43. [[22]]
  44. [1] TRUE
  45. [[23]]
  46. [1] TRUE
  47. [[24]]
  48. [1] TRUE
  49. [[25]]
  50. [1] TRUE
  51. [[26]]
  52. [1] TRUE
  53. [[27]]
  54. [1] TRUE
  55. [[28]]
  56. [1] TRUE
  57. [[29]]
  58. [1] TRUE
  59. [[30]]
  60. [1] TRUE
  61. [[31]]
  62. [1] TRUE
  63. [[32]]
  64. [1] TRUE
  65. [[33]]
  66. [1] TRUE
  67. [[34]]
  68. [1] TRUE
  69. [[35]]
  70. [1] TRUE
  71. [[36]]
  72. [1] TRUE
  73. [[37]]
  74. [1] TRUE
  75. [[38]]
  76. [1] TRUE
  77. [[39]]
  78. [1] TRUE
  79. [[40]]
  80. [1] TRUE
  81. [[41]]
  82. [1] TRUE
  83. [[42]]
  84. [1] TRUE
  85. [[43]]
  86. [1] TRUE
  87. [[44]]
  88. [1] TRUE
  89. [[45]]
  90. [1] TRUE
  91. [[46]]
  92. [1] TRUE
  93. [[47]]
  94. [1] TRUE
  95. [[48]]
  96. [1] TRUE
  97. [[49]]
  98. [1] TRUE
  99. [[50]]
  100. [1] TRUE

这引发了一些问题。is.loaded("c_function")的值是否总是在迭代11到20之间为False?从第21次迭代开始是否保证它总是为True?

英文:

I am using a shared library written in C in my R code. I load the compiled shared library using dyn.load command. I am going to call a shared library function in a parallelized foreach loop. Here is my code:

  1. library(foreach)
  2. library(doParallel)
  3. totalCores = detectCores()
  4. cluster &lt;- makeCluster(totalCores[1]-1)
  5. registerDoParallel(cluster)
  6. dyn.load(&quot;package.so&quot;)
  7. run &lt;- function(i) {
  8. row &lt;- data[i,]
  9. res &lt;- .Call(&quot;c_function&quot;, as.double(row))
  10. return(res)
  11. }
  12. result &lt;- foreach(i=1:nrow(data), .combine = rbind) %dopar% {
  13. run(i)
  14. }

I get the following error:

  1. Error in { :
  2. task 1 failed - &quot;C symbol name &quot;c_function&quot; not in load table&quot;

Although I have loaded the shared library, it seems c_function is not recognized in the parallel tasks. Of course when I let the dyn.load command in the foreach loop the problem is solved:

  1. result &lt;- foreach(i=1:nrow(data), .combine = rbind) %dopar% {
  2. dyn.load(&quot;package.so&quot;)
  3. run(i)
  4. }

But I am not sure if this is the best practice since at each iteration the shared library (package.so) is loaded and it may be not efficient. Any ideas?

Edit:

Regarding to r2even's answer I tested the following code:

  1. foreach(i=1:50,.packages=&#39;rootSolve&#39;) %dopar% {
  2. print(is.loaded(&quot;c_function&quot;))
  3. }

My PC has 10 CPU cores (20 threads) so the value of totalCores variable was 20 when I executed this code. Here is the result:

  1. [[1]]
  2. [1] TRUE
  3. [[2]]
  4. [1] TRUE
  5. [[3]]
  6. [1] TRUE
  7. [[4]]
  8. [1] TRUE
  9. [[5]]
  10. [1] TRUE
  11. [[6]]
  12. [1] TRUE
  13. [[7]]
  14. [1] TRUE
  15. [[8]]
  16. [1] TRUE
  17. [[9]]
  18. [1] TRUE
  19. [[10]]
  20. [1] TRUE
  21. [[11]]
  22. [1] FALSE
  23. [[12]]
  24. [1] FALSE
  25. [[13]]
  26. [1] FALSE
  27. [[14]]
  28. [1] FALSE
  29. [[15]]
  30. [1] FALSE
  31. [[16]]
  32. [1] FALSE
  33. [[17]]
  34. [1] FALSE
  35. [[18]]
  36. [1] FALSE
  37. [[19]]
  38. [1] FALSE
  39. [[20]]
  40. [1] TRUE
  41. [[21]]
  42. [1] TRUE
  43. [[22]]
  44. [1] TRUE
  45. [[23]]
  46. [1] TRUE
  47. [[24]]
  48. [1] TRUE
  49. [[25]]
  50. [1] TRUE
  51. [[26]]
  52. [1] TRUE
  53. [[27]]
  54. [1] TRUE
  55. [[28]]
  56. [1] TRUE
  57. [[29]]
  58. [1] TRUE
  59. [[30]]
  60. [1] TRUE
  61. [[31]]
  62. [1] TRUE
  63. [[32]]
  64. [1] TRUE
  65. [[33]]
  66. [1] TRUE
  67. [[34]]
  68. [1] TRUE
  69. [[35]]
  70. [1] TRUE
  71. [[36]]
  72. [1] TRUE
  73. [[37]]
  74. [1] TRUE
  75. [[38]]
  76. [1] TRUE
  77. [[39]]
  78. [1] TRUE
  79. [[40]]
  80. [1] TRUE
  81. [[41]]
  82. [1] TRUE
  83. [[42]]
  84. [1] TRUE
  85. [[43]]
  86. [1] TRUE
  87. [[44]]
  88. [1] TRUE
  89. [[45]]
  90. [1] TRUE
  91. [[46]]
  92. [1] TRUE
  93. [[47]]
  94. [1] TRUE
  95. [[48]]
  96. [1] TRUE
  97. [[49]]
  98. [1] TRUE
  99. [[50]]
  100. [1] TRUE

It raises several questions. Is the value of is.loaded("c_function") always False only in the the iterations 11 to 20? Is it guaranteed that from the iteration 21 to the rest it is always true?

答案1

得分: 1

尝试这个hack,几乎肯定比重复调用dyn.load要高效得多:

  1. result <- foreach(i=1:nrow(data), .combine = rbind) %dopar% {
  2. if (!is.loaded("c_function")) dyn.load("package.so")
  3. run(i)
  4. }

(未经测试。)

英文:

Try this *hack*, almost certainly less inefficient than repeated calls to dyn.load:

  1. result &lt;- foreach(i=1:nrow(data), .combine = rbind) %dopar% {
  2. if (!is.loaded(&quot;c_function&quot;)) dyn.load(&quot;package.so&quot;)
  3. run(i)
  4. }

(Untested.)

huangapple
  • 本文由 发表于 2023年5月25日 16:58:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76330516.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定