Coverage for tests/test_linked_lists_nblist.py: 85%

75 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-14 15:55 +0200

1import sys 

2import numpy as np 

3import gamdpy as gp 

4from numba import cuda, config 

5import pytest 

6 

7from hypothesis import given, strategies as st, settings, Verbosity, example 

8 

9def kernel_from_devicefunc(devicefunc): 

10 

11 @cuda.jit( device=False) 

12 def kernel(vectors, scalars, ptype, sim_box, nblist, nblist_parameters): 

13 grid = cuda.cg.this_grid() 

14 devicefunc(grid, vectors, scalars, ptype, sim_box, nblist, nblist_parameters) 

15 return kernel 

16 

17def run_nblist(configuration, nblist, cut, compute_plan, compute_flags): 

18 D, num_part = configuration.D, configuration.N 

19 pb, tp, gridsync, UtilizeNIII = [compute_plan[key] for key in ['pb', 'tp', 'gridsync', 'UtilizeNIII']] 

20 num_blocks = (num_part - 1) // pb + 1 

21 

22 

23 params = nblist.get_params(max_cut=cut, compute_plan=compute_plan) 

24 kernel = nblist.get_kernel(configuration, compute_plan, compute_flags, force_update=False) 

25 

26 if compute_plan['gridsync']: 

27 kernel = kernel_from_devicefunc(kernel) 

28 kernel[num_blocks, (pb, tp)](configuration.d_vectors, 

29 configuration.d_scalars, 

30 configuration.d_ptype, 

31 configuration.simbox.d_data, 

32 nblist.d_nblist, 

33 params) 

34 else: 

35 kernel(0, configuration.d_vectors, 

36 configuration.d_scalars, 

37 configuration.d_ptype, 

38 configuration.simbox.d_data, 

39 nblist.d_nblist, 

40 params) 

41 #print(compute_plan, nblist.d_nbflag.copy_to_host()) 

42 nbflag = nblist.d_nbflag.copy_to_host() 

43 assert nbflag[0] == 0 

44 assert nbflag[1] == 0 

45 

46def nblist_test(nx, ny, nz, rho=0.8442, pb=None, tp=None, skin=None, gridsync=None, UtilizeNIII=None, box_shift=0, cut=2.5, verbose=True): 

47 

48 # Generate configuration with a FCC lattice 

49 configuration = gp.Configuration(D=3) 

50 configuration.make_lattice(gp.unit_cells.FCC, cells=(nx, ny, nz), rho=rho) 

51 np.random.seed(0) 

52 configuration['r'] += np.random.uniform(-.3, +.3, configuration['r'].shape) 

53 configuration['r'] = configuration['r'][np.random.permutation(configuration.N),:] 

54 

55 if box_shift != 0.0: 

56 configuration.simbox = gp.LeesEdwards(configuration.D, configuration.simbox.get_lengths(), box_shift) 

57 

58 # Allow for overwriting of the default compute_plan 

59 compute_plan = gp.get_default_compute_plan(configuration) 

60 if pb!=None: 

61 compute_plan['pb'] = pb 

62 if tp!=None: 

63 compute_plan['tp'] = tp 

64 if skin!=None: 

65 compute_plan['skin'] = np.float32(skin) 

66 if gridsync!=None: 

67 compute_plan['gridsync'] = gridsync 

68 if UtilizeNIII!=None: 

69 compute_plan['UtilizeNb'] = UtilizeNIII 

70 if verbose: 

71 print('simbox lengths:', configuration.simbox.get_lengths()) 

72 print('compute_plan: ', compute_plan) 

73 

74 compute_flags = gp.get_default_compute_flags() 

75 

76 configuration.copy_to_device() 

77 nblist = gp.NbListLinkedLists(configuration, [], 300) 

78 run_nblist(configuration, nblist, cut, compute_plan, compute_flags) 

79 nblist_linked_list = nblist.d_nblist.copy_to_host() 

80 

81 #configuration['r'][0,2] += 2*cut # Testing the test: This should make test fail! 

82 configuration.copy_to_device() 

83 nblist = gp.NbList2(configuration, [], 300) 

84 run_nblist(configuration, nblist, cut, compute_plan, compute_flags) 

85 nblist_N_squared = nblist.d_nblist.copy_to_host() 

86 

87 return nblist_linked_list, nblist_N_squared, compute_plan 

88 

89 

90@pytest.mark.experimental 

91@settings(deadline=200_000, max_examples = 8) 

92@given(nx=st.integers(min_value=12, max_value=32), ny=st.integers(min_value=12, max_value=32), nz=st.integers(min_value=12, max_value=32)) 

93def test_nblist(nx, ny, nz): 

94 # hard-code box_shift for now 

95 box_shift = 0.5 

96 N = nx*ny*nz*4 

97 D = 3 

98 nblist_linked_list, nblist_N_squared, compute_plan = nblist_test(nx, ny, nz, box_shift=box_shift, cut=2.5, verbose=False) 

99 total_num_nbs_linked_list = np.sum(nblist_linked_list[:,-1]) 

100 total_num_nbs_N_squared = np.sum(nblist_N_squared[:,-1]) 

101 print(N, nx, ny, nz, 

102 compute_plan, 

103 total_num_nbs_linked_list, total_num_nbs_N_squared, total_num_nbs_linked_list/N) 

104 assert total_num_nbs_linked_list == total_num_nbs_N_squared 

105 assert np.all(nblist_linked_list[:,-1] == nblist_N_squared[:,-1]) # Num nbs for each particle 

106 assert np.all(np.sort(nblist_linked_list, axis=1) == np.sort(nblist_N_squared, axis=1)) # Same nbs, order allowed to differ 

107 return 

108 #for i in range(N): 

109 # nmax_ll = nblist_linked_list[i,-1] 

110 # nblist_linked_list[i, :nmax_ll].sort() 

111 

112 # nmax_n2 = nblist_N_squared[i,-1] 

113 # nblist_N_squared[i, :nmax_n2].sort() 

114 # if not np.all(nblist_linked_list[i] == nblist_N_squared[i]): 

115 # print("disagreement at i=%d" %i) 

116 # not_in_ll = [] 

117 # not_in_n2 = [] 

118 # for item1 in nblist_linked_list[i,:nmax_ll]: 

119 # if not item1 in nblist_N_squared[i,:nmax_n2]: 

120 # not_in_n2.append(item1) 

121 

122 # for item2 in nblist_N_squared[i,:nmax_n2]: 

123 # if not item2 in nblist_linked_list[i,:nmax_ll]: 

124 # not_in_ll.append(item2) 

125 

126 # if len(not_in_ll) > 0: 

127 # print("Not in ll", not_in_ll) 

128 # if len(not_in_n2) > 0: 

129 # print("Not in n2", not_in_n2) 

130 

131 #return nblist_linked_list, nblist_N_squared 

132 

133if __name__ == "__main__": 

134 config.CUDA_LOW_OCCUPANCY_WARNINGS = False 

135 test_nblist() 

136 #nb_ll, nb_n2 = test_nblist(7, 7, 7, -1.1)