예제 #1
0
 def fromProtoModel(cls,
                    protomodel,
                    nsteps=10000,
                    strategy="aggressive",
                    walkerid=0,
                    dump_training=False,
                    dbpath="<rundir>/database.pcl",
                    expected=False,
                    select="all",
                    catch_exceptions=True,
                    keep_meta=True,
                    rundir=None,
                    do_combine=False,
                    seed=None,
                    stopTeleportationAfter=-1):
     ret = cls( walkerid, nsteps=nsteps, dbpath = dbpath, expected=expected,
                select=select, catch_exceptions = catch_exceptions, rundir = rundir,
                do_combine = do_combine, seed = seed, stopTeleportationAfter = \
                stopTeleportationAfter )
     ret.manipulator.M = protomodel
     ret.manipulator.setWalkerId(walkerid)
     ret.manipulator.backupModel()
     if dump_training:
         ## we use the accelerator only to dump the training data
         from accelerator import Accelerator
         ret.accelerator = Accelerator(walkerid=walkerid,
                                       dump_training=True,
                                       is_trained=False)
     return ret
예제 #2
0
def main():
    print("Test")
    acc = Accelerator()

    width = 0.4
    height = 0.2

    t0 = Transformator("T0", width, height)
    p1 = Pipe(width, height, 1.0)
    s0 = Screen("Screen", width, height, 0.2, 0.2)
    t1 = Transformator("T1", width, height)
    q1 = QuadrupoleMagnet("UN4QD11", width, height, 1.0, 0.8)
    q2 = QuadrupoleMagnet("UN4QD12", width, height, 1.0, -0.8)
    sl1 = Slit("Slit1", width, height)
    p2 = Pipe(width, height, 3.0)
    sl2 = Slit("Slit2", width, height)
    k1 = HorizontalKickerMagnet("kicker", width, height, 0.02)
    p3 = Pipe(width, height, 3.0)
    t2 = Transformator("T2", width, height)
    m1 = SectorBendingMagnet("UN4MU1", width, height, length=1.0, angle=0.5)
    t3 = Transformator("T3", width, height)
    s1 = Screen("Screen1", width, height, 0.2, 0.2)
    s2 = Screen("Screen2", width, height, 0.2, 0.2)

    # acc.append_devices([t0])
    acc.append_devices([t0, s0, p1, t1, q1, sl1, q2, sl1, p2, sl2, s1, k1, p3, t2, m1, t3, s2])
    sl2.set_positions(xpos_left=-0.01, xpos_right=0.01, ypos_bottom=-0.01, ypos_top=0.01)
    n = 80000
    '''
    acc.reset()

    simulate(accelerator=acc, num_of_particles=n, threaded=False, measure_time=True)
    print(t0.count.value, " particles in T0\n")
    print(s0.num_of_particles(), " particles in S0\n")
    '''
    acc.reset()

    simulate(accelerator=acc, num_of_particles=n, threaded=True, measure_time=True)
    print(t0.count.value, " particles in T0\n")
    print(s0.num_of_particles(), " particles in S0\n")


    s1.show()
    s2.show()
예제 #3
0
 def __init__(self, scene, args):
     
     self.shader = scene.shader(scene)
     
     self.scene = scene
     self._group_objects()
     self._init_lights()
     
     self.acc = Accelerator(args.choose_opencl_context)
     self._collect_tracer_data()
     self._init_misc()
     self._init_camera_and_image()
     self.ray_state = RayStateBuffers(self)
     self.shader.initialize_material_buffers(self.acc)
     
     program_code = Compiler(self).make_program()
     self.prog = self.acc.build_program(program_code, args.cl_build_options)
예제 #4
0
    def __init__(self,
                 walkerid=0,
                 nsteps=10000,
                 strategy="aggressive",
                 dump_training=False,
                 cheatcode=0,
                 dbpath="./database.pcl",
                 expected=False,
                 select="all",
                 catch_exceptions=True,
                 rundir=None,
                 nevents=100000,
                 do_combine=False,
                 record_history=False,
                 seed=None,
                 stopTeleportationAfter=-1):
        """ initialise the walker
        :param nsteps: maximum number of steps to perform, negative is infinity
        :param cheatcode: cheat mode. 0 is no cheating, 1 is with ranges, 2
                      is the Z323 model.
        :param expected: remove possible signals from database
        :param select: select only subset of results (all for all, em for efficiency maps only, ul for upper limits only, alternatively select for txnames via e.g. "txnames:T1,T2"
        :param catch_exceptions: should we catch exceptions
        :param nevents: number of MC events when computing cross-sections
        :param do_combine: if true, then also perform combinations, either via
                           simplified likelihoods or via pyhf
        :param record_history: if true, attach a history recorder class
        :param seed: random seed, int or None
        :param stopTeleportationAfter: int or None. we stop teleportation after this step nr.
               If negative or None, we dont teleport at all
        """
        if type(walkerid) != int or type(nsteps) != int or type(
                strategy) != str:
            self.pprint("Wrong call of constructor: %s, %s, %s" %
                        (walkerid, nsteps, strategy))
            sys.exit(-2)
        self.walkerid = walkerid  ## walker id, for parallel runs
        self.rundir = rundir
        if rundir == None:
            self.rundir = "./"

        if seed is not None:
            from ptools import helpers
            helpers.seedRandomNumbers(seed + walkerid)
            self.pprint(f"setting random seed to {seed}")

        #Initialize Predictor
        self.predictor = Predictor(self.walkerid,
                                   dbpath=dbpath,
                                   expected=expected,
                                   select=select,
                                   do_combine=do_combine)

        #Initialize Hiscore (with access to the predictor)
        self.hiscoreList = Hiscore(walkerid,
                                   True,
                                   "%s/H%d.hi" % (self.rundir, walkerid),
                                   backup=False,
                                   predictor=self.predictor)
        self.hiscoreList.nkeep = 1

        #Initialize ProtoModel and Manipulator:
        protomodel = ProtoModel(
            self.walkerid,
            keep_meta=True,
            nevents=nevents,
            dbversion=self.predictor.database.databaseVersion)

        self.manipulator = Manipulator(protomodel,
                                       strategy,
                                       do_record=record_history,
                                       seed=seed)
        self.catch_exceptions = catch_exceptions
        self.maxsteps = nsteps
        if stopTeleportationAfter == None:
            stopTeleportationAfter = -1
        # stopTeleportationAfter = self.maxsteps/3.
        self.stopTeleportationAfter = stopTeleportationAfter
        self.accelerator = None
        if record_history:
            from ptools.history import History
            self.recorder = History(f"{self.rundir}/history{walkerid}.list")
            self.manipulator.do_record = True
        jobid = "unknown"
        if "SLURM_JOBID" in os.environ:
            jobid = os.environ["SLURM_JOBID"]
        self.pprint("Ramping up with slurm jobid %s" % jobid)

        if cheatcode <= 0:
            self.takeStep()  # the first step should be considered as "taken"
            #Set current Z and K values to threshold values
            self.currentZ = -0.1
            self.currentK = -20.0
        else:
            self.manipulator.cheat(cheatcode)
            self.predictor.predict(self.protomodel)
            self.pprint ( "Cheat model gets Z=%.2f, K=%.2f" % \
                          ( self.manipulator.M.Z, self.manipulator.M.K ) )
            # self.printStats ( substep=4 )
            self.manipulator.backupModel()
            self.hiscoreList.newResult(self.manipulator)
            self.printStats(substep=5)
            self.currentK = self.manipulator.M.K
            self.currentZ = self.manipulator.M.Z
        if dump_training:
            from accelerator import Accelerator
            ## we use the accelerator only to dump the training data
            self.accelerator = Accelerator(walkerid=walkerid,
                                           dump_training=True,
                                           is_trained=False)
예제 #5
0
class Renderer:
    """
    Main controller class that, when initialized with the Scene, generates
    and compiles the OpenCL code for rendering it and provides methods:
        
        * render_sample for sampling a new batch of rays and accumulating
          the results to an image
        * get_image for accessing the currently rendered result

    """
    # TODO: refactor to better separated classes
    
    def get_image(self):
        imgdata = self.img.get().astype(np.float32)
        img = np.empty(self.img_shape + (3,))
        img[self.image_order[:, 0], self.image_order[:, 1], :] = imgdata[..., 0:3]
        return img
        
    def rays_per_sample(self):
        return self.img_shape[0]*self.img_shape[1]
    
    def __init__(self, scene, args):
        
        self.shader = scene.shader(scene)
        
        self.scene = scene
        self._group_objects()
        self._init_lights()
        
        self.acc = Accelerator(args.choose_opencl_context)
        self._collect_tracer_data()
        self._init_misc()
        self._init_camera_and_image()
        self.ray_state = RayStateBuffers(self)
        self.shader.initialize_material_buffers(self.acc)
        
        program_code = Compiler(self).make_program()
        self.prog = self.acc.build_program(program_code, args.cl_build_options)
    
    def _group_objects(self):
        get_tracer_name = lambda obj: obj.tracer.tracer_kernel_name
        self.scene.objects.sort(key=get_tracer_name)
        
        groups = itertools.groupby(self.scene.objects, key=get_tracer_name)
        groups = [ (k,list(g)) for k,g in groups ]
        object_counts = { k : len(g) for k, g in groups }
        
        offset = 0
        self.object_groups = []
        for name in sorted([k for k,_ in groups]):
            
            count = object_counts[name]
            tracer = self.scene.objects[offset].tracer
            
            self.object_groups.append((tracer,count,offset))
            
            offset += count

        # ------------- Find root container object
        self.root_object_id = 0
        for i in range(len(self.scene.objects)):
            if self.scene.root_object == self.scene.objects[i]:
                self.root_object_id = i+1
    
    def _init_misc(self):
        # TODO: bad
        
        self.max_broadcast_vecs = 6
        self.vec_broadcast = self.acc.new_const_buffer(np.zeros((self.max_broadcast_vecs, 4)))
        self.vec_param_buf = np.zeros((self.max_broadcast_vecs, 4), dtype=np.float32)
        
        # Randomization init
        self.qdirs = camera.quasi_random_direction_sample(self.scene.samples_per_pixel)
        self.qdirs = np.random.permutation(self.qdirs)
    
    def _init_camera_and_image(self):
        scene = self.scene
        
        cam = self.scene.get_camera_rays()
        self.rotmat = scene.get_camera_rotmat()
        fovx_rad = scene.camera_fov / 180.0 * np.pi
        self.pixel_angle = fovx_rad / scene.image.size[0]
        
        self.img_shape = scene.image.size[::-1]
        self.n_pixels = self.img_shape[0] * self.img_shape[1]
        
        self.image_order = self.get_image_order()
        
        cam = cam[self.image_order[:, 0], self.image_order[:, 1], 0:3]
        
        # Device buffers
        self.cam = self.acc.make_vec3_array(cam)
        self.img = self.acc.new_vec3_array((self.n_pixels, ))
    
    def _init_lights(self):
        
        self.bidirectional_light_ids = [i
            for i in range(len(self.scene.objects))
            if self.scene.objects[i].bidirectional_light]
            
        self.bidirectional = len(self.bidirectional_light_ids) > 0
    
    def get_light_point(self):
        light_id = self.bidirectional_light_ids[np.random.randint(len(self.bidirectional_light_ids))]
        light = self.scene.objects[light_id]
        return (light_id, light.tracer.surface_area()) + \
            light.tracer.random_surface_point_and_normal() + \
            light.tracer.center_and_min_sampling_distance()
    
    def _collect_tracer_data(self):
        
        data_items = ['vector', 'integer',
            'param_float3', 'param_int', 'param_float']
        
        data = { k : [] for k in data_items }
        data_sizes = { k : 0 for k in data_items }
        
        object_data_pointer_buffer = []
        const_data_buffers = True
        
        for obj in self.scene.objects:
            
            if obj.tracer.has_data():
                cur_data = obj.tracer.get_data()
            else:
                cur_data = {}
                
            param_values_by_type = {}
            local_param_offsets = []
            
            parameter_types = obj.tracer.parameter_types()
            param_values = obj.tracer.parameter_values()
            
            # two affine transformations -> (3+1)*2 3-vectors
            parameter_types += ['float3']*4
            forward_affine = obj.tracer.global_to_tracer_coordinate_transform()
            inverse_affine = forward_affine.inverse()
            param_values += [
                inverse_affine.linear[0,:],
                inverse_affine.linear[1,:],
                inverse_affine.linear[2,:],
                inverse_affine.translation
            ]
            
            for p_idx in range(len(parameter_types)):
                cl_type = parameter_types[p_idx]
                old = param_values_by_type.get(cl_type, [])
                local_param_offsets.append(len(old))
                param_values_by_type[cl_type] = old + [param_values[p_idx]]
            
            obj.tracer.local_param_offsets = local_param_offsets
            
            for cl_type, params in param_values_by_type.items():
                param_type = 'param_' + cl_type
                assert(param_type in data_items)
                cur_data[param_type] = np.array(params)
            
            offset_buffer = []
            
            for dtype in data_items:
                cur = cur_data.get(dtype)
                n_data = data_sizes[dtype]
                
                offset_buffer.append(n_data)
                
                if cur is not None:
                    if dtype in ['vector','param_float3']:
                        if cur.shape[1] != 3:
                            raise RuntimeError('invalid vector data shape')
                        n_data += cur.shape[0]
                    else:
                        cur = np.ravel(cur)
                        n_data += cur.size
                    
                    data[dtype].append(cur)
                    data_sizes[dtype] = n_data
            
            object_data_pointer_buffer.append(offset_buffer)
        
        self.tracer_data_buffers = []
        self.tracer_const_data_buffers = []
        
        for dtype in data_items:
            values = data[dtype]
            
            if dtype == 'param_int':
                self.object_data_pointer_buffer_offset = data_sizes[dtype]
                values += object_data_pointer_buffer
            
            if len(values) == 0:
                values = None
            else:
                if dtype in ['vector', 'param_float3']:
                    values = np.vstack(values)
                else:
                    values = np.concatenate(values)
                    
                if dtype == 'vector':
                    if const_data_buffers:
                        values = self.acc.make_const_vec3_buffer(values)
                    else:
                        values = self.acc.make_vec3_array(values)
                elif dtype == 'integer':
                    if const_data_buffers:
                        values = self.acc.new_const_buffer(values, dtype=np.int32)
                    else:
                        values = self.acc.to_device(values.astype(np.int32))
                elif dtype == 'param_float3':
                    values = self.acc.make_const_vec3_buffer(values)
                elif dtype == 'param_float':
                    values = self.acc.new_const_buffer(values)
                elif dtype == 'param_int':
                    values = self.acc.new_const_buffer(values, np.int32)
                else:
                    assert(False)
                
            if dtype == 'vector':
                buffers = self.tracer_data_buffers
            elif dtype == 'integer':
                buffers = self.tracer_data_buffers
            elif dtype == 'param_float3':
                buffers = self.tracer_const_data_buffers
            elif dtype == 'param_float':
                buffers = self.tracer_const_data_buffers
            elif dtype == 'param_int':
                buffers = self.tracer_const_data_buffers
            else:
                assert(False)
            
            buffers.append(values)

    # helpers
    
    def _fill_vec(self, data, vec):
        hostbuf = np.float32(vec)
        self.acc.enqueue_copy(self.vec_broadcast, hostbuf)
        self.acc.call('fill_vec_broadcast', self.n_pixels, (data, ), \
            value_args=(self.vec_broadcast, ))

    def new_camera_sample(self):
        
        scene = self.scene
        cam_origin = scene.camera_position
        
        # TODO: quasi random...
        sx = np.float32(np.random.rand())
        sy = np.float32(np.random.rand())
        
        # Tent filter as in smallpt
        if self.scene.tent_filter:
            def tent_filter_transformation(x):
                x *= 2
                if x < 1:
                    return np.sqrt(x)-1
                else:
                    return 1-np.sqrt(2-x)
            
            sx = tent_filter_transformation(sx)
            sy = tent_filter_transformation(sy)
        
        overlap = 0.0
        thetax = (sx-0.5)*self.pixel_angle*(1.0+overlap)
        thetay = (sy-0.5)*self.pixel_angle*(1.0+overlap)
        
        dofx, dofy = camera.random_dof_sample()
        
        dof_pos = (dofx * self.rotmat[:, 0] + dofy * self.rotmat[:, 1]) * scene.camera_dof_fstop
        
        sharp_distance = scene.camera_sharp_distance
        
        tilt = camera.rotmat_tilt_camera(thetax, thetay)
        mat = np.dot(np.dot(self.rotmat, tilt), self.rotmat.transpose())
        mat4 = np.zeros((4, 4))
        mat4[0:3, 0:3] = mat
        mat4[3, 0:3] = dof_pos
        mat4[3, 3] = sharp_distance
        
        cam_origin = cam_origin + dof_pos
        
        return cam_origin, mat4

    def render_sample(self, sample_index):
    
        scene = self.scene
        acc = self.acc
    
        cam_origin, mat4 = self.new_camera_sample()
        
        acc.enqueue_copy(self.vec_broadcast,  mat4.astype(np.float32))
        acc.call('subsample_transform_camera', self.n_pixels, \
            (self.cam, self.ray_state.ray, self.ray_state.pixel), \
            value_args=(self.vec_broadcast,))
        
        self._fill_vec(self.ray_state.pos, cam_origin)
        self.ray_state.whichobject.fill(0)
        #self.ray_state.normal.fill(0)
        self.ray_state.raycolor.fill(1)
        self.ray_state.diffusions_left.fill(scene.min_bounces)
        
        self.ray_state.inside.fill(self.root_object_id)
        
        path_index = 0
        
        self.shader.init_sample(self)
        self.cur_n_pixels = self.n_pixels
        
        for path_index in range(scene.max_bounces):
            if not self.compute_next_path_segment(sample_index, path_index, path_index == scene.max_bounces-1):
                break
    
        acc.finish()
        
        return path_index

    def compute_next_path_segment(self, sample_index, path_index, is_last):
        
        acc = self.acc
        
        self.ray_state.isec_dist[:self.cur_n_pixels].fill(self.scene.max_ray_length)
        
        self.ray_state.whichobject, self.ray_state.last_whichobject = \
          (self.ray_state.last_whichobject, self.ray_state.whichobject)
        
        self.ray_state.which_subobject, self.ray_state.last_which_subobject = \
          (self.ray_state.last_which_subobject, self.ray_state.which_subobject)
        
        for tracer, count, offset in self.object_groups:
            for object_index in range(offset, offset+count):
                acc.call(tracer.tracer_kernel_name, self.cur_n_pixels, \
                    self.ray_state.tracer_kernel_params() + \
                    tuple(self.tracer_data_buffers),
                    value_args=tuple(self.tracer_const_data_buffers) + \
                        (np.int32(object_index+1),))
        
        for tracer, count, offset in self.object_groups:
            acc.call(tracer.normal_kernel_name, self.cur_n_pixels, \
                    self.ray_state.normal_kernel_params() + \
                    tuple(self.tracer_data_buffers),
                    value_args=tuple(self.tracer_const_data_buffers) + \
                    (np.int32(offset+1), np.int32(count)))
        
        if self.bidirectional:
            if path_index == 0:
                self.ray_state.suppress_emission.fill(0)
        
            light_id0, light_area, light_point, light_normal, \
                light_center, min_light_sampling_distance = self.get_light_point()
            
            light_point = np.array(light_point).astype(np.float32)
            light_normal = np.array(light_normal).astype(np.float32)
            light_center = np.array(light_center).astype(np.float32)
            light_area = np.float32(light_area)
            min_light_sampling_distance = np.float32(min_light_sampling_distance)
                
            if is_last:
                light_id1 = np.int32(0)
            else:
                light_id1 = np.int32(light_id0+1)
                self.vec_param_buf[0, :3] = light_point

                acc.enqueue_copy(self.vec_broadcast, self.vec_param_buf)
                acc.call('init_shadow_mask', self.cur_n_pixels, (\
                    self.ray_state.pixel, self.ray_state.shadow_mask,
                    self.ray_state.diffusions_left))
                
                for tracer, count, offset in self.object_groups:
                    acc.call(tracer.shadow_kernel_name, (self.cur_n_pixels, count),
                        self.ray_state.shadow_kernel_params() + \
                        tuple(self.tracer_data_buffers),
                        value_args=tuple(self.tracer_const_data_buffers) + \
                            (self.vec_broadcast, light_id1, np.int32(offset+1), np.int32(count)))
    
        if self.scene.quasirandom and path_index == 1:
            rand_vec = self.qdirs[sample_index, :]
        else:
            rand_vec = utils.normalize(np.random.normal(0, 1, (3, )))
            
        rand_vec = np.array(rand_vec).astype(np.float32) 
        rand_01 = np.float32(np.random.rand())
        self.ray_state.prob[:self.cur_n_pixels].fill(rand_01)
        
        self.vec_param_buf[0, :3] = rand_vec
        self.vec_param_buf[1, :3] = np.random.normal(0, 1,( 3, ))
        # element 2 has color mask
        if self.bidirectional:
            self.vec_param_buf[3, :3] = light_point
            self.vec_param_buf[4, :3] = light_normal
            self.vec_param_buf[5, :3] = light_center
        acc.enqueue_copy(self.vec_broadcast, self.vec_param_buf)
        
        constant_params = self.shader.material_buffers + [self.vec_broadcast]
        if self.bidirectional:
            constant_params = [light_id1, light_area, min_light_sampling_distance] + constant_params
        
        pipeline = ['volumetric', 'emission']
        if not is_last: pipeline += ['reflection', 'refraction', 'diffuse']
        
        for shader_component in pipeline:
        
            acc.call('shader_'+shader_component, self.cur_n_pixels, \
                (self.img, ) + self.ray_state.shader_kernel_params(),
                value_args=tuple(constant_params))
        
        if not is_last:
            
            russian_roulette_prob = np.float32(np.random.rand())
            
            acc.call('culler', self.cur_n_pixels, \
                (self.ray_state.pixel, self.ray_state.raycolor),
                value_args=(russian_roulette_prob,),
                work_group_size=(self.warp_size,))
            
            self.cur_n_pixels = acc.find_non_negative(self.ray_state.pixel, \
                self.ray_state.new_pixel, self.cur_n_pixels)
            
            self.ray_state.pixel, self.ray_state.new_pixel = \
                [self.ray_state.new_pixel, self.ray_state.pixel]
            
            if self.cur_n_pixels == 0: return False
            print '[', self.cur_n_pixels, ']',
        
        return True
        
    def get_image_order(self):
        order = []
        
        width, height = self.img_shape
        
        block_w = 8
        block_h = 4
        
        if width % block_w == 0 and height % block_h == 0:
            for y_block in range(height / block_h):
                for x_block in range(width / block_w):
                    for by in range(block_h):
                        for bx in range(block_w):
                            order.append([bx+x_block*block_w, by+y_block*block_h])
        else:
            print "WARNING: image size should be (%d*x, %d*y)" % (block_w, block_h)
        
            for x in range(width):
                for y in range(height):
                    order.append([x,y])
            
        return np.array(order)
    
    @property
    def warp_size(self):
        return self.acc.warp_size
    
    @property
    def log_warp_size(self):
        return int(round(math.log(self.warp_size,2)))
예제 #6
0
from magnets import SectorBendingMagnet
from magnets import HorizontalKickerMagnet
from diagnostic import Transformator
from diagnostic import Screen
from diagnostic import Slit
import xml.etree.ElementTree as ET

ion = Ion(92, 146, 19, 1000)

print(ion)

ion = Ion(protons=6, neutrons=8, electrons=4, energy=1000)

print(ion)

acc = Accelerator()

width = 0.4
height = 0.2

t0 = Transformator("T0", width, height)
p1 = Pipe(width, height, 1.0)
s0 = Screen("Screen", width, height, 0.2, 0.2)
t1 = Transformator("T1", width, height)
q1 = QuadrupoleMagnet("UN4QD11", width, height, 1.0, 0.8)
q2 = QuadrupoleMagnet("UN4QD12", width, height, 1.0, -0.5)
sl1 = Slit("Slit1", width, height)
p2 = Pipe(width, height, 3.0)
sl2 = Slit("Slit2", width, height)
k1 = HorizontalKickerMagnet("kicker", width, height, 0.02)
p3 = Pipe(width, height, 3.0)