gpp_python_common¶
Contents:
gpp_python_common.hpp¶
Classes and utilities that are useful throughout the gpp_python_* interface code.
This file includes three main groups of things:
- Tools for translating between C++ and Python data sources
- PythonInterfaceInputContainer: captures the most common set of inputs used in gpp_python
- utilities for copying between std::vector and boost::python::list
- A RandomnessSourceContainer for moving consistent RNG state between C++, Python
- Export*() functions for giving Python access to various C++ calls via boost::python.
- enum classes
- optimizer parameter structs
- RandomnessSourceContainer from item 2)
Functions callable from Python generally have the following form:
- Copy vector inputs from references of Python structures to C++ (e.g., boost::python::list to std::vector). Items 1a) and 1b) are helpful for this.
- Construct any temporary objects needed by C++ (e.g., Evaluator/State pairs).
- Compute the desired result with C++ calls.
- Copy/return the desired result from C++ container back into a boost::python::list (or return directly for primitive types) Some of the functions in item 1b) are useful for this.
See other gpp_python_*.cpp files for examples (e.g., gpp_python_expected_improvement.cpp or gpp_python_model_selection.cpp).
General notes about the Python interface:
- We use raw strings (C++11) to pass multiline string literals to boost to specify python docstrings. Our delimiter is: %%. The format is: R"%%(put anything here, no need to escape chars)%%". Unfortunately this confuses linters but it is much more human-readable than alternatives.
- ALL ARRAYS/LISTS MUST BE FLATTENED! What that means: Matrices will be described as A[dim1][dim2]...[dimN] To FLATTEN a matrix is to lay it out in memory C-style; i.e., rightmost index varies the most rapidly. For example: A[3][4] = [4 32 5 2 `` 53 12 8 1`` `` 81 2 93 0]`` would be FLATTENED into an array: A_flat[12] = [4 32 5 2 53 12 8 1 81 2 93 0]
namespace optimal_learning
Macro to allow restrict as a keyword for C++ compilation and CUDA/nvcc compilation. See related entry in gpp_common.hpp for more details.
class PythonInterfaceInputContainer
Container class for translating a standard set of python (list) inputs into std::vector.
Public FunctionsPublic MembersPythonInterfaceInputContainer(const boost::python::list & points_to_sample_in, int dim_in, int num_to_sample_in)Minimal constructor that sets up points_to_sample only; generally used when a GaussianProcess object is already available (e.g., in GaussianProcess member function wrappers).
- Parameters:
points_to_sample[num_to_sample][dim]: points at which to compute GP quantities dim: number of spatial dimension (independent parameters) num_to_sample: number of points being sampled from the GP PythonInterfaceInputContainer(const boost::python::list & points_to_sample_in, const boost::python::list & points_being_sampled_in, int dim_in, int num_to_sample_in, int num_being_sampled_in)Minimal constructor that sets up points_to_sample and points_being_sampled; generally used when a GaussianProcess object is already available (e.g., in Expected Improvement wrappers).
- Parameters:
points_to_sample[num_to_sample][dim]: points at which to evaluate EI and/or its gradient to check their value in future experiments (i.e., test points for GP predictions) pylist points_being_sampled_in[num_being_sampled][dim]: points that are being sampled in concurrent experiments dim: number of spatial dimension (independent parameters) num_to_sample: number of potential future samples; gradients are evaluated wrt these points (i.e., the “q” in q,p-EI) num_being_sampled: number of points being sampled concurrently (i.e., the “p” in q,p-EI) PythonInterfaceInputContainer(const boost::python::list & hyperparameters_in, const boost::python::list & points_sampled_in, const boost::python::list & points_sampled_value_in, const boost::python::list & noise_variance_in, const boost::python::list & points_to_sample_in, int dim_in, int num_sampled_in, int num_to_sample_in)Constructor that sets up GP-related members held in this container; generally used when a GaussianProcess object is not available/relevant (or to construct a GP). Does not set points_being_sampled.
- Parameters:
pylist hyperparameters_in[2]: [0]: alpha: the hyperparameter alpha, (e.g., signal variance, sigma_f^2) [1]: lengths[dim]: the hyperparameter length scales, one per spatial dimension pylist points_sampled_in[num_sampled][dim]: points that have already been sampled pylist points_sampled_value_in[num_sampled]: objective values of the already-sampled points pylist noise_variance_in[num_sampled]: the sigma_n^2 (noise variance) associated w/observation, points_sampled_value pylist points_to_sample_in[num_to_sample][dim]: points at which to compute GP quantities dim: number of spatial dimension (independent parameters) num_sampled: number of already-sampled points num_to_sample: number of points being sampled from the GP int dim
int num_sampled
int num_to_sample
int num_being_sampled
double alpha
std::vector< double > lengths
std::vector< double > points_sampled
std::vector< double > points_sampled_value
std::vector< double > noise_variance
std::vector< double > points_to_sample
std::vector< double > points_being_sampled
class RandomnessSourceContainer
Container for randomness sources to be used with the python interface. Python should create a singleton of this object and then pass it back to any C++ function requiring randomness sources. Outside of testing, we only want a single version of this object floating around in order for all RNGs to remain consistent.
Python generally has minimal interaction with this class; it is meant to be constructed in Python and then passed back to C++ for use.
This class will track enough enough sources so that multithreaded computation is well-defined.
This class exposes its member functions directly to Python; these member functions are for setting and resetting seed values for the randomness sources.
Public FunctionsPublic MembersRandomnessSourceContainer(int num_threads)Creates the randomness container with enough random sources for at most num_threads simultaneous accesses.
Random sources are seeded to a repeatable combination of the default seed and the thread id.
int num_normal_rng()Get the current number of threads being tracked. Can be less than normal_rng_vec.size()
void SetExplicitUniformGeneratorSeed(NormalRNG::EngineType::result_type seed)Seeds uniform generator with the specified seed value
- Parameters:
seed: base seed value to use void SetRandomizedUniformGeneratorSeed(NormalRNG::EngineType::result_type seed)Seeds uniform generator with current time information
- Parameters:
seed: base seed value to use void ResetUniformGeneratorState()Resets uniform generator to its most recently used seed.
void SetExplicitNormalRNGSeed(NormalRNG::EngineType::result_type seed)Seeds RNG of thread i to f_i(seed, thread_id_i) such that f_i != f_j for i != j. f_i is repeatable. so each thread gets a distinct seed that is easily repeatable for testing
Note
every thread is GUARANTEED to have a different seed
- Parameters:
seed: base seed value to use void SetRandomizedNormalRNGSeed(NormalRNG::EngineType::result_type seed)Seeds each thread with a combination of current time, thread_id, and (potentially) other factors. multiple calls to this should produce different seeds modulo aliasing issues
- Parameters:
seed: base seed value to use bool SetNormalRNGSeedPythonList(const boost::python::list & seed_list, const boost::python::list & seed_flag_list)If seed_flag_list[i] is true, sets the normal rng seed of the i-th thread to the value of seed_list[i].
If sizes are invalid (i.e., number of seeds != number of generators), then no changes are made and an error code is returned.
Note
Does not guarantee that all threads receive unique seeds! If that is desired, seed_list should be checked BEFORE calling this function.
- Returns:
- true if successful, false otherwise (due to invalid sizes)
void ResetNormalRNGState()Resets all threads’ RNGs to the seed values they were initialized with. Useful for testing.
void PrintState()OL_DISALLOW_DEFAULT_AND_COPY_AND_ASSIGN(RandomnessSourceContainer)Private MembersUniformRandomGenerator uniform_generator
The uniform random generator that will be used by C++ to make uniform draws.
std::vector< NormalRNG > normal_rng_vec
The normal random generators (one per thread) that will be used by C++ to make N(0, 1)-distributed draws.
Private Static Attributesint num_normal_rng_
length of normal_rng_vec
constexpr NormalRNG::EngineType::result_type kNormalDefaultSeed
constexpr UniformRandomGenerator::EngineType::result_type kUniformDefaultSeed
gpp_python_common.cpp¶
This file contains definitions of infrequently-used or expensive functions declared in gpp_python_common.hpp.
Note: several internal functions of this source file are only called from Export*() functions, so their description, inputs, outputs, etc. comments have been moved. These comments exist in Export*() as Python docstrings, so we saw no need to repeat ourselves.
namespace optimal_learning
Macro to allow restrict as a keyword for C++ compilation and CUDA/nvcc compilation. See related entry in gpp_common.hpp for more details.
Functionsvoid CopyPylistToVector(const boost::python::list & input, int size, std::vector< double > & output)Copies the first doubles elements of a python list (input) into a std::vector (output) Resizes output if needed.
Warning
undefined behavior if the python list contains anything except type double!
- Parameters:
input: python list to copy from size: number of elements to copy - Outputs:
output: std::vector with copies of the first size items of input void CopyPylistToClosedIntervalVector(const boost::python::list & input, int size, std::vector< ClosedInterval > & output)Copies the first size [min, max] pairs from input to output. Size of input MUST be 2*size.
Warning
undefined behavior if the python list contains anything except type double!
- Parameters:
input: python list to copy from size: number of pairs to copy - Outputs:
output: std::vector with copies of the first size items of input boost::python::list VectorToPylist(const std::vector< double > & input)Produces a PyList with the same size as the input vector and that is element-wise equal to the input vector.
- Parameters:
input: std::vector to be copied - Returns:
- python list that is element-wise equivalent to input
void ExportEnumTypes()Export C++’s enum classes to Python; e.g., DomainTypes, OptimizerTypes, etc. Includes docstrings.
void ExportOptimizerParameterStructs()Export the parameter structs from gpp_optimizer_parameters.hpp to Python. Includes docstrings.
void ExportRandomnessContainer()Export the class RandomnessSourceContainer and its member functions to Python. Includes docstrings.