mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 09:40:21 +00:00
Add the X10 language (http://x10-lang.org/).
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -674,3 +674,6 @@
|
|||||||
[submodule "vendor/grammars/sublime-typescript"]
|
[submodule "vendor/grammars/sublime-typescript"]
|
||||||
path = vendor/grammars/sublime-typescript
|
path = vendor/grammars/sublime-typescript
|
||||||
url = https://github.com/Microsoft/TypeScript-Sublime-Plugin
|
url = https://github.com/Microsoft/TypeScript-Sublime-Plugin
|
||||||
|
[submodule "vendor/grammars/X10"]
|
||||||
|
path = vendor/grammars/X10
|
||||||
|
url = git@github.com:x10-lang/x10-highlighting.git
|
||||||
|
|||||||
@@ -144,6 +144,8 @@ vendor/grammars/VBDotNetSyntax:
|
|||||||
- source.vbnet
|
- source.vbnet
|
||||||
vendor/grammars/Vala-TMBundle:
|
vendor/grammars/Vala-TMBundle:
|
||||||
- source.vala
|
- source.vala
|
||||||
|
vendor/grammars/X10:
|
||||||
|
- source.x10
|
||||||
vendor/grammars/abap.tmbundle:
|
vendor/grammars/abap.tmbundle:
|
||||||
- source.abap
|
- source.abap
|
||||||
vendor/grammars/actionscript3-tmbundle:
|
vendor/grammars/actionscript3-tmbundle:
|
||||||
|
|||||||
@@ -3567,6 +3567,16 @@ WebIDL:
|
|||||||
tm_scope: source.webidl
|
tm_scope: source.webidl
|
||||||
ace_mode: text
|
ace_mode: text
|
||||||
|
|
||||||
|
X10:
|
||||||
|
type: programming
|
||||||
|
aliases:
|
||||||
|
- xten
|
||||||
|
ace_mode: text
|
||||||
|
extensions:
|
||||||
|
- .x10
|
||||||
|
color: "#4B6BEF"
|
||||||
|
tm_scope: source.x10
|
||||||
|
|
||||||
XC:
|
XC:
|
||||||
type: programming
|
type: programming
|
||||||
color: "#99DA07"
|
color: "#99DA07"
|
||||||
|
|||||||
72
samples/X10/ArraySum.x10
Normal file
72
samples/X10/ArraySum.x10
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import x10.io.Console;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple illustration of loop parallelization within a single place.
|
||||||
|
*/
|
||||||
|
public class ArraySum {
|
||||||
|
|
||||||
|
var sum:Long;
|
||||||
|
val data:Rail[Long];
|
||||||
|
|
||||||
|
public def this(n:Long) {
|
||||||
|
// Create a Rail with n elements (0..(n-1)), all initialized to 1.
|
||||||
|
data = new Rail[Long](n, 1);
|
||||||
|
sum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
def sum(a:Rail[Long], start:Long, last:Long) {
|
||||||
|
var mySum: Long = 0;
|
||||||
|
for (i in start..(last-1)) {
|
||||||
|
mySum += a(i);
|
||||||
|
}
|
||||||
|
return mySum;
|
||||||
|
}
|
||||||
|
|
||||||
|
def sum(numThreads:Long) {
|
||||||
|
val mySize = data.size/numThreads;
|
||||||
|
finish for (p in 0..(numThreads-1)) async {
|
||||||
|
val mySum = sum(data, p*mySize, (p+1)*mySize);
|
||||||
|
// Multiple activities will simultaneously update
|
||||||
|
// this location -- so use an atomic operation.
|
||||||
|
atomic sum += mySum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static def main(args:Rail[String]) {
|
||||||
|
var size:Long = 5*1000*1000;
|
||||||
|
if (args.size >=1)
|
||||||
|
size = Long.parse(args(0));
|
||||||
|
|
||||||
|
Console.OUT.println("Initializing.");
|
||||||
|
val a = new ArraySum(size);
|
||||||
|
val P = [1,2,4];
|
||||||
|
|
||||||
|
//warmup loop
|
||||||
|
Console.OUT.println("Warming up.");
|
||||||
|
for (numThreads in P)
|
||||||
|
a.sum(numThreads);
|
||||||
|
|
||||||
|
for (numThreads in P) {
|
||||||
|
Console.OUT.println("Starting with " + numThreads + " threads.");
|
||||||
|
a.sum=0;
|
||||||
|
var time: long = - System.nanoTime();
|
||||||
|
a.sum(numThreads);
|
||||||
|
time += System.nanoTime();
|
||||||
|
Console.OUT.println("For p=" + numThreads
|
||||||
|
+ " result: " + a.sum
|
||||||
|
+ ((size==a.sum)? " ok" : " bad")
|
||||||
|
+ " (time=" + (time/(1000*1000)) + " ms)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
50
samples/X10/Cancellation.x10
Normal file
50
samples/X10/Cancellation.x10
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import x10.xrx.Runtime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Demonstrate how to instantiate the X10 runtime as an executor service
|
||||||
|
* submit jobs to the runtime, wait jobs to complete and cancel all jobs
|
||||||
|
*
|
||||||
|
* Compile with: x10c -O -EXECUTOR_MODE=true Cancellation.x10
|
||||||
|
* Run with: X10_CANCELLABLE=true X10_NPLACES=4 x10 -DX10RT_IMPL=JavaSockets Cancellation
|
||||||
|
*/
|
||||||
|
class Cancellation {
|
||||||
|
static def job(id:Long, iterations:Long) = ()=>{
|
||||||
|
at (Place.places().next(here)) async {
|
||||||
|
for (i in 1..iterations) {
|
||||||
|
finish for (p in Place.places()) {
|
||||||
|
at (p) async Console.OUT.println(here+" says hello (job " + id + ", iteration " + i + ")");
|
||||||
|
}
|
||||||
|
Console.ERR.println();
|
||||||
|
System.sleep(200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static def main(args:Rail[String]):void {
|
||||||
|
val w1 = Runtime.submit(job(1, 5));
|
||||||
|
w1.await(); Console.ERR.println("Job 1 completed\n");
|
||||||
|
val w2 = Runtime.submit(job(2, 1000));
|
||||||
|
System.threadSleep(1000);
|
||||||
|
val c1 = Runtime.cancelAll();
|
||||||
|
try { w2.await(); } catch (e:Exception) { Console.ERR.println("Job 2 aborted with exception " + e +"\n"); }
|
||||||
|
c1.await(); // waiting for cancellation to be processed
|
||||||
|
System.threadSleep(1000);
|
||||||
|
Runtime.submit(job(3, 1000));
|
||||||
|
Runtime.submit(job(4, 1000));
|
||||||
|
System.threadSleep(1000);
|
||||||
|
val c2 = Runtime.cancelAll();
|
||||||
|
c2.await();
|
||||||
|
Console.ERR.println("Goodbye\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
52
samples/X10/Fibonacci.x10
Normal file
52
samples/X10/Fibonacci.x10
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import x10.io.Console;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a small program to illustrate the use of
|
||||||
|
* <code>async</code> and <code>finish</code> in a
|
||||||
|
* prototypical recursive divide-and-conquer algorithm.
|
||||||
|
* It is obviously not intended to show a efficient way to
|
||||||
|
* compute Fibonacci numbers in X10.<p>
|
||||||
|
*
|
||||||
|
* The heart of the example is the <code>run</code> method,
|
||||||
|
* which directly embodies the recursive definition of
|
||||||
|
* <pre>
|
||||||
|
* fib(n) = fib(n-1)+fib(n-2);
|
||||||
|
* </pre>
|
||||||
|
* by using an <code>async</code> to compute <code>fib(n-1)</code> while
|
||||||
|
* the current activity computes <code>fib(n-2)</code>. A <code>finish</code>
|
||||||
|
* is used to ensure that both computations are complete before
|
||||||
|
* their results are added together to compute <code>fib(n)</code>
|
||||||
|
*/
|
||||||
|
public class Fibonacci {
|
||||||
|
|
||||||
|
public static def fib(n:long) {
|
||||||
|
if (n<=2) return 1;
|
||||||
|
|
||||||
|
val f1:long;
|
||||||
|
val f2:long;
|
||||||
|
finish {
|
||||||
|
async { f1 = fib(n-1); }
|
||||||
|
f2 = fib(n-2);
|
||||||
|
}
|
||||||
|
return f1 + f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static def main(args:Rail[String]) {
|
||||||
|
val n = (args.size > 0) ? Long.parse(args(0)) : 10;
|
||||||
|
Console.OUT.println("Computing fib("+n+")");
|
||||||
|
val f = fib(n);
|
||||||
|
Console.OUT.println("fib("+n+") = "+f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
86
samples/X10/HeatTransfer_v0.x10
Normal file
86
samples/X10/HeatTransfer_v0.x10
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import x10.array.*;
|
||||||
|
import x10.compiler.Foreach;
|
||||||
|
import x10.compiler.Inline;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a sample program illustrating how to use
|
||||||
|
* X10's array classes. It also illustrates the use
|
||||||
|
* of foreach to acheive intra-place parallelism.
|
||||||
|
*
|
||||||
|
* The program solves a set of 2D partial differential
|
||||||
|
* equations by iteratively applying a 5-point stencil
|
||||||
|
* operation until convergence is reached.
|
||||||
|
*/
|
||||||
|
public class HeatTransfer_v0 {
|
||||||
|
static val EPSILON = 1.0e-5;
|
||||||
|
|
||||||
|
val N:Long;
|
||||||
|
val A:Array_2[Double]{self!=null};
|
||||||
|
val Tmp:Array_2[Double]{self!=null};
|
||||||
|
|
||||||
|
public def this(size:Long) {
|
||||||
|
N = size;
|
||||||
|
A = new Array_2[Double](N+2, N+2); // zero-initialized N+2 * N+2 array of doubles
|
||||||
|
for (j in 1..N) A(0, j) = 1; // set one border row to 1
|
||||||
|
Tmp = new Array_2[Double](A);
|
||||||
|
}
|
||||||
|
|
||||||
|
final @Inline def stencil(x:Long, y:Long):Double {
|
||||||
|
return (A(x-1,y) + A(x+1,y) + A(x,y-1) + A(x,y+1)) / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
def run() {
|
||||||
|
val is = new DenseIterationSpace_2(1,1,N,N);
|
||||||
|
var delta:Double;
|
||||||
|
do {
|
||||||
|
// Compute new values, storing in tmp
|
||||||
|
delta = Foreach.blockReduce(is,
|
||||||
|
(i:Long, j:Long)=>{
|
||||||
|
Tmp(i,j) = stencil(i,j);
|
||||||
|
// Reduce max element-wise delta (A now holds previous values)
|
||||||
|
return Math.abs(Tmp(i,j) - A(i,j));
|
||||||
|
},
|
||||||
|
(a:Double, b:Double)=>Math.max(a,b), 0.0
|
||||||
|
);
|
||||||
|
|
||||||
|
// swap backing data of A and Tmp
|
||||||
|
Array.swap(A, Tmp);
|
||||||
|
} while (delta > EPSILON);
|
||||||
|
}
|
||||||
|
|
||||||
|
def prettyPrintResult() {
|
||||||
|
for (i in 1..N) {
|
||||||
|
for (j in 1..N) {
|
||||||
|
Console.OUT.printf("%1.4f ",A(i,j));
|
||||||
|
}
|
||||||
|
Console.OUT.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static def main(args:Rail[String]) {
|
||||||
|
val n = args.size > 0 ? Long.parse(args(0)) : 8;
|
||||||
|
Console.OUT.println("HeatTransfer example with N="+n+" and epsilon="+EPSILON);
|
||||||
|
Console.OUT.println("Initializing data structures");
|
||||||
|
val ht = new HeatTransfer_v0(n);
|
||||||
|
Console.OUT.println("Beginning computation...");
|
||||||
|
val start = System.nanoTime();
|
||||||
|
ht.run();
|
||||||
|
val stop = System.nanoTime();
|
||||||
|
Console.OUT.printf("...completed in %1.3f seconds.\n", ((stop-start) as double)/1e9);
|
||||||
|
if (n <= 10) {
|
||||||
|
ht.prettyPrintResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
114
samples/X10/HeatTransfer_v1.x10
Normal file
114
samples/X10/HeatTransfer_v1.x10
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import x10.array.*;
|
||||||
|
import x10.compiler.Foreach;
|
||||||
|
import x10.util.Team;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a sample program illustrating how to use
|
||||||
|
* X10's distributed array classes. It also illustrates the use
|
||||||
|
* of foreach to achieve intra-place parallelism and the mixture
|
||||||
|
* of APGAS finish/async/at with Team collective operations.
|
||||||
|
*
|
||||||
|
* This version of the program uses a vanilla DistArray without
|
||||||
|
* ghost regions. As a result, the stencil function does
|
||||||
|
* inefficient fine-grained neighbor communication to get individual values.
|
||||||
|
* Compare this to HeatTransfer_v2 which utilizes ghost regions and
|
||||||
|
* bulk ghost-region exchange functions.
|
||||||
|
*
|
||||||
|
* The program solves a set of 2D partial differential
|
||||||
|
* equations by iteratively applying a 5-point stencil
|
||||||
|
* operation until convergence is reached.
|
||||||
|
*/
|
||||||
|
public class HeatTransfer_v1 {
|
||||||
|
static val EPSILON = 1.0e-5;
|
||||||
|
|
||||||
|
val N:Long;
|
||||||
|
val A:DistArray_BlockBlock_2[Double]{self!=null};
|
||||||
|
val Tmp:DistArray_BlockBlock_2[Double]{self!=null};
|
||||||
|
|
||||||
|
public def this(size:Long) {
|
||||||
|
N = size;
|
||||||
|
val init = (i:Long, j:Long)=>i==0 ? 1.0 : 0.0;
|
||||||
|
A = new DistArray_BlockBlock_2[Double](N+2, N+2, init);
|
||||||
|
Tmp = new DistArray_BlockBlock_2[Double](N+2, N+2, init);
|
||||||
|
}
|
||||||
|
|
||||||
|
final def stencil(x:Long, y:Long):Double {
|
||||||
|
val cls = (dx:Long, dy:Long)=>{
|
||||||
|
val p = A.place(x+dx, y+dy);
|
||||||
|
p == here ? A(x+dx,y+dy) : at (p) A(x+dx,y+dy)
|
||||||
|
};
|
||||||
|
val tmp = cls(-1,0) + cls(1,0) + cls(0,-1) + cls(0,1);
|
||||||
|
return tmp / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
def run() {
|
||||||
|
val myTeam = new Team(A.placeGroup());
|
||||||
|
finish for (p in A.placeGroup()) at (p) async {
|
||||||
|
// Compute the subset of the local indices on which
|
||||||
|
// we want to apply the stencil (the interior points of the N+2 x N+2 grid)
|
||||||
|
val li = A.localIndices();
|
||||||
|
val interior = new DenseIterationSpace_2(li.min(0) == 0 ? 1 : li.min(0),
|
||||||
|
li.min(1) == 0 ? 1 : li.min(1),
|
||||||
|
li.max(0) == N+1 ? N : li.max(0),
|
||||||
|
li.max(1) == N+1 ? N : li.max(1));
|
||||||
|
var delta:Double;
|
||||||
|
do {
|
||||||
|
// Compute new values, storing in tmp
|
||||||
|
val myDelta = Foreach.blockReduce(interior,
|
||||||
|
(i:Long, j:Long)=>{
|
||||||
|
Tmp(i,j) = stencil(i,j);
|
||||||
|
// Reduce max element-wise delta (A now holds previous values)
|
||||||
|
return Math.abs(Tmp(i,j) - A(i,j));
|
||||||
|
},
|
||||||
|
(a:Double, b:Double)=>Math.max(a,b), 0.0
|
||||||
|
);
|
||||||
|
|
||||||
|
myTeam.barrier();
|
||||||
|
|
||||||
|
// Unlike Array, DistArray doesn't provide an optimized swap.
|
||||||
|
// So, until it does, we have to copy the data elements.
|
||||||
|
Foreach.block(interior, (i:Long, j:Long)=>{
|
||||||
|
A(i,j) = Tmp(i,j);
|
||||||
|
});
|
||||||
|
|
||||||
|
delta = myTeam.allreduce(myDelta, Team.MAX);
|
||||||
|
} while (delta > EPSILON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def prettyPrintResult() {
|
||||||
|
for (i in 1..N) {
|
||||||
|
for (j in 1..N) {
|
||||||
|
val x = at (A.place(i,j)) A(i,j);
|
||||||
|
Console.OUT.printf("%1.4f ", x);
|
||||||
|
}
|
||||||
|
Console.OUT.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static def main(args:Rail[String]) {
|
||||||
|
val n = args.size > 0 ? Long.parse(args(0)) : 8;
|
||||||
|
Console.OUT.println("HeatTransfer example with N="+n+" and epsilon="+EPSILON);
|
||||||
|
Console.OUT.println("Initializing data structures");
|
||||||
|
val ht = new HeatTransfer_v1(n);
|
||||||
|
Console.OUT.println("Beginning computation...");
|
||||||
|
val start = System.nanoTime();
|
||||||
|
ht.run();
|
||||||
|
val stop = System.nanoTime();
|
||||||
|
Console.OUT.printf("...completed in %1.3f seconds.\n", ((stop-start) as double)/1e9);
|
||||||
|
if (n <= 10) {
|
||||||
|
ht.prettyPrintResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
44
samples/X10/HelloWholeWorld.x10
Normal file
44
samples/X10/HelloWholeWorld.x10
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import x10.io.Console;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The classic hello world program, with a twist - prints a message
|
||||||
|
* from the command line at every Place.
|
||||||
|
* The messages from each Place may appear in any order, but the
|
||||||
|
* finish ensures that the last message printed will be "Goodbye"
|
||||||
|
* <pre>
|
||||||
|
* Typical output:
|
||||||
|
* [dgrove@linchen samples]$ ./HelloWholeWorld 'best wishes'
|
||||||
|
* Place(1) says hello and best wishes
|
||||||
|
* Place(2) says hello and best wishes
|
||||||
|
* Place(3) says hello and best wishes
|
||||||
|
* Place(0) says hello and best wishes
|
||||||
|
* Goodbye
|
||||||
|
* [dgrove@linchen samples]$
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
class HelloWholeWorld {
|
||||||
|
public static def main(args:Rail[String]):void {
|
||||||
|
if (args.size < 1) {
|
||||||
|
Console.OUT.println("Usage: HelloWholeWorld message");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
finish for (p in Place.places()) {
|
||||||
|
at (p) async Console.OUT.println(here+" says hello and "+args(0));
|
||||||
|
}
|
||||||
|
Console.OUT.println("Goodbye");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
23
samples/X10/HelloWorld.x10
Normal file
23
samples/X10/HelloWorld.x10
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import x10.io.Console;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The classic hello world program, shows how to output to the console.
|
||||||
|
*/
|
||||||
|
class HelloWorld {
|
||||||
|
public static def main(Rail[String]) {
|
||||||
|
Console.OUT.println("Hello World!" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
45
samples/X10/Histogram.x10
Normal file
45
samples/X10/Histogram.x10
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Histogram {
|
||||||
|
public static def compute(data:Rail[Int], numBins:Int) {
|
||||||
|
val bins = new Rail[Int](numBins);
|
||||||
|
finish for (i in data.range) async {
|
||||||
|
val b = data(i) % numBins;
|
||||||
|
atomic bins(b)++;
|
||||||
|
}
|
||||||
|
return bins;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static def run(N:Int, S:Int):Boolean {
|
||||||
|
val a = new Rail[Int](N, (i:long)=> i as int);
|
||||||
|
val b = compute(a, S);
|
||||||
|
val v = b(0);
|
||||||
|
var ok:Boolean = true;
|
||||||
|
for (x in b.range) ok &= (b(x)==v);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static def main(args:Rail[String]) {
|
||||||
|
if (args.size != 2L) {
|
||||||
|
Console.OUT.println("Usage: Histogram SizeOfArray NumberOfBins");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
val N = Int.parse(args(0));
|
||||||
|
val S = Int.parse(args(1));
|
||||||
|
val ok = run(N,S);
|
||||||
|
if (ok) {
|
||||||
|
Console.OUT.println("Test ok.");
|
||||||
|
} else {
|
||||||
|
Console.OUT.println("Test failed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
55
samples/X10/Integrate.x10
Normal file
55
samples/X10/Integrate.x10
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a slightly more realistic example of the
|
||||||
|
* basic computational pattern of using async/finish
|
||||||
|
* to express recursive divide-and-conquer algorithms.
|
||||||
|
* The program does integration via Guassian Quadrature.
|
||||||
|
* <p>
|
||||||
|
* It also can serve as an example of using a closure.
|
||||||
|
*/
|
||||||
|
public class Integrate {
|
||||||
|
static val epsilon = 1.0e-9;
|
||||||
|
|
||||||
|
val fun:(double)=>double;
|
||||||
|
|
||||||
|
public def this(f:(double)=>double) { fun = f; }
|
||||||
|
|
||||||
|
public def computeArea(left:double, right:double) {
|
||||||
|
return recEval(left, fun(left), right, fun(right), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private def recEval(l:double, fl:double, r:double, fr:double, a:double) {
|
||||||
|
val h = (r - l) / 2;
|
||||||
|
val hh = h / 2;
|
||||||
|
val c = l + h;
|
||||||
|
val fc = fun(c);
|
||||||
|
val al = (fl + fc) * hh;
|
||||||
|
val ar = (fr + fc) * hh;
|
||||||
|
val alr = al + ar;
|
||||||
|
if (Math.abs(alr - a) < epsilon) return alr;
|
||||||
|
val expr1:double;
|
||||||
|
val expr2:double;
|
||||||
|
finish {
|
||||||
|
async { expr1 = recEval(c, fc, r, fr, ar); };
|
||||||
|
expr2 = recEval(l, fl, c, fc, al);
|
||||||
|
}
|
||||||
|
return expr1 + expr2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static def main(args:Rail[String]) {
|
||||||
|
val obj = new Integrate((x:double)=>(x*x + 1.0) * x);
|
||||||
|
val xMax = args.size > 0 ? Long.parse(args(0)) : 10;
|
||||||
|
val area = obj.computeArea(0, xMax);
|
||||||
|
Console.OUT.println("The area of (x*x +1) * x from 0 to "+xMax+" is "+area);
|
||||||
|
}
|
||||||
|
}
|
||||||
151
samples/X10/KMeans.x10
Normal file
151
samples/X10/KMeans.x10
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import x10.io.Console;
|
||||||
|
import x10.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A KMeans object o can compute K means of a given set of
|
||||||
|
* points of dimension o.myDim.
|
||||||
|
* <p>
|
||||||
|
* This class implements a sequential program, that is readily parallelizable.
|
||||||
|
*
|
||||||
|
* For a scalable, high-performance version of this benchmark see
|
||||||
|
* KMeans.x10 in the X10 Benchmarks (separate download from x10-lang.org)
|
||||||
|
*/
|
||||||
|
public class KMeans(myDim:Long) {
|
||||||
|
|
||||||
|
static val DIM=2;
|
||||||
|
static val K=4;
|
||||||
|
static val POINTS=2000;
|
||||||
|
static val ITERATIONS=50;
|
||||||
|
static val EPS=0.01F;
|
||||||
|
|
||||||
|
static type ValVector(k:Long) = Rail[Float]{self.size==k};
|
||||||
|
static type ValVector = ValVector(DIM);
|
||||||
|
|
||||||
|
static type Vector(k:Long) = Rail[Float]{self.size==k};
|
||||||
|
static type Vector = Vector(DIM);
|
||||||
|
|
||||||
|
static type SumVector(d:Long) = V{self.dim==d};
|
||||||
|
static type SumVector = SumVector(DIM);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* V represents the sum of 'count' number of vectors of dimension 'dim'.
|
||||||
|
*/
|
||||||
|
static class V(dim:Long) implements (Long)=>Float {
|
||||||
|
var vec: Vector(dim);
|
||||||
|
var count:Int;
|
||||||
|
def this(dim:Long, init:(Long)=>Float): SumVector(dim) {
|
||||||
|
property(dim);
|
||||||
|
vec = new Rail[Float](this.dim, init);
|
||||||
|
count = 0n;
|
||||||
|
}
|
||||||
|
public operator this(i:Long) = vec(i);
|
||||||
|
def makeZero() {
|
||||||
|
for (i in 0..(dim-1))
|
||||||
|
vec(i) =0.0F;
|
||||||
|
count=0n;
|
||||||
|
}
|
||||||
|
def addIn(a:ValVector(dim)) {
|
||||||
|
for (i in 0..(dim-1))
|
||||||
|
vec(i) += a(i);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
def div(f:Int) {
|
||||||
|
for (i in 0..(dim-1))
|
||||||
|
vec(i) /= f;
|
||||||
|
}
|
||||||
|
def dist(a:ValVector(dim)):Float {
|
||||||
|
var dist:Float=0.0F;
|
||||||
|
for (i in 0..(dim-1)) {
|
||||||
|
val tmp = vec(i)-a(i);
|
||||||
|
dist += tmp*tmp;
|
||||||
|
}
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
def dist(a:SumVector(dim)):Float {
|
||||||
|
var dist:Float=0.0F;
|
||||||
|
for (i in 0..(dim-1)) {
|
||||||
|
val tmp = vec(i)-a(i);
|
||||||
|
dist += tmp*tmp;
|
||||||
|
}
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
def print() {
|
||||||
|
Console.OUT.println();
|
||||||
|
for (i in 0..(dim-1)) {
|
||||||
|
Console.OUT.print((i>0? " " : "") + vec(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def normalize() { div(count);}
|
||||||
|
def count() = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def this(myDim:Long):KMeans{self.myDim==myDim} {
|
||||||
|
property(myDim);
|
||||||
|
}
|
||||||
|
static type KMeansData(myK:Long, myDim:Long)= Rail[SumVector(myDim)]{self.size==myK};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute myK means for the given set of points of dimension myDim.
|
||||||
|
*/
|
||||||
|
def computeMeans(myK:Long, points:Rail[ValVector(myDim)]):KMeansData(myK, myDim) {
|
||||||
|
var redCluster : KMeansData(myK, myDim) =
|
||||||
|
new Rail[SumVector(myDim)](myK, (i:long)=> new V(myDim, (j:long)=>points(i)(j)));
|
||||||
|
var blackCluster: KMeansData(myK, myDim) =
|
||||||
|
new Rail[SumVector(myDim)](myK, (i:long)=> new V(myDim, (j:long)=>0.0F));
|
||||||
|
for (i in 1..ITERATIONS) {
|
||||||
|
val tmp = redCluster;
|
||||||
|
redCluster = blackCluster;
|
||||||
|
blackCluster=tmp;
|
||||||
|
for (p in 0..(POINTS-1)) {
|
||||||
|
var closest:Long = -1;
|
||||||
|
var closestDist:Float = Float.MAX_VALUE;
|
||||||
|
val point = points(p);
|
||||||
|
for (k in 0..(myK-1)) { // compute closest mean in cluster.
|
||||||
|
val dist = blackCluster(k).dist(point);
|
||||||
|
if (dist < closestDist) {
|
||||||
|
closestDist = dist;
|
||||||
|
closest = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
redCluster(closest).addIn(point);
|
||||||
|
}
|
||||||
|
for (k in 0..(myK-1))
|
||||||
|
redCluster(k).normalize();
|
||||||
|
|
||||||
|
var b:Boolean = true;
|
||||||
|
for (k in 0..(myK-1)) {
|
||||||
|
if (redCluster(k).dist(blackCluster(k)) > EPS) {
|
||||||
|
b=false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (b)
|
||||||
|
break;
|
||||||
|
for (k in 0..(myK-1))
|
||||||
|
blackCluster(k).makeZero();
|
||||||
|
}
|
||||||
|
return redCluster;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static def main (Rail[String]) {
|
||||||
|
val rnd = new Random(0);
|
||||||
|
val points = new Rail[ValVector](POINTS,
|
||||||
|
(long)=>new Rail[Float](DIM, (long)=>rnd.nextFloat()));
|
||||||
|
val result = new KMeans(DIM).computeMeans(K, points);
|
||||||
|
for (k in 0..(K-1)) result(k).print();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: shiftwidth=4:tabstop=4:expandtab
|
||||||
147
samples/X10/KMeansDist.x10
Normal file
147
samples/X10/KMeansDist.x10
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import x10.array.*;
|
||||||
|
import x10.io.Console;
|
||||||
|
import x10.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A low performance formulation of distributed KMeans using fine-grained asyncs.
|
||||||
|
*
|
||||||
|
* For a highly optimized and scalable, version of this benchmark see
|
||||||
|
* KMeans.x10 in the X10 Benchmarks (separate download from x10-lang.org)
|
||||||
|
*/
|
||||||
|
public class KMeansDist {
|
||||||
|
|
||||||
|
static val DIM=2;
|
||||||
|
static val CLUSTERS=4;
|
||||||
|
static val POINTS=2000;
|
||||||
|
static val ITERATIONS=50;
|
||||||
|
|
||||||
|
public static def main (Rail[String]) {
|
||||||
|
val world = Place.places();
|
||||||
|
val local_curr_clusters =
|
||||||
|
PlaceLocalHandle.make[Array_2[Float]](world, () => new Array_2[Float](CLUSTERS, DIM));
|
||||||
|
val local_new_clusters =
|
||||||
|
PlaceLocalHandle.make[Array_2[Float]](world, () => new Array_2[Float](CLUSTERS, DIM));
|
||||||
|
val local_cluster_counts =
|
||||||
|
PlaceLocalHandle.make[Rail[Int]](world, ()=> new Rail[Int](CLUSTERS));
|
||||||
|
|
||||||
|
val rnd = PlaceLocalHandle.make[Random](world, () => new Random(0));
|
||||||
|
val points = new DistArray_Block_2[Float](POINTS, DIM, world, (Long,Long)=>rnd().nextFloat());
|
||||||
|
|
||||||
|
val central_clusters = new Array_2[Float](CLUSTERS, DIM, (i:Long, j:Long) => {
|
||||||
|
at (points.place(i,j)) points(i,j)
|
||||||
|
});
|
||||||
|
|
||||||
|
val old_central_clusters = new Array_2[Float](CLUSTERS, DIM);
|
||||||
|
|
||||||
|
val central_cluster_counts = new Rail[Int](CLUSTERS);
|
||||||
|
|
||||||
|
for (iter in 1..ITERATIONS) {
|
||||||
|
|
||||||
|
Console.OUT.println("Iteration: "+iter);
|
||||||
|
|
||||||
|
finish {
|
||||||
|
// reset state
|
||||||
|
for (d in world) at (d) async {
|
||||||
|
for ([i,j] in central_clusters.indices()) {
|
||||||
|
local_curr_clusters()(i, j) = central_clusters(i, j);
|
||||||
|
local_new_clusters()(i, j) = 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
local_cluster_counts().clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
finish {
|
||||||
|
// compute new clusters and counters
|
||||||
|
for (p in 0..(POINTS-1)) {
|
||||||
|
at (points.place(p,0)) async {
|
||||||
|
var closest:Long = -1;
|
||||||
|
var closest_dist:Float = Float.MAX_VALUE;
|
||||||
|
for (k in 0..(CLUSTERS-1)) {
|
||||||
|
var dist : Float = 0;
|
||||||
|
for (d in 0..(DIM-1)) {
|
||||||
|
val tmp = points(p,d) - local_curr_clusters()(k, d);
|
||||||
|
dist += tmp * tmp;
|
||||||
|
}
|
||||||
|
if (dist < closest_dist) {
|
||||||
|
closest_dist = dist;
|
||||||
|
closest = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
atomic {
|
||||||
|
for (d in 0..(DIM-1)) {
|
||||||
|
local_new_clusters()(closest,d) += points(p,d);
|
||||||
|
}
|
||||||
|
local_cluster_counts()(closest)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ([i,j] in old_central_clusters.indices()) {
|
||||||
|
old_central_clusters(i, j) = central_clusters(i, j);
|
||||||
|
central_clusters(i, j) = 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
central_cluster_counts.clear();
|
||||||
|
|
||||||
|
finish {
|
||||||
|
val central_clusters_gr = GlobalRef(central_clusters);
|
||||||
|
val central_cluster_counts_gr = GlobalRef(central_cluster_counts);
|
||||||
|
val there = here;
|
||||||
|
for (d in world) at (d) async {
|
||||||
|
// access PlaceLocalHandles 'here' and then data will be captured by at and transfered to 'there' for accumulation
|
||||||
|
val tmp_new_clusters = local_new_clusters();
|
||||||
|
val tmp_cluster_counts = local_cluster_counts();
|
||||||
|
at (there) atomic {
|
||||||
|
for ([i,j] in tmp_new_clusters.indices()) {
|
||||||
|
central_clusters_gr()(i,j) += tmp_new_clusters(i,j);
|
||||||
|
}
|
||||||
|
for (j in 0..(CLUSTERS-1)) {
|
||||||
|
central_cluster_counts_gr()(j) += tmp_cluster_counts(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k in 0..(CLUSTERS-1)) {
|
||||||
|
for (d in 0..(DIM-1)) {
|
||||||
|
central_clusters(k, d) /= central_cluster_counts(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TEST FOR CONVERGENCE
|
||||||
|
var b:Boolean = true;
|
||||||
|
for ([i,j] in old_central_clusters.indices()) {
|
||||||
|
if (Math.abs(old_central_clusters(i, j)-central_clusters(i, j))>0.0001) {
|
||||||
|
b = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (b) break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (d in 0..(DIM-1)) {
|
||||||
|
for (k in 0..(CLUSTERS-1)) {
|
||||||
|
if (k>0)
|
||||||
|
Console.OUT.print(" ");
|
||||||
|
Console.OUT.print(central_clusters(k,d));
|
||||||
|
}
|
||||||
|
Console.OUT.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: shiftwidth=4:tabstop=4:expandtab
|
||||||
144
samples/X10/KMeansDistPlh.x10
Normal file
144
samples/X10/KMeansDistPlh.x10
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2015.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import x10.array.Array;
|
||||||
|
import x10.array.Array_2;
|
||||||
|
import x10.compiler.Foreach;
|
||||||
|
import x10.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A better formulation of distributed KMeans using coarse-grained asyncs to
|
||||||
|
* implement an allreduce pattern for cluster centers and counts.
|
||||||
|
*
|
||||||
|
* For a highly optimized and scalable, version of this benchmark see
|
||||||
|
* KMeans.x10 in the X10 Benchmarks (separate download from x10-lang.org)
|
||||||
|
*/
|
||||||
|
public class KMeansDistPlh {
|
||||||
|
|
||||||
|
static val DIM=2;
|
||||||
|
static val CLUSTERS=4;
|
||||||
|
|
||||||
|
static class ClusterState {
|
||||||
|
val clusters = new Array_2[Float](CLUSTERS, DIM);
|
||||||
|
val clusterCounts = new Rail[Int](CLUSTERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static def main(args:Rail[String]) {
|
||||||
|
val numPoints = args.size > 0 ? Long.parse(args(0)) : 2000;
|
||||||
|
val iterations = args.size > 1 ? Long.parse(args(1)) : 50;
|
||||||
|
val world = Place.places();
|
||||||
|
|
||||||
|
val clusterStatePlh = PlaceLocalHandle.make[ClusterState](world, () => new ClusterState());
|
||||||
|
val currentClustersPlh = PlaceLocalHandle.make[Array_2[Float]](world, () => new Array_2[Float](CLUSTERS, DIM));
|
||||||
|
val pointsPlh = PlaceLocalHandle.make[Array_2[Float]](world, () => {
|
||||||
|
val rand = new Random(here.id);
|
||||||
|
return new Array_2[Float](numPoints/world.size(), DIM, (Long,Long)=>rand.nextFloat());
|
||||||
|
});
|
||||||
|
|
||||||
|
val centralCurrentClusters = new Array_2[Float](CLUSTERS, DIM);
|
||||||
|
val centralNewClusters = new Array_2[Float](CLUSTERS, DIM);
|
||||||
|
val centralClusterCounts = new Rail[Int](CLUSTERS);
|
||||||
|
|
||||||
|
// arbitrarily initialize central clusters to first few points
|
||||||
|
for ([i,j] in centralCurrentClusters.indices()) {
|
||||||
|
centralCurrentClusters(i,j) = pointsPlh()(i,j);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (iter in 1..iterations) {
|
||||||
|
Console.OUT.println("Iteration: "+iter);
|
||||||
|
|
||||||
|
finish {
|
||||||
|
for (place in world) async {
|
||||||
|
val placeClusters = at(place) {
|
||||||
|
val currentClusters = currentClustersPlh();
|
||||||
|
Array.copy(centralCurrentClusters, currentClusters);
|
||||||
|
|
||||||
|
val clusterState = clusterStatePlh();
|
||||||
|
val newClusters = clusterState.clusters;
|
||||||
|
newClusters.clear();
|
||||||
|
val clusterCounts = clusterState.clusterCounts;
|
||||||
|
clusterCounts.clear();
|
||||||
|
|
||||||
|
// compute new clusters and counters
|
||||||
|
val points = pointsPlh();
|
||||||
|
|
||||||
|
for (p in 0..(points.numElems_1-1)) {
|
||||||
|
var closest:Long = -1;
|
||||||
|
var closestDist:Float = Float.MAX_VALUE;
|
||||||
|
for (k in 0..(CLUSTERS-1)) {
|
||||||
|
var dist : Float = 0;
|
||||||
|
for (d in 0..(DIM-1)) {
|
||||||
|
val tmp = points(p,d) - currentClusters(k, d);
|
||||||
|
dist += tmp * tmp;
|
||||||
|
}
|
||||||
|
if (dist < closestDist) {
|
||||||
|
closestDist = dist;
|
||||||
|
closest = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
atomic {
|
||||||
|
for (d in 0..(DIM-1)) {
|
||||||
|
newClusters(closest,d) += points(p,d);
|
||||||
|
}
|
||||||
|
clusterCounts(closest)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clusterState
|
||||||
|
};
|
||||||
|
|
||||||
|
// combine place clusters to central
|
||||||
|
atomic {
|
||||||
|
for ([i,j] in centralNewClusters.indices()) {
|
||||||
|
centralNewClusters(i,j) += placeClusters.clusters(i,j);
|
||||||
|
}
|
||||||
|
for (j in 0..(CLUSTERS-1)) {
|
||||||
|
centralClusterCounts(j) += placeClusters.clusterCounts(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k in 0..(CLUSTERS-1)) {
|
||||||
|
for (d in 0..(DIM-1)) {
|
||||||
|
centralNewClusters(k, d) /= centralClusterCounts(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TEST FOR CONVERGENCE
|
||||||
|
var b:Boolean = true;
|
||||||
|
for ([i,j] in centralCurrentClusters.indices()) {
|
||||||
|
if (Math.abs(centralCurrentClusters(i, j)-centralNewClusters(i, j)) > 0.0001) {
|
||||||
|
b = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.copy(centralNewClusters, centralCurrentClusters);
|
||||||
|
|
||||||
|
if (b) break;
|
||||||
|
|
||||||
|
centralNewClusters.clear();
|
||||||
|
centralClusterCounts.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (d in 0..(DIM-1)) {
|
||||||
|
for (k in 0..(CLUSTERS-1)) {
|
||||||
|
if (k > 0)
|
||||||
|
Console.OUT.print(" ");
|
||||||
|
Console.OUT.print(centralCurrentClusters(k,d));
|
||||||
|
}
|
||||||
|
Console.OUT.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: shiftwidth=4:tabstop=4:expandtab
|
||||||
192
samples/X10/KMeansSPMD.x10
Normal file
192
samples/X10/KMeansSPMD.x10
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import x10.io.Console;
|
||||||
|
import x10.io.File;
|
||||||
|
import x10.io.Marshal;
|
||||||
|
import x10.io.IOException;
|
||||||
|
import x10.util.OptionsParser;
|
||||||
|
import x10.util.Option;
|
||||||
|
import x10.util.Team;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An SPMD formulation of KMeans.
|
||||||
|
*
|
||||||
|
* For a highly optimized and scalable version of this benchmark see
|
||||||
|
* KMeans.x10 in the X10 Benchmarks (separate download from x10-lang.org)
|
||||||
|
*/
|
||||||
|
public class KMeansSPMD {
|
||||||
|
|
||||||
|
public static def printClusters (clusters:Rail[Float], dims:long) {
|
||||||
|
for (d in 0..(dims-1)) {
|
||||||
|
for (k in 0..(clusters.size/dims-1)) {
|
||||||
|
if (k>0)
|
||||||
|
Console.OUT.print(" ");
|
||||||
|
Console.OUT.print(clusters(k*dims+d).toString());
|
||||||
|
}
|
||||||
|
Console.OUT.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static def main (args:Rail[String]) {here == Place.FIRST_PLACE } {
|
||||||
|
|
||||||
|
val opts = new OptionsParser(args, [
|
||||||
|
Option("q","quiet","just print time taken"),
|
||||||
|
Option("v","verbose","print out each iteration"),
|
||||||
|
Option("h","help","this information")
|
||||||
|
], [
|
||||||
|
Option("p","points","location of data file"),
|
||||||
|
Option("i","iterations","quit after this many iterations"),
|
||||||
|
Option("c","clusters","number of clusters to find"),
|
||||||
|
Option("d","dim","number of dimensions"),
|
||||||
|
Option("s","slices","factor by which to oversubscribe computational resources"),
|
||||||
|
Option("n","num","quantity of points")
|
||||||
|
]);
|
||||||
|
if (opts.filteredArgs().size!=0L) {
|
||||||
|
Console.ERR.println("Unexpected arguments: "+opts.filteredArgs());
|
||||||
|
Console.ERR.println("Use -h or --help.");
|
||||||
|
System.setExitCode(1n);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (opts("-h")) {
|
||||||
|
Console.OUT.println(opts.usage(""));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
val fname = opts("-p", "points.dat");
|
||||||
|
val num_clusters=opts("-c",4);
|
||||||
|
val num_slices=opts("-s",1);
|
||||||
|
val num_global_points=opts("-n", 2000);
|
||||||
|
val iterations=opts("-i",50);
|
||||||
|
val dim=opts("-d", 4);
|
||||||
|
val verbose = opts("-v");
|
||||||
|
val quiet = opts("-q");
|
||||||
|
|
||||||
|
if (!quiet)
|
||||||
|
Console.OUT.println("points: "+num_global_points+" clusters: "+num_clusters+" dim: "+dim);
|
||||||
|
|
||||||
|
// file is dimension-major
|
||||||
|
val file = new File(fname);
|
||||||
|
val fr = file.openRead();
|
||||||
|
val init_points = (long) => Float.fromIntBits(Marshal.INT.read(fr).reverseBytes());
|
||||||
|
val num_file_points = (file.size() / dim / 4) as Int;
|
||||||
|
val file_points = new Rail[Float](num_file_points*dim, init_points);
|
||||||
|
|
||||||
|
val team = Team.WORLD;
|
||||||
|
|
||||||
|
val num_slice_points = num_global_points / num_slices / Place.numPlaces();
|
||||||
|
|
||||||
|
finish {
|
||||||
|
for (h in Place.places()) at(h) async {
|
||||||
|
var compute_time:Long = 0;
|
||||||
|
var comm_time:Long = 0;
|
||||||
|
var barrier_time:Long = 0;
|
||||||
|
|
||||||
|
val host_clusters = new Rail[Float](num_clusters*dim, (i:long)=>file_points(i));
|
||||||
|
val host_cluster_counts = new Rail[Int](num_clusters);
|
||||||
|
|
||||||
|
for (slice in 0..(num_slices-1)) {
|
||||||
|
// carve out local portion of points (point-major)
|
||||||
|
val offset = (slice*Place.numPlaces() + here.id) * num_slice_points;
|
||||||
|
if (verbose)
|
||||||
|
Console.OUT.println(h.toString()+" gets "+offset+" len "+num_slice_points);
|
||||||
|
val init = (i:long) => {
|
||||||
|
val p=i%num_slice_points;
|
||||||
|
val d=i/num_slice_points;
|
||||||
|
return file_points(offset+p+d*num_file_points);
|
||||||
|
};
|
||||||
|
|
||||||
|
// these are pretty big so allocate up front
|
||||||
|
val host_points = new Rail[Float](num_slice_points*dim, init);
|
||||||
|
val host_nearest = new Rail[Float](num_slice_points);
|
||||||
|
|
||||||
|
val start_time = System.currentTimeMillis();
|
||||||
|
|
||||||
|
barrier_time -= System.nanoTime();
|
||||||
|
team.barrier();
|
||||||
|
barrier_time += System.nanoTime();
|
||||||
|
|
||||||
|
main_loop: for (iter in 0..(iterations-1)) {
|
||||||
|
|
||||||
|
//if (offset==0) Console.OUT.println("Iteration: "+iter);
|
||||||
|
|
||||||
|
val old_clusters = new Rail[Float](host_clusters.size);
|
||||||
|
Rail.copy(host_clusters, 0L, old_clusters, 0L, host_clusters.size);
|
||||||
|
|
||||||
|
host_clusters.clear();
|
||||||
|
host_cluster_counts.clear();
|
||||||
|
|
||||||
|
compute_time -= System.nanoTime();
|
||||||
|
for (p in 0..(num_slice_points-1)) {
|
||||||
|
var closest:Long = -1;
|
||||||
|
var closest_dist:Float = Float.MAX_VALUE;
|
||||||
|
for (k in 0..(num_clusters-1)) {
|
||||||
|
var dist : Float = 0;
|
||||||
|
for (d in 0..(dim-1)) {
|
||||||
|
val tmp = host_points(p+d*num_slice_points) - old_clusters(k*dim+d);
|
||||||
|
dist += tmp * tmp;
|
||||||
|
}
|
||||||
|
if (dist < closest_dist) {
|
||||||
|
closest_dist = dist;
|
||||||
|
closest = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (d in 0..(dim-1)) {
|
||||||
|
host_clusters(closest*dim+d) += host_points(p+d*num_slice_points);
|
||||||
|
}
|
||||||
|
host_cluster_counts(closest)++;
|
||||||
|
}
|
||||||
|
compute_time += System.nanoTime();
|
||||||
|
|
||||||
|
comm_time -= System.nanoTime();
|
||||||
|
team.allreduce(host_clusters, 0L, host_clusters, 0L, host_clusters.size, Team.ADD);
|
||||||
|
team.allreduce(host_cluster_counts, 0L, host_cluster_counts, 0L, host_cluster_counts.size, Team.ADD);
|
||||||
|
comm_time += System.nanoTime();
|
||||||
|
|
||||||
|
for (k in 0..(num_clusters-1)) {
|
||||||
|
for (d in 0..(dim-1)) host_clusters(k*dim+d) /= host_cluster_counts(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset==0 && verbose) {
|
||||||
|
Console.OUT.println("Iteration: "+iter);
|
||||||
|
printClusters(host_clusters,dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TEST FOR CONVERGENCE
|
||||||
|
for (j in 0..(num_clusters*dim-1)) {
|
||||||
|
if (true/*||Math.abs(clusters_old(j)-host_clusters(j))>0.0001*/) continue main_loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
} // main_loop
|
||||||
|
|
||||||
|
} // slice
|
||||||
|
|
||||||
|
Console.OUT.printf("%d: computation %.3f s communication %.3f s (barrier %.3f s)\n",
|
||||||
|
here.id, compute_time/1E9, comm_time/1E9, barrier_time/1E9);
|
||||||
|
|
||||||
|
team.barrier();
|
||||||
|
|
||||||
|
if (here.id == 0) {
|
||||||
|
Console.OUT.println("\nFinal results:");
|
||||||
|
printClusters(host_clusters,dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // async
|
||||||
|
|
||||||
|
} // finish
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: shiftwidth=4:tabstop=4:expandtab
|
||||||
42
samples/X10/MontyPi.x10
Normal file
42
samples/X10/MontyPi.x10
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import x10.array.DistArray_Unique;
|
||||||
|
import x10.io.Console;
|
||||||
|
import x10.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculation of an approximation to pi by using a Monte Carlo simulation
|
||||||
|
* (throwing darts into the unit square and determining the fraction that land
|
||||||
|
* in the unit circle).
|
||||||
|
*/
|
||||||
|
public class MontyPi {
|
||||||
|
public static def main(args:Rail[String]) {
|
||||||
|
if (args.size != 1L) {
|
||||||
|
Console.OUT.println("Usage: MontyPi <number of points>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
val N = Long.parse(args(0));
|
||||||
|
val initializer = () => {
|
||||||
|
val r = new Random();
|
||||||
|
var result:Long = 0;
|
||||||
|
for(c in 1..N) {
|
||||||
|
val x = r.nextDouble();
|
||||||
|
val y = r.nextDouble();
|
||||||
|
if (x*x +y*y <= 1.0) result++;
|
||||||
|
}
|
||||||
|
result
|
||||||
|
};
|
||||||
|
val result = new DistArray_Unique[Long](Place.places(), initializer);
|
||||||
|
val pi = (4.0*result.reduce((x:Long,y:Long) => x+y, 0) as Double)/(N*Place.numPlaces());
|
||||||
|
Console.OUT.println("The value of pi is " + pi);
|
||||||
|
}
|
||||||
|
}
|
||||||
123
samples/X10/NQueensDist.x10
Normal file
123
samples/X10/NQueensDist.x10
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
* (C) Copyright Australian National University 2011.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import x10.array.DistArray_Unique;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A distributed version of NQueens. Runs over NUM_PLACES.
|
||||||
|
* Identical to NQueensPar, except that work is distributed
|
||||||
|
* over multiple places rather than shared between threads.
|
||||||
|
*/
|
||||||
|
public class NQueensDist {
|
||||||
|
public static val EXPECTED_SOLUTIONS =
|
||||||
|
[0, 1, 0, 0, 2, 10, 4, 40, 92, 352, 724, 2680, 14200, 73712, 365596, 2279184, 14772512];
|
||||||
|
|
||||||
|
val N:Long;
|
||||||
|
val P:Long;
|
||||||
|
val results:DistArray_Unique[Long];
|
||||||
|
val R:LongRange;
|
||||||
|
|
||||||
|
def this(N:Long, P:Long) {
|
||||||
|
this.N=N;
|
||||||
|
this.P=P;
|
||||||
|
this.results = new DistArray_Unique[Long]();
|
||||||
|
this.R = 0..(N-1);
|
||||||
|
}
|
||||||
|
def start() {
|
||||||
|
new Board().distSearch();
|
||||||
|
}
|
||||||
|
def run():Long {
|
||||||
|
finish start();
|
||||||
|
val result = results.reduce(((x:Long,y:Long) => x+y),0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Board {
|
||||||
|
val q: Rail[Long];
|
||||||
|
/** The number of low-rank positions that are fixed in this board for the purposes of search. */
|
||||||
|
var fixed:Long;
|
||||||
|
def this() {
|
||||||
|
q = new Rail[Long](N);
|
||||||
|
fixed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if it is safe to put a queen in file <code>j</code>
|
||||||
|
* on the next rank after the last fixed position.
|
||||||
|
*/
|
||||||
|
def safe(j:Long) {
|
||||||
|
for (k in 0..(fixed-1)) {
|
||||||
|
if (j == q(k) || Math.abs(fixed-k) == Math.abs(j-q(k)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Search all positions for the current board. */
|
||||||
|
def search() {
|
||||||
|
for (k in R) searchOne(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modify the current board by adding a new queen
|
||||||
|
* in file <code>k</code> on rank <code>fixed</code>,
|
||||||
|
* and search for all safe positions with this prefix.
|
||||||
|
*/
|
||||||
|
def searchOne(k:Long) {
|
||||||
|
if (safe(k)) {
|
||||||
|
if (fixed==(N-1)) {
|
||||||
|
// all ranks safely filled
|
||||||
|
atomic NQueensDist.this.results(here.id)++;
|
||||||
|
} else {
|
||||||
|
q(fixed++) = k;
|
||||||
|
search();
|
||||||
|
fixed--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search this board, dividing the work between all places
|
||||||
|
* using a block distribution of the current free rank.
|
||||||
|
*/
|
||||||
|
def distSearch() {
|
||||||
|
val work = R.split(Place.numPlaces());
|
||||||
|
finish for (p in Place.places()) {
|
||||||
|
val myPiece = work(p.id);
|
||||||
|
at (p) async {
|
||||||
|
// implicit copy of 'this' made across the at divide
|
||||||
|
for (k in myPiece) {
|
||||||
|
searchOne(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static def main(args:Rail[String]) {
|
||||||
|
val n = args.size > 0 ? Long.parse(args(0)) : 8;
|
||||||
|
Console.OUT.println("N=" + n);
|
||||||
|
//warmup
|
||||||
|
//finish new NQueensPar(12, 1).start();
|
||||||
|
val P = Place.numPlaces();
|
||||||
|
val nq = new NQueensDist(n,P);
|
||||||
|
var start:Long = -System.nanoTime();
|
||||||
|
val answer = nq.run();
|
||||||
|
val result = answer==EXPECTED_SOLUTIONS(n);
|
||||||
|
start += System.nanoTime();
|
||||||
|
start /= 1000000;
|
||||||
|
Console.OUT.println("NQueensDist " + nq.N + "(P=" + P +
|
||||||
|
") has " + answer + " solutions" +
|
||||||
|
(result? " (ok)." : " (wrong).") +
|
||||||
|
"time=" + start + "ms");
|
||||||
|
}
|
||||||
|
}
|
||||||
117
samples/X10/NQueensPar.x10
Normal file
117
samples/X10/NQueensPar.x10
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
* (C) Copyright Australian National University 2011.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of solutions to the N queens problem.
|
||||||
|
*/
|
||||||
|
public class NQueensPar {
|
||||||
|
public static val EXPECTED_SOLUTIONS =
|
||||||
|
[0, 1, 0, 0, 2, 10, 4, 40, 92, 352, 724, 2680, 14200, 73712, 365596, 2279184, 14772512];
|
||||||
|
|
||||||
|
val N:Int;
|
||||||
|
val P:Int;
|
||||||
|
var nSolutions:Int = 0n;
|
||||||
|
val R:IntRange;
|
||||||
|
|
||||||
|
def this(N:Int, P:Int) {
|
||||||
|
this.N=N;
|
||||||
|
this.P=P;
|
||||||
|
this.R = 0n..(N-1n);
|
||||||
|
}
|
||||||
|
|
||||||
|
def start() {
|
||||||
|
new Board().parSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
class Board {
|
||||||
|
val q: Rail[Int];
|
||||||
|
/** The number of low-rank positions that are fixed in this board for the purposes of search. */
|
||||||
|
var fixed:Int;
|
||||||
|
def this() {
|
||||||
|
q = new Rail[Int](N);
|
||||||
|
fixed = 0n;
|
||||||
|
}
|
||||||
|
|
||||||
|
def this(b:Board) {
|
||||||
|
this.q = new Rail[Int](b.q);
|
||||||
|
this.fixed = b.fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if it is safe to put a queen in file <code>j</code>
|
||||||
|
* on the next rank after the last fixed position.
|
||||||
|
*/
|
||||||
|
def safe(j:Int) {
|
||||||
|
for (k in 0n..(fixed-1n)) {
|
||||||
|
if (j == q(k) || Math.abs(fixed-k) == Math.abs(j-q(k)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Search all positions for the current board. */
|
||||||
|
def search() {
|
||||||
|
for (k in R) searchOne(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modify the current board by adding a new queen
|
||||||
|
* in file <code>k</code> on rank <code>fixed</code>,
|
||||||
|
* and search for all safe positions with this prefix.
|
||||||
|
*/
|
||||||
|
def searchOne(k:Int) {
|
||||||
|
if (safe(k)) {
|
||||||
|
if (fixed==(N-1n)) {
|
||||||
|
// all ranks safely filled
|
||||||
|
atomic NQueensPar.this.nSolutions++;
|
||||||
|
} else {
|
||||||
|
q(fixed++) = k;
|
||||||
|
search();
|
||||||
|
fixed--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search this board, dividing the work between threads
|
||||||
|
* using a block distribution of the current free rank.
|
||||||
|
*/
|
||||||
|
def parSearch() {
|
||||||
|
for (work in R.split(P)) async {
|
||||||
|
val board = new Board(this);
|
||||||
|
for (w in work) {
|
||||||
|
board.searchOne(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static def main(args:Rail[String]) {
|
||||||
|
val n = args.size > 0 ? Int.parse(args(0)) : 8n;
|
||||||
|
Console.OUT.println("N=" + n);
|
||||||
|
//warmup
|
||||||
|
//finish new NQueensPar(12, 1).start();
|
||||||
|
val ps = [1n,2n,4n];
|
||||||
|
for (numTasks in ps) {
|
||||||
|
Console.OUT.println("starting " + numTasks + " tasks");
|
||||||
|
val nq = new NQueensPar(n,numTasks);
|
||||||
|
var start:Long = -System.nanoTime();
|
||||||
|
finish nq.start();
|
||||||
|
val result = (nq.nSolutions as Long)==EXPECTED_SOLUTIONS(nq.N);
|
||||||
|
start += System.nanoTime();
|
||||||
|
start /= 1000000;
|
||||||
|
Console.OUT.println("NQueensPar " + nq.N + "(P=" + numTasks +
|
||||||
|
") has " + nq.nSolutions + " solutions" +
|
||||||
|
(result? " (ok)." : " (wrong).") + "time=" + start + "ms");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
73
samples/X10/QSort.x10
Normal file
73
samples/X10/QSort.x10
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Straightforward quicksort implementation using
|
||||||
|
* naive partition-in-the-middle and not bothering with
|
||||||
|
* well-known optimizations such as using insertion sort
|
||||||
|
* once the partitions get small. This is only intended
|
||||||
|
* as a simple example of an array-based program that
|
||||||
|
* combines a recirsive divide and conquer algorithm
|
||||||
|
* with async and finish, not as a highly efficient
|
||||||
|
* sorting procedure..
|
||||||
|
*/
|
||||||
|
public class QSort {
|
||||||
|
|
||||||
|
private static def partition(data:Rail[int], left:long, right:long) {
|
||||||
|
var i:long = left;
|
||||||
|
var j:long = right;
|
||||||
|
var tmp:int;
|
||||||
|
var pivot:long = data((left + right) / 2);
|
||||||
|
|
||||||
|
while (i <= j) {
|
||||||
|
while (data(i) < pivot) i++;
|
||||||
|
while (data(j) > pivot) j--;
|
||||||
|
if (i <= j) {
|
||||||
|
tmp = data(i);
|
||||||
|
data(i) = data(j);
|
||||||
|
data(j) = tmp;
|
||||||
|
i++;
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static def qsort(data:Rail[int], left:long, right:long) {
|
||||||
|
index:long = partition(data, left, right);
|
||||||
|
finish {
|
||||||
|
if (left < index - 1)
|
||||||
|
async qsort(data, left, index - 1);
|
||||||
|
|
||||||
|
if (index < right)
|
||||||
|
qsort(data, index, right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static def main(args:Rail[String]) {
|
||||||
|
val N = args.size>0 ? Long.parse(args(0)) : 100;
|
||||||
|
val r = new x10.util.Random();
|
||||||
|
val data = new Rail[int](N, (long)=>r.nextInt(9999n));
|
||||||
|
qsort(data, 0, N-1);
|
||||||
|
for (i in 0..(N-1)) {
|
||||||
|
Console.OUT.print(data(i));
|
||||||
|
if (i%10 == 9) {
|
||||||
|
Console.OUT.println();
|
||||||
|
} else {
|
||||||
|
Console.OUT.print(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Console.OUT.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
123
samples/X10/StructSpheres.x10
Normal file
123
samples/X10/StructSpheres.x10
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the X10 project (http://x10-lang.org).
|
||||||
|
*
|
||||||
|
* This file is licensed to You under the Eclipse Public License (EPL);
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.opensource.org/licenses/eclipse-1.0.php
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corporation 2006-2014.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import x10.io.Console;
|
||||||
|
import x10.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a real-world problem in graphics engines --
|
||||||
|
* determining which objects in a large sprawling world are close enough to the
|
||||||
|
* camera to be considered for rendering.
|
||||||
|
*
|
||||||
|
* It illustrates the usage of X10 structs to define new primitive types.
|
||||||
|
* In Native X10, structs are allocated within their containing object/stack frame
|
||||||
|
* and thus using structs instead of classes for Vector3 and WorldObject greatly
|
||||||
|
* improves the memory efficiency of the computation.
|
||||||
|
*
|
||||||
|
* @Author Dave Cunningham
|
||||||
|
* @Author Vijay Saraswat
|
||||||
|
*/
|
||||||
|
class StructSpheres {
|
||||||
|
static type Real = Float;
|
||||||
|
|
||||||
|
static struct Vector3(x:Real, y:Real, z:Real) {
|
||||||
|
public def getX () = x;
|
||||||
|
public def getY () = y;
|
||||||
|
public def getZ () = z;
|
||||||
|
|
||||||
|
public def add (other:Vector3)
|
||||||
|
= Vector3(this.x+other.x, this.y+other.y, this.z+other.z);
|
||||||
|
|
||||||
|
public def neg () = Vector3(-this.x, -this.y, -this.z);
|
||||||
|
|
||||||
|
public def sub (other:Vector3) = add(other.neg());
|
||||||
|
|
||||||
|
public def length () = Math.sqrtf(length2());
|
||||||
|
|
||||||
|
public def length2 () = x*x + y*y + z*z;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct WorldObject {
|
||||||
|
|
||||||
|
def this (x:Real, y:Real, z:Real, r:Real) {
|
||||||
|
pos = Vector3(x,y,z);
|
||||||
|
renderingDistance = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public def intersects (home:Vector3)
|
||||||
|
= home.sub(pos).length2() < renderingDistance*renderingDistance;
|
||||||
|
|
||||||
|
protected val pos:Vector3;
|
||||||
|
protected val renderingDistance:Real;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static def compute():boolean {
|
||||||
|
|
||||||
|
val reps = 7500;
|
||||||
|
|
||||||
|
// The following correspond to a modern out-door computer game:
|
||||||
|
val num_objects = 50000;
|
||||||
|
val world_size = 6000;
|
||||||
|
val obj_max_size = 400;
|
||||||
|
|
||||||
|
val ran = new Random(0);
|
||||||
|
|
||||||
|
// the array can go on the heap
|
||||||
|
// but the elements ought to be /*inlined*/ in the array
|
||||||
|
val spheres =
|
||||||
|
new Rail[WorldObject](num_objects, (i:long) => {
|
||||||
|
val x = (ran.nextDouble()*world_size) as Real;
|
||||||
|
val y = (ran.nextDouble()*world_size) as Real;
|
||||||
|
val z = (ran.nextDouble()*world_size) as Real;
|
||||||
|
val r = (ran.nextDouble()*obj_max_size) as Real;
|
||||||
|
return WorldObject(x,y,z,r);
|
||||||
|
});
|
||||||
|
|
||||||
|
val time_start = System.nanoTime();
|
||||||
|
|
||||||
|
var counter : Long = 0;
|
||||||
|
|
||||||
|
// HOT LOOP BEGINS
|
||||||
|
for (c in 1..reps) {
|
||||||
|
|
||||||
|
val x = (ran.nextDouble()*world_size) as Real;
|
||||||
|
val y = (ran.nextDouble()*world_size) as Real;
|
||||||
|
val z = (ran.nextDouble()*world_size) as Real;
|
||||||
|
|
||||||
|
val pos = Vector3(x,y,z);
|
||||||
|
|
||||||
|
for (i in spheres.range()) {
|
||||||
|
if (spheres(i).intersects(pos)) {
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// HOT LOOP ENDS
|
||||||
|
|
||||||
|
val time_taken = System.nanoTime() - time_start;
|
||||||
|
Console.OUT.println("Total time: "+time_taken/1E9);
|
||||||
|
|
||||||
|
val expected = 109702;
|
||||||
|
val ok = counter == expected;
|
||||||
|
if (!ok) {
|
||||||
|
Console.ERR.println("number of intersections: "+counter
|
||||||
|
+" (expected "+expected+")");
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static def main (Rail[String]) {
|
||||||
|
compute();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
1
vendor/grammars/X10
vendored
Submodule
1
vendor/grammars/X10
vendored
Submodule
Submodule vendor/grammars/X10 added at 05fc5c81cc
Reference in New Issue
Block a user