2

Here's some Julia code:

addprocs()
@everywhere begin
    type Test
        values::Array{Any,1}
        addValue::Function
   function Test()
       this = new()
       this.values = Any[]

       this.addValue = function(v)
           push!(this.values,v)
       end

       return this
   end
end
end
@everywhere t = Test()
@everywhere t.addValue(myid())
@spawnat 2 whos()
r = @spawnat 2 t

I believe this code defines a Test type on all processes and then creates an instance of that type stored in a variable, called t, on each process. This variable is local to that process. I then use one of the Test methods run in parallel on each process to mutate the local instance of Test. In the line

@spawnat 2 whos()

we can see that the local t has indeed been updated. However, I get a HUGE error when trying to fetch any of the remote variables t into a RemoteRef. The error message is quite large, but it leads me to believe that the Julia serialization process cannot handle user-defined types. Can anybody lend some insight? Thank You!

Upadate: A simpler example yielding the same error:

addprocs() 
@everywhere begin
 type Test
    values::Array{Any,1}
    addValue::Function
    function Test()
       this = new()
       this.values = Any[]
       this.addValue = function(v)
           push!(this.values,v)
       end
       return this
   end
end
end
t = Test()
R = RemoteRef(2)
put!(R,t)

1 Answers1

1

I don't know why trying to fetch that composite object with a function field inside, causes the Error..., anyway I encourage you to use Julia way for creating the same functionality:

First of all you don't need to include addValue function inside the Test type, try to separate data storage from functionality:

@everywhere begin
    type Test
        values::Array{Any,1}
        addValue::Function
      function Test()
        this = new()
        this.values = Any[]
        return this
      end
    end
end

@everywhere function addValue(v,t::test)
               push!(t.values,v)
            end

then initialize t everywhere:

@everywhere t = Test()

and mutate t everywhere:

@everywhere addValue(myid(),t)

Secondly run getfield() command on desired process to get local variable:

r = @spawnat 3 getfield(Main,:t)

check the result:

assert(fetch(r).values==[3])

for more details about how to pass variable between processes check this question.

Community
  • 1
  • 1
Reza Afzalan
  • 5,646
  • 3
  • 26
  • 44
  • Thanks for the reply! I did come across the question you linked to, and it does appear that I can fetch and send if I separate methods and properties, per your suggestion. However, it seems like a bug that the type def I used should not be serializable, right? In general, why should I separate data storage from functionality? Seems like a divergence from OOP, which Julia is supposed to support. Also, it seems like a hassle to use Symbols or Expr for passing local variables among procs. Do you agree? – Morgan Frank Nov 04 '15 at 16:19
  • 1
    word is that the newest release (v0.4.1) will resolve my error. :D – Morgan Frank Nov 04 '15 at 16:23
  • In the case that it looks like a bug, I agree with you. If you like the topic of OOP approach in Julia language, check "Julia and Object-Oriented Programming" topic in https://groups.google.com/forum/#!forum/julia-users – Reza Afzalan Nov 04 '15 at 16:33