mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-28 17:20:22 +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"]
|
||||
path = vendor/grammars/sublime-typescript
|
||||
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
|
||||
vendor/grammars/Vala-TMBundle:
|
||||
- source.vala
|
||||
vendor/grammars/X10:
|
||||
- source.x10
|
||||
vendor/grammars/abap.tmbundle:
|
||||
- source.abap
|
||||
vendor/grammars/actionscript3-tmbundle:
|
||||
|
||||
@@ -3567,6 +3567,16 @@ WebIDL:
|
||||
tm_scope: source.webidl
|
||||
ace_mode: text
|
||||
|
||||
X10:
|
||||
type: programming
|
||||
aliases:
|
||||
- xten
|
||||
ace_mode: text
|
||||
extensions:
|
||||
- .x10
|
||||
color: "#4B6BEF"
|
||||
tm_scope: source.x10
|
||||
|
||||
XC:
|
||||
type: programming
|
||||
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