Hi, Dave, You are accessing the method size() of the *field* a_prefix_sum of the current object (i.e., "this"). However, the message says that the *target* of the method *must be local* to the place you are running in. It then says what it thinks that place is, and what it knows about the place where the method target lives.
So, the message says: > /Users/dhudak/osc/research/x10/tutorial/examples/GoodPrefixSum/src/PrefixSum.x10:42: > Place type error: either method target should be local or > method should be global. > Method target: PrefixSum.this.a_prefix_sum > Method target place: null > Current place: PrefixSum#this.home > Method: size The target is "this.a_prefix_sum", and the home place of that object is "null" (which is to say "unknown" -- we ought to improve our error messages). The compiler knows that since you are within a non-global instance method of class PrefixSum, you must be running in the place where the current instance lives, namely "PrefixSum#this.home". You need to tell the compiler that the field a_prefix_sum lives in the same place as the enclosing object. The simplest way to do this is to change the declaration of the field to say: val a_prefix_sum: Array[Int](1)!; or, in a more expanded form val a_prefix_sum: Array[Int](1){self.home==this.home}; This says that the home place of the object the field refers to (self.home) must be the same as the home place of the object that contains the field (this.home). The compiler will statically verify that fact. Since you always initialize that field with a new object created in the constructor, the compiler knows that it must have been created at the place where the enclosing object is being constructed, so you don't have to change anything else in the code. Incidentally, this is a classic example of an underspecified type: the type you specify is a supertype of the type you actually need. However, while the type is underspecified, it is essentially harmless, because the parts of the program we discussed so far do access the object in the correct place, even if the static type information does not reflect that. Your original issue is different. You are invoking place_str() in a place that is not the home place of the enclosing object, and thus the dynamic check (which the compiler inserted for you) fails. When compiling with -STATIC_CALLS, you will get a (legitimate) static error at that point. If you intend to call a method from a place that is not the home place of the object, you need to mark it "global". You also need to ensure that all the data it accesses is either also marked "global", or retrieved via an "at (this)" (same as "at (this.home)"). In your particular case, the method place_str() should be global, as should the field a_prefix_sum. Note that you may have more errors of this kind in the parts of the program that you have not posted to the list. Please address them accordingly. The rule of thumb is that once you start writing multi-place code, you should stop relying on the compiler to insert the dynamic checks for you, but instead bite the bullet, build with -STATIC_CALLS, and fix the errors. Hope this helps, Igor Dave Hudak <dhu...@osc.edu> wrote on 07/30/2010 09:10:49 AM: > Hi Igor (and all), > > Here is the output from the compiler: > > dhu...@oscnet166 125%> x10c++ -STATIC_CALLS -o Driver Driver.x10 > PrefixSum.x10 AsyncPrefixSum.x10 DistPrefixSum.x10 > /Users/dhudak/osc/research/x10/tutorial/examples/GoodPrefixSum/src/AsyncPrefixSum. > x10:48: Place type error: either method target should be local or > method should be global. > Method target: AsyncPrefixSum.this.a_prefix_sum > Method target place: null > Current place: AsyncPrefixSum#this.home > Method: size > /Users/dhudak/osc/research/x10/tutorial/examples/GoodPrefixSum/src/AsyncPrefixSum. > x10:49: Place type error: either method target should be local or > method should be global. > Method target: AsyncPrefixSum.this.a_prefix_sum > Method target place: null > Current place: AsyncPrefixSum#this.home > Method: size > /Users/dhudak/osc/research/x10/tutorial/examples/GoodPrefixSum/src/PrefixSum. > x10:42: Place type error: either method target should be local or > method should be global. > Method target: PrefixSum.this.a_prefix_sum > Method target place: null > Current place: PrefixSum#this.home > Method: size > /Users/dhudak/osc/research/x10/tutorial/examples/GoodPrefixSum/src/DistPrefixSum. > x10:61: Place type error: either method target should be local or > method should be global. > Method target: DistPrefixSum.this > Method target place: null > Current place: p > Method: place_str > 4 errors. > > Let's focus on the third error, since that is from the "easiest" > implementation (single activity, single place). The code is attached. > I think my problem boils down to a lack of understanding about > referencing an object's fields and exactly what "this" means. > > I start out by declaring a class whose objects will allocate an array. > I provide 3 constructors (a default and 2 initialization > constructors). Constructors seem to use "this" for their definition - > is that correct? > > public class PrefixSum { > > val a_prefix_sum: Array[Int](1); > > public def this() { > a_prefix_sum = new Array[Int]([1..2], (Point)=>0); > } > > public def this(length:Int) { > a_prefix_sum = new Array[Int]([1..length], (Point)=>0); > for ((i) in a_prefix_sum) { > a_prefix_sum([i]) = i; > } > } > > public def this(a:Array[Int](1)) > { > a_prefix_sum = new Array[Int](a.region, (Point)=>0); > for ((i) in a_prefix_sum) { > a_prefix_sum([i]) = a([i]); > } > } > > ...then, I get the following error on the following code: > > /Users/dhudak/osc/research/x10/tutorial/examples/GoodPrefixSum/src/PrefixSum. > x10:42: Place type error: either method target should be local or > method should be global. > Method target: PrefixSum.this.a_prefix_sum > Method target place: null > Current place: PrefixSum#this.home > Method: size > > public def str_end():String > { > return a_prefix_sum([a_prefix_sum.size()]).toString(); > } > > So, it looks like accessing the "size" field of a_prefix_sum goes > through "this" - which is the class PrefixSum??? > > Thanks, > Dave > > > On Jul 29, 2010, at 3:08 PM, Igor Peshansky wrote: > > > Hi, Dave, > > > > You're accessing a field (or calling a method) of a remote object > > reference. If you ran the compiler with the -STATIC_CALLS flag, > > you would have gotten a compile-time error. As it is, the > > compiler inserts a dynamic check for you, which then fails at > > runtime. > > > > Try compiling your program with -STATIC_CALLS, and see what the > > compiler reports. > > > > Hope this helps, > > Igor > > P.S. Judging by your stack trace, you seem to be running on a Mac. > > There was a bug with printing Mac stack traces in X10 2.0.5 which > > is fixed in SVN HEAD (so it will work better in the next release). > > > > Dave Hudak <dhu...@osc.edu> wrote on 07/29/2010 12:53:18 PM: > > > >> Hi All, > >> > >> I took Igor's advice on using a cell to pass results back to the > >> calling place. I recoded my function for translating a distarray into > >> a string as follows. The "boo/hoo" statements are line counters: > >> > >> public def place_str(): String > >> { > >> Console.OUT.println("hoo"); > >> var s : String = ""; //var is mutable > >> Console.OUT.println("hoo1"); > >> var first : Boolean = true; //var > >> declaration must include type > >> Console.OUT.println("place_str "+here.id); > >> for (pt in a_prefix_sum | here) { > >> if (first) { > >> first = false; > >> } > >> else { > >> s += ", "; > >> } > >> Console.OUT.println("place_str point = "+pt); > >> s += a_prefix_sum(pt).toString(); //works because > >> toString is global > >> } > >> return s; > >> } > >> > >> public def str():String > >> { > >> var s : String = ""; //var is mutable > >> for (p in a_prefix_sum.dist.places()) { > >> Console.OUT.println("str "+p.id); > >> val z = new Cell[String](null); > >> Console.OUT.println("boo"); > >> val h = here; > >> Console.OUT.println("boo2"); > >> at (p) { > >> Console.OUT.println("boo3"); > >> val q = place_str(); > >> Console.OUT.println("boo4"); > >> at (h) z.set(q); > >> Console.OUT.println("boo5"); > >> } > >> s += z(); > >> if (p.id != (Place.MAX_PLACES - 1)) { > >> s += ", "; > >> } //if > >> Console.OUT.println("s = "+s); > >> } //for i > >> return s; > >> } > >> > >> I am causing an exception when I call the place_str method from any > >> place other that place 0. Here is the output: > >> > >> dhu...@oscnet166 77%> mpirun -np 8 Driver > >> <...snip> > >> str 0 > >> boo > >> boo2 > >> boo3 > >> hoo > >> hoo1 > >> place_str 0 > >> place_str point = (1) > >> place_str point = (2) > >> place_str point = (3) > >> place_str point = (4) > >> boo4 > >> boo5 > >> s = 1, 2, 3, 4, > >> str 1 > >> boo > >> boo2 > >> boo3 > >> Uncaught exception at place 0: x10.lang.ClassCastException (home==1): > >> DistPrefixSum{self.home==here} > >> x10.lang.ClassCastException (home==1): DistPrefixSum{self.home==here} > >> at x10::lang::Throwable::fillInStackTrace() > >> > >> Any ideas? > >> > >> Thanks, > >> Dave > >> On Jul 28, 2010, at 8:05 PM, Igor Peshansky wrote: > >> > >>> Igor Peshansky/Watson/i...@ibmus wrote on 07/28/2010 07:15:02 PM: > >>> > >>>> Dave Hudak <dhu...@osc.edu> wrote on 07/28/2010 02:37:22 PM: > >>>> > >>>>> Hi All, > >>>>> > >>>>> I am trying to write a class that will do a prefix sum on an array. > > I > >>>>> have written the single-place version and a single-place version > > that > >>>>> uses multiple activities to compute the sums. I am now trying to > >>>>> write the distributed version. Both classes are included (I will > >>>>> eventually write an interface for these classes). > >>>>> > >>>>> I have been able to write the constructors and call them without > > run- > >>>>> time exceptions occurring. Now, I want to write a function that > >>>>> returns a single string representation of a dist array. I wrote a > >>>>> function that should create a string representation of all dist > > array > >>>>> elements at a given location (I called it place_str), and then I > > want > >>>>> to loop over all places: > >>>>> > >>>>> (from DistPrefixSum.x10): > >>>>> > >>>>> public def str():String > >>>>> { > >>>>> var s : String = ""; //var is mutable > >>>>> for (var place_id:int=0; place_id<Place.MAX_PLACES; place_id++) > > > >>> { > >>>>> s += at (Place.places(place_id)) place_str(); > >>>>> if (place_id != (Place.MAX_PLACES - 1)) { > >>>>> s += ", "; > >>>>> } //if > >>>>> } //for i > >>>>> return s; > >>>>> } > >>>>> > >>>>> My error occurs on the at statement: > >>>>> > >>>>> dhu...@oscnet166 35%> x10c++ -O -o Driver Driver.x10 PrefixSum.x10 > >>>>> AsyncPrefixSum.x10 DistPrefixSum.x10 > >>>>> > >>>> > >>> > >> > > > /Users/dhudak/osc/research/x10/tutorial/examples/GoodPrefixSum/src/DistPrefixSum. > >>>>> x10:49: Local variable "place_id" is accessed from an inner class or > > a > >>>>> closure, and must be declared final or shared. > >>>>> 1 error. > >>>>> > >>>>> Does anyone have any recommendations? Creating a single string from > > a > >>>>> dist array of integers is a reduction just like finding the sum or > > max > >>>>> of the entries, so I figure its well understood... > >>>> > >>>> Dave, > >>>> > >>>> This is a bug in the typechecking of at expressions. You can work > >>> around > >>>> this by changing the body of the for loop to > >>>> > >>>> val z = new Cell[String](null); > >>>> val h = here; > >>>> at (Place.places(place_id)) { val q = place_str(); at (h) > >>> z.set(q); > >>>> } > >>>> s += z(); > >>>> if (place_id != (Place.MAX_PLACES - 1)) { > >>>> s += ", "; > >>>> } //if > >>>> > >>>> The above code is less efficient, but it should work. > >>>> I've opened a JIRA issue: > > http://jira.codehaus.org/browse/XTENLANG-1632 > >>> . > >>>> Please watch that issue for updates on the fix. > >>>> Igor > >>> > >>> Dave, > >>> > >>> The fix turned out to be simple. This is now fixed in SVN HEAD > > (r15224), > >>> and will be available in the next X10 release (or you can build from > > SVN > >>> to pick up the fix). > >>> Igor -- Igor Peshansky (note the spelling change!) IBM T.J. Watson Research Center X10: Parallel Productivity and Performance (http://x10-lang.org/) XJ: No More Pain for XML's Gain (http://www.research.ibm.com/xj/) "I hear and I forget. I see and I remember. I do and I understand" -- Confucius ------------------------------------------------------------------------------ The Palm PDK Hot Apps Program offers developers who use the Plug-In Development Kit to bring their C/C++ apps to Palm for a share of $1 Million in cash or HP Products. Visit us here for more details: http://p.sf.net/sfu/dev2dev-palm _______________________________________________ X10-users mailing list X10-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/x10-users