Skip to content

[BUG] Big memory usage for density evaluation #121

@leila-pujal

Description

@leila-pujal

Describe the bug

Big memory usage for density evaluation

To Reproduce

I attach the system I used to test:
iron_hexacarbonyl.tar.gz

mol=load_one("iron_hexacarbonyl.fchk")
dm = mol.one_rdms['scf']
basis, coord_types = from_iodata(mol)
becke = BeckeWeights(order=3)

oned = GaussChebyshevType2(100)
rgrid = BeckeTF(1e-4, 1.5).transform_1d_grid(oned)
grid = MolGrid.horton_molgrid(mol.atcoords, mol.atnums, rgrid, 1030, becke)

evaluate_density(dm, basis, grid.points, coord_type=coord_types)

Expected behaviour

I don't know if this could be improved, I am just reporting the behaviour as an issue.

Screenshots

System Information:

  • OS: 18.04.5 LTS
  • Python version: 3.6.10
  • NumPy version: 1.18.1
  • SciPy version: 1.4.1

Additional context

For computing the density it starts with evaluate_density(), then evaluates each orbital by computing the density for the basis functions and then it obtains the total density by using the density matrix. For evaluating the basis functions density, it is done in _deriv.py module inside _eval_deriv_contractions(). To monitor the memory I used several prints with nbytes for arrays and @profile from memory_profiler import profile. To monitor the memory of each contraction I printed the associated memory of matrix_contraction in base one

matrix_contraction = np.concatenate(matrix_contraction, axis=0)
. Then I profiled the memory in _eval_deriv_contractions(), evaluate_density() and evaluate_density_using_evaluated_orbs. With the information I gathered I think the memory dependcy in the code is as follows. Through the evaluation of all the generalized contractions, the memory will scale as a function of AO orbitals generated for each angular momentum. S-generalized contractions are the lowest memory cost and to obtain the memory cost for higher angular momentum generalized contractions you have to multiply the memory cost of the S-generalized contractions by the number of generated atomic orbitals (e.g l=1, 3p orbitals. Increase in memory = S-generalized contractions-memory x 3) The base memory corresponding to S-generalized contractions scales linearly with the number of points of the molecular grid. I fitted some values for not so big molecular sizes and I got the following regression S-generalized contractions memory (MB)=(0.000008150229943 *n_points) - 0.24118548. I checked to predict for some bigger ones and the predicted value was around 2MB wrong.
To show the agreement of the memory predicted with the one monitored I used iron_hexacarbonyl:

For a radial grid =100points
angular = 1030
Total = 100 * 1202 * 13atoms = 1562600

Iron hexacarbonyl
Total atoms 13
Total electrons 108
Total number generalized contractions 113
Atom types Fe oxygen carbon
total number 1 6 6
s shell 5 4 4
p shell 4 2 3
d shell 2 2 2
f shell 1    

Base memory for S-generalized contractions = 12.49MB

  Memory = base x AO_generated x number_shells      
  nitrogen oxygen carbon  
s shell 60 MB 48 MB 48 MB  
p shell 144 MB 72 MB 108 MB  
d shell 144 MB 144 MB 144 MB  
f shell 120 MB 0 0  
total (1atom) 468 MB 264MB 300MB total memory
Total all atoms 468 MB 1584 MB 1800 MB 3852 MB

The values I obtained profiling the code are shown in the following pictures:

this is the profiling for evaluate density()
image

You can see evaluates basis increases almost the same memory that it has been calculated in line 78.

But also, there's a spike of memory that it is not shown here that occurs in evaluate_density_using_evaluated_orbs. The profiling for this is shown in the following image.
image

Here you can see in line 63 where the memory is doubled.

Metadata

Metadata

Labels

bugSomething isn't workingenhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions