Skip to content

Commit

Permalink
Improve tests (#138)
Browse files Browse the repository at this point in the history
* Fix bug in systemtest where ref data was always regenerated

* Reduce test verbosity

* Fix flaky optmagk test

* Use persistent swpref in sw_timeit

* Fix PCSMO system test twin matrix

* Silence warnings in tests

* OpenMP mex improvements

Zero initialises arrays in chol_omp
  seems to fix remaining flaky mex tests
Change omp critical to atomic for better performance

* Improve optmagstr params test with new mock

* Fix chol_omp error code collision
  • Loading branch information
mducle committed Apr 18, 2023
1 parent 8f4eecf commit 4ede5fa
Show file tree
Hide file tree
Showing 20 changed files with 163 additions and 105 deletions.
8 changes: 7 additions & 1 deletion +sw_tests/+system_tests/systemtest_spinwave.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
properties
generate_reference_data = false;
reference_data = [];
reference_data_dir = fullfile('.', 'test_data');
reference_data_dir = fullfile('.', 'test_data', 'system_tests');
relToll = 0.01;
absToll = 1e-6;
swobj = [];
cleanup_warnings = {};
end

methods (TestClassSetup)
Expand Down Expand Up @@ -183,6 +184,11 @@ function generate_or_verify_generic(testCase, data, fieldname)
testCase.verify_test_data(data, testCase.reference_data.(fieldname));
end
end
function disable_warnings(testCase, varargin)
testCase.cleanup_warnings = [testCase.cleanup_warnings, ...
{onCleanup(@(c) cellfun(@(c) warning('on', c), varargin))}];
cellfun(@(c) warning('off', c), varargin);
end
end

end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ function test_AFM_kagome(testCase)
% use structural unit cell with incommensurate k
AF33kagome.genmagstr('mode','helical','unit','lu', 'k', k,...
'n',n, 'S', S, 'nExt',[1 1 1]);
testCase.disable_warnings('spinw:spinwave:NonPosDefHamiltonian');
spec_incom = AF33kagome.spinwave(qarg, 'hermit', true);
spec_incom = sw_egrid(spec_incom, 'component','Sperp', 'Evect',evec);
% use supercell k=0 structure
Expand All @@ -64,7 +65,7 @@ function test_AFM_kagome(testCase)
function test_two_matom_per_unit_cell(testCase)
% setup structure (taken from tutorial 19)
FeCuChain = spinw;
FeCuChain.genlattice('lat_const',[3 8 4],'spgr','P 1')
FeCuChain.genlattice('lat_const',[3 8 4],'sym','P 1')
FeCuChain.addatom('label','MCu2','r',[0 0 0])
FeCuChain.addatom('label','MFe2','r',[0 1/2 0])

Expand All @@ -84,6 +85,9 @@ function test_two_matom_per_unit_cell(testCase)
evec = 0:1.5:5;

% use structural unit cell with incommensurate k
testCase.disable_warnings('spinw:spinwave:NonPosDefHamiltonian', ...
'spinw:magstr:NotExact', ...
'spinw:spinwave:Twokm');
FeCuChain.genmagstr('mode','helical','k', k,...
'S', S, 'nExt',[1 1 1]);
spec_incom = FeCuChain.spinwave(qarg, 'hermit', true);
Expand All @@ -101,7 +105,7 @@ function test_two_matom_per_unit_cell(testCase)

function test_two_sym_equiv_matoms_per_unit_cell(testCase)
sw = spinw;
sw.genlattice('lat_const',[4,5,12],'spgr','I m m m')
sw.genlattice('lat_const',[4,5,12],'sym','I m m m')
sw.addatom('S', 1, 'r',[0 0 0]);
sw.addmatrix('label', 'J', 'value', 1);
sw.addmatrix('label', 'A', 'value', diag([0 0 -0.1]))
Expand All @@ -116,6 +120,7 @@ function test_two_sym_equiv_matoms_per_unit_cell(testCase)
evec = 0:0.5:1.5;

% use structural unit cell with incommensurate k
testCase.disable_warnings('spinw:genmagstr:SnParallel');
sw.genmagstr('mode','helical','k', k,...
'S', S, 'nExt',[1 1 1]);
spec_incom = sw.spinwave(qarg, 'hermit', true);
Expand Down
2 changes: 2 additions & 0 deletions +sw_tests/+system_tests/systemtest_spinwave_pcsmo.m
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ function test_pcsmo(testCase, usehorace)
testCase.verify_test_data({w0(1:numel(w1)) s0(1:numel(w1))}, {w1 s1});
testCase.generate_or_verify_generic({w0 s0}, 'data_horace');
else
testCase.swobj.twin.rotc(3,3,2) = 0; % Changed in code #85, but not in test .mat file
testCase.disable_warnings('spinw:spinwave:NonPosDefHamiltonian');
spec = testCase.swobj.spinwave(qln, 'formfact', true, 'saveV', true, 'saveH', true, 'optmem', 2);
spec = sw_egrid(spec, 'Evect', linspace(0, 100, 200));
spec = sw_neutron(spec);
Expand Down
1 change: 1 addition & 0 deletions +sw_tests/+unit_tests/unittest_spinw_addatom.m
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ function test_add_single_atom_custom_parameters(testCase, property_value)

function test_add_atom_with_custom_scatt_length(testCase, b_name)
b = 2;
testCase.disable_warnings('spinw:addatom:DeprecationWarning');
testCase.swobj.addatom('r', [0;0;0], b_name, b)
expected_unit_cell = testCase.default_unit_cell;
expected_unit_cell.b = [b; 1];
Expand Down
5 changes: 5 additions & 0 deletions +sw_tests/+unit_tests/unittest_spinw_genlattice.m
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,14 @@ function test_spgr_throws_deprecation_warning(testCase)
end

function test_spgr_and_sym_throws_error(testCase)
testCase.disable_warnings('spinw:genlattice:DeprecationWarning');
testCase.verifyError(...
@() testCase.swobj.genlattice('spgr', 3, 'sym', 3), ...
'spinw:genlattice:WrongInput');
end

function test_spacegroup_property(testCase, sym_param_name, spgr)
testCase.disable_warnings('spinw:genlattice:DeprecationWarning');
testCase.swobj.genlattice(sym_param_name, spgr);
expected_latt = testCase.default_latt;
expected_latt.sym = testCase.P2_sym;
Expand All @@ -79,13 +81,15 @@ function test_spacegroup_property(testCase, sym_param_name, spgr)
end

function test_label_always_used(testCase, sym_param_name, spgr_type)
testCase.disable_warnings('spinw:genlattice:DeprecationWarning');
label = 'label';
testCase.swobj.genlattice(sym_param_name, spgr_type, ...
'label', label);
testCase.verify_val(testCase.swobj.lattice.label, label)
end

function test_spacegroup_with_sym_operation_matrix(testCase, sym_param_name)
testCase.disable_warnings('spinw:genlattice:DeprecationWarning');
testCase.swobj.genlattice(sym_param_name, testCase.P2_sym);
expected_latt = testCase.default_latt;
expected_latt.sym = testCase.P2_sym;
Expand Down Expand Up @@ -166,6 +170,7 @@ function test_basis_vector_and_rotation_matrix(testCase, basis_vecs)
function test_spacegroup_with_cell_input(testCase, sym_param_name)
spgr_str = '-x,y,-z';
label = 'label';
testCase.disable_warnings('spinw:genlattice:DeprecationWarning');
testCase.swobj.genlattice(sym_param_name, {spgr_str, label});
expected_latt = testCase.default_latt;
expected_latt.sym = testCase.P2_sym;
Expand Down
9 changes: 5 additions & 4 deletions +sw_tests/+unit_tests/unittest_spinw_genmagstr.m
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ function test_helical_multiatom_nExt_nMagExt_spins(testCase)
'k', k', ...
'nExt', nExt, ...
'F', [-1i 2 0 -2; 1 2i 0 -2i; 0 0 1 0]);
testCase.verify_obj(swobj.mag_str, expected_mag_str);
testCase.verify_obj(swobj.mag_str, expected_mag_str);
end
function test_helical_multiatom_multik_multin(testCase)
swobj = copy(testCase.swobj);
Expand Down Expand Up @@ -536,8 +536,9 @@ function test_tile_multik_provided_k_set_to_zero(testCase)
swobj.addatom('r', [0.5 0.5 0], 'S', 1);
S = cat(3, [1 0; 0 1; 0 0], [0 1; 0 0; 1 0]);
k = 0.5*ones(size(S, 3), 3);
swobj.genmagstr('mode', 'tile', ...
'S', S, 'k', k);
testCase.assertWarning(...
@() swobj.genmagstr('mode', 'tile', 'S', S, 'k', k), ...
'spinw:genmagstr:UnreadInput');
expected_mag_str = testCase.default_mag_str;
expected_mag_str.F = sqrt(2)/2*[1 1; 0 1; 1 0];
testCase.verify_obj(swobj.mag_str, expected_mag_str);
Expand Down Expand Up @@ -652,4 +653,4 @@ function test_func_custom_symbolic(testCase)
testCase.verify_obj(swobj.mag_str, expected_mag_str);
end
end
end
end
11 changes: 9 additions & 2 deletions +sw_tests/+unit_tests/unittest_spinw_intmatrix.m
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ function test_intmatrix_fitmode_true_plotmode_true(testCase)
end

function test_intmatrix_fitmode_true_DM_interaction(testCase)
testCase.swobj.addcoupling('mat', 'D', 'bond', 3, 'subIdx', 1);
testCase.verifyWarning( ...
@() testCase.swobj.addcoupling('mat', 'D', 'bond', 3, 'subIdx', 1), ...
'spinw:addcoupling:SymetryLowered');

[SS, SI, RR] = testCase.swobj.intmatrix('fitmode', true);

Expand All @@ -142,6 +144,7 @@ function test_intmatrix_fitmode_true_DM_interaction(testCase)

function test_intmatrix_fitmode_false(testCase)
% add all different types of interaction
testCase.disable_warnings('spinw:addcoupling:SymetryLowered');
testCase.swobj.addmatrix('label','Janiso','value', ...
diag([1,2,3]))
for mat_name = {'D', 'gen', 'Janiso'}
Expand Down Expand Up @@ -171,7 +174,9 @@ function test_intmatrix_zeroC_false_removes_zero_matrices(testCase)

function test_intmatrix_conjugate(testCase)
% add coupling between two different atoms
testCase.swobj.addcoupling('mat', 'gen', 'bond', 3, 'subIdx', 1);
testCase.verifyWarning( ...
@() testCase.swobj.addcoupling('mat', 'gen', 'bond', 3, 'subIdx', 1), ...
'spinw:addcoupling:SymetryLowered');
% zero other couplings for brevity (will be omitted by zeroC)
testCase.swobj.addmatrix('label', 'J1', 'value', 0)
testCase.swobj.addmatrix('label', 'J2', 'value', 0)
Expand Down Expand Up @@ -234,6 +239,7 @@ function test_extend_true_with_supercell(testCase)
end

function test_sortDM_reorders_bonds(testCase)
testCase.disable_warnings('spinw:addcoupling:SymetryLowered');
testCase.swobj.addmatrix('label', 'J2', 'value', 0);
% make face-centred to have bond order depend on sortDM
testCase.swobj.genlattice('sym', 'F m m m');
Expand Down Expand Up @@ -287,6 +293,7 @@ function symbolic_obj_with_fitmode_true(testCase)

function symbolic_obj_with_fitmode_false(testCase)
% add all different types of interaction
testCase.disable_warnings('spinw:addcoupling:SymetryLowered');
testCase.swobj.addmatrix('label','Janiso','value', ...
diag([1,2,3]))
for mat_name = {'D', 'gen', 'Janiso'}
Expand Down
3 changes: 2 additions & 1 deletion +sw_tests/+unit_tests/unittest_spinw_optmagk.m
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ function test_fm_chain_optk(testCase)
function test_afm_chain_optk(testCase)
testCase.swobj.addmatrix('label', 'J1', 'value', 1);
testCase.swobj.addcoupling('mat', 'J1', 'bond', 1);
testCase.swobj.optmagk;
% Use seed for reproducibility
testCase.swobj.optmagk('seed', 1);
expected_mag_str = testCase.default_mag_str;
expected_mag_str.k = [0.5; 0; 0];
testCase.verify_val(testCase.swobj.mag_str, expected_mag_str, ...
Expand Down
5 changes: 3 additions & 2 deletions +sw_tests/+unit_tests/unittest_spinw_optmagsteep.m
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ function test_output_to_fid(testCase)
end

function test_plot_moment_each_iteration(testCase, existing_plot)
testCase.disable_warnings('MATLAB:dispatcher:nameConflict');
if existing_plot
existing_fig = testCase.swobj.plot();
end
Expand Down Expand Up @@ -217,10 +218,10 @@ function test_not_move_moments_in_field_more_than_Hmin(testCase)

function test_multiple_atoms_in_unit_cell(testCase)
testCase.swobj.addatom('r',[0.5; 0.5; 0.5],'S',1)
testCase.swobj.gencoupling('maxDistance', 6);
testCase.swobj.gencoupling('maxDistance', 6, 'dMin', 0.1);
testCase.swobj.addaniso('A'); % add again as cleared above
% add AFM coupling of spins in same unit cell
testCase.swobj.addcoupling('mat', 'J1', 'bond', 3, 'dMin', 0.1);
testCase.swobj.addcoupling('mat', 'J1', 'bond', 3);
testCase.swobj.genmagstr('mode', 'direct', 'S', [0 0; 0 0; 1 1], ...
'k',[0, 0, 0]); % FM initial state

Expand Down
26 changes: 14 additions & 12 deletions +sw_tests/+unit_tests/unittest_spinw_optmagstr.m
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ function test_optmagstr_tri_af_out_planar_xmin_xmax(testCase)
function test_optmagstr_tri_af_nExt_init(testCase)
% Test that if a magnetic structure is initialised with nExt,
% it is used in optmagstr
testCase.disable_warnings('spinw:genmagstr:SnParallel');
testCase.tri.genmagstr('mode', 'random', 'nExt', [3 1 1]);
testCase.tri.optmagstr('func', @gm_planar, ...
'xmin', [0 pi/2 pi 0 0 0 0 0], ...
Expand Down Expand Up @@ -195,6 +196,7 @@ function test_optmagstr_tri_af_custom_func_wrong_number_of_inputs(testCase)
end

function test_optmagstr_tri_af_epsilon(testCase)
testCase.disable_warnings('spinw:genmagstr:SnParallel');
% Test that large epsilon doesn't rotate spins
testCase.tri.optmagstr('epsilon', 1.);
expected_mag_str = testCase.opt_tri_mag_str;
Expand Down Expand Up @@ -235,19 +237,18 @@ function test_optmagstr_tri_tid(testCase)
end

function test_optmagstr_optimisation_params(testCase, optparams)
% We could just mock optimset and check correct args are passed
% through, but Matlab doesn't allow mocking functions, and our
% mock_function doesn't support complex return values such as
% structs. So just check the output struct. O.
% We could also check for non-convergence but this is a bit
% flaky on different systems.
xmin = [0 0 0 0 0 0 0];
xmax = [pi/2 0 1/2 0 0 0 0];
out = testCase.afc.optmagstr('xmin', xmin, 'xmax', xmax, ...
optparams{:});
% Test that params are in output struct
for i=1:2:length(optparams)
testCase.verifyEqual(out.param.(optparams{i}), optparams{i+1})
mock_optimset = sw_tests.utilities.mock_function('optimset', ...
optimset('Display', 'off', optparams{:}));
testCase.disable_warnings('spinw:genmagstr:SnParallel');
testCase.afc.optmagstr('xmin', xmin, 'xmax', xmax, ...
optparams{:});
testCase.assertEqual(mock_optimset.n_calls, 1);
argslower = cellfun(@(c) lower(c), mock_optimset.arguments{1}(1:2:end), 'UniformOutput', false);
for ii = find(ismember(argslower, optparams(1:2:end)))
jj = find(ismember(optparams(1:2:end), argslower{ii}));
testCase.verifyEqual(mock_optimset.arguments{1}{2*ii}, optparams{2*jj});
end
end

Expand Down Expand Up @@ -280,6 +281,7 @@ function test_dm_multiatom_spherical3d(testCase)
sq.addcoupling('mat', 'DM', 'bond', 1);
sq.addmatrix('value', 1, 'label', 'J1');
sq.addcoupling('mat', 'J1', 'bond', 2);
testCase.disable_warnings('spinw:genmagstr:SnParallel');
% Sometimes fails to find min, run multiple times
sq.optmagstr('func', @gm_spherical3d, ...
'xmin', [-pi/2 -pi -pi/2 -pi, 0 0 0, 0 0], ...
Expand All @@ -298,4 +300,4 @@ function test_dm_multiatom_spherical3d(testCase)

end

end
end
Loading

0 comments on commit 4ede5fa

Please sign in to comment.