From 43e9390b8d3d8c039bfab794ff2bca65d9a664c1 Mon Sep 17 00:00:00 2001 From: nmannall Date: Tue, 23 Jul 2024 15:24:59 +0100 Subject: [PATCH] Split reframe tests into multiple files --- reframe_tests/tests/reframe_tests.py | 315 ------------------ reframe_tests/tests/test_2d_models.py | 56 ++++ reframe_tests/tests/test_example_models.py | 42 +++ reframe_tests/tests/test_geometry.py | 74 ++++ reframe_tests/tests/test_materials.py | 26 ++ reframe_tests/tests/test_pmls.py | 28 ++ reframe_tests/tests/test_sources.py | 56 ++++ reframe_tests/tests/test_subgrids.py | 46 +++ .../tests/test_taskfarm_functionality.py | 47 +++ 9 files changed, 375 insertions(+), 315 deletions(-) delete mode 100644 reframe_tests/tests/reframe_tests.py create mode 100644 reframe_tests/tests/test_2d_models.py create mode 100644 reframe_tests/tests/test_example_models.py create mode 100644 reframe_tests/tests/test_geometry.py create mode 100644 reframe_tests/tests/test_materials.py create mode 100644 reframe_tests/tests/test_pmls.py create mode 100644 reframe_tests/tests/test_sources.py create mode 100644 reframe_tests/tests/test_subgrids.py create mode 100644 reframe_tests/tests/test_taskfarm_functionality.py diff --git a/reframe_tests/tests/reframe_tests.py b/reframe_tests/tests/reframe_tests.py deleted file mode 100644 index 5ab2d9fa..00000000 --- a/reframe_tests/tests/reframe_tests.py +++ /dev/null @@ -1,315 +0,0 @@ -import reframe as rfm -from base_tests import ( - GprMaxAPIRegressionTest, - GprMaxBScanRegressionTest, - GprMaxMPIRegressionTest, - GprMaxRegressionTest, - GprMaxTaskfarmRegressionTest, -) -from reframe.core.builtins import parameter, run_after, run_before - -"""ReFrame tests for basic functionality - - Usage: - cd gprMax/reframe_tests - reframe -C configuraiton/{CONFIG_FILE} -c reframe_tests.py -c base_tests.py -r -""" - - -@rfm.simple_test -class TestAscan(GprMaxRegressionTest): - tags = { - "test", - "serial", - "ascan", - "2d", - "hertzian_dipole", - "waveform", - "material", - "box", - "cylinder", - } - sourcesdir = "src/example_models" - model = parameter(["cylinder_Ascan_2D"]) - - -@rfm.simple_test -class TestBscan(GprMaxBScanRegressionTest): - tags = { - "test", - "serial", - "bscan", - "steps", - "waveform", - "hertzian_dipole", - "material", - "box", - "cylinder", - } - sourcesdir = "src/bscan_tests" - model = parameter(["cylinder_Bscan_2D"]) - num_models = parameter([64]) - - -@rfm.simple_test -class TestSingleNodeTaskfarm(GprMaxTaskfarmRegressionTest): - tags = { - "test", - "mpi", - "taskfarm", - "steps", - "waveform", - "hertzian_dipole", - "material", - "box", - "cylinder", - } - num_tasks = 8 - num_tasks_per_node = 8 - serial_dependency = TestBscan - model = serial_dependency.model - num_models = serial_dependency.num_models - - -@rfm.simple_test -class TestMultiNodeTaskfarm(GprMaxTaskfarmRegressionTest): - tags = { - "test", - "mpi", - "taskfarm", - "steps", - "waveform", - "hertzian_dipole", - "material", - "box", - "cylinder", - } - num_tasks = 32 - num_tasks_per_node = 8 - serial_dependency = TestBscan - model = serial_dependency.model - num_models = serial_dependency.num_models - - -@rfm.simple_test -class Test2DModelXY(GprMaxRegressionTest): - tags = {"test", "serial", "2d", "waveform", "hertzian_dipole"} - sourcesdir = "src/2d_tests" - model = parameter(["2D_EzHxHy"]) - - -@rfm.simple_test -class Test2DModelXZ(GprMaxRegressionTest): - tags = {"test", "serial", "2d", "waveform", "hertzian_dipole"} - sourcesdir = "src/2d_tests" - model = parameter(["2D_EyHxHz"]) - - -@rfm.simple_test -class Test2DModelYZ(GprMaxRegressionTest): - tags = {"test", "serial", "2d", "waveform", "hertzian_dipole"} - sourcesdir = "src/2d_tests" - model = parameter(["2D_ExHyHz"]) - - -@rfm.simple_test -class TestHertzianDipoleSource(GprMaxRegressionTest): - tags = {"test", "serial", "hertzian_dipole", "waveform"} - sourcesdir = "src/source_tests" - model = parameter(["hertzian_dipole_fs"]) - - -@rfm.simple_test -class TestMagneticDipoleSource(GprMaxRegressionTest): - tags = {"test", "serial", "magnetic_dipole", "waveform"} - sourcesdir = "src/source_tests" - model = parameter(["magnetic_dipole_fs"]) - - -@rfm.simple_test -class TestDispersiveMaterials(GprMaxRegressionTest): - tags = {"test", "serial", "hertzian_dipole", "waveform", "material", "dispersive", "box"} - sourcesdir = "src/material_tests" - model = parameter(["hertzian_dipole_dispersive"]) - - -@rfm.simple_test -class TestTransmissionLineSource(GprMaxRegressionTest): - tags = {"test", "serial", "transmission_line", "waveform"} - sourcesdir = "src/source_tests" - model = parameter(["transmission_line_fs"]) - - -@rfm.simple_test -class TestEdgeGeometry(GprMaxRegressionTest): - tags = {"test", "serial", "geometry", "edge", "transmission_line", "waveform", "antenna"} - sourcesdir = "src/geomtry_tests/edge_geometry" - model = parameter(["antenna_wire_dipole_fs"]) - is_antenna_model = True - - -@rfm.simple_test -class TestSubgrids(GprMaxAPIRegressionTest): - tags = { - "test", - "api", - "serial", - "subgrid", - "hertzian_dipole", - "waveform", - "material", - "dispersive", - "cylinder", - } - sourcesdir = "src/subgrid_tests" - model = parameter(["cylinder_fs"]) - - -@rfm.simple_test -class TestSubgridsWithAntennaModel(GprMaxAPIRegressionTest): - tags = { - "test", - "api", - "serial", - "subgrid", - "antenna", - "material", - "box", - "fractal_box", - "add_surface_roughness", - } - sourcesdir = "src/subgrid_tests" - model = parameter(["gssi_400_over_fractal_subsurface"]) - is_antenna_model = True - - @run_after("init") - def skip_test(self): - self.skip_if(self.current_system.name == "archer2", "Takes ~1hr 30m on ARCHER2") - - -@rfm.simple_test -class Test2DModelXYMpi(GprMaxMPIRegressionTest): - tags = {"test", "mpi", "2d", "waveform", "hertzian_dipole"} - mpi_layout = parameter([[4, 4, 1]]) - serial_dependency = Test2DModelXY - model = serial_dependency.model - - -@rfm.simple_test -class Test2DModelXZMpi(GprMaxMPIRegressionTest): - tags = {"test", "mpi", "2d", "waveform", "hertzian_dipole"} - mpi_layout = parameter([[4, 1, 4]]) - serial_dependency = Test2DModelXZ - model = serial_dependency.model - - -@rfm.simple_test -class Test2DModelYZMpi(GprMaxMPIRegressionTest): - tags = {"test", "mpi", "2d", "waveform", "hertzian_dipole"} - mpi_layout = parameter([[1, 4, 4]]) - serial_dependency = Test2DModelYZ - model = serial_dependency.model - - -@rfm.simple_test -class TestHertzianDipoleSourceMpi(GprMaxMPIRegressionTest): - tags = {"test", "mpi", "hertzian_dipole", "waveform"} - mpi_layout = parameter([[3, 3, 3]]) - serial_dependency = TestHertzianDipoleSource - model = serial_dependency.model - - -@rfm.simple_test -class TestMagneticDipoleSourceMpi(GprMaxMPIRegressionTest): - tags = {"test", "mpi", "magnetic_dipole", "waveform"} - mpi_layout = parameter([[3, 3, 3]]) - serial_dependency = TestMagneticDipoleSource - model = serial_dependency.model - - -@rfm.simple_test -class TestDispersiveMaterialsMpi(GprMaxMPIRegressionTest): - tags = {"test", "mpi", "hertzian_dipole", "waveform", "material", "dispersive", "box"} - mpi_layout = parameter([[3, 3, 3]]) - serial_dependency = TestDispersiveMaterials - model = serial_dependency.model - - -@rfm.simple_test -class TestTransmissionLineSourceMpi(GprMaxMPIRegressionTest): - tags = {"test", "mpi", "transmission_line", "waveform"} - mpi_layout = parameter([[3, 3, 3]]) - serial_dependency = TestTransmissionLineSource - model = serial_dependency.model - - -@rfm.simple_test -class TestEdgeGeometryMpi(GprMaxMPIRegressionTest): - tags = {"test", "mpi", "geometry", "edge", "transmission_line", "waveform", "antenna"} - mpi_layout = parameter([[3, 3, 3]]) - serial_dependency = TestEdgeGeometry - model = serial_dependency.model - is_antenna_model = True - - -@rfm.simple_test -class TestBoxGeometryNoPml(GprMaxRegressionTest): - tags = {"test", "serial", "geometery", "box"} - sourcesdir = "src/geometry_tests/box_geometry" - model = parameter(["box_full_model", "box_half_model", "box_single_rank"]) - - @run_before("run") - def add_gprmax_commands(self): - self.prerun_cmds.append(f"echo '#pml_cells: 0' >> {self.input_file}") - - -@rfm.simple_test -class TestBoxGeometryDefaultPml(GprMaxRegressionTest): - tags = {"test", "serial", "geometery", "box"} - sourcesdir = "src/geometry_tests/box_geometry" - model = parameter( - [ - "box_full_model", - "box_half_model", - "box_single_rank", - "box_outside_pml", - "box_single_rank_outside_pml", - ] - ) - - -@rfm.simple_test -class TestBoxGeometryNoPmlMpi(GprMaxMPIRegressionTest): - tags = {"test", "mpi", "geometery", "box"} - mpi_layout = parameter([[2, 2, 2], [3, 3, 3], [4, 4, 4]]) - serial_dependency = TestBoxGeometryNoPml - model = serial_dependency.model - - @run_before("run") - def add_gprmax_commands(self): - self.prerun_cmds.append(f"echo '#pml_cells: 0' >> {self.input_file}") - - -@rfm.simple_test -class TestBoxGeometryDefaultPmlMpi(GprMaxMPIRegressionTest): - tags = {"test", "mpi", "geometery", "box"} - mpi_layout = parameter([[2, 2, 2], [3, 3, 3], [4, 4, 4]]) - serial_dependency = TestBoxGeometryDefaultPml - model = serial_dependency.model - - -@rfm.simple_test -class TestSingleCellPml(GprMaxRegressionTest): - tags = {"test", "serial", "geometery", "box", "pml"} - sourcesdir = "src/pml_tests" - model = parameter(["single_cell_pml_2d"]) - rx_outputs = ["Hx"] - - -@rfm.simple_test -class TestSingleCellPmlMpi(GprMaxMPIRegressionTest): - tags = {"test", "mpi", "geometery", "box", "pml"} - mpi_layout = parameter([[2, 2, 1], [3, 3, 1]]) - serial_dependency = TestSingleCellPml - model = serial_dependency.model - rx_outputs = ["Hx"] diff --git a/reframe_tests/tests/test_2d_models.py b/reframe_tests/tests/test_2d_models.py new file mode 100644 index 00000000..81b1c572 --- /dev/null +++ b/reframe_tests/tests/test_2d_models.py @@ -0,0 +1,56 @@ +import reframe as rfm +from reframe.core.builtins import parameter + +from reframe_tests.tests.base_tests import GprMaxMPIRegressionTest, GprMaxRegressionTest + +"""Reframe regression tests for 2D models (TMx, TMy, and TMz) +""" + + +@rfm.simple_test +class Test2DModelXY(GprMaxRegressionTest): + tags = {"test", "serial", "2d", "waveform", "hertzian_dipole"} + sourcesdir = "src/2d_tests" + model = parameter(["2D_EzHxHy"]) + + +@rfm.simple_test +class Test2DModelXZ(GprMaxRegressionTest): + tags = {"test", "serial", "2d", "waveform", "hertzian_dipole"} + sourcesdir = "src/2d_tests" + model = parameter(["2D_EyHxHz"]) + + +@rfm.simple_test +class Test2DModelYZ(GprMaxRegressionTest): + tags = {"test", "serial", "2d", "waveform", "hertzian_dipole"} + sourcesdir = "src/2d_tests" + model = parameter(["2D_ExHyHz"]) + + +"""Test MPI Functionality +""" + + +@rfm.simple_test +class Test2DModelXYMpi(GprMaxMPIRegressionTest): + tags = {"test", "mpi", "2d", "waveform", "hertzian_dipole"} + mpi_layout = parameter([[4, 4, 1]]) + serial_dependency = Test2DModelXY + model = serial_dependency.model + + +@rfm.simple_test +class Test2DModelXZMpi(GprMaxMPIRegressionTest): + tags = {"test", "mpi", "2d", "waveform", "hertzian_dipole"} + mpi_layout = parameter([[4, 1, 4]]) + serial_dependency = Test2DModelXZ + model = serial_dependency.model + + +@rfm.simple_test +class Test2DModelYZMpi(GprMaxMPIRegressionTest): + tags = {"test", "mpi", "2d", "waveform", "hertzian_dipole"} + mpi_layout = parameter([[1, 4, 4]]) + serial_dependency = Test2DModelYZ + model = serial_dependency.model diff --git a/reframe_tests/tests/test_example_models.py b/reframe_tests/tests/test_example_models.py new file mode 100644 index 00000000..f430faec --- /dev/null +++ b/reframe_tests/tests/test_example_models.py @@ -0,0 +1,42 @@ +import reframe as rfm +from reframe.core.builtins import parameter + +from reframe_tests.tests.base_tests import GprMaxBScanRegressionTest, GprMaxRegressionTest + +"""Reframe regression tests for example models in gprMax documentation +""" + + +@rfm.simple_test +class TestAscan(GprMaxRegressionTest): + tags = { + "test", + "serial", + "ascan", + "2d", + "hertzian_dipole", + "waveform", + "material", + "box", + "cylinder", + } + sourcesdir = "src/example_models" + model = parameter(["cylinder_Ascan_2D"]) + + +@rfm.simple_test +class TestBscan(GprMaxBScanRegressionTest): + tags = { + "test", + "serial", + "bscan", + "steps", + "waveform", + "hertzian_dipole", + "material", + "box", + "cylinder", + } + sourcesdir = "src/bscan_tests" + model = parameter(["cylinder_Bscan_2D"]) + num_models = parameter([64]) diff --git a/reframe_tests/tests/test_geometry.py b/reframe_tests/tests/test_geometry.py new file mode 100644 index 00000000..c6056a67 --- /dev/null +++ b/reframe_tests/tests/test_geometry.py @@ -0,0 +1,74 @@ +import reframe as rfm +from reframe.core.builtins import parameter, run_before + +from reframe_tests.tests.base_tests import GprMaxMPIRegressionTest, GprMaxRegressionTest + +"""Reframe regression tests for models defining geometry +""" + + +@rfm.simple_test +class TestBoxGeometryDefaultPml(GprMaxRegressionTest): + tags = {"test", "serial", "geometery", "box"} + sourcesdir = "src/geometry_tests/box_geometry" + model = parameter( + [ + "box_full_model", + "box_half_model", + "box_single_rank", + "box_outside_pml", + "box_single_rank_outside_pml", + ] + ) + + +@rfm.simple_test +class TestBoxGeometryNoPml(GprMaxRegressionTest): + tags = {"test", "serial", "geometery", "box"} + sourcesdir = "src/geometry_tests/box_geometry" + model = parameter(["box_full_model", "box_half_model", "box_single_rank"]) + + @run_before("run") + def add_gprmax_commands(self): + self.prerun_cmds.append(f"echo '#pml_cells: 0' >> {self.input_file}") + + +@rfm.simple_test +class TestEdgeGeometry(GprMaxRegressionTest): + tags = {"test", "serial", "geometry", "edge", "transmission_line", "waveform", "antenna"} + sourcesdir = "src/geomtry_tests/edge_geometry" + model = parameter(["antenna_wire_dipole_fs"]) + is_antenna_model = True + + +"""Test MPI Functionality +""" + + +@rfm.simple_test +class TestBoxGeometryDefaultPmlMpi(GprMaxMPIRegressionTest): + tags = {"test", "mpi", "geometery", "box"} + mpi_layout = parameter([[2, 2, 2], [3, 3, 3], [4, 4, 4]]) + serial_dependency = TestBoxGeometryDefaultPml + model = serial_dependency.model + + +@rfm.simple_test +class TestBoxGeometryNoPmlMpi(GprMaxMPIRegressionTest): + tags = {"test", "mpi", "geometery", "box"} + mpi_layout = parameter([[2, 2, 2], [3, 3, 3], [4, 4, 4]]) + serial_dependency = TestBoxGeometryNoPml + model = serial_dependency.model + + @run_before("run") + def add_gprmax_commands(self): + self.prerun_cmds.append(f"echo '#pml_cells: 0' >> {self.input_file}") + + +@rfm.simple_test +class TestEdgeGeometryMpi(GprMaxMPIRegressionTest): + tags = {"test", "mpi", "geometry", "edge", "transmission_line", "waveform", "antenna"} + mpi_layout = parameter([[3, 3, 3]]) + serial_dependency = TestEdgeGeometry + model = serial_dependency.model + is_antenna_model = True diff --git a/reframe_tests/tests/test_materials.py b/reframe_tests/tests/test_materials.py new file mode 100644 index 00000000..f0de4773 --- /dev/null +++ b/reframe_tests/tests/test_materials.py @@ -0,0 +1,26 @@ +import reframe as rfm +from reframe.core.builtins import parameter + +from reframe_tests.tests.base_tests import GprMaxMPIRegressionTest, GprMaxRegressionTest + +"""Reframe regression tests for each gprMax source +""" + + +@rfm.simple_test +class TestDispersiveMaterials(GprMaxRegressionTest): + tags = {"test", "serial", "hertzian_dipole", "waveform", "material", "dispersive", "box"} + sourcesdir = "src/material_tests" + model = parameter(["hertzian_dipole_dispersive"]) + + +"""Test MPI Functionality +""" + + +@rfm.simple_test +class TestDispersiveMaterialsMpi(GprMaxMPIRegressionTest): + tags = {"test", "mpi", "hertzian_dipole", "waveform", "material", "dispersive", "box"} + mpi_layout = parameter([[3, 3, 3]]) + serial_dependency = TestDispersiveMaterials + model = serial_dependency.model diff --git a/reframe_tests/tests/test_pmls.py b/reframe_tests/tests/test_pmls.py new file mode 100644 index 00000000..a25ddbf3 --- /dev/null +++ b/reframe_tests/tests/test_pmls.py @@ -0,0 +1,28 @@ +import reframe as rfm +from reframe.core.builtins import parameter + +from reframe_tests.tests.base_tests import GprMaxMPIRegressionTest, GprMaxRegressionTest + +"""Reframe regression tests for models defining geometry +""" + + +@rfm.simple_test +class TestSingleCellPml(GprMaxRegressionTest): + tags = {"test", "serial", "geometery", "box", "pml"} + sourcesdir = "src/pml_tests" + model = parameter(["single_cell_pml_2d"]) + rx_outputs = ["Hx"] + + +"""Test MPI Functionality +""" + + +@rfm.simple_test +class TestSingleCellPmlMpi(GprMaxMPIRegressionTest): + tags = {"test", "mpi", "geometery", "box", "pml"} + mpi_layout = parameter([[2, 2, 1], [3, 3, 1]]) + serial_dependency = TestSingleCellPml + model = serial_dependency.model + rx_outputs = ["Hx"] diff --git a/reframe_tests/tests/test_sources.py b/reframe_tests/tests/test_sources.py new file mode 100644 index 00000000..f058406f --- /dev/null +++ b/reframe_tests/tests/test_sources.py @@ -0,0 +1,56 @@ +import reframe as rfm +from reframe.core.builtins import parameter + +from reframe_tests.tests.base_tests import GprMaxMPIRegressionTest, GprMaxRegressionTest + +"""Reframe regression tests for each gprMax source +""" + + +@rfm.simple_test +class TestHertzianDipoleSource(GprMaxRegressionTest): + tags = {"test", "serial", "hertzian_dipole", "waveform"} + sourcesdir = "src/source_tests" + model = parameter(["hertzian_dipole_fs"]) + + +@rfm.simple_test +class TestMagneticDipoleSource(GprMaxRegressionTest): + tags = {"test", "serial", "magnetic_dipole", "waveform"} + sourcesdir = "src/source_tests" + model = parameter(["magnetic_dipole_fs"]) + + +@rfm.simple_test +class TestTransmissionLineSource(GprMaxRegressionTest): + tags = {"test", "serial", "transmission_line", "waveform"} + sourcesdir = "src/source_tests" + model = parameter(["transmission_line_fs"]) + + +"""Test MPI Functionality +""" + + +@rfm.simple_test +class TestHertzianDipoleSourceMpi(GprMaxMPIRegressionTest): + tags = {"test", "mpi", "hertzian_dipole", "waveform"} + mpi_layout = parameter([[3, 3, 3]]) + serial_dependency = TestHertzianDipoleSource + model = serial_dependency.model + + +@rfm.simple_test +class TestMagneticDipoleSourceMpi(GprMaxMPIRegressionTest): + tags = {"test", "mpi", "magnetic_dipole", "waveform"} + mpi_layout = parameter([[3, 3, 3]]) + serial_dependency = TestMagneticDipoleSource + model = serial_dependency.model + + +@rfm.simple_test +class TestTransmissionLineSourceMpi(GprMaxMPIRegressionTest): + tags = {"test", "mpi", "transmission_line", "waveform"} + mpi_layout = parameter([[3, 3, 3]]) + serial_dependency = TestTransmissionLineSource + model = serial_dependency.model diff --git a/reframe_tests/tests/test_subgrids.py b/reframe_tests/tests/test_subgrids.py new file mode 100644 index 00000000..cc3f9de9 --- /dev/null +++ b/reframe_tests/tests/test_subgrids.py @@ -0,0 +1,46 @@ +import reframe as rfm +from reframe.core.builtins import parameter, run_after + +from reframe_tests.tests.base_tests import GprMaxAPIRegressionTest + +"""Reframe regression tests for subgrids +""" + + +@rfm.simple_test +class TestSubgrids(GprMaxAPIRegressionTest): + tags = { + "test", + "api", + "serial", + "subgrid", + "hertzian_dipole", + "waveform", + "material", + "dispersive", + "cylinder", + } + sourcesdir = "src/subgrid_tests" + model = parameter(["cylinder_fs"]) + + +@rfm.simple_test +class TestSubgridsWithAntennaModel(GprMaxAPIRegressionTest): + tags = { + "test", + "api", + "serial", + "subgrid", + "antenna", + "material", + "box", + "fractal_box", + "add_surface_roughness", + } + sourcesdir = "src/subgrid_tests" + model = parameter(["gssi_400_over_fractal_subsurface"]) + is_antenna_model = True + + @run_after("init") + def skip_test(self): + self.skip_if(self.current_system.name == "archer2", "Takes ~1hr 30m on ARCHER2") diff --git a/reframe_tests/tests/test_taskfarm_functionality.py b/reframe_tests/tests/test_taskfarm_functionality.py new file mode 100644 index 00000000..9154952f --- /dev/null +++ b/reframe_tests/tests/test_taskfarm_functionality.py @@ -0,0 +1,47 @@ +import reframe as rfm + +from reframe_tests.tests.base_tests import GprMaxTaskfarmRegressionTest +from reframe_tests.tests.test_example_models import TestBscan + +"""Reframe regression tests for taskfarm functionality +""" + + +@rfm.simple_test +class TestSingleNodeTaskfarm(GprMaxTaskfarmRegressionTest): + tags = { + "test", + "mpi", + "taskfarm", + "steps", + "waveform", + "hertzian_dipole", + "material", + "box", + "cylinder", + } + num_tasks = 8 + num_tasks_per_node = 8 + serial_dependency = TestBscan + model = serial_dependency.model + num_models = serial_dependency.num_models + + +@rfm.simple_test +class TestMultiNodeTaskfarm(GprMaxTaskfarmRegressionTest): + tags = { + "test", + "mpi", + "taskfarm", + "steps", + "waveform", + "hertzian_dipole", + "material", + "box", + "cylinder", + } + num_tasks = 32 + num_tasks_per_node = 8 + serial_dependency = TestBscan + model = serial_dependency.model + num_models = serial_dependency.num_models