1- if (getRversion() > = " 4.4.0" ) {
1+ message(" makeClusterSequential() ..." )
2+
3+ # # Requires R (>= 4.4.0)
4+ if (getRversion() < " 4.4.0" ) {
5+ message(" Skipping because R version is less than 4.4.0" )
6+ message(" makeClusterSequential() ... skipped" )
7+ } else {
28 library(parallelly )
9+
10+ # # Temporarily override parallel::makeCluster and parallel::stopCluster
11+ # # to use the sequential versions
12+ old_makeCluster <- parallel :: makeCluster
13+ old_stopCluster <- parallel :: stopCluster
14+ on.exit({
15+ unlockBinding(" makeCluster" , getNamespace(" parallel" ))
16+ assign(" makeCluster" , old_makeCluster , envir = getNamespace(" parallel" ))
17+ unlockBinding(" stopCluster" , getNamespace(" parallel" ))
18+ assign(" stopCluster" , old_stopCluster , envir = getNamespace(" parallel" ))
19+ }, add = TRUE )
20+
21+ unlockBinding(" makeCluster" , getNamespace(" parallel" ))
22+ assign(" makeCluster" , makeClusterSequential , envir = getNamespace(" parallel" ))
23+ unlockBinding(" stopCluster" , getNamespace(" parallel" ))
24+ assign(" stopCluster" , function (cl ) {
25+ # # Do nothing for sequential_cluster, as it's not a real parallel cluster
26+ # # Except for invalidating the node state
27+ for (node in cl ) {
28+ if (inherits(node , " sequential_node" )) {
29+ node $ envir [[" ...parallelly.valid..." ]] <- FALSE
30+ }
31+ }
32+ }, envir = getNamespace(" parallel" ))
33+
334 library(parallel )
4-
35+
536 cl <- makeClusterSequential()
6- print( cl )
37+ stopifnot(inherits( cl , " sequential_cluster " ), length( cl ) == 1L )
738
8- y_truth <- lapply(X = 1 : 3 , FUN = sqrt )
39+ # # Test print.sequential_cluster
40+ capture.output(print(cl ))
41+
42+ # # Test print.sequential_node
43+ capture.output(print(cl [[1 ]]))
44+
45+ # # Test basic parLapply functionality
946 y <- parLapply(cl , X = 1 : 3 , fun = sqrt )
10- str(y )
11- stopifnot(identical(y , y_truth ))
12-
13- pid <- Sys.getpid()
14- print(pid )
15- y <- clusterEvalQ(cl , Sys.getpid())
16- str(y )
17- stopifnot(identical(y [[1 ]], pid ))
18-
47+ stopifnot(identical(y , lapply(1 : 3 , sqrt )))
48+
49+ # # Test clusterEvalQ with side effects
50+ abc <- 3.14
1951 y <- clusterEvalQ(cl , { abc <- 42 ; abc })
20- str(y )
21- stopifnot(! exists(" abc" , inherits = FALSE ))
52+ stopifnot(identical(y , list (42 )), abc == 3.14 )
2253
54+ # # Test stopping the cluster
2355 stopCluster(cl )
24- print(cl )
56+
57+ # # Test accessing an invalid node (after stopCluster)
58+ res <- tryCatch({
59+ parallel :: sendData(cl [[1 ]], list (type = " EXEC" , data = list (fun = identity , args = list (1 ))))
60+ }, error = function (e ) e )
61+ stopifnot(inherits(res , " simpleError" ), grepl(" node is no longer valid" , res $ message ))
62+
63+
64+ # # Re-create cluster for other tests
65+ cl <- makeClusterSequential()
66+ node <- cl [[1 ]]
67+
68+ # # Test sendData with "DONE" type
69+ parallel :: sendData(node , list (type = " DONE" ))
70+ stopifnot(! isTRUE(node $ envir [[" ...parallelly.valid..." ]]))
71+
72+ # # Test sendData with unknown type
73+ # # Test sendData with unknown type
74+ # # Re-create cluster for this test, as the previous one was invalidated
75+ cl_unknown <- makeClusterSequential()
76+ node_unknown <- cl_unknown [[1 ]]
2577
2678 res <- tryCatch({
27- y <- clusterEvalQ(cl , { 42 })
28- }, error = identity )
29- print(res )
30- stopifnot(inherits(res , " error" ))
31- } # # if (getRversion() >= "4.4.0")
79+ parallel :: sendData(node_unknown , list (type = " UNKNOWN" ))
80+ }, error = function (e ) e )
81+ message(" Error message for UNKNOWN type: " , res $ message )
82+ stopifnot(inherits(res , " simpleError" ), grepl(" type = ['‘]UNKNOWN['’] not yet implemented" , res $ message ))
83+
84+ # # Test recvData internal error
85+ # # Re-create cluster for this test
86+ cl_internal_error <- makeClusterSequential()
87+ node_internal_error <- cl_internal_error [[1 ]]
88+
89+ # # Manipulate internal state to trigger error
90+ node_internal_error $ envir [[" value" ]] <- list (type = " BAD_TYPE" )
91+
92+ res <- tryCatch({
93+ parallel :: recvData(node_internal_error )
94+ }, error = function (e ) e )
95+ stopifnot(inherits(res , " simpleError" ), grepl(" INTERNAL ERROR" , res $ message ))
96+
97+ message(" makeClusterSequential() ... done" )
98+ }
0 commit comments