sgdml/predict.py
def prepare_parallel(
        self, n_bulk=1, n_reps=1, return_is_from_cache=False
    ):  # noqa: C901
        """
        Find and set the optimal parallelization parameters for the
        currently loaded model, running on a particular system. The result
        also depends on the number of geometries `n_bulk` that will be
        passed at once when calling the `predict` function.

        This function runs a benchmark in which the prediction routine is
        repeatedly called `n_reps`-times (default: 1) with varying parameter
        configurations, while the runtime is measured for each one. The
        optimal parameters are then cached for fast retrival in future
        calls of this function.

        We recommend calling this function after initialization of this
        class, as it will drastically increase the performance of the
        `predict` function.

        Note
        ----
                Depending on the parameter `n_reps`, this routine may take
                some seconds/minutes to complete. However, once a
                statistically significant number of benchmark results has
                been gathered for a particular configuration, it starts
                returning almost instantly.

        Parameters
        ----------
                n_bulk : int, optional
                        Number of geometries that will be passed to the
                        `predict` function in each call (performance
                        will be optimized for that exact use case).
                n_reps : int, optional
                        Number of repetitions (bigger value: more
                        accurate, but also slower).
                return_is_from_cache : bool, optional
                        If enabled, this function returns a second value
                        indicating if the returned results were obtained
                        from cache.
    
        Returns
        -------
                int
                        Force and energy prediciton speed in geometries
                        per second.
                boolean, optional
                        Return, whether this function obtained the results
                        from cache. 
        """

        global n_perms

        # Retrieve cached benchmark results, if available.
        bmark_result = self._load_cached_bmark_result(n_bulk)
        if bmark_result is not None:

            num_workers, batch_size, bulk_mp, gps = bmark_result

            self._set_batch_size(batch_size)
            self._set_num_workers(num_workers)
            self._set_bulk_mp(bulk_mp)

            if return_is_from_cache:
                is_from_cache = True
                return gps, is_from_cache
            else:
                return gps

        best_results = []
        last_i = None

        best_gps = 0
        gps_min = 0.0

        best_params = None

        # reps_done = 0
        r_dummy = np.random.rand(n_bulk, self.n_atoms * 3)

        def _dummy_predict():
            self.predict(r_dummy)
            # reps_done += 1
            # print(reps_done)

        bulk_mp_rng = [True, False] if n_bulk > 1 else [False]
        for bulk_mp in bulk_mp_rng:
            # self._bulk_mp = bulk_mp
            self._set_bulk_mp(bulk_mp)

            if bulk_mp is False:
                last_i = 0

            num_workers_rng = (
                list(range(self._max_processes, 1, -1))
                if bulk_mp
                else list(range(1, self._max_processes + 1))
            )

            # num_workers_rng_sizes = [batch_size for batch_size in batch_size_rng if min_batch_size % batch_size == 0]

            # for num_workers in range(min_num_workers,self._max_processes+1):
            for num_workers in num_workers_rng:
                if not bulk_mp and self.n_train % num_workers != 0:
                    continue
                    # if bulk_mp and n_bulk % num_workers != 0:
                    # 	continue
                self._set_num_workers(num_workers)

                best_gps = 0
                gps_rng = (np.inf, 0.0)  # min and max per num_workers

                min_batch_size = (
                    min(self.n_train, n_bulk)
                    if bulk_mp
                    else int(np.ceil(self.n_train / num_workers))
                )
                batch_size_rng = list(range(min_batch_size, 0, -1))

                # for i in range(0,min_batch_size):
                batch_size_rng_sizes = [
                    batch_size
                    for batch_size in batch_size_rng
                    if min_batch_size % batch_size == 0
                ]

                # print('batch_size_rng_sizes ' + str(bulk_mp))
                # print(batch_size_rng_sizes)

                i_done = 0
                i_dir = 1
                i = 0 if last_i is None else last_i
                # i = 0

                # print(batch_size_rng_sizes)
                while i >= 0 and i < len(batch_size_rng_sizes):

                    batch_size = batch_size_rng_sizes[i]
                    self._set_batch_size(batch_size)

                    i_done += 1

                    gps = (
                        n_bulk * n_reps / (timeit.timeit(_dummy_predict, number=n_reps))
                    )

                    # print(
                    #    '{:2d}@{:d} {:d} | {:7.2f} gps'.format(
                    #        num_workers, batch_size, bulk_mp, gps
                    #    )
                    # )

                    # print(batch_size * self.n_atoms * n_perms)

                    gps_rng = (
                        min(gps_rng[0], gps),
                        max(gps_rng[1], gps),
                    )  # min and max per num_workers

                    # gps_min_max = min(gps_min_max[0], gps), max(gps_min_max[1], gps)

                    # print('     best_gps ' + str(best_gps))

                    # NEW

                    # if gps > best_gps and gps > gps_min: # gps is still going up, everything is good
                    #     best_gps = gps
                    #     best_params = num_workers, batch_size, bulk_mp
                    # else:
                    #     break

                    # if gps > best_gps: # gps is still going up, everything is good
                    #     best_gps = gps
                    #     best_params = num_workers, batch_size, bulk_mp
                    # else: # gps did not go up wrt. to previous step

                    #     # can we switch the search direction?
                    #     #   did we already?
                    #     #   we checked two consecutive configurations
                    #     #   are bigger batch sizes possible?

                    #     print(batch_size_rng_sizes)

                    #     turn_search_dir = i_dir > 0 and i_done == 2 and batch_size != batch_size_rng_sizes[1]

                    #     # only turn, if the current gps is not lower than the lowest overall
                    #     if turn_search_dir and gps >= gps_min:
                    #         i -= 2 * i_dir
                    #         i_dir = -1
                    #         print('><')
                    #         continue
                    #     else:
                    #         print('>>break ' + str(i_done))
                    #         break

                    # NEW

                    # gps still going up?
                    # AND: gps not lower than the lowest overall?
                    # if gps < best_gps and gps >= gps_min:
                    if gps < best_gps:
                        if (
                            i_dir > 0
                            and i_done == 2
                            and batch_size
                            != batch_size_rng_sizes[
                                1
                            ]  # there is no point in turning if this is the second batch size in the range
                        ):  # do we turn?
                            i -= 2 * i_dir
                            i_dir = -1
                            # print('><')
                            continue
                        else:
                            # if batch_size == batch_size_rng_sizes[1]:
                            # 	i -= 1*i_dir
                            # print('>>break ' + str(i_done))
                            break
                    else:
                        best_gps = gps
                        best_params = num_workers, batch_size, bulk_mp

                        # if gps < best_gps:
                        #    break
                        # else:
                        # 	best_gps = gps
                        # 	best_params = num_workers, batch_size, bulk_mp

                    if (
                        not bulk_mp and n_bulk > 1
                    ):  # stop search early when multiple cpus are available and the 1 cpu case is tested
                        if (
                            gps < gps_min
                        ):  # if the batch size run is lower than the lowest overall, stop right here
                            # print('breaking here')
                            break

                    # if gps < gps_min:  # if the batch size run is lower than the lowest overall, stop right here
                    #    break

                    i += 1 * i_dir

                last_i = i - 1 * i_dir
                i_dir = 1

                if len(best_results) > 0:
                    overall_best_gps = max(best_results, key=lambda x: x[1])[1]
                    if best_gps < overall_best_gps:
                        # print('breaking, because best of last test was worse than overall best so far')
                        break

                    # if best_gps < gps_min:
                    #    print('breaking here3')
                    #    break

                gps_min = gps_rng[0]  # FIX me: is this the overall min?
                # print ('gps_min ' + str(gps_min))

                # print ('best_gps')
                # print (best_gps)

                # if len(best_results) > 0 and best_gps < overall_best_gps:
                #    break

                best_results.append(
                    (best_params, best_gps)
                )  # best results per num_workers

        (num_workers, batch_size, bulk_mp), gps = max(best_results, key=lambda x: x[1])

        # Cache benchmark results.
        self._save_cached_bmark_result(n_bulk, num_workers, batch_size, bulk_mp, gps)

        self._set_batch_size(batch_size)
        self._set_num_workers(num_workers)
        self._set_bulk_mp(bulk_mp)

        if return_is_from_cache:
            is_from_cache = False
            return gps, is_from_cache
        else:
            return gps

        Find and set the optimal parallelization parameters for the
        currently loaded model, running on a particular system. The result
        also depends on the number of geometries `n_bulk` that will be
        passed at once when calling the `predict` function.

        This function runs a benchmark in which the prediction routine is
        repeatedly called `n_reps`-times (default: 1) with varying parameter
        configurations, while the runtime is measured for each one. The
        optimal parameters are then cached for fast retrival in future
        calls of this function.

        We recommend calling this function after initialization of this
        class, as it will drastically increase the performance of the
        `predict` function.

        Note
        ----
                Depending on the parameter `n_reps`, this routine may take
                some seconds/minutes to complete. However, once a
                statistically significant number of benchmark results has
                been gathered for a particular configuration, it starts
                returning almost instantly.

        Parameters
        ----------
                n_bulk : int, optional
                        Number of geometries that will be passed to the
                        `predict` function in each call (performance
                        will be optimized for that exact use case).
                n_reps : int, optional
                        Number of repetitions (bigger value: more
                        accurate, but also slower).
                return_is_from_cache : bool, optional
                        If enabled, this function returns a second value
                        indicating if the returned results were obtained
                        from cache.
    
        Returns
        -------
                int
                        Force and energy prediciton speed in geometries
                        per second.
                boolean, optional
                        Return, whether this function obtained the results
                        from cache. 
        
Find and set the optimal parallelization parameters for the
currently loaded model, running on a particular system. The result
also depends on the number of geometries `n_bulk` that will be
passed at once when calling the `predict` function.

This function runs a benchmark in which the prediction routine is
repeatedly called `n_reps`-times (default: 1) with varying parameter
configurations, while the runtime is measured for each one. The
optimal parameters are then cached for fast retrival in future
calls of this function.

We recommend calling this function after initialization of this
class, as it will drastically increase the performance of the
`predict` function.

Note

Depending on the parameter `n_reps`, this routine may take
some seconds/minutes to complete. However, once a
statistically significant number of benchmark results has
been gathered for a particular configuration, it starts
returning almost instantly.

Parameters

n_bulk : int, optional
Number of geometries that will be passed to the
`predict` function in each call (performance
will be optimized for that exact use case).
n_reps : int, optional
Number of repetitions (bigger value: more
accurate, but also slower).
return_is_from_cache : bool, optional
If enabled, this function returns a second value
indicating if the returned results were obtained
from cache.

Returns

int
Force and energy prediciton speed in geometries
per second.
boolean, optional
Return, whether this function obtained the results
from cache.
Find and set the optimal parallelization parameters for the currently loaded model running on a particular system . The result also depends on the number of geometries ` n_bulk ` that will be passed at once when calling the ` predict ` function . This function runs a benchmark in which the prediction routine is repeatedly called ` n_reps ` - times ( default : 1 ) with varying parameter configurations while the runtime is measured for each one . The optimal parameters are then cached for fast retrival in future calls of this function . We recommend calling this function after initialization of this class as it will drastically increase the performance of the ` predict ` function . Note Depending on the parameter ` n_reps ` this routine may take some seconds / minutes to complete . However once a statistically significant number of benchmark results has been gathered for a particular configuration it starts returning almost instantly . Parameters n_bulk : int optional Number of geometries that will be passed to the ` predict ` function in each call ( performance will be optimized for that exact use case ) . n_reps : int optional Number of repetitions ( bigger value : more accurate but also slower ) . return_is_from_cache : bool optional If enabled this function returns a second value indicating if the returned results were obtained from cache . Returns int Force and energy prediciton speed in geometries per second . boolean optional Return whether this function obtained the results from cache .
def prepare_parallel(
        self, n_bulk=1, n_reps=1, return_is_from_cache=False
    ):  
        global n_perms
        bmark_result = self._load_cached_bmark_result(n_bulk)
        if bmark_result is not None:
            num_workers, batch_size, bulk_mp, gps = bmark_result
            self._set_batch_size(batch_size)
            self._set_num_workers(num_workers)
            self._set_bulk_mp(bulk_mp)
            if return_is_from_cache:
                is_from_cache = True
                return gps, is_from_cache
            else:
                return gps
        best_results = []
        last_i = None
        best_gps = 0
        gps_min = 0.0
        best_params = None
        r_dummy = np.random.rand(n_bulk, self.n_atoms * 3)
        def _dummy_predict():
            self.predict(r_dummy)
        bulk_mp_rng = [True, False] if n_bulk > 1 else [False]
        for bulk_mp in bulk_mp_rng:
            self._set_bulk_mp(bulk_mp)
            if bulk_mp is False:
                last_i = 0
            num_workers_rng = (
                list(range(self._max_processes, 1, -1))
                if bulk_mp
                else list(range(1, self._max_processes + 1))
            )
            for num_workers in num_workers_rng:
                if not bulk_mp and self.n_train % num_workers != 0:
                    continue
                self._set_num_workers(num_workers)
                best_gps = 0
                gps_rng = (np.inf, 0.0)  
                min_batch_size = (
                    min(self.n_train, n_bulk)
                    if bulk_mp
                    else int(np.ceil(self.n_train / num_workers))
                )
                batch_size_rng = list(range(min_batch_size, 0, -1))
                batch_size_rng_sizes = [
                    batch_size
                    for batch_size in batch_size_rng
                    if min_batch_size % batch_size == 0
                ]
                i_done = 0
                i_dir = 1
                i = 0 if last_i is None else last_i
                while i >= 0 and i < len(batch_size_rng_sizes):
                    batch_size = batch_size_rng_sizes[i]
                    self._set_batch_size(batch_size)
                    i_done += 1
                    gps = (
                        n_bulk * n_reps / (timeit.timeit(_dummy_predict, number=n_reps))
                    )
                    batch_size * self.n_atoms * n_perms)
                    gps_rng = (
                        min(gps_rng[0], gps),
                        max(gps_rng[1], gps),
                    )  
                    '     best_gps ' + str(best_gps))
                     # gps did not go up wrt. to previous step
                    if gps < best_gps:
                        if (
                            i_dir > 0
                            and i_done == 2
                            and batch_size
                            != batch_size_rng_sizes[
                                1
                            ]  
                        ):  
                            i -= 2 * i_dir
                            i_dir = -1
                            '><')
                            continue
                        else:
                            '>>break ' + str(i_done))
                            break
                    else:
                        best_gps = gps
                        best_params = num_workers, batch_size, bulk_mp
                    if (
                        not bulk_mp and n_bulk > 1
                    ):  
                        if (
                            gps < gps_min
                        ):  
                            'breaking here')
                            break
                    # if gps < gps_min:  
                    i += 1 * i_dir
                last_i = i - 1 * i_dir
                i_dir = 1
                if len(best_results) > 0:
                    overall_best_gps = max(best_results, key=lambda x: x[1])[1]
                    if best_gps < overall_best_gps:
                        'breaking, because best of last test was worse than overall best so far')
                        break
                gps_min = gps_rng[0]  
                best_results.append(
                    (best_params, best_gps)
                )  
        (num_workers, batch_size, bulk_mp), gps = max(best_results, key=lambda x: x[1])
        self._save_cached_bmark_result(n_bulk, num_workers, batch_size, bulk_mp, gps)
        self._set_batch_size(batch_size)
        self._set_num_workers(num_workers)
        self._set_bulk_mp(bulk_mp)
        if return_is_from_cache:
            is_from_cache = False
            return gps, is_from_cache
        else:
            return gps
def prepare_parallel ( self , n_bulk = 1 , n_reps = 1 , return_is_from_cache = False ) : global n_perms bmark_result = self . _load_cached_bmark_result ( n_bulk ) if bmark_result is not None : num_workers , batch_size , bulk_mp , gps = bmark_result self . _set_batch_size ( batch_size ) self . _set_num_workers ( num_workers ) self . _set_bulk_mp ( bulk_mp ) if return_is_from_cache : is_from_cache = True return gps , is_from_cache else : return gps best_results = [ ] last_i = None best_gps = 0 gps_min = 0.0 best_params = None r_dummy = np . random . rand ( n_bulk , self . n_atoms * 3 ) def _dummy_predict ( ) : self . predict ( r_dummy ) bulk_mp_rng = [ True , False ] if n_bulk > 1 else [ False ] for bulk_mp in bulk_mp_rng : self . _set_bulk_mp ( bulk_mp ) if bulk_mp is False : last_i = 0 num_workers_rng = ( list ( range ( self . _max_processes , 1 , - 1 ) ) if bulk_mp else list ( range ( 1 , self . _max_processes + 1 ) ) ) for num_workers in num_workers_rng : if not bulk_mp and self . n_train % num_workers != 0 : continue self . _set_num_workers ( num_workers ) best_gps = 0 gps_rng = ( np . inf , 0.0 ) min_batch_size = ( min ( self . n_train , n_bulk ) if bulk_mp else int ( np . ceil ( self . n_train / num_workers ) ) ) batch_size_rng = list ( range ( min_batch_size , 0 , - 1 ) ) batch_size_rng_sizes = [ batch_size for batch_size in batch_size_rng if min_batch_size % batch_size == 0 ] i_done = 0 i_dir = 1 i = 0 if last_i is None else last_i while i >= 0 and i < len ( batch_size_rng_sizes ) : batch_size = batch_size_rng_sizes [ i ] self . _set_batch_size ( batch_size ) i_done += 1 gps = ( n_bulk * n_reps / ( timeit . timeit ( _dummy_predict , number = n_reps ) ) ) gps_rng = ( min ( gps_rng [ 0 ] , gps ) , max ( gps_rng [ 1 ] , gps ) , ) if gps < best_gps : if ( i_dir > 0 and i_done == 2 and batch_size != batch_size_rng_sizes [ 1 ] ) : i -= 2 * i_dir i_dir = - 1 continue else : break else : best_gps = gps best_params = num_workers , batch_size , bulk_mp if ( not bulk_mp and n_bulk > 1 ) : if ( gps < gps_min ) : break i += 1 * i_dir last_i = i - 1 * i_dir i_dir = 1 if len ( best_results ) > 0 : overall_best_gps = max ( best_results , key = lambda x : x [ 1 ] ) [ 1 ] if best_gps < overall_best_gps : break gps_min = gps_rng [ 0 ] best_results . append ( ( best_params , best_gps ) ) ( num_workers , batch_size , bulk_mp ) , gps = max ( best_results , key = lambda x : x [ 1 ] ) self . _save_cached_bmark_result ( n_bulk , num_workers , batch_size , bulk_mp , gps ) self . _set_batch_size ( batch_size ) self . _set_num_workers ( num_workers ) self . _set_bulk_mp ( bulk_mp ) if return_is_from_cache : is_from_cache = False return gps , is_from_cache else : return gps
Find and set the optimal parallelization parameters for the
currently loaded model, running on a particular system.
Find and set the optimal parallelization parameters for the currently loaded model running on a particular system .
# noqa: C901 """
        Find and set the optimal parallelization parameters for the
        currently loaded model, running on a particular system. The result
        also depends on the number of geometries `n_bulk` that will be
        passed at once when calling the `predict` function.

        This function runs a benchmark in which the prediction routine is
        repeatedly called `n_reps`-times (default: 1) with varying parameter
        configurations, while the runtime is measured for each one. The
        optimal parameters are then cached for fast retrival in future
        calls of this function.

        We recommend calling this function after initialization of this
        class, as it will drastically increase the performance of the
        `predict` function.

        Note
        ----
                Depending on the parameter `n_reps`, this routine may take
                some seconds/minutes to complete. However, once a
                statistically significant number of benchmark results has
                been gathered for a particular configuration, it starts
                returning almost instantly.

        Parameters
        ----------
                n_bulk : int, optional
                        Number of geometries that will be passed to the
                        `predict` function in each call (performance
                        will be optimized for that exact use case).
                n_reps : int, optional
                        Number of repetitions (bigger value: more
                        accurate, but also slower).
                return_is_from_cache : bool, optional
                        If enabled, this function returns a second value
                        indicating if the returned results were obtained
                        from cache.
    
        Returns
        -------
                int
                        Force and energy prediciton speed in geometries
                        per second.
                boolean, optional
                        Return, whether this function obtained the results
                        from cache. 
        """ # Retrieve cached benchmark results, if available. # reps_done = 0 # reps_done += 1 # print(reps_done) # self._bulk_mp = bulk_mp # num_workers_rng_sizes = [batch_size for batch_size in batch_size_rng if min_batch_size % batch_size == 0] # for num_workers in range(min_num_workers,self._max_processes+1): # if bulk_mp and n_bulk % num_workers != 0: # 	continue # min and max per num_workers # for i in range(0,min_batch_size): # print('batch_size_rng_sizes ' + str(bulk_mp)) # print(batch_size_rng_sizes) # i = 0 # print(batch_size_rng_sizes) # print( #    '{:2d}@{:d} {:d} | {:7.2f} gps'.format( #        num_workers, batch_size, bulk_mp, gps #    ) # ) # print(batch_size * self.n_atoms * n_perms) # min and max per num_workers # gps_min_max = min(gps_min_max[0], gps), max(gps_min_max[1], gps) # print('     best_gps ' + str(best_gps)) # NEW # if gps > best_gps and gps > gps_min: # gps is still going up, everything is good #     best_gps = gps #     best_params = num_workers, batch_size, bulk_mp # else: #     break # if gps > best_gps: # gps is still going up, everything is good #     best_gps = gps #     best_params = num_workers, batch_size, bulk_mp # else: # gps did not go up wrt. to previous step #     # can we switch the search direction? #     #   did we already? #     #   we checked two consecutive configurations #     #   are bigger batch sizes possible? #     print(batch_size_rng_sizes) #     turn_search_dir = i_dir > 0 and i_done == 2 and batch_size != batch_size_rng_sizes[1] #     # only turn, if the current gps is not lower than the lowest overall #     if turn_search_dir and gps >= gps_min: #         i -= 2 * i_dir #         i_dir = -1 #         print('><') #         continue #     else: #         print('>>break ' + str(i_done)) #         break # NEW # gps still going up? # AND: gps not lower than the lowest overall? # if gps < best_gps and gps >= gps_min: # there is no point in turning if this is the second batch size in the range # do we turn? # print('><') # if batch_size == batch_size_rng_sizes[1]: # 	i -= 1*i_dir # print('>>break ' + str(i_done)) # if gps < best_gps: #    break # else: # 	best_gps = gps # 	best_params = num_workers, batch_size, bulk_mp # stop search early when multiple cpus are available and the 1 cpu case is tested # if the batch size run is lower than the lowest overall, stop right here # print('breaking here') # if gps < gps_min:  # if the batch size run is lower than the lowest overall, stop right here #    break # print('breaking, because best of last test was worse than overall best so far') # if best_gps < gps_min: #    print('breaking here3') #    break # FIX me: is this the overall min? # print ('gps_min ' + str(gps_min)) # print ('best_gps') # print (best_gps) # if len(best_results) > 0 and best_gps < overall_best_gps: #    break # best results per num_workers # Cache benchmark results.
self
n_bulk
n_reps
return_is_from_cache