mailr15437 - /branches/frame_order_testing/maths_fns/frame_order_matrix_ops.py


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

Header


Content

Posted by edward on March 06, 2012 - 11:17:
Author: bugman
Date: Tue Mar  6 11:17:58 2012
New Revision: 15437

URL: http://svn.gna.org/viewcvs/relax?rev=15437&view=rev
Log:
Initial parallelisation of the pseudo-ellipse frame order target function for 
the multi-processor.

This currently functions only for the uni-processor fabric, more work on the 
data structures within
the memo is required before the mpi4py fabric is functional.  A number of 
classes and functions have
been added:

    - The Slave_command_pcs_pseudo_ellipse_qrint class:  the 
pcs_numeric_int_pseudo_ellipse_qrint()
    function has been split up so that its numerical integration code is 
within this class.
    - The Memo_pcs_pseudo_ellipse_qrint class:  Currently being used to hold 
the number of
    integration points.
    - The Result_command_pcs_pseudo_ellipse_qrint class:  Is currently being 
used to transfer the
    number of integration points into the memo.
    - The subdivide() function:  Used to split up the points into blocks for 
each slave processor.
    It is currently broken for >1 slaves.

These changes do not increase the Frame_order.test_cam_pseudo_ellipse system 
test timings.


Modified:
    branches/frame_order_testing/maths_fns/frame_order_matrix_ops.py

Modified: branches/frame_order_testing/maths_fns/frame_order_matrix_ops.py
URL: 
http://svn.gna.org/viewcvs/relax/branches/frame_order_testing/maths_fns/frame_order_matrix_ops.py?rev=15437&r1=15436&r2=15437&view=diff
==============================================================================
--- branches/frame_order_testing/maths_fns/frame_order_matrix_ops.py 
(original)
+++ branches/frame_order_testing/maths_fns/frame_order_matrix_ops.py Tue Mar  
6 11:17:58 2012
@@ -27,7 +27,7 @@
 import dep_check
 
 # Python module imports.
-from math import acos, cos, pi, sin, sqrt
+from math import acos, ceil, cos, pi, sin, sqrt
 from numpy import cross, dot, inner, sinc, transpose
 from numpy.linalg import norm
 from random import uniform
@@ -41,7 +41,7 @@
 from maths_fns.kronecker_product import kron_prod, transpose_23
 from maths_fns.pseudo_ellipse import pec
 from maths_fns.rotation_matrix import euler_to_R_zyz, two_vect_to_R
-from multi import Processor_box
+from multi import Memo, Processor_box, Result_command, Slave_command
 
 
 def compile_1st_matrix_pseudo_ellipse(matrix, theta_x, theta_y, sigma_max):
@@ -1525,28 +1525,20 @@
     processor_box = Processor_box() 
     processor = processor_box.processor
 
-    # Loop over the samples.
-    num = 0
-    for i in range(len(points)):
-        # Unpack the point.
-        theta, phi, sigma = points[i]
-
-        # Calculate theta_max.
-        theta_max = tmax_pseudo_ellipse(phi, theta_x, theta_y)
-
-        # Outside of the distribution, so skip the point.
-        if theta > theta_max:
-            continue
-        if sigma > sigma_max or sigma < -sigma_max:
-            continue
-
-        # Calculate the PCSs for this state.
-        pcs_pivot_motion_full_qrint(theta_i=theta, phi_i=phi, sigma_i=sigma, 
full_in_ref_frame=full_in_ref_frame, r_pivot_atom=r_pivot_atom, 
r_pivot_atom_rev=r_pivot_atom_rev, r_ln_pivot=r_ln_pivot, A=A, 
R_eigen=R_eigen, RT_eigen=RT_eigen, Ri_prime=Ri_prime, pcs_theta=pcs_theta, 
pcs_theta_err=pcs_theta_err, missing_pcs=missing_pcs)
-
-        # Increment the number of points.
-        num += 1
+    # Subdivide the points.
+    for block in subdivide(points, processor.processor_size()):
+        # Initialise the slave command and memo.
+        command = Slave_command_pcs_pseudo_ellipse_qrint(points=block, 
theta_x=theta_x, theta_y=theta_x, sigma_max=sigma_max, 
full_in_ref_frame=full_in_ref_frame, r_pivot_atom=r_pivot_atom, 
r_pivot_atom_rev=r_pivot_atom_rev, r_ln_pivot=r_ln_pivot, A=A, 
R_eigen=R_eigen, RT_eigen=RT_eigen, Ri_prime=Ri_prime, pcs_theta=pcs_theta, 
pcs_theta_err=pcs_theta_err, missing_pcs=missing_pcs)
+        memo = Memo_pcs_pseudo_ellipse_qrint()
+
+        # Queue the block.
+        processor.add_to_queue(command, memo)
+
+    # Wait for completion.
+    processor.run_queue()
 
     # Calculate the PCS and error.
+    num = memo.num_pts
     for i in range(len(pcs_theta)):
         for j in range(len(pcs_theta[i])):
             # The average PCS.
@@ -2411,6 +2403,37 @@
     return matrix_rot
 
 
+def subdivide(points, processors):
+    """Split the points up into a number of blocks based on the number of 
processors.
+
+    @param points:      The integration points to split up.
+    @type points:       numpy rank-2, 3D array
+    @param processors:  The number of slave processors.
+    @type processors:   int
+    """
+
+    # Uni-processor mode, so no need to split.
+    if processors == 1:
+        yield points
+
+    # Multi-processor mode.
+    else:
+        # The number of points.
+        N = len(points)
+
+        # The number of points per block (rounding up when needed so that 
there are no accidentally left out points).
+        block_size = int(ceil(N / float(processors)))
+
+        # Loop over the blocks.
+        for i in range(processors):
+            # The indices.
+            index1 = i*block_size
+            index2 = (i+1)*block_size
+
+            # Yield the next block.
+            yield points[index1:index2]
+
+
 def tmax_pseudo_ellipse(phi, theta_x, theta_y):
     """The pseudo-ellipse tilt-torsion polar angle.
 
@@ -2432,3 +2455,130 @@
 
     # Return the maximum angle.
     return theta_x * theta_y / sqrt((cos(phi)*theta_y)**2 + 
(sin(phi)*theta_x)**2)
+
+
+
+class Memo_pcs_pseudo_ellipse_qrint(Memo):
+    """The memo object for the quasi-random pseudo-ellipse PCS numerical 
integration."""
+
+
+
+class Result_command_pcs_pseudo_ellipse_qrint(Result_command):
+    """The result command for the quasi-random pseudo-ellipse PCS numerical 
integration."""
+
+    def __init__(self, processor, memo_id=None, num_pts=None, 
completed=True):
+        """Store all the slave results for processing on the master.
+
+        @param processor:   The 
+        """
+
+        # Execute the base class __init__() method.
+        super(Result_command_pcs_pseudo_ellipse_qrint, 
self).__init__(processor=processor, completed=completed)
+
+        # Store the arguments.
+        self.memo_id = memo_id
+        self.num_pts = num_pts
+
+
+    def run(self, processor, memo):
+        """The process the partial PCS calculation.
+
+        @param processor:   The master slave instance.
+        @type processor:    Processor instance
+        @param memo:        The specific memo object.
+        @type memo:         Memo instance
+        """
+
+        # Store the number of points in the memo.
+        memo.num_pts = self.num_pts
+
+
+
+class Slave_command_pcs_pseudo_ellipse_qrint(Slave_command):
+    """The slave command for the quasi-random pseudo-ellipse PCS numerical 
integration."""
+
+    def __init__(self, points=None, theta_x=None, theta_y=None, 
sigma_max=None, full_in_ref_frame=None, r_pivot_atom=None, 
r_pivot_atom_rev=None, r_ln_pivot=None, A=None, R_eigen=None, RT_eigen=None, 
Ri_prime=None, pcs_theta=None, pcs_theta_err=None, missing_pcs=None):
+        """Set up the slave command, storing the integration points.
+
+        @keyword points:            The subdivision of points to process on 
the slave processor.
+        @type points:               numpy rank-2, 3D array
+        @keyword theta_x:           The x-axis half cone angle.
+        @type theta_x:              float
+        @keyword theta_y:           The y-axis half cone angle.
+        @type theta_y:              float
+        @keyword sigma_max:         The maximum torsion angle.
+        @type sigma_max:            float
+        @keyword full_in_ref_frame: An array of flags specifying if the 
tensor in the reference frame is the full or reduced tensor.
+        @type full_in_ref_frame:    numpy rank-1 array
+        @keyword r_pivot_atom:      The pivot point to atom vector.
+        @type r_pivot_atom:         numpy rank-2, 3D array
+        @keyword r_pivot_atom_rev:  The reversed pivot point to atom vector.
+        @type r_pivot_atom_rev:     numpy rank-2, 3D array
+        @keyword r_ln_pivot:        The lanthanide position to pivot point 
vector.
+        @type r_ln_pivot:           numpy rank-2, 3D array
+        @keyword A:                 The full alignment tensor of the 
non-moving domain.
+        @type A:                    numpy rank-2, 3D array
+        @keyword R_eigen:           The eigenframe rotation matrix.
+        @type R_eigen:              numpy rank-2, 3D array
+        @keyword RT_eigen:          The transpose of the eigenframe rotation 
matrix (for faster calculations).
+        @type RT_eigen:             numpy rank-2, 3D array
+        @keyword Ri_prime:          The empty rotation matrix for the 
in-frame isotropic cone motion, used to calculate the PCS for each state i in 
the numerical integration.
+        @type Ri_prime:             numpy rank-2, 3D array
+        @keyword pcs_theta:         The storage structure for the 
back-calculated PCS values.
+        @type pcs_theta:            numpy rank-2 array
+        @keyword pcs_theta_err:     The storage structure for the 
back-calculated PCS errors.
+        @type pcs_theta_err:        numpy rank-2 array
+        @keyword missing_pcs:       A structure used to indicate which PCS 
values are missing.
+        @type missing_pcs:          numpy rank-2 array
+         """
+
+        # Store the arguments.
+        self.points = points
+        self.theta_x = theta_x
+        self.theta_y = theta_y
+        self.sigma_max = sigma_max
+        self.full_in_ref_frame = full_in_ref_frame
+        self.r_pivot_atom = r_pivot_atom
+        self.r_pivot_atom_rev = r_pivot_atom_rev
+        self.r_ln_pivot = r_ln_pivot
+        self.A = A
+        self.R_eigen = R_eigen
+        self.RT_eigen = RT_eigen
+        self.Ri_prime = Ri_prime
+        self.pcs_theta = pcs_theta
+        self.pcs_theta_err = pcs_theta_err
+        self.missing_pcs = missing_pcs
+
+
+    def run(self, processor, completed):
+        """The PCS calculation.
+
+        @param processor:   The master slave instance.
+        @type processor:    Processor instance
+        @param completed:   A flag specifying if execution is completed.
+        @type completed:    bool
+        """
+
+        # Loop over the samples.
+        num = 0
+        for i in range(len(self.points)):
+            # Unpack the point.
+            theta, phi, sigma = self.points[i]
+
+            # Calculate theta_max.
+            theta_max = tmax_pseudo_ellipse(phi, self.theta_x, self.theta_y)
+
+            # Outside of the distribution, so skip the point.
+            if theta > theta_max:
+                continue
+            if sigma > self.sigma_max or sigma < -self.sigma_max:
+                continue
+
+            # Calculate the PCSs for this state.
+            pcs_pivot_motion_full_qrint(theta_i=theta, phi_i=phi, 
sigma_i=sigma, full_in_ref_frame=self.full_in_ref_frame, 
r_pivot_atom=self.r_pivot_atom, r_pivot_atom_rev=self.r_pivot_atom_rev, 
r_ln_pivot=self.r_ln_pivot, A=self.A, R_eigen=self.R_eigen, 
RT_eigen=self.RT_eigen, Ri_prime=self.Ri_prime, pcs_theta=self.pcs_theta, 
pcs_theta_err=self.pcs_theta_err, missing_pcs=self.missing_pcs)
+
+            # Increment the number of points.
+            num += 1
+
+        # Process the results on the master.
+        
processor.return_object(Result_command_pcs_pseudo_ellipse_qrint(processor, 
memo_id=self.memo_id, num_pts=num))




Related Messages


Powered by MHonArc, Updated Tue Mar 06 12:00:02 2012