Beispiel #1
0
def build_module_from_op_list(op_list: List[Dict],
                              remove_ops=False,
                              thres=None) -> tq.QuantumModule:
    logger.info(f"Building module from op_list...")
    thres = 1e-5 if thres is None else thres
    n_removed_ops = 0
    ops = []
    for info in op_list:
        params = info['params']

        if remove_ops:
            if params is not None:
                params = np.array(params) if isinstance(params, Iterable) \
                    else np.array([params])
                params = params % (2 * np.pi)
                params[params > np.pi] -= 2 * np.pi
                if all(abs(params) < thres):
                    n_removed_ops += 1
                    continue

        op = tq.op_name_dict[info['name']](
            has_params=info['has_params'],
            trainable=info['trainable'],
            wires=info['wires'],
            n_wires=info['n_wires'],
            init_params=info['params'],
        )
        ops.append(op)

    if n_removed_ops > 0:
        logger.warning(f"Remove in total {n_removed_ops} pruned operations.")
    else:
        logger.info(f"Do not remove any operations.")

    return tq.QuantumModuleFromOps(ops)
    def _trigger(self) -> None:
        start_time = time.perf_counter()
        self.callbacks.before_epoch()

        with torch.no_grad():
            orig_is_add_noise = self.trainer.model.nodes[
                0].noise_model_tq.is_add_noise
            orig_noise_total_prob = self.trainer.model.nodes[
                0].noise_model_tq.noise_total_prob
            orig_mode = self.trainer.model.nodes[0].noise_model_tq.mode

            for node in self.trainer.model.nodes:
                node.noise_model_tq.noise_total_prob = self.noise_total_prob
                node.noise_model_tq.is_add_noise = True
                node.noise_model_tq.mode = 'train'

            for feed_dict in tqdm.tqdm(self.dataflow, ncols=0):
                self.callbacks.before_step(feed_dict)
                output_dict = self.trainer.run_step(feed_dict)
                self.callbacks.after_step(output_dict)

            for node in self.trainer.model.nodes:
                node.noise_model_tq.is_add_noise = orig_is_add_noise
                node.noise_model_tq.noise_total_prob = orig_noise_total_prob
                node.noise_model_tq.mode = orig_mode

        self.callbacks.after_epoch()
        logger.info('Inference finished in {}.'.format(
            humanize.naturaldelta(time.perf_counter() - start_time)))
Beispiel #3
0
    def forward(self, x, verbose=False, use_qiskit=False):
        bsz = x.shape[0]

        if use_qiskit:
            x = self.qiskit_processor.process_multi_measure(
                self.q_device, self.q_layer, self.measure)
        else:
            self.q_device.reset_states(bsz=1)
            self.q_layer(self.q_device)
            x = self.measure(self.q_device)

        hamil_coefficients = torch.tensor(
            [hamil['coefficient'] for hamil in self.hamil_info['hamil_list']],
            device=x.device).double()

        for k, hamil in enumerate(self.hamil_info['hamil_list']):
            for wire, observable in zip(hamil['wires'], hamil['observables']):
                if observable == 'i':
                    x[k][wire] = 1
            for wire in range(self.q_device.n_wires):
                if wire not in hamil['wires']:
                    x[k][wire] = 1

        if verbose:
            logger.info(f"[use_qiskit]={use_qiskit}, expectation:\n {x.data}")

        x = torch.cumprod(x, dim=-1)[:, -1].double()
        x = torch.dot(x, hamil_coefficients)

        if x.dim() == 0:
            x = x.unsqueeze(0)

        return x
Beispiel #4
0
    def _trigger(self):
        if self.scalar not in self.trainer.summary:
            logger.warning(
                f'`{self.scalar}` has not been added to `trainer.summary`.')
            return
        step, value = self.trainer.summary[self.scalar][-1]

        if self.step is not None and step <= self.step:
            logger.warning(
                f'`{self.scalar}` has not been updated since last trigger.')
            return
        self.step = step

        if (self.best is None
                or (self.extreme == 'min' and value < self.best[1])
                or (self.extreme == 'max' and value > self.best[1])):
            self.best = (step, value)
            save_path = os.path.join(self.save_dir, self.name + '.pt')
            try:
                io.save(save_path, self.trainer.state_dict())
            except OSError:
                logger.exception(
                    f'Error occurred when saving checkpoint "{save_path}".')
            else:
                logger.info(f'Checkpoint saved: "{save_path}" ({value:.5g}).')

        if self.best is not None:
            self.trainer.summary.add_scalar(self.scalar + '/' + self.extreme,
                                            self.best[1])
Beispiel #5
0
    def forward(self, x, verbose=False, use_qiskit=False):
        bsz = x.shape[0]

        if getattr(self.arch, 'down_sample_kernel_size', None) is not None:
            x = F.avg_pool2d(x, self.arch['down_sample_kernel_size'])

        x = x.view(bsz, -1)

        if use_qiskit:
            x = self.qiskit_processor.process_parameterized(
                self.q_device, self.encoder, self.q_layer, self.measure, x)
        else:
            self.encoder(self.q_device, x)
            self.q_layer(self.q_device)
            x = self.measure(self.q_device)

        if verbose:
            logger.info(f"[use_qiskit]={use_qiskit}, expectation:\n {x.data}")

        if getattr(self.arch, 'output_len', None) is not None:
            x = x.reshape(bsz, -1, self.arch.output_len).sum(-1)

        if x.dim() > 2:
            x = x.squeeze()

        x = F.log_softmax(x, dim=1)
        return x
 def get_n_ops_per_chunk(self):
     """separate the space to several subspace"""
     n_chunks = self.strategy['n_chunks']
     if self.strategy['chunk_mode'] == 'same_interval':
         logger.warning(f"same_interval chunking may cause extra long "
                        f"time to sample a sub network because of the "
                        f"Central Limit Theorem of n_ops in a subnet")
         self.n_ops_per_chunk = list(np.linspace(self.n_ops_smallest,
                                                 self.n_ops_largest,
                                                 n_chunks + 1).astype(int))
     elif self.strategy['chunk_mode'] == 'same_n_samples':
         logger.info("estimating the chunks...")
         n_ops_all = []
         n_chunk_est_samples = self.strategy['n_chunk_est_samples']
         for k in range(n_chunk_est_samples):
             sample_arch = self.get_random_sample_arch()
             n_ops_all.append(self.get_sample_stats(sample_arch))
         n_ops_all.sort()
         idx_all = np.linspace(0, n_chunk_est_samples - 1, n_chunks +
                               1).astype(int)
         self.n_ops_per_chunk = [n_ops_all[idx] for idx in idx_all]
         self.n_ops_per_chunk[0] = self.n_ops_smallest
         self.n_ops_per_chunk[-1] = self.n_ops_largest
     else:
         raise NotImplementedError(
             f"chunk mode {self.strategy['chunk_mode']} not supported.")
Beispiel #7
0
 def _trigger(self) -> None:
     texts = []
     for name, scalar in sorted(self.scalars.items()):
         if self.matcher.match(name):
             texts.append(f'[{name}] = {scalar:.5g}')
     if texts:
         logger.info('\n+ '.join([''] + texts))
     self.scalars.clear()
Beispiel #8
0
    def _trigger_epoch(self) -> None:
        if self.trainer.epoch_num < self.trainer.num_epochs:
            self.times.append(time.perf_counter() - self.last_time)
            self.last_time = time.perf_counter()

            estimated_time = (self.trainer.num_epochs -
                              self.trainer.epoch_num) * np.mean(self.times)
            logger.info('Estimated time left: {}.'.format(
                humanize.naturaldelta(estimated_time)))
Beispiel #9
0
def log_acc(output_all, target_all, k=1):
    _, indices = output_all.topk(k, dim=1)
    masks = indices.eq(target_all.view(-1, 1).expand_as(indices))
    size = target_all.shape[0]
    corrects = masks.sum().item()
    accuracy = corrects / size
    loss = F.nll_loss(output_all, target_all).item()
    logger.info(f"Accuracy: {accuracy}")
    logger.info(f"Loss: {loss}")
Beispiel #10
0
 def _trigger(self) -> None:
     save_path = os.path.join(self.save_dir,
                              f'step-{self.trainer.global_step}.pt')
     try:
         io.save(save_path, self.trainer.state_dict())
     except OSError:
         logger.exception(
             f'Error occurred when saving checkpoint "{save_path}".')
     else:
         logger.info(f'Checkpoint saved: "{save_path}".')
         self._add_checkpoint(save_path)
def state_tq_vs_qiskit_test():
    bsz = 1
    for n_wires in range(2, 10):
        q_dev = tq.QuantumDevice(n_wires=n_wires)
        q_dev.reset_states(bsz=bsz)

        x = torch.randn((1, 100000), dtype=F_DTYPE)
        q_layer = AllRandomLayer(n_wires=n_wires,
                                 wires=list(range(n_wires)),
                                 n_ops_rd=500,
                                 n_ops_cin=500,
                                 n_funcs=500,
                                 qiskit_compatible=True)

        q_layer(q_dev, x)
        state_tq = q_dev.states.reshape(bsz, -1)
        state_tq = switch_little_big_endian_state(state_tq.data.numpy())

        # qiskit
        circ = tq2qiskit(q_layer, x)
        # Select the StatevectorSimulator from the Aer provider
        simulator = Aer.get_backend('statevector_simulator')

        # Execute and get counts
        result = execute(circ, simulator).result()
        state_qiskit = result.get_statevector(circ)

        stable_threshold = 1e-5
        try:
            # WARNING: need to remove the global phase! The qiskit simulated
            # results sometimes has global phase shift.
            global_phase = find_global_phase(state_tq,
                                             np.expand_dims(state_qiskit, 0),
                                             stable_threshold)

            if global_phase is None:
                logger.exception(f"Cannot find a stable enough factor to "
                                 f"reduce the global phase, increase the "
                                 f"stable_threshold and try again")
                raise RuntimeError

            assert np.allclose(state_tq * global_phase,
                               state_qiskit,
                               atol=1e-6)
            logger.info(f"PASS tq vs qiskit [n_wires]={n_wires}")

        except AssertionError:
            logger.exception(f"FAIL tq vs qiskit [n_wires]={n_wires}")
            raise AssertionError

        except RuntimeError:
            raise RuntimeError

    logger.info(f"PASS tq vs qiskit statevector test")
Beispiel #12
0
    def _trigger(self) -> None:
        start_time = time.perf_counter()
        self.callbacks.before_epoch()

        with torch.no_grad():
            for feed_dict in tqdm.tqdm(self.dataflow, ncols=0):
                self.callbacks.before_step(feed_dict)
                output_dict = self.trainer.run_step(feed_dict)
                self.callbacks.after_step(output_dict)

        self.callbacks.after_epoch()
        logger.info('Inference finished in {}.'.format(
            humanize.naturaldelta(time.perf_counter() - start_time)))
Beispiel #13
0
    def _before_train(self) -> None:
        checkpoints = glob.glob(os.path.join(self.load_dir, 'step-*.pt'))
        if not checkpoints:
            logger.warning(f'No checkpoints found: "{self.load_dir}".')
            return

        load_path = max(checkpoints, key=os.path.getmtime)
        try:
            state_dict = io.load(load_path, map_location='cpu')
            self.trainer.load_state_dict(state_dict)
        except OSError:
            logger.exception(
                f'Error occurred when loading checkpoint "{load_path}".')
        else:
            logger.info(f'Checkpoint loaded: "{load_path}".')
Beispiel #14
0
    def train(self,
              dataflow: DataLoader,
              *,
              num_epochs: int = 9999999,
              callbacks: Optional[List[Callback]] = None) -> None:
        self.dataflow = dataflow
        self.steps_per_epoch = len(self.dataflow)
        self.num_epochs = num_epochs

        if callbacks is None:
            callbacks = []
        self.callbacks = Callbacks(callbacks)
        self.summary = Summary()

        try:
            self.callbacks.set_trainer(self)
            self.summary.set_trainer(self)

            self.epoch_num = 0
            self.global_step = 0

            train_time = time.perf_counter()
            self.before_train()

            while self.epoch_num < self.num_epochs:
                self.epoch_num += 1
                self.local_step = 0

                logger.info('Epoch {}/{} started.'.format(
                    self.epoch_num, self.num_epochs))
                epoch_time = time.perf_counter()
                self.before_epoch()

                for feed_dict in self.dataflow:
                    self.local_step += 1
                    self.global_step += 1

                    self.before_step(feed_dict)
                    output_dict = self.run_step(feed_dict)
                    self.after_step(output_dict)

                    self.trigger_step()

                self.after_epoch()
                logger.info('Training finished in {}.'.format(
                    humanize.naturaldelta(time.perf_counter() - epoch_time)))

                self.trigger_epoch()
                logger.info('Epoch finished in {}.'.format(
                    humanize.naturaldelta(time.perf_counter() - epoch_time)))

            logger.success('{} epochs of training finished in {}.'.format(
                self.num_epochs,
                humanize.naturaldelta(time.perf_counter() - train_time)))
        except StopTraining as e:
            logger.info('Training was stopped by {}.'.format(str(e)))
        finally:
            self.after_train()
def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument('config', metavar='FILE', help='config file')
    parser.add_argument('--run-dir', metavar='DIR', help='run directory')
    parser.add_argument('--pdb', action='store_true', help='pdb')
    parser.add_argument('--gpu', type=str, help='gpu ids', default=None)
    args, opts = parser.parse_known_args()

    configs.load(args.config, recursive=True)
    configs.update(opts)

    if configs.debug.pdb or args.pdb:
        pdb.set_trace()

    if args.gpu is not None:
        os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu

    if configs.debug.set_seed:
        torch.manual_seed(configs.debug.seed)
        np.random.seed(configs.debug.seed)

    if configs.run.device == 'gpu':
        device = torch.device('cuda')
    elif configs.run.device == 'cpu':
        device = torch.device('cpu')
    else:
        raise ValueError(configs.run.device)

    logger.info(' '.join([sys.executable] + sys.argv))
    logger.info(f'Profiling started: "{args.run_dir}".' + '\n' + f'{configs}')

    inputs = torch.tensor(torch.rand(configs.run.bsz, 1, 28, 28),
                          device=device)

    model = builder.make_model()
    model.to(device)

    with profiler.profile(record_shapes=True) as prof:
        with profiler.record_function("model_inference"):
            for _ in range(3):
                time.sleep(0.5)
                model(inputs)

    # for _ in range(3):
    #     model(inputs)

    prof.export_chrome_trace("part1_static.json")
Beispiel #16
0
def main() -> None:
    torch.backends.cudnn.benchmark = True

    parser = argparse.ArgumentParser()
    parser.add_argument('config', metavar='FILE', help='config file')
    parser.add_argument('--ckpt-dir', metavar='DIR', help='run directory')
    parser.add_argument('--pdb', action='store_true', help='pdb')
    parser.add_argument('--gpu', type=str, help='gpu ids', default=None)
    parser.add_argument('--print-configs',
                        action='store_true',
                        help='print ALL configs')
    args, opts = parser.parse_known_args()

    configs.load(args.config, recursive=True)
    configs.update(opts)

    if configs.debug.pdb or args.pdb:
        pdb.set_trace()

    if configs.debug.set_seed:
        torch.manual_seed(configs.debug.seed)
        np.random.seed(configs.debug.seed)

    if args.print_configs:
        print_conf = configs
    else:
        print_conf = get_cared_configs(configs, 'train')

    logger.info(f"Generate subnet started: \n {print_conf}")

    model = builder.make_model()

    sampler = ArchSampler(
        model,
        strategy=configs.model.sampler.strategy,
        n_layers_per_block=configs.model.arch.n_layers_per_block)

    arch_all = []
    for _ in range(100):
        arch = sampler.get_random_sample_arch()
        arch_all.append(arch)

    arch_all.sort(key=lambda x: x[-1])

    for arch in arch_all:
        logger.info(f"blk {arch[-1]} arch: {arch}")
def unitary_tq_vs_qiskit_test():
    for n_wires in range(2, 10):
        q_dev = tq.QuantumDevice(n_wires=n_wires)
        x = torch.randn((1, 100000), dtype=F_DTYPE)
        q_layer = AllRandomLayer(n_wires=n_wires,
                                 wires=list(range(n_wires)),
                                 n_ops_rd=500,
                                 n_ops_cin=500,
                                 n_funcs=500,
                                 qiskit_compatible=True)

        unitary_tq = q_layer.get_unitary(q_dev, x)
        unitary_tq = switch_little_big_endian_matrix(unitary_tq.data.numpy())

        # qiskit
        circ = tq2qiskit(q_layer, x)
        simulator = Aer.get_backend('unitary_simulator')
        result = execute(circ, simulator).result()
        unitary_qiskit = result.get_unitary(circ)

        stable_threshold = 1e-5
        try:
            # WARNING: need to remove the global phase! The qiskit simulated
            # results sometimes has global phase shift.
            global_phase = find_global_phase(unitary_tq, unitary_qiskit,
                                             stable_threshold)

            if global_phase is None:
                logger.exception(f"Cannot find a stable enough factor to "
                                 f"reduce the global phase, increase the "
                                 f"stable_threshold and try again")
                raise RuntimeError

            assert np.allclose(unitary_tq * global_phase,
                               unitary_qiskit,
                               atol=1e-6)
            logger.info(f"PASS tq vs qiskit [n_wires]={n_wires}")

        except AssertionError:
            logger.exception(f"FAIL tq vs qiskit [n_wires]={n_wires}")
            raise AssertionError

        except RuntimeError:
            raise RuntimeError

    logger.info(f"PASS tq vs qiskit unitary test")
Beispiel #18
0
    def forward(self, x, verbose=False, use_qiskit=False):
        bsz = x.shape[0]
        x = F.avg_pool2d(x, 6).view(bsz, 16)

        if use_qiskit:
            x = self.qiskit_processor.process_parameterized(
                self.q_device, self.encoder, self.q_layer, self.measure, x)
        else:
            self.encoder(self.q_device, x)
            self.q_layer(self.q_device)
            x = self.measure(self.q_device)

        if verbose:
            logger.info(f"[use_qiskit]={use_qiskit}, expectation:\n {x.data}")

        x = x.squeeze()
        x = F.log_softmax(x, dim=1)
        return x
def measurement_tq_vs_qiskit_test():
    bsz = 1
    for n_wires in range(2, 10):
        q_dev = tq.QuantumDevice(n_wires=n_wires)
        q_dev.reset_states(bsz=bsz)

        x = torch.randn((1, 100000), dtype=F_DTYPE)
        q_layer = AllRandomLayer(n_wires=n_wires,
                                 wires=list(range(n_wires)),
                                 n_ops_rd=500,
                                 n_ops_cin=500,
                                 n_funcs=500,
                                 qiskit_compatible=True)

        q_layer(q_dev, x)
        measurer = tq.MeasureAll(obs=tq.PauliZ)
        # flip because qiskit is from N to 0, tq is from 0 to N
        measured_tq = np.flip(measurer(q_dev).data[0].numpy())

        # qiskit
        circ = tq2qiskit(q_layer, x)
        circ.measure(list(range(n_wires)), list(range(n_wires)))

        # Select the QasmSimulator from the Aer provider
        simulator = Aer.get_backend('qasm_simulator')

        # Execute and get counts
        result = execute(circ, simulator, shots=1000000).result()
        counts = result.get_counts(circ)
        measured_qiskit = get_expectations_from_counts(counts, n_wires=n_wires)

        try:
            # WARNING: the measurement has randomness, so tolerate larger
            # differences (MAX 20%) between tq and qiskit
            # typical mean difference is less than 1%
            diff = np.abs(measured_tq - measured_qiskit).mean()
            diff_ratio = (np.abs(
                (measured_tq - measured_qiskit) / measured_qiskit)).mean()
            logger.info(f"Diff: tq vs qiskit {diff} \t Diff Ratio: "
                        f"{diff_ratio}")
            assert np.allclose(measured_tq,
                               measured_qiskit,
                               atol=1e-4,
                               rtol=2e-1)
            logger.info(f"PASS tq vs qiskit [n_wires]={n_wires}")

        except AssertionError:
            logger.exception(f"FAIL tq vs qiskit [n_wires]={n_wires}")
            raise AssertionError

    logger.info(f"PASS tq vs qiskit measurement test")
              f'.motivation.txt',
              'a') as \
            wfid:
        for setting in [
                'nonorm',
                # 'bnormnolast'
        ]:
            for device in [
                    'x2',
                    'lima',
                    'santiago',
                    # 'belem',
                    # 'quito'
            ]:

                last_step = last_step_dict[args.dataset][args.name]
                pres = [
                    'python', 'examples/eval.py', f'examples/configs/'
                    f'{args.dataset}/{args.name}/eval/'
                    f'{device}/real/opt2/noancilla/'
                    f'300_s{last_step}{valid}.yml', '--jobs=5', '--verbose',
                    '--gpu=2', f'--hub={args.hub}', '--run-dir'
                ]

                exp = f'runs/{args.dataset}.{args.name}.train.noaddnoise.' \
                      f'{setting}.u3cu3_0.{node_dict[device]}.default'
                logger.info(f"running command {pres + [exp]}")

                if not args.print:
                    subprocess.call(pres + [exp], stderr=wfid)
Beispiel #21
0
def main() -> None:
    torch.backends.cudnn.benchmark = True

    parser = argparse.ArgumentParser()
    parser.add_argument('config', metavar='FILE', help='config file')
    parser.add_argument('--run-dir', metavar='DIR', help='run directory')
    parser.add_argument('--pdb', action='store_true', help='pdb')
    parser.add_argument('--verbose', action='store_true', help='verbose')
    parser.add_argument('--gpu', type=str, help='gpu ids', default=None)
    parser.add_argument('--print-configs',
                        action='store_true',
                        help='print ALL configs')
    parser.add_argument('--jobs',
                        type=int,
                        default=None,
                        help='max parallel job on qiskit')
    parser.add_argument('--hub', type=str, default=None, help='IBMQ provider')

    args, opts = parser.parse_known_args()

    configs.load(os.path.join(args.run_dir, 'metainfo', 'configs.yaml'))
    configs.load(args.config, recursive=True)
    configs.update(opts)

    # for eval, always need load weights
    configs.ckpt.weight_from_scratch = False

    if configs.debug.pdb or args.pdb:
        pdb.set_trace()

    configs.verbose = args.verbose
    configs.qiskit.hub = args.hub

    if args.gpu is not None:
        os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu

    if args.jobs is not None:
        configs.qiskit.max_jobs = args.jobs

    if configs.run.device == 'gpu':
        device = torch.device('cuda')
    elif configs.run.device == 'cpu':
        device = torch.device('cpu')
    else:
        raise ValueError(configs.run.device)

    if args.print_configs:
        print_conf = configs
    else:
        print_conf = get_cared_configs(configs, 'eval')

    logger.info(f'Evaluation started: "{args.run_dir}".' + '\n' +
                f'{print_conf}')

    eval_config_dir = args.config.replace('/', '.').replace(
        'examples.', '').replace('.yml', '').replace('configs.', '')
    configs.eval_config_dir = eval_config_dir
    configs.run_dir = args.run_dir

    # if configs.qiskit.use_qiskit:
    #     IBMQ.load_account()
    #     if configs.run.bsz == 'qiskit_max':
    #         configs.run.bsz = IBMQ.get_provider(hub='ibm-q').get_backend(
    #             configs.qiskit.backend_name).configuration().max_experiments

    dataset = builder.make_dataset()
    sampler = torch.utils.data.SequentialSampler(
        dataset[configs.dataset.split])
    dataflow = torch.utils.data.DataLoader(
        dataset[configs.dataset.split],
        sampler=sampler,
        batch_size=configs.run.bsz,
        num_workers=configs.run.workers_per_gpu,
        pin_memory=True)

    state_dict = io.load(os.path.join(args.run_dir, configs.ckpt.name),
                         map_location='cpu')
    model_load = state_dict['model_arch']
    model = builder.make_model()
    for module_load, module in zip(model_load.modules(), model.modules()):
        if isinstance(module, tq.RandomLayer):
            # random layer, need to restore the architecture
            module.rebuild_random_layer_from_op_list(
                n_ops_in=module_load.n_ops,
                wires_in=module_load.wires,
                op_list_in=module_load.op_list,
            )

    model.load_state_dict(state_dict['model'], strict=False)

    solution = None
    if 'solution' in state_dict.keys():
        solution = state_dict['solution']
        logger.info(f"Evaluate the solution {solution}")
        logger.info(f"Original score: {state_dict['score']}")
        model.set_sample_arch(solution['arch'])

    if 'v_c_reg_mapping' in state_dict.keys():
        if getattr(model, 'q_layer', None) is not None:
            try:
                model.measure.set_v_c_reg_mapping(
                    state_dict['v_c_reg_mapping'])
            except AttributeError:
                logger.warning(f"Cannot set v_c_reg_mapping.")
        elif getattr(model, 'nodes', None) is not None:
            for k, node in enumerate(model.nodes):
                node.measure.set_v_c_reg_mapping(
                    state_dict['v_c_reg_mapping'][k])

    if state_dict.get('q_layer_op_list', None) is not None and not \
            configs.model.load_op_list:
        logger.warning(f"the model has op_list but is not loaded!!")

    if configs.model.load_op_list:
        assert state_dict['q_layer_op_list'] is not None
        logger.warning(f"Loading the op_list, will replace the q_layer in "
                       f"the original model!")
        if getattr(model, 'q_layer', None) is not None:
            q_layer = build_module_from_op_list(
                op_list=state_dict['q_layer_op_list'],
                remove_ops=configs.prune.eval.remove_ops,
                thres=configs.prune.eval.remove_ops_thres)
            model.q_layer = q_layer
        elif getattr(model, 'nodes', None) is not None:
            for k, node in enumerate(model.nodes):
                q_layer = build_module_from_op_list(
                    op_list=state_dict['q_layer_op_list'][k],
                    remove_ops=configs.prune.eval.remove_ops,
                    thres=configs.prune.eval.remove_ops_thres)
                node.q_layer = q_layer

    if state_dict.get('noise_model_tq', None) is not None:
        # the readout error is ALSO applied for eval and test so need load
        # noise_model_tq
        if getattr(model, 'q_layer', None) is not None:
            model.set_noise_model_tq(state_dict['noise_model_tq'])
            if getattr(configs, 'add_noise', False):
                model.noise_model_tq.mode = 'train'
                model.noise_model_tq.noise_total_prob = \
                    configs.noise_total_prob
            else:
                model.noise_model_tq.mode = 'test'
        elif getattr(model, 'nodes', None) is not None:
            for k, node in enumerate(model.nodes):
                node.set_noise_model_tq(state_dict['noise_model_tq'][k])
                if getattr(configs, 'add_noise', False):
                    node.noise_model_tq.mode = 'train'
                    node.noise_model_tq.noise_total_prob = \
                        configs.noise_total_prob
                else:
                    node.noise_model_tq.mode = 'test'

    if configs.model.transpile_before_run:
        # transpile the q_layer
        logger.warning(f"Transpile the q_layer to basis gate set before "
                       f"evaluation, will replace the q_layer!")
        processor = builder.make_qiskit_processor()

        circ = tq2qiskit(model.q_device, model.q_layer)
        """
        add measure because the transpile process may permute the wires, 
        so we need to get the final q reg to c reg mapping 
        """
        circ.measure(list(range(model.q_device.n_wires)),
                     list(range(model.q_device.n_wires)))

        if solution is not None:
            processor.set_layout(solution['layout'])
            logger.warning(f"Set layout {solution['layout']} for transpile!")

        logger.info("Transpiling circuit...")
        circ_transpiled = processor.transpile(circs=circ)
        q_layer = qiskit2tq(circ=circ_transpiled)

        model.measure.set_v_c_reg_mapping(get_v_c_reg_mapping(circ_transpiled))
        model.q_layer = q_layer

    if configs.legalization.legalize:
        legalize_unitary(model)

    if configs.act_quant.add_in_eval:
        quantizers = []
        assert getattr(model, 'nodes', None) is not None
        if getattr(configs.act_quant, 'act_quant_bit', None) is not None:
            # settings from config file has higher priority
            act_quant_bit = configs.act_quant.act_quant_bit
            act_quant_ratio = configs.act_quant.act_quant_ratio
            act_quant_level = configs.act_quant.act_quant_level
            act_quant_lower_bound = configs.act_quant.act_quant_lower_bound
            act_quant_upper_bound = configs.act_quant.act_quant_upper_bound
            logger.warning(f"Get act_quant setting from config file!")
        elif state_dict.get('act_quant', None) is not None:
            act_quant_bit = state_dict['act_quant']['act_quant_bit']
            act_quant_ratio = state_dict['act_quant']['act_quant_ratio']
            act_quant_level = state_dict['act_quant']['act_quant_level']
            act_quant_lower_bound = state_dict['act_quant'][
                'act_quant_lower_bound']
            act_quant_upper_bound = state_dict['act_quant'][
                'act_quant_upper_bound']
            logger.warning(f"Get act_quant setting from ckpt file!")
        elif getattr(configs.trainer, 'act_quant_bit', None) is not None:
            # if the act_quant info is not stored in ckpt, use the info from
            # training config file
            act_quant_bit = configs.trainer.act_quant_bit
            act_quant_ratio = configs.trainer.act_quant_ratio
            act_quant_level = configs.trainer.act_quant_level
            act_quant_lower_bound = configs.trainer.act_quant_lower_bound
            act_quant_upper_bound = configs.trainer.act_quant_upper_bound
            logger.warning(f"Get act_quant setting from previous training "
                           f"config file!")
        else:
            raise NotImplementedError('No act_quant info specified!')

        logger.warning(f"act_quant_bit={act_quant_bit}, "
                       f"act_quant_ratio={act_quant_ratio}, "
                       f"act_quant_level={act_quant_level}, "
                       f"act_quant_lower_bound={act_quant_lower_bound}, "
                       f"act_quant_upper_bound={act_quant_upper_bound}")

        for k, node in enumerate(model.nodes):
            if configs.trainer.act_quant_skip_last_node and k == len(
                    model.nodes) - 1:
                continue
            quantizer = PACTActivationQuantizer(
                module=node,
                precision=act_quant_bit,
                level=act_quant_level,
                alpha=1.0,
                backprop_alpha=False,
                quant_ratio=act_quant_ratio,
                device=device,
                lower_bound=act_quant_lower_bound,
                upper_bound=act_quant_upper_bound,
            )
            quantizers.append(quantizer)

        for quantizer in quantizers:
            quantizer.register_hook()

    if getattr(configs, 'pre_specified_mean', None) is not None and \
            configs.pre_specified_std \
            is not None:
        for k, node in enumerate(model.nodes):
            node.pre_specified_mean_std = {
                'mean': configs.pre_specified_mean[k],
                'std': configs.pre_specified_std[k],
            }

    model.to(device)
    model.eval()

    if configs.qiskit.use_qiskit:
        qiskit_processor = builder.make_qiskit_processor()
        if configs.qiskit.initial_layout is not None:
            layout = configs.qiskit.initial_layout
            logger.warning(f"Use layout {layout} from config file")
        elif 'solution' in state_dict.keys():
            layout = state_dict['solution']['layout']
            logger.warning(f"Use layout {layout} from checkpoint file")
        else:
            layout = None
            logger.warning(f"No specified layout")
        qiskit_processor.set_layout(layout)
        model.set_qiskit_processor(qiskit_processor)

    if getattr(configs.model.arch, 'sample_arch', None) is not None:
        sample_arch = configs.model.arch.sample_arch
        logger.warning(f"Setting sample arch {sample_arch} from config file!")
        if isinstance(sample_arch, str):
            # this is the name of arch
            sample_arch = get_named_sample_arch(model.arch_space, sample_arch)
            logger.warning(f"Decoded sample arch: {sample_arch}")
        model.set_sample_arch(sample_arch)

    if configs.get_n_params:
        n_params = model.count_sample_params()
        logger.info(f"Number of sampled params: {n_params}")
        exit(0)

    if configs.qiskit.est_success_rate:
        circ_parameterized, params = tq2qiskit_parameterized(
            model.q_device, model.encoder.func_list)
        circ_fixed = tq2qiskit(model.q_device, model.q_layer)
        circ = circ_parameterized + circ_fixed
        transpiled_circ = model.qiskit_processor.transpile(circ)

        success_rate = get_success_rate(model.qiskit_processor.properties,
                                        transpiled_circ)
        logger.info(f"Success rate: {success_rate}")
        logger.info(f"Size: {transpiled_circ.size()}")
        logger.info(f"Depth: {transpiled_circ.depth()}")
        logger.info(f"Width: {transpiled_circ.width()}")
        exit(0)

    total_params = sum(p.numel() for p in model.parameters())
    logger.info(f'Model Size: {total_params}')

    if hasattr(model, 'sample_arch') and not configs.model.load_op_list:
        n_params = model.count_sample_params()
        logger.info(f"Number of sampled params: {n_params}")

    with torch.no_grad():
        target_all = None
        output_all = None
        for feed_dict in tqdm.tqdm(dataflow):
            if configs.run.device == 'gpu':
                inputs = feed_dict[configs.dataset.input_name].cuda(
                    non_blocking=True)
                targets = feed_dict[configs.dataset.target_name].cuda(
                    non_blocking=True)
            else:
                inputs = feed_dict[configs.dataset.input_name]
                targets = feed_dict[configs.dataset.target_name]

            outputs = model(inputs,
                            verbose=configs.verbose,
                            use_qiskit=configs.qiskit.use_qiskit)

            if target_all is None:
                target_all = targets
                output_all = outputs
            else:
                target_all = torch.cat([target_all, targets], dim=0)
                output_all = torch.cat([output_all, outputs], dim=0)
            # if configs.verbose:
            #     logger.info(f"Measured log_softmax: {outputs}")
            if not configs.dataset.name == 'vqe':
                log_acc(output_all, target_all)

    logger.info("Final:")
    if not configs.dataset.name == 'vqe':
        log_acc(output_all, target_all)
    else:
        logger.info(f"Eigenvalue: {output_all.detach().cpu().numpy()}")
Beispiel #22
0
def main() -> None:
    dist.init()

    torch.backends.cudnn.benchmark = True
    torch.cuda.set_device(dist.local_rank())

    parser = argparse.ArgumentParser()
    parser.add_argument('config', metavar='FILE', help='config file')
    parser.add_argument('--run-dir', metavar='DIR', help='run directory')
    args, opts = parser.parse_known_args()

    configs.load(args.config, recursive=True)
    configs.update(opts)

    if args.run_dir is None:
        args.run_dir = auto_set_run_dir()
    else:
        set_run_dir(args.run_dir)

    logger.info(' '.join([sys.executable] + sys.argv))
    logger.info(f'Experiment started: "{args.run_dir}".' + '\n' + f'{configs}')

    dataset = builder.make_dataset()
    dataflow = {}
    for split in dataset:
        sampler = torch.utils.data.DistributedSampler(
            dataset[split],
            num_replicas=dist.size(),
            rank=dist.rank(),
            shuffle=(split == 'train'),
        )
        dataflow[split] = torch.utils.data.DataLoader(
            dataset[split],
            batch_size=configs.batch_size // dist.size(),
            sampler=sampler,
            num_workers=configs.workers_per_gpu,
            pin_memory=True,
        )

    model = builder.make_model()
    model = torch.nn.parallel.DistributedDataParallel(
        model.cuda(),
        device_ids=[dist.local_rank()],
    )

    criterion = builder.make_criterion()
    optimizer = builder.make_optimizer(model)
    scheduler = builder.make_scheduler(optimizer)

    trainer = ClassificationTrainer(
        model=model,
        criterion=criterion,
        optimizer=optimizer,
        scheduler=scheduler,
        amp_enabled=configs.amp.enabled,
    )
    trainer.train_with_defaults(
        dataflow['train'],
        num_epochs=configs.num_epochs,
        callbacks=[
            SaverRestore(),
            InferenceRunner(
                dataflow['test'],
                callbacks=[
                    TopKCategoricalAccuracy(k=1, name='acc/top1'),
                    TopKCategoricalAccuracy(k=5, name='acc/top5'),
                ],
            ),
            MaxSaver('acc/top1'),
            Saver(),
        ],
    )
Beispiel #23
0
def switch_little_big_endian_matrix_test():
    logger.info(switch_little_big_endian_matrix(np.ones((16, 16))))
    logger.info(switch_little_big_endian_matrix(np.ones((5, 16, 16))))
Beispiel #24
0
def main() -> None:
    # dist.init()
    torch.backends.cudnn.benchmark = True
    # torch.cuda.set_device(dist.local_rank())

    parser = argparse.ArgumentParser()
    parser.add_argument('config', metavar='FILE', help='config file')
    parser.add_argument('--run-dir', metavar='DIR', help='run directory')
    parser.add_argument('--pdb', action='store_true', help='pdb')
    parser.add_argument('--gpu', type=str, help='gpu ids', default=None)
    args, opts = parser.parse_known_args()

    configs.load(args.config, recursive=True)
    configs.update(opts)

    if configs.debug.pdb or args.pdb:
        pdb.set_trace()

    if args.gpu is not None:
        os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu

    if configs.debug.set_seed:
        torch.manual_seed(configs.debug.seed)
        np.random.seed(configs.debug.seed)

    if configs.run.device == 'gpu':
        device = torch.device('cuda')
    elif configs.run.device == 'cpu':
        device = torch.device('cpu')
    else:
        raise ValueError(configs.run.device)

    if isinstance(configs.optimizer.lr, str):
        configs.optimizer.lr = eval(configs.optimizer.lr)

    if args.run_dir is None:
        args.run_dir = auto_set_run_dir()
    else:
        set_run_dir(args.run_dir)

    logger.info(' '.join([sys.executable] + sys.argv))
    logger.info(f'Experiment started: "{args.run_dir}".' + '\n' + f'{configs}')

    dataset = builder.make_dataset()
    dataflow = dict()

    for split in dataset:
        sampler = torch.utils.data.RandomSampler(dataset[split])
        dataflow[split] = torch.utils.data.DataLoader(
            dataset[split],
            batch_size=configs.run.bsz,
            sampler=sampler,
            num_workers=configs.run.workers_per_gpu,
            pin_memory=True)

    model = builder.make_model()
    model.to(device)
    # model = torch.nn.parallel.DistributedDataParallel(
    #     model.cuda(),
    #     device_ids=[dist.local_rank()],
    #     find_unused_parameters=True)

    total_params = sum(p.numel() for p in model.parameters())
    logger.info(f'Model Size: {total_params}')

    # logger.info(f'Model MACs: {profile_macs(model, inputs)}')

    criterion = builder.make_criterion()
    optimizer = builder.make_optimizer(model)
    scheduler = builder.make_scheduler(optimizer)

    trainer = LayerRegressionTrainer(model=model,
                                     criterion=criterion,
                                     optimizer=optimizer,
                                     scheduler=scheduler)
    trainer.train_with_defaults(
        dataflow['train'],
        num_epochs=configs.run.n_epochs,
        callbacks=[
            # SaverRestore(),
            InferenceRunner(dataflow=dataflow['valid'], callbacks=[]),
            MaxSaver('loss/valid'),
            # Saver(),
        ])
Beispiel #25
0
def main() -> None:
    # dist.init()
    torch.backends.cudnn.benchmark = True
    # torch.cuda.set_device(dist.local_rank())

    parser = argparse.ArgumentParser()
    parser.add_argument('config', metavar='FILE', help='config file')
    parser.add_argument('--ckpt-dir', metavar='DIR', help='run directory')
    parser.add_argument('--pdb', action='store_true', help='pdb')
    parser.add_argument('--gpu', type=str, help='gpu ids', default=None)
    parser.add_argument('--print-configs',
                        action='store_true',
                        help='print ALL configs')
    args, opts = parser.parse_known_args()

    configs.load(args.config, recursive=True)
    configs.update(opts)

    if configs.debug.pdb or args.pdb:
        pdb.set_trace()

    if args.gpu is not None:
        os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu

    if configs.debug.set_seed:
        torch.manual_seed(configs.debug.seed)
        np.random.seed(configs.debug.seed)

    if configs.run.device == 'gpu':
        device = torch.device('cuda')
    elif configs.run.device == 'cpu':
        device = torch.device('cpu')
    else:
        raise ValueError(configs.run.device)

    if isinstance(configs.optimizer.lr, str):
        configs.optimizer.lr = eval(configs.optimizer.lr)

    # set the run dir according to config file's name
    args.run_dir = 'runs/' + args.config.replace('/', '.').replace(
        'examples.', '').replace('.yml', '').replace('configs.', '')
    set_run_dir(args.run_dir)

    logger.info(' '.join([sys.executable] + sys.argv))

    if args.print_configs:
        print_conf = configs
    else:
        print_conf = get_cared_configs(configs, 'train')

    logger.info(f'Training started: "{args.run_dir}".' + '\n' +
                f'{print_conf}')

    dataset = builder.make_dataset()
    dataflow = dict()

    # for split in dataset:
    #     sampler = torch.utils.data.distributed.DistributedSampler(
    #         dataset[split],
    #         num_replicas=dist.size(),
    #         rank=dist.rank(),
    #         shuffle=(split == 'train'))
    #     dataflow[split] = torch.utils.data.DataLoader(
    #         dataset[split],
    #         batch_size=configs.run.bsz // dist.size(),
    #         sampler=sampler,
    #         num_workers=configs.run.workers_per_gpu,
    #         pin_memory=True)

    for split in dataset:
        if split == 'train':
            sampler = torch.utils.data.RandomSampler(dataset[split])
            batch_size = configs.run.bsz
        else:
            # for valid and test, use SequentialSampler to make the train.py
            # and eval.py results consistent
            sampler = torch.utils.data.SequentialSampler(dataset[split])
            batch_size = getattr(configs.run, 'eval_bsz', configs.run.bsz)

        dataflow[split] = torch.utils.data.DataLoader(
            dataset[split],
            batch_size=batch_size,
            sampler=sampler,
            num_workers=configs.run.workers_per_gpu,
            pin_memory=True)

    model = builder.make_model()

    state_dict = {}
    solution = None
    score = None
    if configs.ckpt.load_ckpt:
        logger.warning('Loading checkpoint!')
        state_dict = io.load(os.path.join(args.ckpt_dir, configs.ckpt.name),
                             map_location='cpu')
        if getattr(state_dict, 'model_arch', None) is not None:
            model_load = state_dict['model_arch']
            for module_load, module in zip(model_load.modules(),
                                           model.modules()):
                if isinstance(module, tq.RandomLayer):
                    # random layer, need to restore the architecture
                    module.rebuild_random_layer_from_op_list(
                        n_ops_in=module_load.n_ops,
                        wires_in=module_load.wires,
                        op_list_in=module_load.op_list,
                    )

        if not configs.ckpt.weight_from_scratch:
            model.load_state_dict(state_dict['model'], strict=False)
        else:
            logger.warning(f"DO NOT load weight, train weights from scratch!")

        if 'solution' in state_dict.keys():
            solution = state_dict['solution']
            logger.info(f"Loading the solution {solution}")
            logger.info(f"Original score: {state_dict['score']}")
            model.set_sample_arch(solution['arch'])
            score = state_dict['score']

        if 'v_c_reg_mapping' in state_dict.keys():
            try:
                model.measure.set_v_c_reg_mapping(
                    state_dict['v_c_reg_mapping'])
            except AttributeError:
                logger.warning(f"Cannot set v_c_reg_mapping.")

        if configs.model.load_op_list:
            assert state_dict['q_layer_op_list'] is not None
            logger.warning(f"Loading the op_list, will replace the q_layer in "
                           f"the original model!")
            q_layer = build_module_from_op_list(state_dict['q_layer_op_list'])
            model.q_layer = q_layer

    if configs.model.transpile_before_run:
        # transpile the q_layer
        logger.warning(f"Transpile the q_layer to basis gate set before "
                       f"training, will replace the q_layer!")
        processor = builder.make_qiskit_processor()

        if getattr(model, 'q_layer', None) is not None:
            circ = tq2qiskit(model.q_device, model.q_layer)
            """
            add measure because the transpile process may permute the wires, 
            so we need to get the final q reg to c reg mapping 
            """
            circ.measure(list(range(model.q_device.n_wires)),
                         list(range(model.q_device.n_wires)))
            logger.info("Transpiling circuit...")

            if solution is not None:
                processor.set_layout(solution['layout'])
                logger.warning(
                    f"Set layout {solution['layout']} for transpile!")

            circ_transpiled = processor.transpile(circs=circ)
            q_layer = qiskit2tq(circ=circ_transpiled)

            model.measure.set_v_c_reg_mapping(
                get_v_c_reg_mapping(circ_transpiled))
            model.q_layer = q_layer

            if configs.trainer.add_noise:
                # noise-aware training
                noise_model_tq = builder.make_noise_model_tq()
                noise_model_tq.is_add_noise = True
                noise_model_tq.v_c_reg_mapping = get_v_c_reg_mapping(
                    circ_transpiled)
                noise_model_tq.p_c_reg_mapping = get_p_c_reg_mapping(
                    circ_transpiled)
                noise_model_tq.p_v_reg_mapping = get_p_v_reg_mapping(
                    circ_transpiled)
                model.set_noise_model_tq(noise_model_tq)

        elif getattr(model, 'nodes', None) is not None:
            # every node has a noise model because it is possible that
            # different nodes run on different QC
            for node in model.nodes:
                circ = tq2qiskit(node.q_device, node.q_layer)
                circ.measure(list(range(node.q_device.n_wires)),
                             list(range(node.q_device.n_wires)))
                circ_transpiled = processor.transpile(circs=circ)
                q_layer = qiskit2tq(circ=circ_transpiled)

                node.measure.set_v_c_reg_mapping(
                    get_v_c_reg_mapping(circ_transpiled))
                node.q_layer = q_layer

                if configs.trainer.add_noise:
                    # noise-aware training
                    noise_model_tq = builder.make_noise_model_tq()
                    noise_model_tq.is_add_noise = True
                    noise_model_tq.v_c_reg_mapping = get_v_c_reg_mapping(
                        circ_transpiled)
                    noise_model_tq.p_c_reg_mapping = get_p_c_reg_mapping(
                        circ_transpiled)
                    noise_model_tq.p_v_reg_mapping = get_p_v_reg_mapping(
                        circ_transpiled)
                    node.set_noise_model_tq(noise_model_tq)

    if getattr(configs.model.arch, 'sample_arch', None) is not None and \
            not configs.model.transpile_before_run:
        sample_arch = configs.model.arch.sample_arch
        logger.warning(f"Setting sample arch {sample_arch} from config file!")
        if isinstance(sample_arch, str):
            # this is the name of arch
            sample_arch = get_named_sample_arch(model.arch_space, sample_arch)
            logger.warning(f"Decoded sample arch: {sample_arch}")
        model.set_sample_arch(sample_arch)

    if configs.trainer.name == 'pruning_trainer':
        """
        in pruning, convert the super layers to module list, otherwise the 
        pruning ratio is difficulty to set
        """
        logger.warning(f"Convert sampled layer to module list layer!")
        model.q_layer = build_module_from_op_list(
            build_module_op_list(model.q_layer))

    model.to(device)
    # model = torch.nn.parallel.DistributedDataParallel(
    #     model.cuda(),
    #     device_ids=[dist.local_rank()],
    #     find_unused_parameters=True)
    if getattr(model, 'sample_arch', None) is not None and \
            not configs.model.transpile_before_run and \
            not configs.trainer.name == 'pruning_trainer':
        n_params = model.count_sample_params()
        logger.info(f"Number of sampled params: {n_params}")

    total_params = sum(p.numel() for p in model.parameters())
    logger.info(f'Model Size: {total_params}')

    # logger.info(f'Model MACs: {profile_macs(model, inputs)}')

    criterion = builder.make_criterion()
    optimizer = builder.make_optimizer(model)
    scheduler = builder.make_scheduler(optimizer)
    trainer = builder.make_trainer(model=model,
                                   criterion=criterion,
                                   optimizer=optimizer,
                                   scheduler=scheduler)
    trainer.solution = solution
    trainer.score = score

    # trainer state_dict will be loaded in a callback
    callbacks = builder.make_callbacks(dataflow, state_dict)

    trainer.train_with_defaults(dataflow['train'],
                                num_epochs=configs.run.n_epochs,
                                callbacks=callbacks)
Beispiel #26
0
def switch_little_big_endian_state_test():
    logger.info(switch_little_big_endian_state(np.ones((5, 16))))
    logger.info(switch_little_big_endian_state(np.arange(8)))
Beispiel #27
0
def main() -> None:
    torch.backends.cudnn.benchmark = True

    parser = argparse.ArgumentParser()
    parser.add_argument('config', metavar='FILE', help='config file')
    parser.add_argument('--run-dir', metavar='DIR', help='run directory')
    parser.add_argument('--pdb', action='store_true', help='pdb')
    parser.add_argument('--gpu', type=str, help='gpu ids', default=None)
    parser.add_argument('--jobs',
                        type=int,
                        default=None,
                        help='max parallel job on qiskit')
    parser.add_argument('--print-configs',
                        action='store_true',
                        help='print ALL configs')
    args, opts = parser.parse_known_args()

    configs.load(os.path.join(args.run_dir, 'metainfo', 'configs.yaml'))
    configs.load(args.config, recursive=True)
    configs.update(opts)

    if configs.debug.pdb or args.pdb:
        pdb.set_trace()

    if args.gpu is not None:
        os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu

    if args.jobs is not None:
        configs.qiskit.max_jobs = args.jobs

    # if use qiskit, then not need to estimate success rate
    assert not (configs.es.est_success_rate and configs.qiskit.use_qiskit)

    if configs.run.device == 'gpu':
        device = torch.device('cuda')
    elif configs.run.device == 'cpu':
        device = torch.device('cpu')
    else:
        raise ValueError(configs.run.device)

    if args.print_configs:
        print_conf = configs
    else:
        print_conf = get_cared_configs(configs, 'es')

    logger.info(f'Evolutionary Search started: "{args.run_dir}".' + '\n' +
                f'{print_conf}')

    if configs.qiskit.use_qiskit:
        IBMQ.load_account()
        if configs.run.bsz == 'qiskit_max':
            provider = get_provider(configs.qiskit.backend_name)
            configs.run.bsz = provider.get_backend(
                configs.qiskit.backend_name).configuration().max_experiments

    dataset = builder.make_dataset()
    sampler = torch.utils.data.SequentialSampler(
        dataset[configs.dataset.split])
    dataflow = torch.utils.data.DataLoader(
        dataset[configs.dataset.split],
        sampler=sampler,
        batch_size=configs.run.bsz,
        num_workers=configs.run.workers_per_gpu,
        pin_memory=True)

    state_dict = io.load(os.path.join(args.run_dir, configs.ckpt.name),
                         map_location=device)

    model_load = state_dict['model_arch']
    model = builder.make_model()
    for module_load, module in zip(model_load.modules(), model.modules()):
        if isinstance(module, tq.RandomLayer):
            # random layer, need to restore the architecture
            module.rebuild_random_layer_from_op_list(
                n_ops_in=module_load.n_ops,
                wires_in=module_load.wires,
                op_list_in=module_load.op_list,
            )

    model.load_state_dict(state_dict['model'], strict=False)

    if configs.legalization.legalize:
        legalize_unitary(model)
    model.to(device)
    model.eval()

    es_dir = 'es_runs/' + args.config.replace('/', '.').replace(
        'examples.', '').replace('.yml', '').replace('configs.', '')
    io.save(os.path.join(es_dir, 'metainfo/configs.yaml'), configs.dict())

    writer = SummaryWriter(os.path.normpath(os.path.join(es_dir, 'tb')))

    if configs.qiskit.use_qiskit or configs.es.est_success_rate:
        IBMQ.load_account()
        provider = get_provider(configs.qiskit.backend_name)

        properties = provider.get_backend(
            configs.qiskit.backend_name).properties()
        if configs.qiskit.backend_name == 'ibmq_qasm_simulator':
            if configs.qiskit.noise_model_name == 'ibmq_16_melbourne':
                n_available_wires = 15
        else:
            n_available_wires = len(properties.qubits)
        qiskit_processor = builder.make_qiskit_processor()
        model.set_qiskit_processor(qiskit_processor)
    else:
        n_available_wires = model.q_device.n_wires

    total_params = sum(p.numel() for p in model.parameters())
    logger.info(f'Model Size: {total_params}')

    es_engine = EvolutionEngine(
        population_size=configs.es.population_size,
        parent_size=configs.es.parent_size,
        mutation_size=configs.es.mutation_size,
        mutation_prob=configs.es.mutation_prob,
        crossover_size=configs.es.crossover_size,
        n_wires=model.q_device.n_wires,
        n_available_wires=n_available_wires,
        arch_space=model.arch_space,
        gene_mask=configs.es.gene_mask,
        random_search=configs.es.random_search,
    )

    evaluator = Evaluator()

    logger.info(f"Start Evolution Search")
    for k in range(configs.es.n_iterations):
        logger.info(f"ES iteration {k}:")
        solutions = es_engine.ask()
        scores, best_solution_accuracy, best_solution_loss, \
            best_solution_success_rate, best_solution_score \
            = evaluator.evaluate_all(model, dataflow, solutions, writer, k,
                                     configs.es.population_size)
        es_engine.tell(scores)
        logger.info(f"Best solution: {es_engine.best_solution}")
        logger.info(f"Best score: {es_engine.best_score}")

        assert best_solution_score == es_engine.best_score
        writer.add_text('es/best_solution_arch', str(es_engine.best_solution),
                        k)
        writer.add_scalar('es/best_solution_accuracy', best_solution_accuracy,
                          k)
        writer.add_scalar('es/best_solution_loss', best_solution_loss, k)
        writer.add_scalar('es/best_solution_success_rate',
                          best_solution_success_rate, k)
        writer.add_scalar('es/best_solution_score', es_engine.best_score, k)

        # store the model and solution after every iteration
        state_dict = dict()
        if not configs.qiskit.use_real_qc:
            state_dict['model_arch'] = model
        state_dict['model'] = model.state_dict()
        state_dict['solution'] = es_engine.best_solution
        state_dict['score'] = es_engine.best_score
        if not configs.dataset.name == 'vqe':
            state_dict['encoder_func_list'] = model.encoder.func_list
        state_dict['q_layer_op_list'] = build_module_op_list(model.q_layer)
        io.save(os.path.join(es_dir, 'checkpoints/best_solution.pt'),
                state_dict)

    logger.info(f"\n Best solution evaluation on tq:")
    # eval the best solution
    evaluator.evaluate_all(model, dataflow, [es_engine.best_solution])
Beispiel #28
0
    def evaluate_all(self,
                     model,
                     dataflow,
                     solutions,
                     writer=None,
                     iter_n=None,
                     population_size=None):
        scores = []

        best_solution = None
        best_solution_accuracy = 0
        best_solution_loss = 0
        best_solution_success_rate = 0
        best_solution_score = 999999

        for i, solution in tqdm.tqdm(enumerate(solutions)):
            fingerprint = solution.copy()
            arch = solution['arch']
            fingerprint['arch'] = arch[:arch[-1] *
                                       configs.model.arch.n_layers_per_block]
            fingerprint['arch'].append(arch[-1])
            fingerprint = str(fingerprint)
            if fingerprint in self.solution_lib.keys():
                """circuit has been simulated before"""
                logger.info(f"loaded from lib")
                loss = self.solution_lib[fingerprint]['loss']
                accuracy = self.solution_lib[fingerprint]['accuracy']
                success_rate = self.solution_lib[fingerprint]['success_rate']
            else:
                if model.qiskit_processor is not None:
                    model.qiskit_processor.set_layout(solution['layout'])
                model.set_sample_arch(solution['arch'])
                with torch.no_grad():
                    target_all = None
                    output_all = None
                    for feed_dict in dataflow:
                        if configs.run.device == 'gpu':
                            inputs = feed_dict[
                                configs.dataset.input_name].cuda(
                                    non_blocking=True)
                            targets = feed_dict[
                                configs.dataset.target_name].cuda(
                                    non_blocking=True)
                        else:
                            inputs = feed_dict[configs.dataset.input_name]
                            targets = feed_dict[configs.dataset.target_name]

                        outputs = model(inputs,
                                        use_qiskit=configs.qiskit.use_qiskit)

                        if target_all is None:
                            target_all = targets
                            output_all = outputs
                        else:
                            target_all = torch.cat([target_all, targets],
                                                   dim=0)
                            output_all = torch.cat([output_all, outputs],
                                                   dim=0)

                if configs.dataset.name == 'vqe':
                    loss = output_all[0].item()
                    accuracy = -1
                else:
                    k = 1
                    _, indices = output_all.topk(k, dim=1)
                    masks = indices.eq(
                        target_all.view(-1, 1).expand_as(indices))
                    size = target_all.shape[0]
                    corrects = masks.sum().item()
                    accuracy = corrects / size
                    loss = F.nll_loss(output_all, target_all).item()

                if configs.es.est_success_rate:
                    circ_parameterized, params = tq2qiskit_parameterized(
                        model.q_device, model.encoder.func_list)
                    circ_fixed = tq2qiskit(model.q_device, model.q_layer)
                    circ = circ_parameterized + circ_fixed
                    transpiled_circ = model.qiskit_processor.transpile(circ)

                    success_rate = get_success_rate(
                        model.qiskit_processor.properties, transpiled_circ)
                else:
                    success_rate = 1

                self.solution_lib[fingerprint] = {
                    'loss': loss,
                    'accuracy': accuracy,
                    'success_rate': success_rate,
                }
            if configs.es.score_mode == 'loss_succ':
                score = loss / success_rate
            elif configs.es.score_mode == 'acc_succ':
                score = -accuracy * success_rate
            else:
                raise NotImplementedError

            scores.append(score)
            logger.info(f"Current solution: {solution}\n"
                        f"Accuracy: {accuracy:.5f}, Loss: {loss:.5f}, "
                        f"Success Rate: {success_rate: .5f}, "
                        f"Score: {score:.5f}")

            if score < best_solution_score:
                best_solution = solution
                best_solution_accuracy = accuracy
                best_solution_success_rate = success_rate
                best_solution_loss = loss
                best_solution_score = score

            logger.info(f"Best of iteration: "
                        f"Solution: {best_solution}\n"
                        f"Accuracy: {best_solution_accuracy:.5f}, "
                        f"Loss: {best_solution_loss:.5f}, "
                        f"Success Rate: {best_solution_success_rate: .5f}, "
                        f"Score: {best_solution_score:.5f}")

            if population_size is not None and writer is not None and \
                    population_size is not None:
                writer.add_scalar('es/accuracy', accuracy,
                                  iter_n * population_size + i)
                writer.add_scalar('es/loss', loss,
                                  iter_n * population_size + i)
                writer.add_scalar('es/success_rate', success_rate,
                                  iter_n * population_size + i)
                writer.add_scalar('es/score', score,
                                  iter_n * population_size + i)

        return scores, best_solution_accuracy, best_solution_loss, \
            best_solution_success_rate, best_solution_score
Beispiel #29
0
def main() -> None:
    dist.init()

    torch.backends.cudnn.benchmark = True
    torch.cuda.set_device(dist.local_rank())

    parser = argparse.ArgumentParser()
    parser.add_argument('config', metavar='FILE', help='config file')
    parser.add_argument('--run-dir', metavar='DIR', help='run directory')
    parser.add_argument('--name', type=str, help='model name')
    args, opts = parser.parse_known_args()

    configs.load(args.config, recursive=True)
    configs.update(opts)

    if args.run_dir is None:
        args.run_dir = auto_set_run_dir()
    else:
        set_run_dir(args.run_dir)

    logger.info(' '.join([sys.executable] + sys.argv))
    logger.info(f'Experiment started: "{args.run_dir}".' + '\n' + f'{configs}')

    dataset = builder.make_dataset()
    dataflow = dict()
    for split in dataset:
        sampler = torch.utils.data.distributed.DistributedSampler(
            dataset[split],
            num_replicas=dist.size(),
            rank=dist.rank(),
            shuffle=(split == 'train'))
        dataflow[split] = torch.utils.data.DataLoader(
            dataset[split],
            batch_size=configs.batch_size if split == 'train' else 1,
            sampler=sampler,
            num_workers=configs.workers_per_gpu,
            pin_memory=True,
            collate_fn=dataset[split].collate_fn)

    
    if 'spvnas' in args.name.lower():
        model = spvnas_specialized(args.name)
    elif 'spvcnn' in args.name.lower():
        model = spvcnn(args.name)
    elif 'mink' in args.name.lower():
        model = minkunet(args.name)
    else:
        raise NotImplementedError
    
    #model = builder.make_model()
    model = torch.nn.parallel.DistributedDataParallel(
        model.cuda(),
        device_ids=[dist.local_rank()],
        find_unused_parameters=True)
    model.eval()

    criterion = builder.make_criterion()
    optimizer = builder.make_optimizer(model)
    scheduler = builder.make_scheduler(optimizer)
    meter = MeanIoU(configs.data.num_classes, 
                    configs.data.ignore_label)

    trainer = SemanticKITTITrainer(model=model,
                          criterion=criterion,
                          optimizer=optimizer,
                          scheduler=scheduler,
                          num_workers=configs.workers_per_gpu,
                          seed=configs.train.seed
                          )
    callbacks=Callbacks([
                          SaverRestore(),
                          MeanIoU(
                              configs.data.num_classes, 
                              configs.data.ignore_label
                          )
                      ])
    callbacks._set_trainer(trainer)
    trainer.callbacks = callbacks
    trainer.dataflow = dataflow['test']
    
    
    trainer.before_train()
    trainer.before_epoch()
    
    # important
    model.eval()
    
    for feed_dict in tqdm(dataflow['test'], desc='eval'):
        _inputs = dict()
        for key, value in feed_dict.items():
            if not 'name' in key:
                _inputs[key] = value.cuda()

        inputs = _inputs['lidar']
        targets = feed_dict['targets'].F.long().cuda(non_blocking=True)
        outputs = model(inputs)
       
        invs = feed_dict['inverse_map']
        all_labels = feed_dict['targets_mapped']
        _outputs = []
        _targets = []
        for idx in range(invs.C[:, -1].max()+1):
            cur_scene_pts = (inputs.C[:, -1] == idx).cpu().numpy()
            cur_inv = invs.F[invs.C[:, -1] == idx].cpu().numpy()
            cur_label = (all_labels.C[:, -1] == idx).cpu().numpy()
            outputs_mapped = outputs[cur_scene_pts][
                cur_inv].argmax(1)
            targets_mapped = all_labels.F[cur_label]
            _outputs.append(outputs_mapped)
            _targets.append(targets_mapped)
        outputs = torch.cat(_outputs, 0)
        targets = torch.cat(_targets, 0)
        output_dict = {
            'outputs': outputs,
            'targets': targets
        }
        trainer.after_step(output_dict)
    
    trainer.after_epoch()
Beispiel #30
0
    def train(self,
              dataflow: DataLoader,
              *,
              num_epochs: int = 9999999,
              eval_interval: int = None,
              splits: List[str] = None,
              callbacks: Optional[List[Callback]] = None) -> None:
        self.dataflow = dataflow
        self.steps_per_epoch = len(self.dataflow)
        self.num_epochs = num_epochs

        if callbacks is None:
            callbacks = []
        self.callbacks = Callbacks(callbacks)
        if splits is None:
            self.summary = {"0": Summary()}
        else:
            self.summary = {s: Summary(split=s) for s in splits}

        try:
            self.callbacks.set_trainer(self)
            for s in self.summary.values():
                s.set_trainer(self)

            self.epoch_num = 0
            self.global_step = 0

            train_time = time.perf_counter()
            self.before_train()

            while self.epoch_num < self.num_epochs:
                self.epoch_num += 1
                self.local_step = 0

                logger.info("Epoch {}/{} started.".format(
                    self.epoch_num, self.num_epochs))
                epoch_time = time.perf_counter()
                self.before_epoch()

                for feed_dict in self.dataflow:
                    self.local_step += 1
                    self.global_step += 1

                    self.before_step(feed_dict)
                    output_dict = self.run_step(feed_dict)
                    self.after_step(output_dict)

                    self.trigger_step()

                self.after_epoch()
                logger.info("Training finished in {}.".format(
                    humanize.naturaldelta(time.perf_counter() - epoch_time)))

                if eval_interval is not None:
                    if self.epoch_num % eval_interval == 0:
                        self.trigger_epoch()
                else:
                    self.trigger_epoch()
                logger.info("Epoch finished in {}.".format(
                    humanize.naturaldelta(time.perf_counter() - epoch_time)))

            logger.success("{} epochs of training finished in {}.".format(
                self.num_epochs,
                humanize.naturaldelta(time.perf_counter() - train_time),
            ))
        except StopTraining as e:
            logger.info("Training was stopped by {}.".format(str(e)))
        finally:
            self.after_train()