BioJulia/BioSymbols.jl

Errors thrown when using symbols as pmap input with multiple Julia processes

Closed this issue · 3 comments

Expected Behavior

Amino acid and nucleic acid symbols are passed along like other values when using multiple Julia processes.

Current Behavior

Error is thrown when using more than one Julia process.

Possible Solution / Implementation

Steps to Reproduce (for bugs)

  1. start interpreter with julia -p 2
julia> using BioSymbols
julia> f(aa) = aa
julia> pmap(f, [AA_A])
ERROR: MethodError: no method matching write(::TCPSocket, ::BioSymbols.DNA)
Closest candidates are:
  write(::IO, ::Any) at io.jl:284
  write(::IO, ::Any...) at io.jl:286
  write(::IO, ::Complex) at complex.jl:175
  ...
Stacktrace:
 [1] #573 at ./asyncmap.jl:178 [inlined]
 [2] foreach(::Base.##573#575, ::Array{Any,1}) at ./abstractarray.jl:1733
 [3] maptwice(::Function, ::Channel{Any}, ::Array{Any,1}, ::Array{BioSymbols.DNA,1}, ::Vararg{Array{BioSymbols.DNA,1},N} where N) at ./asyncmap.jl:178
 [4] wrap_n_exec_twice(::Channel{Any}, ::Array{Any,1}, ::Base.Distributed.##204#207{WorkerPool}, ::Function, ::Array{BioSymbols.DNA,1}, ::Vararg{Array{BioSymbols.DNA,1},N} where N) at ./asyncmap.jl:154
 [5] #async_usemap#558(::Function, ::Void, ::Function, ::Base.Distributed.##188#190, ::Array{BioSymbols.DNA,1}, ::Vararg{Array{BioSymbols.DNA,1},N} where N) at ./asyncmap.jl:103
 [6] (::Base.#kw##async_usemap)(::Array{Any,1}, ::Base.#async_usemap, ::Function, ::Array{BioSymbols.DNA,1}, ::Vararg{Array{BioSymbols.DNA,1},N} where N) at ./<missing>:0
 [7] (::Base.#kw##asyncmap)(::Array{Any,1}, ::Base.#asyncmap, ::Function, ::Array{BioSymbols.DNA,1}) at ./<missing>:0
 [8] #pmap#203(::Bool, ::Int64, ::Void, ::Array{Any,1}, ::Void, ::Function, ::WorkerPool, ::Function, ::Array{BioSymbols.DNA,1}) at ./distributed/pmap.jl:126
 [9] pmap(::WorkerPool, ::Function, ::Array{BioSymbols.DNA,1}) at ./distributed/pmap.jl:101
 [10] #pmap#213(::Array{Any,1}, ::Function, ::Function, ::Array{BioSymbols.DNA,1}) at ./distributed/pmap.jl:156
 [11] pmap(::Function, ::Array{BioSymbols.DNA,1}) at ./distributed/pmap.jl:156

Your Environment

  • Package Version used: 2.0.0
  • Julia Version used: 0.6.3
  • Operating System and version (desktop or mobile): Linux 4.13.0

Thanks for flagging this up @rusty122. I can recreate this behaviour too.

I think the issue is that there are no read and write methods for the DNA, RNA, and AminoAcid types:

julia> write(STDOUT, AA_A)
ERROR: MethodError: no method matching write(::Base.TTY, ::BioSymbols.AminoAcid)

So if I provide a write method:

julia> @everywhere Base.write(io::IO, x::BioSymbols.DNA) = write(io, reinterpret(UInt8, x))

julia> pmap(f, [DNA_A])
ERROR: On worker 2:
MethodError: Cannot `convert` an object of type Type{BioSymbols.DNA} to an object of type Array{UInt8,1}
This may have arisen from a call to the constructor Array{UInt8,1}(...),
since type constructors fall back to convert methods.
read at ./io.jl:528

So when I provide a read method too:

julia> @everywhere Base.read(io::IO, ::Type{BioSymbols.DNA}) = reinterpret(BioSymbols.DNA, read(io, UInt8))

julia> pmap(f, [DNA_A])
1-element Array{BioSymbols.DNA,1}:
 DNA_A

julia> @everywhere f(dna) = Char(dna)

julia> pmap(f, [DNA_A])
1-element Array{Char,1}:
 'A'

I'll schedule these methods to be included in the next release, along with a few other minor changes.

Thanks for flagging this up @rusty122, release v2.0.1 should fix this behaviour. It may take a day or so for it to be merged into METADATA.jl, or you could clone the master branch with Pkg.clone in the meantime.

Great! Glad there was an easy fix.