From maechler at stat.math.ethz.ch  Wed Feb  6 10:29:15 2013
From: maechler at stat.math.ethz.ch (Martin Maechler)
Date: Wed, 6 Feb 2013 10:29:15 +0100
Subject: [Rd] best practice for packages using mclapply to avoid tcltk
In-Reply-To: <CAErODj9qtvB=s0zphXywin5ZpXozVKdj0qeRvAp9cyFy3O8coA@mail.gmail.com>
References: <CAErODj_1hg8+x5SvOmoL8V9RMNgMAN_fXGBLcsJhgnH_k2jOgw@mail.gmail.com>
	<F667EFC5-41D0-4F56-AE80-FCBDBE65F46E@r-project.org>
	<CAErODj9qtvB=s0zphXywin5ZpXozVKdj0qeRvAp9cyFy3O8coA@mail.gmail.com>
Message-ID: <20754.8811.443519.383545@stat.math.ethz.ch>

>>>>> "PJ" == Paul Johnson <pauljohn32 at gmail.com>
>>>>>     on Tue, 5 Feb 2013 22:25:01 -0600 writes:

    > On Sun, Feb 3, 2013 at 1:34 PM, Simon Urbanek
    > <simon.urbanek at r-project.org> wrote:
    >> As Peter pointed out earlier, this is better addressed by
    >> disabling the Tcl/Tk event loop in forked processes.
    >> 
    > Dear Simon:

    > I don't understand.  Can you please try to say it again?

    > I find Peter's comment (on Jan 3, 2013, thread title:
    > weird bug with parallel, RSQlite and tcltk):

    > "More likely, the wisdom of calling R_ProcessEvents and
    > R_PolledEvents in parallel processes should be
    > questioned. I tend to think that they should both be
    > disabled completely conditionally on R_isForkedChild.
    > At least in the Tk loop, some of the events are
    > generated as responses to specific queries, and having
    > one process ask for something and another one handling
    > the reply, leaving the first one waiting indefinitely,
    > is just Not Right."

    > That suggested to me the problem is in R itself, or the
    > tcltk package

Well, it should have suggested that the problem should be
addressed "in R itself"...
and it now has been:

The NEWS  for R 2.15.2 patched (and hence "R devel" and all
    	      	       	       	future versions of R)
now contain

      The Tcl/Tk event loop is inhibited in a forked child (as in e.g.
      mclapply().


    > If package writers don't follow my suggestion, what do
    > they think they should do instead?

Package writers should  add a 
---------------------------
Depends:  R (>= 2.15.3)
---------------------------
to their DESCRIPTION .... but probably only after that is released  :-)

--
Martin


    > pj
    >> Cheers, Simon
    >> 
    >> On Feb 2, 2013, at 5:02 PM, Paul Johnson wrote:
    >> 
    >>> Dear R-devel friends:
    >>> 
    >>> I'm back to bother you again about the conflict between
    >>> mclapply and tcltk. I've been monitoring several
    >>> packages that want to use mclapply to parallelize
    >>> computations and need to figure out what should be done.
    >>> 
    >>> It appears tcltk cannot be safely unloaded, so the best
    >>> we can do is check for the presence of tcltk and stop if
    >>> it is found before mclapply() is used.
    >>> 
    >>> I wish you would please review my suggestion below.
    >>> Maybe checkForTcltk() could be used in the parallel
    >>> package. Otherwise, we are letting people run with
    >>> scissors.
    >>> 
    >>> There's a warning about this in ?mclapply
    >>> 
    >>> It is _strongly discouraged_ to use these functions in
    >>> GUI or embedded environments, because it leads to
    >>> several processes sharing the same GUI which will likely
    >>> cause chaos (and possibly crashes).  Child processes
    >>> should never use on-screen graphics devices.(Warning in
    >>> ?mclapply)
    >>> 
    >>> Bug report:
    >>> (https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=15040
    >>> )
    >>> 
    >>> By the way, what is "embedded environments" in ?mclapply
    >>> 
    >>> ## I don't want to crash your system, but if you want to
    >>> see a freeze-up: ## change 0 to 1 and run this: if (0){
    >>> library(parallel) library(tcltk) example(mclapply) }
    >>> 
    >>> ## What are packagers supposed to do if they want to
    >>> call mclapply?  ## It appears to me the best a package
    >>> can do is scan for tcltk and ## stop. Here's a function
    >>> that does so.
    >>> 
    >>> checkForTcltk <- function(){ if ("tcltk" %in%
    >>> loadedNamespaces()){ stop("This function cannot be used
    >>> because the R tcltk package is loaded. It is necessary
    >>> to Close R, and re-run the program making sure that
    >>> tcltk is never loaded before this function is called.")
    >>> } }
    >>> 
    >>> ## put that to use.  MCLApply <- function(){ if
    >>> (!require(parallel)) stop ("parallel wouldn't load")
    >>> checkForTcltk() example(mclapply) }
    >>> 
    >>> ## test that:
    >>> 
    >>> checkForTcltk() MCLApply()
    >>> 
    >>> library(tcltk) checkForTcltk()
    >>> 
    >>> 
    >>> ## Why can't tcltk just be unloaded? I don't understand,
    >>> but it is a deep ## problem.
    >>> 
    >>> ## Consider the ominous warnings in R detach's help:
    >>> ##
    >>> ## "Unloading some namespaces has undesirable side
    >>> effects: e.g.  ## unloading ?grid? closes all graphics
    >>> devices, and on most systems ## ?tcltk? cannot be
    >>> reloaded once it has been unloaded and may crash ## R if
    >>> this is attempted." (Note: section of ?detach).
    >>> ##
    >>> ## To be fair, that does not say unloading tcltk is
    >>> fatal, but ## reloading it is fatal. And I've seen
    >>> plenty of times when ## unloading it is fatal.
    >>> 
    >>> ## Example 1. Crash on library.dynam.unload()
    >>> detach("package:tcltk", unload = TRUE)
    >>> library.dynam.unload("tcltk", system.file(package =
    >>> "tcltk"))
    >>> 
    >>> ## Output ## > library.dynam.unload("tcltk",
    >>> system.file(package = "tcltk"))
    >>> ## >
    >>> ## *** caught segfault *** ## address 0x7f69c9d99580,
    >>> cause 'memory not mapped'
    >>> 
    >>> ## Possible actions: ## 1: abort (with core dump, if
    >>> enabled) ## 2: normal R exit ## 3: exit R without saving
    >>> workspace ## 4: exit R saving workspace ## Selection: ##
    >>> Process R segmentation fault at Sat Feb 2 13:55:08 2013
    >>> 
    >>> 
    >>> ## Example 2.  library(tcltk) detach("package:tcltk",
    >>> unload = TRUE) library.dynam.unload("tcltk",
    >>> system.file(package = "tcltk")) example(mclapply)
    >>> 
    >>> ## Output:
    >>> 
    >>> ## > example(mclapply)
    >>> 
    >>> ## *** caught segfault *** ## address 0x7f25ccbfe000,
    >>> cause 'memory not mapped'
    >>> 
    >>> ## Possible actions: ## 1: abort (with core dump, if
    >>> enabled) ## 2: normal R exit ## 3: exit R without saving
    >>> workspace ## 4: exit R saving workspace ## Selection:
    >>> 
    >>> 
    >>> pj
    >>> 
    >>> --
    >>> Paul E. Johnson Professor, Political Science



[Rd] best practice for packages using mclapply to avoid tcltk
Martin Maechler