Ejemplo n.º 1
0
    def test_base(self):
        """unit tests for Qadapter subclasses. A more complete coverage would require integration testing."""
        self.maxDiff = None
        aequal, atrue, afalse = self.assertEqual, self.assertTrue, self.assertFalse
        sub_classes = QueueAdapter.__subclasses__()

        # Test if we can instantiate the concrete classes with the abc protocol.
        for subc in sub_classes:
            print("subclass: ", subc)

            # Create the adapter subclass.
            self.QDICT["queue"]["qtype"] = subc.QTYPE
            qad = make_qadapter(**self.QDICT)
            print(qad)
            hw = qad.hw
            giga = 1024

            # Test the programmatic interface used to change job parameters.
            aequal(qad.num_launches, 0)
            afalse(qad.has_omp)
            atrue(qad.has_mpi)
            qad.set_mpi_procs(2)
            aequal(qad.mpi_procs, 2)
            atrue(qad.pure_mpi)
            afalse(qad.pure_omp)
            afalse(qad.hybrid_mpi_omp)
            aequal(qad.mem_per_proc, giga)
            qad.set_mem_per_proc(2 * giga)
            aequal(qad.mem_per_proc, 2 * giga)
            aequal(qad.timelimit, 120)

            # Enable OMP
            qad.set_omp_threads(2)
            aequal(qad.omp_threads, 2)
            atrue(qad.has_omp)
            afalse(qad.pure_mpi)
            afalse(qad.pure_omp)
            atrue(qad.hybrid_mpi_omp)

            atrue(
                qad.hw.can_use_omp_threads(hw.sockets_per_node *
                                           hw.cores_per_socket))
            afalse(
                qad.hw.can_use_omp_threads(hw.sockets_per_node *
                                           hw.cores_per_socket + 1))

            # Test the creation of the script
            script = qad.get_script_str("job.sh",
                                        "/launch/dir",
                                        "executable",
                                        "qout_path",
                                        "qerr_path",
                                        stdin="STDIN",
                                        stdout="STDOUT",
                                        stderr="STDERR")

            # Test whether qad can be serialized with Pickle.
            deserialized_qads = self.serialize_with_pickle(qad, test_eq=False)

            for new_qad in deserialized_qads:
                new_script = new_qad.get_script_str("job.sh",
                                                    "/launch/dir",
                                                    "executable",
                                                    "qout_path",
                                                    "qerr_path",
                                                    stdin="STDIN",
                                                    stdout="STDOUT",
                                                    stderr="STDERR")
                aequal(new_script, script)

            # Test can_run and distribute
            # The hardware has num_nodes=3, sockets_per_node=2, cores_per_socket=4, mem_per_node="8 Gb"
            afalse(
                qad.can_run_pconf(
                    ParalConf(mpi_ncpus=hw.num_cores + 1,
                              omp_ncpus=1,
                              mem_per_cpu=0.1)))
            afalse(
                qad.can_run_pconf(
                    ParalConf(mpi_ncpus=4, omp_ncpus=9, mem_per_cpu=0.1)))
            afalse(
                qad.can_run_pconf(
                    ParalConf(mpi_ncpus=4, omp_ncpus=1,
                              mem_per_cpu=10 * giga)))

            d = qad.distribute(mpi_procs=4, omp_threads=1, mem_per_proc=giga)
            assert d.num_nodes == 1 and d.mpi_per_node == 4 and d.exact

            d = qad.distribute(mpi_procs=16, omp_threads=1, mem_per_proc=giga)
            assert d.num_nodes == 2 and d.mpi_per_node == 8 and d.exact

            # not enough memory per node but can distribute.
            d = qad.distribute(mpi_procs=8,
                               omp_threads=1,
                               mem_per_proc=2 * giga)
            assert d.num_nodes == 2 and d.mpi_per_node == 4 and not d.exact

            # mem_per_proc > mem_per_node!
            with self.assertRaises(qad.Error):
                d = qad.distribute(mpi_procs=9,
                                   omp_threads=1,
                                   mem_per_proc=10 * giga)

            # TODO
            # not commensurate with node
            #d = qad.distribute(mpi_procs=9, omp_threads=1, mem_per_proc=giga)
            #assert d.num_nodes == 3 and d.mpi_per_node == 3 and not d.exact

            with self.assertRaises(qad.Error):
                qad.set_mpi_procs(25)
                qad.validate()
            with self.assertRaises(qad.Error):
                qad.set_mpi_procs(100)
                qad.validate()
            with self.assertRaises(qad.Error):
                qad.set_omp_threads(10)
                qad.validate()
            with self.assertRaises(qad.Error):
                qad.set_mem_per_proc(9 * giga)
                qad.validate()

        # Test if one can register a customized class.
        class MyAdapter(SlurmAdapter):
            QTYPE = "myslurm"

        SlurmAdapter.register(MyAdapter)
        assert issubclass(MyAdapter, QueueAdapter)

        self.QDICT["queue"]["qtype"] = "myslurm"
        qad = make_qadapter(**self.QDICT)
        assert isinstance(qad, MyAdapter)
Ejemplo n.º 2
0
    def test_base(self):
        """unit tests for Qadapter subclasses. A more complete coverage would require integration testing."""
        self.maxDiff = None
        aequal, atrue, afalse = self.assertEqual, self.assertTrue, self.assertFalse
        sub_classes = QueueAdapter.__subclasses__()

        # Test if we can instantiate the concrete classes with the abc protocol.
        for subc in sub_classes:
            print("subclass: ", subc)

            # Create the adapter subclass.
            self.QDICT["queue"]["qtype"] = subc.QTYPE
            qad = make_qadapter(**self.QDICT)
            print(qad)
            hw = qad.hw
            giga = 1024

            # Test the programmatic interface used to change job parameters.
            aequal(qad.num_launches, 0)
            afalse(qad.has_omp)
            atrue(qad.has_mpi)
            qad.set_mpi_procs(2)
            aequal(qad.mpi_procs, 2)
            atrue(qad.pure_mpi)
            afalse(qad.pure_omp)
            afalse(qad.hybrid_mpi_omp)
            aequal(qad.mem_per_proc, giga)
            qad.set_mem_per_proc(2 * giga)
            aequal(qad.mem_per_proc, 2 * giga)
            aequal(qad.timelimit, 120)

            # Enable OMP
            qad.set_omp_threads(2)
            aequal(qad.omp_threads, 2)
            atrue(qad.has_omp)
            afalse(qad.pure_mpi)
            afalse(qad.pure_omp)
            atrue(qad.hybrid_mpi_omp)

            atrue(qad.hw.can_use_omp_threads(hw.sockets_per_node * hw.cores_per_socket))
            afalse(qad.hw.can_use_omp_threads(hw.sockets_per_node * hw.cores_per_socket + 1))

            # Test the creation of the script
            script = qad.get_script_str("job.sh", "/launch/dir", "executable", "qout_path", "qerr_path", 
                                        stdin="STDIN", stdout="STDOUT", stderr="STDERR")

            # Test whether qad can be serialized with Pickle.
            deserialized_qads = self.serialize_with_pickle(qad, test_eq=False)

            for new_qad in deserialized_qads:
                new_script = new_qad.get_script_str("job.sh", "/launch/dir", "executable", "qout_path", "qerr_path", 
                                                    stdin="STDIN", stdout="STDOUT", stderr="STDERR")
                aequal(new_script, script)

            # Test can_run and distribute
            # The hardware has num_nodes=3, sockets_per_node=2, cores_per_socket=4, mem_per_node="8 Gb"
            afalse(qad.can_run_pconf(ParalConf(mpi_ncpus=hw.num_cores+1, omp_ncpus=1, mem_per_cpu=0.1)))
            afalse(qad.can_run_pconf(ParalConf(mpi_ncpus=4, omp_ncpus=9, mem_per_cpu=0.1)))
            afalse(qad.can_run_pconf(ParalConf(mpi_ncpus=4, omp_ncpus=1, mem_per_cpu=10 * giga)))

            d = qad.distribute(mpi_procs=4, omp_threads=1, mem_per_proc=giga)
            assert d.num_nodes == 1 and d.mpi_per_node == 4 and d.exact

            d = qad.distribute(mpi_procs=16, omp_threads=1, mem_per_proc=giga)
            assert d.num_nodes == 2 and d.mpi_per_node == 8 and d.exact

            # not enough memory per node but can distribute.
            d = qad.distribute(mpi_procs=8, omp_threads=1, mem_per_proc=2 * giga)
            assert d.num_nodes == 2 and d.mpi_per_node == 4 and not d.exact

            # mem_per_proc > mem_per_node!
            with self.assertRaises(qad.Error):
                d = qad.distribute(mpi_procs=9, omp_threads=1, mem_per_proc=10 * giga)

            # TODO
            # not commensurate with node
            #d = qad.distribute(mpi_procs=9, omp_threads=1, mem_per_proc=giga)
            #assert d.num_nodes == 3 and d.mpi_per_node == 3 and not d.exact

            with self.assertRaises(qad.Error): 
                qad.set_mpi_procs(25)
                qad.validate()
            with self.assertRaises(qad.Error): 
                qad.set_mpi_procs(100)
                qad.validate()
            with self.assertRaises(qad.Error): 
                qad.set_omp_threads(10)
                qad.validate()
            with self.assertRaises(qad.Error): 
                qad.set_mem_per_proc(9 * giga)
                qad.validate()

        # Test if one can register a customized class.
        class MyAdapter(SlurmAdapter):
            QTYPE = "myslurm"

        SlurmAdapter.register(MyAdapter)
        assert issubclass(MyAdapter, QueueAdapter)

        self.QDICT["queue"]["qtype"] = "myslurm"
        qad = make_qadapter(**self.QDICT)
        assert isinstance(qad, MyAdapter)