Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plasma optimization #399

Merged
merged 24 commits into from
Sep 25, 2015
Merged

Conversation

wkerzendorf
Copy link
Member

rewrite of some functions to make them faster. There are still some functions to go and specifically one function is already in C/Cython and would need to be sped-up there.

@wkerzendorf
Copy link
Member Author

@unoebauer this is now a factor of 3. One function is now in C and takes up a significant fraction of the time. The other slower function is the random blackbody nu function, the reimplementation would probably significantly speed that up (currently 1/3 of the non-montecarlo functions).

@mreinecke I'll mark a function that is cython (so very close to C). but that can probably be sped up by openmp (array operations).

p_transition[j, k] /= norm_factor[k]


def calculate_transition_probabilities(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mreinecke this is the beast. You could just write it in C and maybe with openmp it would be faster. I'm wondering if memory bandwidth is an issue here.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On 08/25/15 18:25, Wolfgang Kerzendorf wrote:

  • cdef end_id = 0
  • for i in range(len(reference_levels) - 1):
  •    norm_factor[:] = 0.0
    
  •    for j in range(reference_levels[i], reference_levels[i + 1]):
    
  •        for k in range(p_transition.shape[1]):
    
  •            norm_factor[k] += p_transition[j, k]
    
  •    for j in range(reference_levels[i], reference_levels[i + 1]):
    
  •        for k in range(0, p_transition.shape[1]):
    
  •            if norm_factor[k] == 0.0:
    
  •                continue
    
  •            p_transition[j, k] /= norm_factor[k]
    
    +def calculate_transition_probabilities(

@mreinecke this is the beast. You could just write it in C and maybe with openmp it would be faster. I'm wondering if memory bandwidth is an issue here.

It may be possible to optimize this a bit, but there are a few issues to
consider first:

  • how large are the individual loop iteration counts (roughly, order of
    magnitude is fine)? This determines the best arrangement of the nested
    loops.
  • Is it known how the array p_transition is laid out in memory on the
    Python side? We won't gain any performace by tweaking the routine as
    long as the glue code between Python and C has to do things like array
    copying and maybe even transposition. This is because this function is
    absolutely dominated by memory accesses; the cost of arithmetic is
    negligible in comparison.
  • related to the point above: does "p_transition[j, k]" in Cython mean
    the same as "p_transition[j][k]" in C? More specifically, will
    p_transition[j][k] and p_transition[j][k+1] be neighbours in memory?

Overall it would be beneficial if "p_transition" could be stored in a
way that elements with j and j+1 are neighbouring in memory, but I'm not
sure if the memory layout is constrained somehow by other considerations.

Cheers,
Martin

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Martin - do you want to meet? maybe this is easier discussed in person.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On 08/26/15 10:44, Wolfgang Kerzendorf wrote:

  • cdef end_id = 0
  • for i in range(len(reference_levels) - 1):
  •    norm_factor[:] = 0.0
    
  •    for j in range(reference_levels[i], reference_levels[i + 1]):
    
  •        for k in range(p_transition.shape[1]):
    
  •            norm_factor[k] += p_transition[j, k]
    
  •    for j in range(reference_levels[i], reference_levels[i + 1]):
    
  •        for k in range(0, p_transition.shape[1]):
    
  •            if norm_factor[k] == 0.0:
    
  •                continue
    
  •            p_transition[j, k] /= norm_factor[k]
    
    +def calculate_transition_probabilities(

Martin - do you want to meet? maybe this is easier discussed in person.

Sure, but I have a few quick things to finish now. I'll let you know!

@unoebauer
Copy link
Contributor

@wkerzendorf Travis fails because of a NameError related to jit. Maybe because you removed numba?

@unoebauer
Copy link
Contributor

@wkerzendorf
So, I removed the last jist statement left in the PR. But running the tardis_example with this code version still fails, but now with an error in ion_population.py:

tardis.io.config_reader - INFO - Reading Atomic Data from kurucz_cd23_chianti_H_He.h5
tardis.atomic - INFO - Read Atom Data with UUID=5ca3035ca8b311e3bb684437e69d75d7 and MD5=21095dd25faa1683f4c90c911a00c3f8
tardis.io.config_reader - INFO - "initial_t_inner" is not specified in the plasma section - initializing to 9933.95199592 K with given luminosity
tardis.io.config_reader - WARNING - No "species" given - ignoring other NLTE options given:
{   'classical_nebular': False, 'coronal_approximation': False}
tardis.io.config_reader - WARNING - No convergence criteria selected - just damping by 0.5 for w, t_rad and t_inner
tardis.plasma.base - WARNING - dot2tex missing. Plasma graph will not be generated.
Traceback (most recent call last):
  File "/home/ulrich/python-virtualenv/tardis-devel/bin/tardis", line 4, in <module>
    __import__('pkg_resources').run_script('tardis-sn==1.0.1', 'tardis')
  File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 534, in run_script
    self.require(requires)[0].run_script(script_name, ns)
  File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 1438, in run_script
    execfile(script_filename, namespace, namespace)
  File "/home/ulrich/python-virtualenv/tardis-devel/lib/python2.7/site-packages/tardis_sn-1.0.1-py2.7-linux-x86_64.egg/EGG-INFO/scripts/tardis", line 63, in <module>
    radial1d_mdl = model.Radial1DModel(tardis_config)
  File "/home/ulrich/python-virtualenv/tardis-devel/local/lib/python2.7/site-packages/tardis_sn-1.0.1-py2.7-linux-x86_64.egg/tardis/model.py", line 132, in __init__
    link_t_rad_t_electron=0.9, helium_treatment=tardis_config.plasma.helium_treatment)
  File "/home/ulrich/python-virtualenv/tardis-devel/local/lib/python2.7/site-packages/tardis_sn-1.0.1-py2.7-linux-x86_64.egg/tardis/plasma/standard_plasmas.py", line 117, in __init__
    previous_beta_sobolevs=initial_beta_sobolevs)
  File "/home/ulrich/python-virtualenv/tardis-devel/local/lib/python2.7/site-packages/tardis_sn-1.0.1-py2.7-linux-x86_64.egg/tardis/plasma/base.py", line 23, in __init__
    self.update(**kwargs)
  File "/home/ulrich/python-virtualenv/tardis-devel/local/lib/python2.7/site-packages/tardis_sn-1.0.1-py2.7-linux-x86_64.egg/tardis/plasma/base.py", line 144, in update
    self.plasma_properties_dict[module_name].update()
  File "/home/ulrich/python-virtualenv/tardis-devel/local/lib/python2.7/site-packages/tardis_sn-1.0.1-py2.7-linux-x86_64.egg/tardis/plasma/properties/base.py", line 86, in update
    *self._get_input_values()))
  File "/home/ulrich/python-virtualenv/tardis-devel/local/lib/python2.7/site-packages/tardis_sn-1.0.1-py2.7-linux-x86_64.egg/tardis/plasma/properties/ion_population.py", line 62, in calculate
    self.phis[start_id - i:end_id - i - 1] = phis
ValueError: could not broadcast input array from shape (93,20) into shape (88,20)

@wkerzendorf
Copy link
Member Author

@unoebauer - it works for me when running the tardis_example.yml now. but still struggling with the tests.

@unoebauer
Copy link
Contributor

@wkerzendorf - still doesn't work for me. It still fails with the same shape mismatch error as before...

@wkerzendorf
Copy link
Member Author

@unoebauer tardis_example?

@wkerzendorf
Copy link
Member Author

@unoebauer sorry - I just see that it is. hmm.

@unoebauer
Copy link
Contributor

@wkerzendorf Good news: the last commit fixed the convergence issue in the plasma part
Bad news: a simple tardis_example calculation still fails immediately with the shape mismatch error

@unoebauer
Copy link
Contributor

Ok - the shape mismatch error may be connected to pandas. It occurred when using pandas 0.14.1 (debian jessie). After upgrading to pandas 0.16.2, tardis_example runs without problems

@wkerzendorf
Copy link
Member Author

@unoebauer it works (well the coverage still sucks 😉 but I'll update this one a bit more)

@aoifeboyle
Copy link
Contributor

When I run this I get a bunch of these errors in the initial iteration:
SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.
Does anyone else?

@wkerzendorf
Copy link
Member Author

@aoifeboyle I wonder if this is the problem that comes from not having it merged with the newest master. Can you locate it?

@aoifeboyle
Copy link
Contributor

@wkerzendorf Could you merge this PR soonish?

@wkerzendorf
Copy link
Member Author

@aoifeboyle are we ready to merge this.

@aoifeboyle
Copy link
Contributor

@wkerzendorf Yes, sure.

wkerzendorf added a commit that referenced this pull request Sep 25, 2015
@wkerzendorf wkerzendorf merged commit e91c79c into tardis-sn:master Sep 25, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants