mailr15537 - in /1.3: multi/test_implementation2.py test_suite/unit_tests/_multi/test___init__.py


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by edward on March 19, 2012 - 10:13:
Author: bugman
Date: Mon Mar 19 10:13:21 2012
New Revision: 15537

URL: http://svn.gna.org/viewcvs/relax?rev=15537&view=rev
Log:
Started to create a second script to demonstrate a working implementation of 
the multi package.


Added:
    1.3/multi/test_implementation2.py
      - copied, changed from r15475, 1.3/multi/test_implementation.py
Modified:
    1.3/test_suite/unit_tests/_multi/test___init__.py

Copied: 1.3/multi/test_implementation2.py (from r15475, 
1.3/multi/test_implementation.py)
URL: 
http://svn.gna.org/viewcvs/relax/1.3/multi/test_implementation2.py?p2=1.3/multi/test_implementation2.py&p1=1.3/multi/test_implementation.py&r1=15475&r2=15537&rev=15537&view=diff
==============================================================================
--- 1.3/multi/test_implementation.py (original)
+++ 1.3/multi/test_implementation2.py Mon Mar 19 10:13:21 2012
@@ -1,47 +1,28 @@
-"""A reference implementation of the multi-processor package.
+"""A reference implementation of the multi-processor package demonstrating 
pre-sending of data.
 
 Description
 ===========
 
-This is a basic but full implementation of the multi-processor package to 
demonstrate how it is used.
+This implementation of the multi-processor package is used to demonstrate 
how to pre-send invariant data once to all slaves to minimise the data 
transfer for each parallelised calculation block.
 
 
 Testing
 =======
 
-To run in uni-processor mode on a dual core system, change the MULTI 
variable to False and type::
-
-$ python test_implementation.py
-
-
-To run in mpi4py multi-processor mode with one master and two slave 
processors on minimally a dual core system, change the MULTI variable to True 
and type::
-
-$ mpiexec -n 3 python test_implementation.py
-
-For a single dual core CPU (Intel Core 2 Duo E8400 at 3.00GHz), the total 
times averaged over 5 runs are:
-    - Uni-processor:        51.548 seconds 
(51.054+52.224+51.257+51.112+52.093)
-    - Mpi4py-processor:     28.008 seconds 
(30.719+27.218+27.799+26.343+27.961)
-    - Scaling efficiency:   1.840
-
-
-Linux
------
-
-For multi-core systems and Linux 2.6, the following might be required to 
prevent the master processor from taking 100% of one CPU core while waiting 
for the slaves:
-
-# echo "1" > /proc/sys/kernel/sched_compat_yield
-
-This appears to be an OpenMPI problem with late 2.6 Linux kernels.
+To run in mpi4py multi-processor mode with one master and two slave 
processors, type::
+
+$ mpiexec -n 3 python test_implementation2.py
 """
 
 # Python module imports.
-from numpy import dot, float64, zeros
+from numpy import array, dot, float64, zeros
+from numpy.linalg import norm
 try:
     import cProfile as profile
 except ImportError:
     import profile
 import pstats
-from random import uniform
+from random import gauss
 import sys
 
 # Modify the module path.
@@ -52,14 +33,8 @@
 
 
 # Module variables.
-PROFILE = True
-MULTI = True
-if MULTI:
-    FABRIC = 'mpi4py'
-    PROCESSOR_NUM = 2
-else:
-    FABRIC = 'uni'
-    PROCESSOR_NUM = 1
+FABRIC = 'mpi4py'
+PROCESSOR_NUM = 2
 
 
 def print_stats(stats, status=0):
@@ -69,6 +44,72 @@
     pstats.Stats(stats).sort_stats('cumulative').print_stats()
 
 
+def quaternion_to_R(quat, R):
+    """Convert a quaternion into rotation matrix form.
+
+    This is from Wikipedia 
(http://en.wikipedia.org/wiki/Rotation_matrix#Quaternion), where::
+
+            | 1 - 2y**2 - 2z**2      2xy - 2zw          2xz + 2yw     |
+        Q = |     2xy + 2zw      1 - 2x**2 - 2z**2      2yz - 2xw     |,
+            |     2xz - 2yw          2yz + 2xw      1 - 2x**2 - 2y**2 |
+
+    and where the quaternion is defined as q = (w, x, y, z).  This has been 
verified using Simo
+    Saerkkae's "Notes on Quaternions" at http://www.lce.hut.fi/~ssarkka/.
+
+
+    @param quat:    The quaternion.
+    @type quat:     numpy 4D, rank-1 array
+    @param R:       A 3D matrix to convert to the rotation matrix.
+    @type R:        numpy 3D, rank-2 array
+    """
+
+    # Alias.
+    (w, x, y, z) = quat
+
+    # Repetitive calculations.
+    x2 = 2.0 * x**2
+    y2 = 2.0 * y**2
+    z2 = 2.0 * z**2
+    xw = 2.0 * x*w
+    xy = 2.0 * x*y
+    xz = 2.0 * x*z
+    yw = 2.0 * y*w
+    yz = 2.0 * y*z
+    zw = 2.0 * z*w
+
+    # The diagonal.
+    R[0, 0] = 1.0 - y2 - z2
+    R[1, 1] = 1.0 - x2 - z2
+    R[2, 2] = 1.0 - x2 - y2
+
+    # The off-diagonal.
+    R[0, 1] = xy - zw
+    R[0, 2] = xz + yw
+    R[1, 2] = yz - xw
+
+    R[1, 0] = xy + zw
+    R[2, 0] = xz - yw
+    R[2, 1] = yz + xw
+
+
+def R_random_hypersphere(R):
+    """Generate a random rotation matrix using 4D hypersphere point picking.
+
+    A quaternion is generated by creating a 4D vector with each value 
randomly selected from a
+    Gaussian distribution, and then normalising.
+
+    @param R:       A 3D matrix to convert to the rotation matrix.
+    @type R:        numpy 3D, rank-2 array
+    """
+
+    # The quaternion.
+    quat = array([gauss(0, 1), gauss(0, 1), gauss(0, 1), gauss(0, 1)], 
float64)
+    quat = quat / norm(quat)
+
+    # Convert the quaternion to a rotation matrix.
+    quaternion_to_R(quat, R)
+
+
 
 class Main:
     """The program."""
@@ -77,17 +118,24 @@
         """Set up some initial variables."""
 
         # The total number of calculations to perform by all slave 
processors.
-        self.N = 2000000
+        self.N = 20000
 
         # Variable for counting the completed calculations (to demonstrate 
slave->master communication).
         self.num = 0
 
+        # The invariant data to pass to the slaves once.
+        self.real_length = 2.0
+        self.vect = array([1, 2, 3], float64)
+        self.vect = self.vect / norm(self.vect) * self.real_length
+
 
     def run(self):
         """This required method executes the entire program."""
 
         # Initialise the Processor box singleton.
         processor_box = Processor_box()
+
+        print "\n\nHELLO: ", processor_box.processor.rank(), self.vect
 
         # Loop over the slaves.
         num = processor_box.processor.processor_size()
@@ -181,26 +229,22 @@
 
 
 
-class Test_slave_command(Slave_command):
-    """The slave command for use by the slave processor."""
-
-    def __init__(self, N=0):
+class Test_slave_command_presend(Slave_command):
+    """The slave command used to pre-send data to the slave processors."""
+
+    def __init__(self, vect=None):
         """Set up the slave command object for the slave processor.
 
-        @keyword N:     The number of calculations for the slave to perform.
-        @type N:        int
+        @keyword vect:  The invariant vector used in all the slave 
calculations.
+        @type vect:     int
         """
 
         # Store the argument.
-        self.N = N
-
-        # Initialise some matrices.
-        self.A = zeros((3, 3), float64)
-        self.B = zeros((3, 3), float64)
+        self.vect = vect
 
 
     def run(self, processor, completed=False):
-        """Essential method for performing calculations on the slave 
processors.
+        """Do nothing.
 
         @param processor:   The slave processor object.
         @type processor:    Processor instance
@@ -208,17 +252,46 @@
         @type completed:    bool
         """
 
+
+
+class Test_slave_command(Slave_command):
+    """The slave command for use by the slave processor."""
+
+    def __init__(self, N=0):
+        """Set up the slave command object for the slave processor.
+
+        @keyword N:     The number of calculations for the slave to perform.
+        @type N:        int
+        """
+
+        # Store the argument.
+        self.N = N
+
+        # Initialise the rotation matrix.
+        self.R = zeros((3, 3), float64)
+
+
+    def run(self, processor, completed=False):
+        """Essential method for performing calculations on the slave 
processors.
+
+        @param processor:   The slave processor object.
+        @type processor:    Processor instance
+        @keyword completed: A flag specifying if the slave calculation is 
completed.  This is currently meaningless, but will be passed to this run() 
method anyway so it needs to be present.
+        @type completed:    bool
+        """
+
         # Perform some random useless time-consuming stuff.
         num_calcs = 0
         for i in range(self.N):
-            # Randomise the matrices.
-            for j in range(3):
-                for k in range(3):
-                    self.A[j, k] = uniform(0, 1)
-                    self.B[j, k] = uniform(0, 1)
-
-            # Perform some linear algebra.
-            dot(self.A, self.B)
+            # Random rotation matrix.
+            R_random_hypersphere(self.R)
+
+            continue
+            # Rotate the vector.
+            new_vect = dot(self.R, self.vect)
+
+            # The length sum.
+            self.length += norm(new_vect)
 
             # Keep track of the number of calculations.
             num_calcs += 1
@@ -231,14 +304,10 @@
 # Set up the processor.
 processor = load_multiprocessor(FABRIC, Application_callback(master=Main()), 
processor_size=PROCESSOR_NUM, verbosity=1)
 
-# Run in multi-processor mode.
-if not PROFILE:
-    processor.run()
-
-# Run in multi-processor mode with profiling.
-else:
-    # Replace the default profiling print out function.
-    profile.Profile.print_stats = print_stats
-
-    # Execute with profiling.
-    profile.runctx('processor.run()', globals(), locals())
+processor.run()
+
+# Replace the default profiling print out function.
+profile.Profile.print_stats = print_stats
+
+# Execute with profiling.
+#profile.runctx('processor.run()', globals(), locals())

Modified: 1.3/test_suite/unit_tests/_multi/test___init__.py
URL: 
http://svn.gna.org/viewcvs/relax/1.3/test_suite/unit_tests/_multi/test___init__.py?rev=15537&r1=15536&r2=15537&view=diff
==============================================================================
--- 1.3/test_suite/unit_tests/_multi/test___init__.py (original)
+++ 1.3/test_suite/unit_tests/_multi/test___init__.py Mon Mar 19 10:13:21 2012
@@ -40,4 +40,4 @@
         self.package_path = sys.path[0] + sep + 'multi'
 
         # Blacklisted scripts.
-        self.blacklist = ['test_implementation.py']
+        self.blacklist = ['test_implementation.py', 
'test_implementation2.py']




Related Messages


Powered by MHonArc, Updated Mon Mar 19 10:40:02 2012