1 /*
2   This file is part of MADNESS.
3 
4   Copyright (C) 2007,2010 Oak Ridge National Laboratory
5 
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2 of the License, or
9   (at your option) any later version.
10 
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   GNU General Public License for more details.
15 
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20   For more information please contact:
21 
22   Robert J. Harrison
23   Oak Ridge National Laboratory
24   One Bethel Valley Road
25   P.O. Box 2008, MS-6367
26 
27   email: harrisonrj@ornl.gov
28   tel:   865-241-3937
29   fax:   865-572-0680
30 */
31 
32 //#define WORLD_INSTANTIATE_STATIC_TEMPLATES
33 #include <madness/world/MADworld.h>
34 
35 using namespace std;
36 using namespace madness;
37 
38 class Array : public WorldObject<Array> {
39     vector<double> v;
40 public:
41     /// Make block distributed array with size elements
Array(World & world,size_t size)42     Array(World& world, size_t size)
43         : WorldObject<Array>(world), v((size-1)/world.size()+1)
44     {
45         process_pending();
46     }
47 
48     /// Return the process in which element i resides
owner(size_t i) const49     ProcessID owner(size_t i) const {return i/v.size();};
50 
51     /// Read element i
read(size_t i) const52     Future<double> read(size_t i) const {
53         if (owner(i) == world.rank())
54             return Future<double>(v[i-world.rank()*v.size()]);
55         else
56             return send(owner(i), &Array::read, i);
57     }
58 
59     /// Write element i
write(size_t i,double value)60     void write(size_t i, double value) {
61         if (owner(i) == world.rank())
62             v[i-world.rank()*v.size()] = value;
63         else
64             send(owner(i), &Array::write, i, value);
65     }
66 };
67 
68 
main(int argc,char ** argv)69 int main(int argc, char** argv) {
70     SafeMPI::Init(argc, argv);
71     madness::World world(SafeMPI::COMM_WORLD);
72 
73     Array a(world, 10000), b(world, 10000);
74 
75     // Without regard to locality, initialize a[i]=i*10, b[i]=i*7
76     for (int i=world.rank(); i<10000; i+=world.size()) {
77         a.write(i, 10.0*i);
78         b.write(i,  7.0*i);
79     }
80     world.gop.fence();
81 
82     // All processes verify 100 random values from each array
83     for (int j=0; j<100; j++) {
84         size_t i = world.rand()%10000;
85         Future<double> vala = a.read(i);
86         Future<double> valb = b.read(i);
87         // Could do work here until results are available
88         MADNESS_ASSERT(vala.get() == 10.0*i);
89         MADNESS_ASSERT(valb.get() ==  7.0*i);
90     }
91     world.gop.fence();
92 
93     if (world.rank() == 0) print("OK!");
94     SafeMPI::Finalize();
95 }
96 
97