Ejemplo n.º 1
0
    def run(self):

        #initialize mpi variables
        comm = MPI.COMM_WORLD   # MPI environment
        size = comm.Get_size()  # number of threads
        rank = comm.Get_rank()  # number of the current thread 

        parser = self.create_arg_parser()
        args = parser.parse_args() # set argument parser

        config = ConfigParser.SafeConfigParser()
        config.read(args.config_file) # set config file parser

        logging.basicConfig(filename='lsdmap.log',
                            filemode='w',
                            format="%(levelname)s:%(name)s:%(asctime)s: %(message)s",
                            datefmt="%H:%M:%S",
                            level=logging.DEBUG)


        logging.info('intializing LSDMap with %d processors...' % size)
        self.initialize(comm, config, args)
        logging.info('LSDMap initialized')

        if size > self.npoints:
            logging.error("number of threads should be less than the number of frames")
            raise ValueError

        npoints_thread = self.npoints_per_thread[rank]
        coords_thread = np.array([self.coords[idx] for idx in self.idxs_thread])
        weights_thread = np.array([self.weights[idx] for idx in self.idxs_thread])

        if args.dminput is None:
            # compute the distance matrix
            DistanceMatrix = mt.DistanceMatrix(coords_thread, self.coords, metric=self.metric, metric_prms=self.metric_prms)
            distance_matrix_thread = DistanceMatrix.distance_matrix
            neighbor_matrix_thread, idx_neighbor_matrix_thread = DistanceMatrix.get_neighbor_matrix()
            logging.info("distance matrix computed")
        else:
            # load distance matrix
            distance_matrix_thread = self.load_distance_matrix(comm,args)
            neighbor_matrix_thread, idx_neighbor_matrix_thread = mt.get_neighbor_matrix(distance_matrix_thread)
            logging.info("distance matrix loaded")

        # compute kth neighbor local scales if needed
        if self.status_epsilon in ['kneighbor', 'kneighbor_mean']:
            #epsilon_thread = []
            epsilon_threadv = np.zeros(npoints_thread,dtype='float')
            for idx, line in enumerate(idx_neighbor_matrix_thread):
                cum_weight = 0
                for jdx in line[1:]:
                    cum_weight += self.weights[jdx]
                    if cum_weight >= self.k:
                        break
                #epsilon_thread.append(distance_matrix_thread[idx,jdx])
                epsilon_threadv[idx] = distance_matrix_thread[idx,jdx]

            self.epsilon = np.zeros(self.npoints, dtype='float')
            comm.Allgatherv(epsilon_threadv, (self.epsilon, self.npoints_per_thread, self.offsets_per_thread, MPI.DOUBLE))

            if self.status_epsilon == 'kneighbor_mean':
                mean_value_epsilon = np.mean(self.epsilon) # compute the mean value of the local scales
                self.epsilon = mean_value_epsilon * np.ones(self.npoints)  # and set it as the new constant local scale

            logging.info("kneighbor local scales computed")

        epsilon_thread = np.array([self.epsilon[idx] for idx in self.idxs_thread])

        # compute kernel
        kernel = self.compute_kernel(comm, npoints_thread, distance_matrix_thread, weights_thread, epsilon_thread)

        # diagonalize kernel
        params= p_arpack._ParallelSymmetricArpackParams(comm, kernel, self.neigs)
        while not params.converged:
            params.iterate()
        eigs, evs = params.extract(return_eigenvectors=True)

        # normalize eigenvectors
        self.evsu = np.copy(evs) # store unormalized eigenvectors
        evs /= np.sqrt(self.d_vector[:,np.newaxis])
        norm = np.sqrt(np.sum(evs**2, axis=0))
        evs /= norm[np.newaxis,:]
        

        # store eigenvalues/eigenvectors
        self.eigs = eigs
        self.evs = evs

        logging.info("kernel diagonalized")
    
        if rank == 0:    
            self.save(config, args)
        logging.info("Eigenvalues/eigenvectors saved (.eg/.ev files)")

        # store nearest neighbors in .nn file if specified via -n option
        if args.nnfile is not None:
            logging.info("Saving nearest neighbors")
            self.save_nneighbors(comm, args, neighbor_matrix, idx_neighbor_matrix, epsilon_thread)

        if (args.dmfile is not None) and (args.dminput is None):
            logging.info("Saving distance matrix")
            self.save_distance_matrix(comm, args, distance_matrix_thread)

        logging.info("LSDMap computation done")