|
34 | 34 | from gpu4pyscf.lib import multi_gpu |
35 | 35 | from gpu4pyscf.gto.mole import ( |
36 | 36 | PTR_BAS_COORD, SortedMole, RysIntEnvVars, PBCIntEnvVars, |
37 | | - extract_pgto_params, groupby) |
| 37 | + extract_pgto_params, groupby, _split_l_ctr_groups) |
38 | 38 | from gpu4pyscf.scf.jk import ( |
39 | 39 | _nearest_power2, _scale_sp_ctr_coeff, _cache_q_cond_and_non0pairs, |
40 | 40 | _check_rsh_factors, SHM_SIZE, libvhf_rys) |
@@ -175,8 +175,11 @@ def int3c2e_evaluator(self, ao_pair_batch_size=None, aux_batch_size=None, |
175 | 175 | bas_ij_cache = {k: v for k, v in mol.iter_pair_by_l(self.bas_ij_cache)} |
176 | 176 | else: |
177 | 177 | bas_ij_cache = self.bas_ij_cache |
| 178 | + # Bound pair work alongside the auxiliary-shell task subdivision. |
| 179 | + pair_batch_size = np.minimum(nsp_per_block[0]*4, |
| 180 | + np.maximum(nsp_per_block[0]//4, 16)) |
178 | 181 | bas_ij_idx, shl_pair_offsets = mol.aggregate_shl_pairs( |
179 | | - bas_ij_cache, nsp_per_block[0]*4) |
| 182 | + bas_ij_cache, pair_batch_size) |
180 | 183 | ao_pair_loc = get_ao_pair_loc(mol.uniq_l_ctr[:,0], bas_ij_cache, cart) |
181 | 184 | nao_pair = ao_pair_loc[-1].get() |
182 | 185 |
|
@@ -210,6 +213,10 @@ def int3c2e_evaluator(self, ao_pair_batch_size=None, aux_batch_size=None, |
210 | 213 | uniq_l_ctr_aux = auxmol.uniq_l_ctr |
211 | 214 | aux_loc = auxmol.ao_loc |
212 | 215 | if aux_batch_size is None: |
| 216 | + # Follow df.j_engine_3c2e.Int3c2eOpt.contract_auxvec's 16-shell tasks. |
| 217 | + uniq_l_ctr_aux, aux_counts = _split_l_ctr_groups( |
| 218 | + auxmol.uniq_l_ctr, auxmol.l_ctr_counts, [16]*(laux+1)) |
| 219 | + l_ctr_aux_offsets = np.append(0, np.cumsum(aux_counts)) |
213 | 220 | ksh_offsets_cpu = l_ctr_aux_offsets |
214 | 221 | aux_splits = [0, len(ksh_offsets_cpu)-1] |
215 | 222 | else: |
@@ -410,7 +417,10 @@ def contract_auxvec(self, auxvec): |
410 | 417 | self.bas_ij_cache, nsp_per_block[0]*4) |
411 | 418 | gout_stride = cp.asarray(gout_stride, dtype=np.int32) |
412 | 419 |
|
413 | | - l_ctr_aux_offsets = np.append(0, np.cumsum(auxmol.l_ctr_counts)) |
| 420 | + # Split auxbasis into small batches for load balance |
| 421 | + _, aux_counts = _split_l_ctr_groups( |
| 422 | + auxmol.uniq_l_ctr, auxmol.l_ctr_counts, [16]*(laux+1)) |
| 423 | + l_ctr_aux_offsets = np.append(0, np.cumsum(aux_counts)) |
414 | 424 | ksh_offsets = cp.asarray(l_ctr_aux_offsets + mol.nbas, dtype=np.int32) |
415 | 425 | log.debug1('sp_blocks = %d, ksh_blocks = %d, shm_size = %d B', |
416 | 426 | len(shl_pair_offsets)-1, len(ksh_offsets)-1, shm_size_max) |
@@ -785,8 +795,11 @@ def _int3c2e_ip1_evaluator(int3c2e_opt, scheme, batch_size, |
785 | 795 | laux = auxmol.uniq_l_ctr[:,0].max() |
786 | 796 | shm_size_max = shm_size[:laux+1,:lmax+1,:lmax+1].max() |
787 | 797 |
|
| 798 | + # Bound serial work in each derivative-integral task. |
| 799 | + pair_batch_size = np.minimum(nsp_per_block[0]*4, |
| 800 | + np.maximum(nsp_per_block[0]//4, 16)) |
788 | 801 | bas_ij_idx, shl_pair_offsets = mol.aggregate_shl_pairs( |
789 | | - int3c2e_opt.bas_ij_cache, nsp_per_block[0]*4) |
| 802 | + int3c2e_opt.bas_ij_cache, pair_batch_size) |
790 | 803 | ao_pair_loc = get_ao_pair_loc(mol.uniq_l_ctr[:,0], int3c2e_opt.bas_ij_cache) |
791 | 804 | nao_pair = int(ao_pair_loc[-1].get()) |
792 | 805 |
|
|
0 commit comments