Dear Torsten,
2009/3/23 Torsten Anders <[email protected]>
> Dear Raphael,
>
> Thanks for your reply, and sorry for my delayed response.
>
No problem.
If the objects never reach the toplevel space, there should be no problem
> with those objects. Simply check that
> - the objects are created by running the script only,
> - no object reference is accessible from the root variable, and
>
>
> Actually, I want to return the object as solution from the script. Now, I
> could return a "textual version" (nested records which could later be turned
> into the object again). However, the distribution strategy needs in any
> case access to the object. So, objects are communicated between spaces.
>
>
> - no object is ever sent on a port that belongs to the toplevel space.
>
> If all three conditions above are satisfied, the objects are not the
> problem. Also make sure that your classes do not use shared state or
> resources (like System, FD, and so on). If the classes depend on something
> like the FD module, then make the search functor (the one you give to the
> search engine) import the modules where the classes are defined, and make
> the script refer explicitly to that imported module.
>
>
> Could you perhaps briefly explain why this is necessary?
>
Sure. The distribution in Mozart (or any distributed language) is not
transparent for resources. A resource is something that is bound to a
particular instance of a virtual machine, and which cannot be made available
remotely in a reasonable fashion.
For instance, the procedure FD.sum refers to a builtin inside a native
module. Some native builtins (like Number.'+') are automatically rebound to
the site where they are sent. But this only works for builtins that are
considered as part of the language. For the other builtins, there are two
classical ways to use that procedure remotely:
(1) One strategy is to make the procedure remotely callable (RPC). But that
is not feasible in the case of FD.sum, because that procedure must access
*atomically* to the constraint store of the caller. The performance
overhead would be ridiculously high. This is why if you send FD.sum on a
remote site, it will appear remotely as an opaque, unusable resource.
(2) The other strategy is to use the same native module on the remote site;
it is achieved by applying a functor on the remote site that gives access to
the local instance of the native module (if present).
> By the way, can you describe more precisely the problem you are
> experiencing? We could give you better advice if we have a bit more info...
>
>
> Sure :) Below is a dummy definition which results in a similar error
> message to what I get when I use my musical score objects in a script for
> parallel search. Please keep in mind that the example below is only intended
> to demonstrate this error I am getting.
>
> Any comments how I can twist the example below to get objects working
> within parallel search?
>
Gotcha! ;-) I found mistakes in the "functorized" script that let resources
escape:
declarefunctor MyDataF
> import
> FD
> export
> MyClass
> define
> %% dummy class
> class MyClass
>
> attr val
> meth init(val:?Val<={FD.decl})
> @val = Val
> end
> meth val($) @val end
> end
> end
> [MyData] = {Module.apply [MyDataF]}
> Machines = init(localhost:2)
>
MyData.myClass is a class that accesses a resource (FD.decl). This is what
the error message says: the remote site only sees an unusable resource
reference that stands for FD.decl. So the class as such should not be
exported, because it refers to a resource on its creation site. Instead,
you should import (or apply) the functor MyDataF in your script below:
> functor ScriptF
> import FD
> export Script
> define
> %% dummy script
> proc {Script Root}
> X = {New MyData.myClass init}
> Y = {New MyData.myClass init}
> Z = {New MyData.myClass init(val: 7)}
> in
> Root = unit(X Y Z)
> {X val($)} + {Y val($)} =: {Z val($)} % (A)
> {X val($)} <: {Y val($)} % (B)
> %%
> {FD.distribute ff [{X val($)} {Y val($)}]}
> end
> end
>
Now, there are two other resources used in that functor: they are "hidden"
in lines (A) and (B). The compiler expands the statement X+Y=:Z as {BiSumC
[X Y] '=:' Z}, where BiSum is a direct reference to the builtin FD.sum.
This builtin reference is therefore not inside the lexical scope of the
functor. This is a limitation of the compiler. The above two lines must
make explicit references to FD, i.e.,
{FD.sum [{X val($)} {Y val($)}] '=:' {Z val($)}}
{FD.less {X val($)} {Y val($)}}
The nice equation syntax does not work with distributed programs :-(
Removing those "dangling" resource references should already make you one
step further. Passing objects as solutions of scripts should work, provided
you don't use a method that accesses a resource. In your example above, the
method val is safe, but init is not. Be careful also that constrained
variables are distributed as read-onlys, so you may be in trouble if your
solutions are not fully determined.
I will let you think about this, and see how much work would be required to
adapt your program. Don't hesitate to ask if you find some other unexpected
behavior, or if my explanation is unclear...
Cheers,
raph
_________________________________________________________________________________
mozart-users mailing list
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users