def test_random(ctx_factory): context = ctx_factory() queue = cl.CommandQueue(context) from pyopencl.clrandom import RanluxGenerator if has_double_support(context.devices[0]): dtypes = [np.float32, np.float64] else: dtypes = [np.float32] gen = RanluxGenerator(queue, 5120) for ary_size in [300, 301, 302, 303, 10007]: for dtype in dtypes: ran = cl_array.zeros(queue, ary_size, dtype) gen.fill_uniform(ran) assert (0 < ran.get()).all() assert (ran.get() < 1).all() gen.synchronize(queue) ran = cl_array.zeros(queue, ary_size, dtype) gen.fill_uniform(ran, a=4, b=7) assert (4 < ran.get()).all() assert (ran.get() < 7).all() ran = gen.normal(queue, (10007, ), dtype, mu=4, sigma=3) dtypes = [np.int32] for dtype in dtypes: ran = gen.uniform(queue, (10000007, ), dtype, a=200, b=300) assert (200 <= ran.get()).all() assert (ran.get() < 300).all()
def test_random(ctx_factory): context = ctx_factory() queue = cl.CommandQueue(context) from pyopencl.clrandom import RanluxGenerator if has_double_support(context.devices[0]): dtypes = [np.float32, np.float64] else: dtypes = [np.float32] gen = RanluxGenerator(queue, 5120) for ary_size in [300, 301, 302, 303, 10007]: for dtype in dtypes: ran = cl_array.zeros(queue, ary_size, dtype) gen.fill_uniform(ran) assert (0 < ran.get()).all() assert (ran.get() < 1).all() gen.synchronize(queue) ran = cl_array.zeros(queue, ary_size, dtype) gen.fill_uniform(ran, a=4, b=7) assert (4 < ran.get()).all() assert (ran.get() < 7).all() ran = gen.normal(queue, (10007,), dtype, mu=4, sigma=3) dtypes = [np.int32] for dtype in dtypes: ran = gen.uniform(queue, (10000007,), dtype, a=200, b=300) assert (200 <= ran.get()).all() assert (ran.get() < 300).all()
class GeneticAlgorithmOpenCL(GeneticAlgorithm): class Population: # Crossover modes CM_SEPARATE = 0 # Separate probabilities for translation/rotation genes CM_COMBINE = 1 # Combined probability for translation/rotation genes def __init__(self, size = 0, dna_size = 0, \ cl_ctx = None, cl_queue = None, rng = None, cl_prg = None): self.size = size self.dna_size = dna_size # OpenCL self.cl_ctx = cl_ctx self.cl_queue = cl_queue self.rng = rng self.cl_prg = cl_prg # Matrix of i by j for individuals and genes (DNA) respectively self.individuals_np = None self.individuals_buf = None self.new_individuals_np = None self.new_individuals_buf = None self.crossover_translation_mode_np = np.array([], dtype = int) self.crossover_translation_mode_buf = None self.crossover_rotation_mode_np = np.array([], dtype = int) self.crossover_rotation_mode_buf = None self.crossover_probability_np = np.array([], dtype = float) self.crossover_probability_buf = None self.mutation_probability_np = np.array([], dtype = float) self.mutation_probability_buf = None def setup_opencl(self): mf = cl.mem_flags # Setup device buffers self.individuals_buf = cl.array.zeros(self.cl_queue, \ (self.size, self.dna_size), \ dtype = float) self.new_individuals_buf = cl.array.zeros(self.cl_queue, \ (self.size, self.dna_size), \ dtype = float) self.crossover_translation_mode_np = np.array([self.crossover_translation_mode], \ dtype = int) self.crossover_translation_mode_buf = cl.Buffer(self.cl_ctx, \ mf.READ_ONLY | mf.COPY_HOST_PTR, \ hostbuf = self.crossover_translation_mode_np) self.crossover_rotation_mode_np = np.array([self.crossover_rotation_mode], \ dtype = int) self.crossover_rotation_mode_buf = cl.Buffer(self.cl_ctx, \ mf.READ_ONLY | mf.COPY_HOST_PTR, \ hostbuf = self.crossover_rotation_mode_np) self.crossover_probability_np = np.array([self.crossover_probability], \ dtype = float) self.crossover_probability_buf = cl.Buffer(self.cl_ctx, \ mf.READ_ONLY | mf.COPY_HOST_PTR, \ hostbuf = self.crossover_probability_np) self.mutation_probability_np = np.array([self.mutation_probability], \ dtype = float) self.mutation_probability_buf = cl.Buffer(self.cl_ctx, \ mf.READ_ONLY | mf.COPY_HOST_PTR, \ hostbuf = self.mutation_probability_np) def __repr__(self): self.individuals_np = self.individuals_buf.get() ret = "Individuals:\n" for idx, individual in enumerate(self.individuals_np): ret += "[%3d] " % (idx + 1) ret += "%6.2f %6.2f %6.2f | " % (individual[0], \ individual[1], \ individual[2]) ret += "%6.2f %6.2fi %6.2fj %6.2fk | " % (individual[3], \ individual[4], \ individual[5], \ individual[6]) for torsion in individual[7:]: ret += " %5.2f" % torsion ret += "\n" return ret def get_individual(self, idx = 0): self.individuals_np = self.individuals_buf.get() return self.individuals_np[idx] def create(self, dna_size_buf = None, dock = None): self.rng.fill_uniform(self.individuals_buf) # Construct individuals self.cl_prg.construct_individuals(self.cl_queue, \ (self.size,), None, \ dock.lo_grid_buf, \ dock.dist_grid_buf, \ dna_size_buf, \ self.individuals_buf.data) def scoring(self, dock = None, \ cl_ctx = None, cl_queue = None): dock.reset_poses(self.size, self.individuals_buf, \ cl_ctx, cl_queue) dock.calc_energy() def min_score(self, dock = None): scores = dock.e_totals_buf.get() return scores.min() def crossover(self, parents_idx, ttl_torsions, rng): return None def mutate(self, individual, mutation_chance, \ lo_grid, hi_grid, ttl_torsions, rng): return None class Settler(Population): def __init__(self, size = 0, dna_size = 0, \ cl_ctx = None, cl_queue = None, rng = None, cl_prg = None): GeneticAlgorithmOpenCL.Population.__init__(self, size, dna_size, \ cl_ctx, cl_queue, \ rng, cl_prg) self.crossover_translation_mode = self.CM_COMBINE self.crossover_rotation_mode = self.CM_COMBINE self.crossover_probability = 0.5 self.mutation_probability = 0.25 # OpenCL self.setup_opencl() class Nomad(Population): def __init__(self, size = 0, dna_size = 0, \ cl_ctx = None, cl_queue = None, rng = None, cl_prg = None): GeneticAlgorithmOpenCL.Population.__init__(self, size, dna_size, \ cl_ctx, cl_queue, \ rng, cl_prg) self.crossover_translation_mode = self.CM_SEPARATE self.crossover_rotation_mode = self.CM_SEPARATE self.crossover_probability = 0.5 self.mutation_probability = 0.75 # OpenCL self.setup_opencl() def __init__(self, dock = None, cl_device_type = None): GeneticAlgorithm.__init__(self, dock) # OpenCL self.cl_device_type = cl_device_type if self.cl_device_type == "gpu": self.cl_ctx = cl.Context(dev_type = cl.device_type.GPU) elif self.cl_device_type == "cpu": self.cl_ctx = cl.Context(dev_type = cl.device_type.CPU) else: # manual selection self.cl_ctx = cl.create_some_context() self.cl_queue = cl.CommandQueue(self.cl_ctx) self.cl_filename = "./OpenCL/GeneticAlgorithm.cl" fh = open(self.cl_filename, 'r') cl_code = "".join(fh.readlines()) self.cl_prg = cl.Program(self.cl_ctx, cl_code).build() self.rng = None # OpenCL buffer self.population_size_np = np.array([], dtype = int) self.population_size_buf = None self.dna_size_np = np.array([], dtype = int) self.dna_size_buf = None self.max_inherited_prob_np = np.array([], dtype = int) self.max_inherited_prob_buf = None self.normalizer_np = np.array([], dtype = int) self.normalizer_buf = None self.chances_np = None self.chances_buf = None self.chances_sum_buf = None self.dna1_buf = None self.dna2_buf = None self.ttl_reproduction_rns_np = np.array([], dtype = int) self.ttl_reproduction_rns_buf = None self.reproduction_rns_buf = None self.mutation_chance_np = np.array([], dtype = float) self.mutation_chance_buf = None def setup_opencl(self): # OpenCL setup self.dock.setup_opencl(self.cl_ctx, self.cl_queue) # Setup OpenCL device buffer mf = cl.mem_flags self.population_size_np = np.array([self.population_size], dtype = int) self.population_size_buf = cl.Buffer(self.cl_ctx, \ mf.READ_ONLY | mf.COPY_HOST_PTR, \ hostbuf = self.population_size_np) self.dna_size = 3 + 4 + self.dock.get_total_torsions() self.dna_size_np = np.array([self.dna_size], dtype = int) self.dna_size_buf = cl.Buffer(self.cl_ctx, \ mf.READ_ONLY | mf.COPY_HOST_PTR, \ hostbuf = self.dna_size_np) self.max_inherited_prob_np = np.array([self.max_inherited_prob], \ dtype = int) self.max_inherited_prob_buf = cl.Buffer(self.cl_ctx, \ mf.READ_ONLY | mf.COPY_HOST_PTR, \ hostbuf = self.max_inherited_prob_np) self.normalizer_np = np.array([self.ttl_ligand_atoms], dtype = int) self.normalizer_buf = cl.Buffer(self.cl_ctx, \ mf.READ_ONLY | mf.COPY_HOST_PTR, \ hostbuf = self.normalizer_np) self.chances_buf = cl.array.zeros(self.cl_queue, (self.population_size), \ dtype = int) self.chances_sum_buf = cl.array.zeros(self.cl_queue, (self.population_size), \ dtype = int) self.dna1_buf = cl.array.zeros(self.cl_queue, \ (self.population_size, self.dna_size), \ dtype = float) self.dna2_buf = cl.array.zeros(self.cl_queue, \ (self.population_size, self.dna_size), \ dtype = float) # Reproduction random numbers needed per individual: # - Selecting parents: 2 # - Crossing over: Use new_individuals_buf # - Mutation: 1 + 2 + total torsions # - Mutation pose: 3 + 4 + total torsions ttl_reproduction_rns = 2 + 1 + 2 + self.ttl_torsions + \ 3 + 4 + self.ttl_torsions self.ttl_reproduction_rns_np = np.array([ttl_reproduction_rns], \ dtype = int) self.ttl_reproduction_rns_buf = cl.Buffer(self.cl_ctx, \ mf.READ_ONLY | mf.COPY_HOST_PTR, \ hostbuf = self.ttl_reproduction_rns_np) self.reproduction_rns_buf = cl.array.zeros(self.cl_queue, \ (self.population_size, ttl_reproduction_rns), \ dtype = float) self.mutation_chance_np = np.array([self.mutation_chance], dtype = float) self.mutation_chance_buf = cl.Buffer(self.cl_ctx, \ mf.READ_ONLY | mf.COPY_HOST_PTR, \ hostbuf = self.mutation_chance_np) # Setup OpenCL buffer for docking object self.dock.setup_opencl_buffer(self.population_size, \ self.cl_ctx, self.cl_queue) def setup_rng(self): self.rng = RanluxGenerator(self.cl_queue) def setup(self): # Call parent setup GeneticAlgorithm.setup(self) # OpenCL self.setup_opencl() def select(self, population): # Get individual scores population.scoring(self.dock, self.cl_ctx, self.cl_queue) self.cl_prg.calc_chances(self.cl_queue, (self.population_size,), None, \ self.dock.e_totals_buf.data, \ self.normalizer_buf, \ self.max_inherited_prob_buf, \ self.chances_buf.data) def reproduce(self, population): self.rng.fill_uniform(population.new_individuals_buf) self.rng.fill_uniform(self.reproduction_rns_buf) self.cl_prg.reproduce(self.cl_queue, (self.population_size,), None, \ self.population_size_buf, \ self.chances_buf.data, \ self.ttl_reproduction_rns_buf, \ self.reproduction_rns_buf.data, \ self.dna_size_buf, \ population.individuals_buf.data, \ population.crossover_translation_mode_buf, \ population.crossover_rotation_mode_buf, \ population.crossover_probability_buf, \ self.mutation_chance_buf, \ population.mutation_probability_buf, \ self.dock.ttl_torsions_buf, \ self.dock.lo_grid_buf, \ self.dock.dist_grid_buf, \ self.chances_sum_buf.data, \ self.dna1_buf.data, \ self.dna2_buf.data, \ population.new_individuals_buf.data) cl.enqueue_copy(self.cl_queue, population.individuals_buf.data, \ population.new_individuals_buf.data) def run(self): self.setup() # Define multiple population self.nomad = self.Nomad(self.population_size, self.dna_size, \ self.cl_ctx, self.cl_queue, \ self.rng, self.cl_prg) self.settler = self.Settler(self.population_size, self.dna_size, \ self.cl_ctx, self.cl_queue, \ self.rng, self.cl_prg) population_min_scores = [] for community_idx in xrange(self.community_size): tic = time() # Nomad portion nomad_min_score = float("inf") self.nomad.create(self.dna_size_buf, self.dock) if VERBOSE: print self.nomad for gen_idx in xrange(self.num_gen): self.select(self.nomad) self.reproduce(self.nomad) nomad_min_score = self.nomad.min_score(self.dock) # Settler portion settler_min_score = float("inf") cl.enqueue_copy(self.cl_queue, self.settler.individuals_buf.data, \ self.nomad.individuals_buf.data) if VERBOSE: print self.settler for gen_idx in xrange(self.num_gen): self.select(self.settler) self.reproduce(self.settler) if VERBOSE: print self.settler settler_min_score = self.settler.min_score(self.dock) population_min_scores.append([nomad_min_score, settler_min_score]) toc = time() print "Elapsed time community %4d: %10.2f - Minimum Scores: %12.3f, %12.3f" \ % (community_idx + 1, toc - tic, \ nomad_min_score, settler_min_score) print "Community Minimum Scores: %s" % population_min_scores