Hi Ed.

You may see, that I have corrected this. :-)

The profiling scripts was a tremendous help here!

I think the clearest image for you would be to just make a diff on the
target function and on the lib function, between
the branches.

Best
Troels



2014-06-10 11:22 GMT+02:00 Edward d'Auvergne <[email protected]>:

> Hi Troels,
>
> This might be out of date due to the huge number of commits I'm only
> starting to look through now, but there is a problem with this change.
> The issue is with numpy data structure initialisations - this should
> never happen in the target function itself.  That is insanely far too
> computationally expensive as you have many memory allocations at the
> start, and automatic Python garbage collection at the end of the
> function which deletes all of these structures.  All numpy structures
> should be created in the __init__() method (or a method called from
> __init__()).  You then pack the parameters into the required data
> structure in the target function, recycling the numpy structures as
> much as possible.
>
> Regards,
>
> Edward
>
>
>
> On 7 June 2014 21:43,  <[email protected]> wrote:
> > Author: tlinnet
> > Date: Sat Jun  7 21:43:19 2014
> > New Revision: 23723
> >
> > URL: http://svn.gna.org/viewcvs/relax?rev=23723&view=rev
> > Log:
> > Initial try to alter the target function calc_CR72_chi2.
> >
> > This is the first test to restructure the arrays, to allow for higher
> dimensional computation.
> > All numpy arrays have to have same shape to allow to multiply together.
> > The dimensions should be [ei][si][mi][oi][di]. [Experiment][spins][spec.
> frq][offset][disp points].
> > This is complicated with number of disp point can change per
> spectrometer frequency.
> >
> > Task #7807 (https://gna.org/task/index.php?7807): Speed-up of
> dispersion models for Clustered analysis.
> >
> > This implementation brings a high overhead.
> > The first test shows no winning of time.
> > The creation of arrays takes all the time.
> >
> > Checked on MacBook Pro
> > 2.4 GHz Intel Core i5
> > 8 GB 1067 Mhz DDR3 RAM.
> > Python Distribution -- Python 2.7.3 |EPD 7.3-2 (32-bit)|
> >
> > Timing for:
> > 3 fields, [600. * 1E6, 800. * 1E6, 900. * 1E6]
> > ('sfrq: ', 600000000.0, 'number of cpmg frq', 15)
> > ('sfrq: ', 800000000.0, 'number of cpmg frq', 20)
> > ('sfrq: ', 900000000.0, 'number of cpmg frq', 22)
> > iterations of function call: 1000
> >
> > Timed for simulating 1 or 100 clustered spins.
> >
> > For TRUNK
> >
> > 1 spin:
> >    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
> >      3000    0.267    0.000    0.313    0.000 cr72.py:100(r2eff_CR72)
> >      1000    0.056    0.000    0.434    0.000
> relax_disp.py:456(calc_CR72_chi2)
> >      3000    0.045    0.000    0.061    0.000 chi2.py:32(chi2)
> >
> > 100 spins:
> >    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
> >    300000   26.315    0.000   30.771    0.000 cr72.py:100(r2eff_CR72)
> >      1000    5.498    0.005   42.660    0.043
> relax_disp.py:456(calc_CR72_chi2)
> >    300000    4.438    0.000    6.021    0.000 chi2.py:32(chi2)
> >
> > TESTING
> >
> > 1 spin:
> >    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
> >     19013    0.278    0.000    0.278    0.000
> {numpy.core.multiarray.array}
> >      1000    0.191    0.000    0.777    0.001
> relax_disp.py:457(calc_CR72_chi2)
> >      1000    0.147    0.000    0.197    0.000 cr72.py:101(r2eff_CR72)
> >      3000    0.044    0.000    0.061    0.000 chi2.py:32(chi2)
> >
> > 100 spins:
> >    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
> >   1504904   25.215    0.000   25.215    0.000
> {numpy.core.multiarray.array}
> >      1000   17.261    0.017   51.180    0.051
> relax_disp.py:457(calc_CR72_chi2)
> >    300000    4.637    0.000    6.310    0.000 chi2.py:32(chi2)
> >
> > Modified:
> >     branches/disp_spin_speed/target_functions/relax_disp.py
> >
> > Modified: branches/disp_spin_speed/target_functions/relax_disp.py
> > URL:
> http://svn.gna.org/viewcvs/relax/branches/disp_spin_speed/target_functions/relax_disp.py?rev=23723&r1=23722&r2=23723&view=diff
> >
> ==============================================================================
> > --- branches/disp_spin_speed/target_functions/relax_disp.py
> (original)
> > +++ branches/disp_spin_speed/target_functions/relax_disp.py     Sat Jun
>  7 21:43:19 2014
> > @@ -27,6 +27,7 @@
> >  # Python module imports.
> >  from copy import deepcopy
> >  from math import pi
> > +import numpy as np
> >  from numpy import complex64, dot, float64, int16, sqrt, zeros
> >
> >  # relax module imports.
> > @@ -470,29 +471,86 @@
> >          @rtype:         float
> >          """
> >
> > +        # Get the shape of back_calc structure.
> > +        back_calc_shape = list( np.asarray(self.back_calc).shape )
> > +
> > +        # Find which frequency has the maximum number of disp points.
> > +        # To let the numpy array operate well together, the broadcast
> size has to be equal for all shapes.
> > +        max_num_disp_points = np.max(self.num_disp_points)
> > +
> > +        # Create numpy arrays to pass to the lib function.
> > +        # All numpy arrays have to have same shape to allow to multiply
> together.
> > +        # The dimensions should be [ei][si][mi][oi][di].
> [Experiment][spins][spec. frq][offset][disp points].
> > +        # The number of disp point can change per spectrometer, so we
> make the maximum size.
> > +        R20A_a = np.ones(back_calc_shape + [max_num_disp_points])
> > +        R20B_a = np.ones(back_calc_shape + [max_num_disp_points])
> > +        pA_a = np.ones(back_calc_shape + [max_num_disp_points])
> > +        dw_frq_a = np.ones(back_calc_shape + [max_num_disp_points])
> > +        kex_a = np.ones(back_calc_shape + [max_num_disp_points])
> > +        cpmg_frqs_a = np.ones(back_calc_shape + [max_num_disp_points])
> > +        num_disp_points_a = np.ones(back_calc_shape +
> [max_num_disp_points])
> > +        back_calc_a = np.ones(back_calc_shape + [max_num_disp_points])
> > +
> > +        # Loop over the experiment types.
> > +        for ei in range(self.num_exp):
> > +            # Loop over the spins.
> > +            for si in range(self.num_spins):
> > +                # Loop over the spectrometer frequencies.
> > +                for mi in range(self.num_frq):
> > +                    # Loop over the offsets.
> > +                    for oi in range(self.num_offsets[ei][si][mi]):
> > +                        # Extract number of dispersion points.
> > +                        num_disp_points =
> self.num_disp_points[ei][si][mi][oi]
> > +
> > +                         # The R20 index.
> > +                        r20_index = mi + si*self.num_frq
> > +
> > +                        # Store r20a and r20b values per disp point.
> > +                        R20A_a[ei][si][mi][oi] = np.array(
> [R20A[r20_index]] * max_num_disp_points, float64)
> > +                        R20B_a[ei][si][mi][oi]  = np.array(
> [R20B[r20_index]] * max_num_disp_points, float64)
> > +
> > +                        # Convert dw from ppm to rad/s.
> > +                        dw_frq = dw[si] * self.frqs[ei][si][mi]
> > +
> > +                        # Store dw_frq per disp point.
> > +                        dw_frq_a[ei][si][mi][oi] = np.array( [dw_frq] *
> max_num_disp_points, float64)
> > +
> > +                        # Store pA and kex per disp point.
> > +                        pA_a[ei][si][mi][oi] = np.array( [pA] *
> max_num_disp_points, float64)
> > +                        kex_a[ei][si][mi][oi] = np.array( [kex] *
> max_num_disp_points, float64)
> > +
> > +                        # Extract cpmg_frqs and num_disp_points from
> lists.
> > +                        cpmg_frqs_a[ei][si][mi][oi][:num_disp_points] =
> self.cpmg_frqs[ei][mi][oi]
> > +
>  num_disp_points_a[ei][si][mi][oi][:num_disp_points] =
> self.num_disp_points[ei][si][mi][oi]
> > +
> > +        ## Back calculate the R2eff values.
> > +        r2eff_CR72(r20a=R20A_a, r20b=R20B_a, pA=pA_a, dw=dw_frq_a,
> kex=kex_a, cpmg_frqs=cpmg_frqs_a, back_calc = back_calc_a,
> num_points=num_disp_points_a)
> > +
> >          # Initialise.
> >          chi2_sum = 0.0
> >
> > -        # Loop over the spins.
> > -        for si in range(self.num_spins):
> > -            # Loop over the spectrometer frequencies.
> > -            for mi in range(self.num_frq):
> > -                # The R20 index.
> > -                r20_index = mi + si*self.num_frq
> > -
> > -                # Convert dw from ppm to rad/s.
> > -                dw_frq = dw[si] * self.frqs[0][si][mi]
> > -
> > -                # Back calculate the R2eff values.
> > -                r2eff_CR72(r20a=R20A[r20_index], r20b=R20B[r20_index],
> pA=pA, dw=dw_frq, kex=kex, cpmg_frqs=self.cpmg_frqs[0][mi][0], back_calc =
> self.back_calc[0][si][mi][0], num_points=self.num_disp_points[0][si][mi][0])
> > -
> > -                # For all missing data points, set the back-calculated
> value to the measured values so that it has no effect on the chi-squared
> value.
> > -                for di in range(self.num_disp_points[0][si][mi][0]):
> > -                    if self.missing[0][si][mi][0][di]:
> > -                        self.back_calc[0][si][mi][0][di] =
> self.values[0][si][mi][0][di]
> > -
> > -                # Calculate and return the chi-squared value.
> > -                chi2_sum += chi2(self.values[0][si][mi][0],
> self.back_calc[0][si][mi][0], self.errors[0][si][mi][0])
> > +        # Now return the values back to the structure of self.back_calc
> object.
> > +        ## For all missing data points, set the back-calculated value
> to the measured values so that it has no effect on the chi-squared value.
> > +        # Loop over the experiment types.
> > +        for ei in range(self.num_exp):
> > +            # Loop over the spins.
> > +            for si in range(self.num_spins):
> > +                # Loop over the spectrometer frequencies.
> > +                for mi in range(self.num_frq):
> > +                    # Loop over the offsets.
> > +                    for oi in range(self.num_offsets[ei][si][mi]):
> > +                        # Extract number of dispersion points.
> > +                        num_disp_points =
> self.num_disp_points[ei][si][mi][oi]
> > +
> > +                        self.back_calc[ei][si][mi][oi] =
> back_calc_a[ei][si][mi][oi][:num_disp_points]
> > +
> > +
> > +                        for di in
> range(self.num_disp_points[ei][si][mi][oi]):
> > +                            if self.missing[ei][si][mi][oi][di]:
> > +                                self.back_calc[ei][si][mi][oi][di] =
> self.values[ei][si][mi][oi][di]
> > +
> > +                        ## Calculate and return the chi-squared value.
> > +                        chi2_sum += chi2(self.values[ei][si][mi][oi],
> self.back_calc[ei][si][mi][oi], self.errors[ei][si][mi][oi])
> >
> >          # Return the total chi-squared value.
> >          return chi2_sum
> >
> >
> > _______________________________________________
> > relax (http://www.nmr-relax.com)
> >
> > This is the relax-commits mailing list
> > [email protected]
> >
> > To unsubscribe from this list, get a password
> > reminder, or change your subscription options,
> > visit the list information page at
> > https://mail.gna.org/listinfo/relax-commits
>
> _______________________________________________
> relax (http://www.nmr-relax.com)
>
> This is the relax-devel mailing list
> [email protected]
>
> To unsubscribe from this list, get a password
> reminder, or change your subscription options,
> visit the list information page at
> https://mail.gna.org/listinfo/relax-devel
>
_______________________________________________
relax (http://www.nmr-relax.com)

This is the relax-devel mailing list
[email protected]

To unsubscribe from this list, get a password
reminder, or change your subscription options,
visit the list information page at
https://mail.gna.org/listinfo/relax-devel

Reply via email to