def testMultiBreakdown(self): configs = [ HardwareConfig(cpu_ids=[0, 1], gpu_ids=[0]), HardwareConfig(cpu_ids=[2, 3], gpu_ids=[1]) ] result = cg.createRunOptionsForConfigGroup(configs, "2016", self._default_options) expected = [[{ **self.common, 'nt': 2, 'pinoffset': 0, 'ntmpi': 1, 'ntomp': 2, 'gputasks': '0' }, { **self.common, 'nt': 2, 'pinoffset': 2, 'ntmpi': 1, 'ntomp': 2, 'gputasks': '1' }], [{ **self.common, 'nt': 2, 'pinoffset': 0, 'ntmpi': 2, 'ntomp': 1, 'gputasks': '00' }, { **self.common, 'nt': 2, 'pinoffset': 2, 'ntmpi': 2, 'ntomp': 1, 'gputasks': '11' }]] self.assertCountEqual(result, expected)
def setUp(self): self.config1 = HardwareConfig() self.config1.cpu_ids = [0, 2, 4] self.config1.gpu_ids = [0] self.config2 = HardwareConfig() self.config2.cpu_ids = [0, 2, 4] self.config2.gpu_ids = [0]
def testMultipleDecompositionWithOddRankOption(self): # with 6 cpus and 3 gpus, the 3x option exists but not the 2x self.config.cpu_ids = [0, 1, 2, 3, 4, 5] self.config.gpu_ids = [0, 1, 2] single_cpu_option = [HardwareConfig(cpu_ids=[i], gpu_ids=[math.floor(i / 2)]) for i in range(6)] two_cpu_option = [HardwareConfig(cpu_ids=[i, i+1], gpu_ids=[gpu_id]) for gpu_id, i in enumerate((0, 2, 4))] self.expected_base.append(single_cpu_option) self.expected_base.append(two_cpu_option) result = generateConfigSplitOptions(self.config) self.assertCountEqual(self.expected_base, result)
def testMultipleDecompositionWithOneGpu(self): self.config.cpu_ids = [0, 1, 2, 3] self.config.gpu_ids = [0] single_cpu_option = [HardwareConfig(cpu_ids=[i], gpu_ids=[0]) for i in range(4)] double_cpu_option = [HardwareConfig(cpu_ids=[i, i + 1], gpu_ids=[0]) for i in (0, 2)] self.expected_base.append(single_cpu_option) self.expected_base.append(double_cpu_option) result = generateConfigSplitOptions(self.config) self.assertCountEqual(self.expected_base, result)
def testMultipleDecompositionWithMultipleGpus(self): # with 6 cpus and 2 gpus, the 3x option should not exist self.config.cpu_ids = [0, 1, 2, 3, 4, 5] self.config.gpu_ids = [0, 1] single_cpu_option = [HardwareConfig(cpu_ids=[i], gpu_ids=[math.floor(i / 3)]) for i in range(6)] three_cpu_option = [HardwareConfig(cpu_ids=[i, i+1, i+2], gpu_ids=[gpu_id]) for gpu_id, i in enumerate((0, 3))] self.expected_base.append(single_cpu_option) self.expected_base.append(three_cpu_option) result = generateConfigSplitOptions(self.config) self.assertCountEqual(self.expected_base, result)
def testLimitSimsPerGpuDefault(self): # This case tests that there is no config with 1 CPU - there would be 6, which # violates the max of 4. self.config.cpu_ids = [0, 1, 2, 3, 4, 5] self.config.gpu_ids = [0] self.expected_base.append([HardwareConfig(cpu_ids=[0, 1, 2], gpu_ids=[0]), HardwareConfig(cpu_ids=[3, 4, 5], gpu_ids=[0])]) self.expected_base.append([HardwareConfig(cpu_ids=[0, 1], gpu_ids=[0]), HardwareConfig(cpu_ids=[2, 3], gpu_ids=[0]), HardwareConfig(cpu_ids=[4, 5], gpu_ids=[0])]) result = generateConfigSplitOptions(self.config) self.assertCountEqual(self.expected_base, result)
def testOnlyPrimeDivision(self): self.config.cpu_ids = [0, 1, 2] self.config.gpu_ids = [0] options = [HardwareConfig(cpu_ids=[i], gpu_ids=[0]) for i in range(3)] self.expected_base.append(options) result = generateConfigSplitOptions(self.config) self.assertCountEqual(self.expected_base, result)
def testGetAndSet(self): cpu = [1, 2, 3] gpu = [4, 5] hw_config = HardwareConfig(cpu_ids=cpu, gpu_ids=gpu) self.assertEqual(hw_config.num_cpus, 3) self.assertEqual(hw_config.num_gpus, 2) self.assertEqual(hw_config.cpu_ids, [1, 2, 3]) self.assertEqual(hw_config.gpu_ids, [4, 5])
def testNoGpusAndPinStride(self): config = HardwareConfig(cpu_ids=[0, 2, 4]) cg.addConfigDependentOptions(self.options, config) self.assertDictEqual(self.options, { "pin": "on", "pinstride": 2, "pinoffset": 0, "nt": 3, "nb": "cpu" })
def testWithGpus(self): config = HardwareConfig(cpu_ids=[0, 1], gpu_ids=[1]) cg.addConfigDependentOptions(self.options, config) self.assertDictEqual(self.options, { "pin": "on", "pinstride": 1, "pinoffset": 0, "nt": 2, "nb": "gpu" })
def testSingleCPUAndOffset(self): config = HardwareConfig(cpu_ids=[5]) cg.addConfigDependentOptions(self.options, config) self.assertDictEqual(self.options, { "pin": "on", "pinstride": 1, "pinoffset": 5, "nt": 1, "nb": "cpu" })
def _executeGenerateWorkflow(args: argparse.Namespace) -> None: logger: logging.Logger = logging.getLogger("gromax") logger.info("Generating run options.") # Assign hardware config cpu_ids: List[int] = parseIDString(args.cpu_ids) logger.info("CPU IDs: {}".format(cpu_ids)) num_cpus: int = len(cpu_ids) if num_cpus % 2 == 1: logger.warning( "Detected an odd number of CPU IDs ({}), this is atypical.".format( num_cpus)) gpu_ids: List[int] = parseIDString(args.gpu_ids) logger.info("GPU IDs: {}".format(gpu_ids)) num_gpus: int = len(gpu_ids) modval: int = num_cpus % num_gpus if modval != 0: logger.warning( "Number of CPUs({}) is not divisible by the number of GPUs({}), will only use {} CPUs." .format(num_cpus, num_gpus, num_cpus - modval)) cpu_ids = cpu_ids[:-modval] hw_config: HardwareConfig = HardwareConfig(cpu_ids=cpu_ids, gpu_ids=gpu_ids) generate_options: GenerateOptions = _populateGenerateOptions(args) if args.single_sim_only: config_splits: List[List[HardwareConfig]] = [[hw_config]] else: config_splits: List[List[HardwareConfig]] = generateConfigSplitOptions( hw_config, max_sims_per_gpu=generate_options.max_sims_per_gpu) logger.debug("Generated {} hardware config breakdowns".format( len(config_splits))) run_opts: List[List[Dict]] = [] for config_split in config_splits: run_opts.extend( createRunOptionsForConfigGroup(config_split, args.gmx_version, generate_options)) # Serialize options. out_file: str = args.run_file # TODO Make this configurable and robust gmx: str = args.gmx_executable + " mdrun" tpr: str = args.tpr num_trials: int = args.trials_per_group WriteRunScript(out_file, ParamsToString(run_opts, tpr, gmx, num_trials))
def testFailsInvalidVersion(self): with self.assertRaises(ValueError): cg.createRunOptionsForConfigGroup([HardwareConfig(cpu_ids=[0])], "2015", self._default_options)
def testEmpty(self): self.assertEqual(HardwareConfig(), HardwareConfig())
def testGpuIDFailureNotAnInt(self, mock_fatal): hw_config = HardwareConfig() hw_config.gpu_ids = [1, 1.7584, 3] mock_fatal.assert_called_with("All gpu ids must be integers: {} is not an int".format(1.7584))
def testGpuIDFailureNotAList(self, mock_fatal): hw_config = HardwareConfig() hw_config.gpu_ids = 5 mock_fatal.assert_called_with("gpu_ids paramater must be iterable")
def testRepr(self): config = HardwareConfig(cpu_ids=[1, 2], gpu_ids=[5]) self.assertEqual(config.__repr__(), "\nHardware config:\n\tcpu IDs : [1, 2]\n\tgpu IDs : [5]")
def setUp(self): self.config = HardwareConfig() self.expected_base = [[self.config]]
def testGpuIDFailureNotPositive(self, mock_fatal): hw_config = HardwareConfig() hw_config.gpu_ids = [1, 3, -1] mock_fatal.assert_called_with("Cannot have a negative GPU ID")
def setUp(self): self.config = HardwareConfig(cpu_ids=[0, 1, 2, 3]) self._default_options: cg.GenerateOptions = cg.GenerateOptions( generate_exhaustive_options=True, max_sims_per_gpu=4)
def testEmpty(self): hw_config = HardwareConfig() self.assertEqual(hw_config.num_cpus, 0) self.assertEqual(hw_config.num_gpus, 0) self.assertFalse(len(hw_config.cpu_ids)) self.assertFalse(len(hw_config.gpu_ids))