예제 #1
0
파일: CLVar.py 프로젝트: hagisgit/SLIC
 def __init__(self, shape=(1,), addspc='global', cltype='float', name=None):
     self._ctrl = CLController()
     self._name = 'var' + str(id(self))
     if name:
         self._name = name
     self._addspc = addspc
     self._cltype = cltype
     self._buffer = None
     self._grp = None
     self._argkerns = []
     if len(shape) > 3:
         raise ValueError('max. no of dims = 3.')
     self._shape = shape
     if self._addspc == 'global':
         self._value = np.zeros((shape + (typeconv._vl_t[cltype],)), dtype=typeconv._t_cl_np[cltype])
     elif self._addspc == 'local':
         self._value = CLVar.Value_local(shape + (typeconv._vl_t[cltype],), typeconv._t_cl_np[cltype])
     elif self._addspc == 'scalar':
         if  (cltype[-1] not in '24816') and not(cltype == 'half'):
             self._shape = ()
             self._value = np.array(0, dtype=typeconv._t_cl_np[cltype])
         else:
             raise ValueError('No vector types or incomplete types allowed.')
     self._write_buffer()
     self._ctrl.register(self)
예제 #2
0
파일: CLVar.py 프로젝트: hagisgit/qcl
 def __init__(self, shape=(1,), addspc="global", cltype="float", name=None):
     self._initdone = False
     self._ctrl = CLController()
     self._name = "var" + str(self._ctrl._varcnt)
     if name:
         self._name = name
     self._addspc = addspc
     self._cltype = cltype
     self._buffer = None
     self._grp = None
     self._argkerns = []
     if len(shape) > 3:
         raise ValueError("max. no of dims = 3.")
     self._shape = shape
     if self._addspc == "global":
         self._value = np.zeros((shape + (CLVar._vl_t[cltype],)), dtype=CLVar._t_cl_np[cltype])
     elif self._addspc == "local":
         self._value = CLVar.Value_local(shape + (CLVar._vl_t[cltype],), CLVar._t_cl_np[cltype])
     elif self._addspc == "scalar":
         if (cltype[-1] not in "24816") and not (cltype == "half"):
             self._shape = ()
             self._value = np.array(0, dtype=CLVar._t_cl_np[cltype])
         else:
             raise ValueError("No vector types or incomplete types allowed.")
     self._write_buffer()
     self._init_genkerns()
     self._ctrl.register(self)
     self._initdone = True
예제 #3
0
파일: CLVar.py 프로젝트: hagisgit/SLIC
class CLVar(object):
    
    def var_like(var):
        return CLVar(shape=var.shape, addspc=var._addspc, cltype=var._cltype)
    
    class Value_local(object):
        def __init__(self, shape, dtype):
            self._shape = shape
            self.itemsize = np.dtype(dtype).itemsize
            self.dtype = np.dtype(dtype)
            s = 1
            for v in shape:
                s *= v
            self.size = s
        
        @property 
        def shape(self):
            return self._shape
            
        @shape.setter
        def shape(self, shape):
            s = 1
            for v in shape:
                s *= v
            self.size = s
            self._shape = shape
            
        def _reverse_shape(self):
            return self._shape[::-1]
    
    def __init__(self, shape=(1,), addspc='global', cltype='float', name=None):
        self._ctrl = CLController()
        self._name = 'var' + str(id(self))
        if name:
            self._name = name
        self._addspc = addspc
        self._cltype = cltype
        self._buffer = None
        self._grp = None
        self._argkerns = []
        if len(shape) > 3:
            raise ValueError('max. no of dims = 3.')
        self._shape = shape
        if self._addspc == 'global':
            self._value = np.zeros((shape + (typeconv._vl_t[cltype],)), dtype=typeconv._t_cl_np[cltype])
        elif self._addspc == 'local':
            self._value = CLVar.Value_local(shape + (typeconv._vl_t[cltype],), typeconv._t_cl_np[cltype])
        elif self._addspc == 'scalar':
            if  (cltype[-1] not in '24816') and not(cltype == 'half'):
                self._shape = ()
                self._value = np.array(0, dtype=typeconv._t_cl_np[cltype])
            else:
                raise ValueError('No vector types or incomplete types allowed.')
        self._write_buffer()
        self._ctrl.register(self)
    
    def __str__(self):
        if self._addspc == 'global' or self._addspc == 'scalar':
            return str(self.value)
        else:
            return 'local ' + str(self._cltype) + ' ' + str(self.shape) 
            
    def __len__(self):
        if (self._addspc == 'global') or (self._addspc == 'local'):
            return self.shape[0]
        else:
            raise NotImplementedError('Scalar variables have no length.')
    
    def info(self):
        return str(self._addspc) + ' ' + self._name + ':\n' + 'buffer=' + str(self._buffer) + '\ncltype=' + str(self._cltype) + '\nnp_type=' + str(self._value.dtype) + '\nshape=' + str(self._shape) + '\nnp_shape=' + str(self._value.shape)
    
    @property
    def value(self):
        self._read_buffer()
        if self._addspc == 'global':
            return self._value
        elif self._addspc == 'scalar':
            if (self._cltype == 'float') or (self._cltype == 'double') or (self._cltype == 'real'):
                return float(self._value)
            else:
                return int(self._value)
        else:
            return None
        
    @value.setter
    def value(self, val):
        self.set_value(val)
            
    def set_value(self, ipt, dontsync=False):
        if self._addspc == 'global':
            val = np.array(ipt, dtype=self._value.dtype)
            if (len(val.shape) > 1) and (len(val.shape) <= 4) and (val.shape[len(val.shape) - 1] == self._value.shape[len(self._value.shape) - 1]):
                self._value = val
                self._shape = val.shape[:-1]
            else:
                raise ValueError('Value must be of the same shape-type.')
            if not(dontsync) and self._grp:
                self._grp.sync(self)
        elif self._addspc == 'local':
            raise ValueError('Local variables cannot be set on host device.')
        elif self._addspc == 'scalar':
            try:
                float(ipt)
            except:
                raise ValueError('Invalid value. Input for scalar addspc must be a scalar number type.')
            val = np.array(ipt, dtype=self._value.dtype)
            self._value = val
        self._write_buffer()
        for kern in self._argkerns: # Do this last! Otherwise kernels will crash, because buffers are reset...
            kern._set_kernargs()
            
    @property
    def shape(self):
        return self._shape
        
    @shape.setter
    def shape(self, shp):
        if self._addspc == 'global':
            self._read_buffer()
            self._value.resize(shp + (self._value.shape[-1],))
            self.value = np.array(self._value)
        elif self._addspc == 'local':
            self._value.shape = shp + (self._value.shape[-1],)
            self._shape = shp
            
    def set_shape_wo_read(self, shp):
        if self._addspc == 'global':
            self._value.resize(shp + (self._value.shape[-1],))
            self.value = np.array(self._value)
        elif self._addspc == 'local':
            self._value.shape = shp + (self._value.shape[-1],)
            self._shape = shp
    
    def _reverse_shape(self):
        return self._shape[::-1]

    @property
    def name(self):
        return self._name
    
    #@timing
    def _read_buffer(self):
        if (self._addspc == 'global'):
            buf = cl.enqueue_map_buffer(self._ctrl.clqueue, self._buffer, cl.map_flags.READ, offset=0, shape=self._value.shape, dtype=self._value.dtype, order="C", strides=None, wait_for=None, is_blocking=True)[0]
            #cl.enqueue_read_buffer(self._ctrl.clqueue, self._buffer, self._value)            
            self._ctrl.clqueue.finish()
            self._value = np.array(buf)
            del buf

    #@timing
    def _write_buffer(self):
        if (self._addspc == 'global'):
            self._buffer = cl.Buffer(self._ctrl.clcontext, cl.mem_flags.READ_WRITE | cl.mem_flags.COPY_HOST_PTR, size=self._value.nbytes, hostbuf=self._value)
        elif (self._addspc == 'local'):
            self._buffer = None
        elif (self._addspc == 'scalar'):
            self._buffer = self._value
            
    def _register_grp(self, grp):
        self._grp = grp
        
    def _register_argkern(self, kern):
        if not kern in self._argkerns:
            self._argkerns.append(kern)
    
    def _unregister_argkern(self, kern):
        self._argkerns.remove(kern)
예제 #4
0
파일: CLVar.py 프로젝트: hagisgit/qcl
class CLVar(object):
    _t_np_cl = {}
    _t_np_cl[np.dtype("float16")] = "half"
    _t_np_cl[np.dtype("float32")] = "float"
    _t_np_cl[np.dtype("float64")] = "double"
    _t_np_cl[np.dtype("int8")] = "char"
    _t_np_cl[np.dtype("int16")] = "short"
    _t_np_cl[np.dtype("int32")] = "int"
    _t_np_cl[np.dtype("int64")] = "long"
    _t_np_cl[np.dtype("uint8")] = "uchar"
    _t_np_cl[np.dtype("uint16")] = "ushort"
    _t_np_cl[np.dtype("uint32")] = "uint"
    _t_np_cl[np.dtype("uint64")] = "ulong"
    _t_cl_np = {val: key for key, val in _t_np_cl.iteritems()}
    _t_cl_np.update({val + "2": key for key, val in _t_np_cl.iteritems()})
    _t_cl_np.update({val + "4": key for key, val in _t_np_cl.iteritems()})
    _t_cl_np.update({val + "8": key for key, val in _t_np_cl.iteritems()})
    _t_cl_np.update({val + "16": key for key, val in _t_np_cl.iteritems()})
    _t_cl_np["real"] = np.dtype("float64") if CLController().is_double_fp else np.dtype("float32")
    _t_cl_np["real2"] = np.dtype("float64") if CLController().is_double_fp else np.dtype("float32")
    _t_cl_np["real4"] = np.dtype("float64") if CLController().is_double_fp else np.dtype("float32")
    _t_cl_np["real8"] = np.dtype("float64") if CLController().is_double_fp else np.dtype("float32")
    _t_cl_np["real16"] = np.dtype("float64") if CLController().is_double_fp else np.dtype("float32")
    _vecls = [1, 2, 4, 8, 16]
    _vdict = {1: "", 2: "2", 4: "4", 8: "8", 16: "16"}
    _vl_t = {(v + _vdict[l]): l for l in _vecls for v in _t_cl_np.keys()}

    class Value_local(object):
        def __init__(self, shape, dtype):
            self.shape = shape
            self.itemsize = dtype.itemsize
            self.dtype = dtype
            s = 1
            for v in shape:
                s *= v
            self.size = s

    def __init__(self, shape=(1,), addspc="global", cltype="float", name=None):
        self._initdone = False
        self._ctrl = CLController()
        self._name = "var" + str(self._ctrl._varcnt)
        if name:
            self._name = name
        self._addspc = addspc
        self._cltype = cltype
        self._buffer = None
        self._grp = None
        self._argkerns = []
        if len(shape) > 3:
            raise ValueError("max. no of dims = 3.")
        self._shape = shape
        if self._addspc == "global":
            self._value = np.zeros((shape + (CLVar._vl_t[cltype],)), dtype=CLVar._t_cl_np[cltype])
        elif self._addspc == "local":
            self._value = CLVar.Value_local(shape + (CLVar._vl_t[cltype],), CLVar._t_cl_np[cltype])
        elif self._addspc == "scalar":
            if (cltype[-1] not in "24816") and not (cltype == "half"):
                self._shape = ()
                self._value = np.array(0, dtype=CLVar._t_cl_np[cltype])
            else:
                raise ValueError("No vector types or incomplete types allowed.")
        self._write_buffer()
        self._init_genkerns()
        self._ctrl.register(self)
        self._initdone = True

    def __str__(self):
        if self._addspc == "global" or self._addspc == "scalar":
            return str(self.value)
        else:
            return "local " + str(self._cltype) + " " + str(self.shape)

    def __len__(self):
        if (self._addspc == "global") or (self._addspc == "local"):
            return self.shape[0]
        else:
            raise NotImplementedError("Scalar variables have no length.")

    def info(self):
        return (
            str(self._addspc)
            + " "
            + self._name
            + ":\n"
            + str(self.value)
            + "\nbuffer="
            + str(self._buffer)
            + "\ncltype="
            + str(self._cltype)
            + "\nnp_type="
            + str(self._value.dtype)
            + "\nshape="
            + str(self._shape)
            + "\nnp_shape="
            + str(self._value.shape)
        )

    @property
    def value(self):
        self._read_buffer()
        return self._value

    @value.setter
    def value(self, val):
        self.set_value(val)

    def set_value(self, ipt, dontsync=False):
        if self._addspc == "global":
            val = np.array(ipt, dtype=self._value.dtype)
            if (
                (len(val.shape) > 1)
                and (len(val.shape) <= 4)
                and (val.shape[len(val.shape) - 1] == self._value.shape[len(self._value.shape) - 1])
            ):
                self._value = val
                self._shape = val.shape[:-1]
            else:
                raise ValueError("Value must be of the same shape.")
            if not (dontsync) and self._grp:
                self._grp.sync(self)
        elif self._addspc == "local":
            raise ValueError("Local variables cannot be set on host device.")
        elif self._addspc == "scalar":
            try:
                float(ipt)
            except:
                raise ValueError("Invalid value. Input for scalar addspc must be a scalar number type.")
            val = np.array(ipt, dtype=self._value.dtype)
            self._value = val
        for kern in self._argkerns:
            kern._set_kernargs()
        self._write_buffer()

    @property
    def shape(self):
        return self._shape

    @shape.setter
    def shape(self, shp):
        if self._addspc == "global":
            self._value.resize(shp + (self._value.shape[-1],))
            self.value = self._value
        elif self._addspc == "local":
            self._value.shape = shp + (self._value.shape[-1],)
            self._shape = shp

    @property
    def name(self):
        return self._name

    def _read_buffer(self):
        if self._addspc == "global":
            buf = cl.enqueue_map_buffer(
                self._ctrl.clqueue,
                self._buffer,
                cl.map_flags.READ,
                offset=0,
                shape=self._value.shape,
                dtype=self._value.dtype,
                order="C",
                strides=None,
                wait_for=None,
                is_blocking=True,
            )[0]
            self._ctrl.clqueue.finish()
            self._value = np.array(buf)
            del buf

    def _write_buffer(self):
        if self._addspc == "global":
            self._buffer = cl.Buffer(
                self._ctrl.clcontext,
                cl.mem_flags.READ_WRITE | cl.mem_flags.COPY_HOST_PTR,
                size=self._value.nbytes,
                hostbuf=self._value,
            )
        elif self._addspc == "local":
            self._buffer = None
        elif self._addspc == "scalar":
            self._buffer = self._value

    def _register_grp(self, grp):
        self._grp = grp

    def _register_argkern(self, kern):
        if not kern in self._argkerns:
            self._argkerns.append(kern)

    def _init_genkerns(self):
        if self._addspc == "local" or self._addspc == "scalar":
            return
        src = ""
        if self._ctrl.is_double_fp:
            src += tg.DECL_DOUBLE
        else:
            src += tg.DECL_FLOAT
        src += tg.tmplv_add
        src += tg.tmplv_sub
        src += tg.tmplv_mul
        src += tg.tmplv_div
        src += tg.tmplv_iadd
        src += tg.tmplv_isub
        src += tg.tmplv_imul
        src += tg.tmplv_idiv
        src += tg.tmpls_add
        src += tg.tmpls_sub
        src += tg.tmpls_mul
        src += tg.tmpls_div
        src += tg.tmpls_iadd
        src += tg.tmpls_isub
        src += tg.tmpls_imul
        src += tg.tmpls_idiv
        if (CLVar._vl_t[self._cltype] <= 4) and (
            ("float" in self._cltype) or ("double" in self._cltype) or ("real" in self._cltype)
        ):
            src += tg.tmplv_dot
            src += tg.tmpls_dot
        if (CLVar._vl_t[self._cltype] == 4) and (
            ("float" in self._cltype) or ("double" in self._cltype) or ("real" in self._cltype)
        ):
            src += tg.tmplv_cross
        type_wol = str(self._cltype).replace(str(CLVar._vl_t[self._cltype]), "")
        src = src.replace("$type_wol", type_wol)
        src = src.replace("$type", self._cltype)
        self._prg = cl.Program(CLController().clcontext, src).build()

    def __add__(self, other):
        if isinstance(other, CLVar):
            if self._addspc == "global":
                if not other._cltype == self._cltype:
                    raise ValueError("Values must be of same type.")
                if not (self.shape == other.shape):
                    raise ValueError("Values must be of same shape.")
                ret = CLVar(
                    addspc="global", cltype=self._cltype, shape=self.shape, name=(self.name + "_plus_" + other.name)
                )
                self._prg.__getattr__(self._cltype + "_addv")(
                    CLController().clqueue, self.shape, None, self._buffer, other._buffer, ret._buffer
                )
                self._ctrl.clqueue.finish()
                return ret
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                if other._addspc == "global":
                    raise ValueError("Cannot operate a vector on a scalar.")
                    return None
                if other._addspc == "scalar":
                    ret = CLVar(addspc="scalar", cltype=self._cltype, name=(self.name + "_plus_" + other.name))
                    ret.value = self._value + other.value
                    return ret
        if isinstance(other, int) or isinstance(other, float):
            if self._addspc == "global":
                type_wol = str(self._cltype).replace(str(CLVar._vl_t[self._cltype]), "")
                oth = CLVar(addspc="scalar", cltype=type_wol)
                oth.value = other
                ret = CLVar(
                    addspc="global", cltype=self._cltype, shape=self.shape, name=(self.name + "_plus_" + oth.name)
                )
                self._prg.__getattr__(self._cltype + "_adds")(
                    CLController().clqueue, self.shape, None, self._buffer, oth._buffer, ret._buffer
                )
                self._ctrl.clqueue.finish()
                return ret
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                ret = CLVar(addspc="scalar", cltype=self._cltype, name=(self.name + "_plus_" + "unnamed"))
                ret.value = self._value + other
                return ret

    def __sub__(self, other):
        if isinstance(other, CLVar):
            if self._addspc == "global":
                if not other._cltype == self._cltype:
                    raise ValueError("Values must be of same type.")
                if not (self.shape == other.shape):
                    raise ValueError("Values must be of same shape.")
                ret = CLVar(
                    addspc="global", cltype=self._cltype, shape=self.shape, name=(self.name + "_minus_" + other.name)
                )
                self._prg.__getattr__(self._cltype + "_subv")(
                    CLController().clqueue, self.shape, None, self._buffer, other._buffer, ret._buffer
                )
                self._ctrl.clqueue.finish()
                return ret
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                if other._addspc == "global":
                    raise ValueError("Cannot operate a vector on a scalar.")
                    return None
                if other._addspc == "scalar":
                    ret = CLVar(addspc="scalar", cltype=self._cltype, name=(self.name + "_minus_" + other.name))
                    ret.value = self._value - other.value
                    return ret
        if isinstance(other, int) or isinstance(other, float):
            if self._addspc == "global":
                type_wol = str(self._cltype).replace(str(CLVar._vl_t[self._cltype]), "")
                oth = CLVar(addspc="scalar", cltype=type_wol)
                oth.value = other
                ret = CLVar(
                    addspc="global", cltype=self._cltype, shape=self.shape, name=(self.name + "_minus_" + oth.name)
                )
                self._prg.__getattr__(self._cltype + "_subs")(
                    CLController().clqueue, self.shape, None, self._buffer, oth._buffer, ret._buffer
                )
                self._ctrl.clqueue.finish()
                return ret
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                ret = CLVar(addspc="scalar", cltype=self._cltype, name=(self.name + "_minus_" + "unnamed"))
                ret.value = self._value - other
                return ret

    def __mul__(self, other):
        if isinstance(other, CLVar):
            if self._addspc == "global":
                if not other._cltype == self._cltype:
                    raise ValueError("Values must be of same type.")
                if not (self.shape == other.shape):
                    raise ValueError("Values must be of same shape.")
                ret = CLVar(
                    addspc="global", cltype=self._cltype, shape=self.shape, name=(self.name + "_times_" + other.name)
                )
                self._prg.__getattr__(self._cltype + "_mulv")(
                    CLController().clqueue, self.shape, None, self._buffer, other._buffer, ret._buffer
                )
                self._ctrl.clqueue.finish()
                return ret
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                if other._addspc == "global":
                    raise ValueError("Cannot operate a vector on a scalar.")
                    return None
                if other._addspc == "scalar":
                    ret = CLVar(addspc="scalar", cltype=self._cltype, name=(self.name + "_times_" + other.name))
                    ret.value = self._value * other.value
                    return ret
        if isinstance(other, int) or isinstance(other, float):
            if self._addspc == "global":
                type_wol = str(self._cltype).replace(str(CLVar._vl_t[self._cltype]), "")
                oth = CLVar(addspc="scalar", cltype=type_wol)
                oth.value = other
                ret = CLVar(
                    addspc="global", cltype=self._cltype, shape=self.shape, name=(self.name + "_times_" + oth.name)
                )
                self._prg.__getattr__(self._cltype + "_muls")(
                    CLController().clqueue, self.shape, None, self._buffer, oth._buffer, ret._buffer
                )
                self._ctrl.clqueue.finish()
                return ret
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                ret = CLVar(addspc="scalar", cltype=self._cltype, name=(self.name + "_times_" + "unnamed"))
                ret.value = self._value * other
                return ret

    def __div__(self, other):
        if isinstance(other, CLVar):
            if self._addspc == "global":
                if not other._cltype == self._cltype:
                    raise ValueError("Values must be of same type.")
                if not (self.shape == other.shape):
                    raise ValueError("Values must be of same shape.")
                ret = CLVar(
                    addspc="global", cltype=self._cltype, shape=self.shape, name=(self.name + "_divby_" + other.name)
                )
                self._prg.__getattr__(self._cltype + "_divv")(
                    CLController().clqueue, self.shape, None, self._buffer, other._buffer, ret._buffer
                )
                self._ctrl.clqueue.finish()
                return ret
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                if other._addspc == "global":
                    raise ValueError("Cannot operate a vector on a scalar.")
                    return None
                if other._addspc == "scalar":
                    ret = CLVar(addspc="scalar", cltype=self._cltype, name=(self.name + "_divby_" + other.name))
                    ret.value = self._value / other.value
                    return ret
        if isinstance(other, int) or isinstance(other, float):
            if self._addspc == "global":
                type_wol = str(self._cltype).replace(str(CLVar._vl_t[self._cltype]), "")
                oth = CLVar(addspc="scalar", cltype=type_wol)
                oth.value = other
                ret = CLVar(
                    addspc="global", cltype=self._cltype, shape=self.shape, name=(self.name + "_divby_" + oth.name)
                )
                self._prg.__getattr__(self._cltype + "_divs")(
                    CLController().clqueue, self.shape, None, self._buffer, oth._buffer, ret._buffer
                )
                self._ctrl.clqueue.finish()
                return ret
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                ret = CLVar(addspc="scalar", cltype=self._cltype, name=(self.name + "_divby_" + "unnamed"))
                ret.value = self._value / other
                return ret

    def __iadd__(self, other):
        if isinstance(other, CLVar):
            if self._addspc == "global":
                if not other._cltype == self._cltype:
                    raise ValueError("Values must be of same type.")
                if not (self.shape == other.shape):
                    raise ValueError("Values must be of same shape.")
                self._prg.__getattr__(self._cltype + "_iaddv")(
                    CLController().clqueue, self.shape, None, self._buffer, other._buffer
                )
                self._ctrl.clqueue.finish()
                return self
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                if other._addspc == "global":
                    raise ValueError("Cannot operate a vector on a scalar.")
                    return None
                if other._addspc == "scalar":
                    self.value = self._value + other.value
                    return self
        if isinstance(other, int) or isinstance(other, float):
            if self._addspc == "global":
                type_wol = str(self._cltype).replace(str(CLVar._vl_t[self._cltype]), "")
                oth = CLVar(addspc="scalar", cltype=type_wol)
                oth.value = other
                self._prg.__getattr__(self._cltype + "_iadds")(
                    CLController().clqueue, self.shape, None, self._buffer, oth._buffer
                )
                self._ctrl.clqueue.finish()
                return self
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                self.value = self._value + other
                return self

    def __isub__(self, other):
        if isinstance(other, CLVar):
            if self._addspc == "global":
                if not other._cltype == self._cltype:
                    raise ValueError("Values must be of same type.")
                if not (self.shape == other.shape):
                    raise ValueError("Values must be of same shape.")
                self._prg.__getattr__(self._cltype + "_isubv")(
                    CLController().clqueue, self.shape, None, self._buffer, other._buffer
                )
                self._ctrl.clqueue.finish()
                return self
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                if other._addspc == "global":
                    raise ValueError("Cannot operate a vector on a scalar.")
                    return None
                if other._addspc == "scalar":
                    self.value = self._value - other.value
                    return self
        if isinstance(other, int) or isinstance(other, float):
            if self._addspc == "global":
                type_wol = str(self._cltype).replace(str(CLVar._vl_t[self._cltype]), "")
                oth = CLVar(addspc="scalar", cltype=type_wol)
                oth.value = other
                self._prg.__getattr__(self._cltype + "_isubs")(
                    CLController().clqueue, self.shape, None, self._buffer, oth._buffer
                )
                self._ctrl.clqueue.finish()
                return self
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                self.value = self._value - other
                return self

    def __imul__(self, other):
        if isinstance(other, CLVar):
            if self._addspc == "global":
                if not other._cltype == self._cltype:
                    raise ValueError("Values must be of same type.")
                if not (self.shape == other.shape):
                    raise ValueError("Values must be of same shape.")
                self._prg.__getattr__(self._cltype + "_imulv")(
                    CLController().clqueue, self.shape, None, self._buffer, other._buffer
                )
                self._ctrl.clqueue.finish()
                return self
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                if other._addspc == "global":
                    raise ValueError("Cannot operate a vector on a scalar.")
                    return None
                if other._addspc == "scalar":
                    self.value = self._value * other.value
                    return self
        if isinstance(other, int) or isinstance(other, float):
            if self._addspc == "global":
                type_wol = str(self._cltype).replace(str(CLVar._vl_t[self._cltype]), "")
                oth = CLVar(addspc="scalar", cltype=type_wol)
                oth.value = other
                self._prg.__getattr__(self._cltype + "_imuls")(
                    CLController().clqueue, self.shape, None, self._buffer, oth._buffer
                )
                self._ctrl.clqueue.finish()
                return self
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                self.value = self._value * other
                return self

    def __idiv__(self, other):
        if isinstance(other, CLVar):
            if self._addspc == "global":
                if not other._cltype == self._cltype:
                    raise ValueError("Values must be of same type.")
                if not (self.shape == other.shape):
                    raise ValueError("Values must be of same shape.")
                self._prg.__getattr__(self._cltype + "_idivv")(
                    CLController().clqueue, self.shape, None, self._buffer, other._buffer
                )
                self._ctrl.clqueue.finish()
                return self
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                if other._addspc == "global":
                    raise ValueError("Cannot operate a vector on a scalar.")
                    return None
                if other._addspc == "scalar":
                    self.value = self._value / other.value
                    return self
        if isinstance(other, int) or isinstance(other, float):
            if self._addspc == "global":
                type_wol = str(self._cltype).replace(str(CLVar._vl_t[self._cltype]), "")
                oth = CLVar(addspc="scalar", cltype=type_wol)
                oth.value = other
                self._prg.__getattr__(self._cltype + "_idivs")(
                    CLController().clqueue, self.shape, None, self._buffer, oth._buffer
                )
                self._ctrl.clqueue.finish()
                return self
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                self.value = self._value / other
                return self

    def dot(self, other, res=None):
        if CLVar._vl_t[self._cltype] > 4:
            raise ValueError("Dot product only defined for floating point vector types with length <= 4.")
        if isinstance(other, CLVar):
            if self._addspc == "global":
                if not other._cltype == self._cltype:
                    raise ValueError("Values must be of same type.")
                if not (self.shape == other.shape):
                    raise ValueError("Values must be of same shape.")
                type_wol = str(self._cltype).replace(str(CLVar._vl_t[self._cltype]), "")
                ret = res
                if res == None:
                    ret = CLVar(
                        addspc="global", cltype=type_wol, shape=self.shape, name=(self.name + "_dot_" + other.name)
                    )
                self._prg.__getattr__(self._cltype + "_dotv")(
                    CLController().clqueue, self.shape, None, self._buffer, other._buffer, ret._buffer
                )
                self._ctrl.clqueue.finish()
                return ret
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                if other._addspc == "global":
                    raise ValueError("Cannot operate a vector on a scalar.")
                    return None
                if other._addspc == "scalar":
                    ret = CLVar(addspc="scalar", cltype=self._cltype, name=(self.name + "_dot_" + other.name))
                    ret.value = self._value * other.value
                    return ret
        if isinstance(other, int) or isinstance(other, float):
            if self._addspc == "global":
                type_wol = str(self._cltype).replace(str(CLVar._vl_t[self._cltype]), "")
                oth = CLVar(addspc="scalar", cltype=type_wol)
                oth.value = other
                ret = res
                if res == None:
                    ret = CLVar(
                        addspc="global", cltype=type_wol, shape=self.shape, name=(self.name + "_dot_" + "unnamed")
                    )
                self._prg.__getattr__(self._cltype + "_dots")(
                    CLController().clqueue, self.shape, None, self._buffer, oth._buffer, ret._buffer
                )
                self._ctrl.clqueue.finish()
                return ret
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                ret = CLVar(addspc="scalar", cltype=self._cltype, name=(self.name + "_dot_" + "unnamed"))
                ret.value = self._value * other
                return ret

    def cross(self, other, res=None):
        if not (CLVar._vl_t[self._cltype] == 4):
            raise ValueError("Cross product only defined for floating point vector types with length = 4.")
        if isinstance(other, CLVar):
            if self._addspc == "global":
                if not other._cltype == self._cltype:
                    raise ValueError("Values must be of same type.")
                if not (self.shape == other.shape):
                    raise ValueError("Values must be of same shape.")
                ret = res
                if res == None:
                    ret = CLVar(
                        addspc="global",
                        cltype=self._cltype,
                        shape=self.shape,
                        name=(self.name + "_cross_" + other.name),
                    )
                self._prg.__getattr__(self._cltype + "_crossv")(
                    CLController().clqueue, self.shape, None, self._buffer, other._buffer, ret._buffer
                )
                self._ctrl.clqueue.finish()
                return ret
            if self._addspc == "local":
                return None
            if self._addspc == "scalar":
                raise ValueError("Cross product only defined for floating point vector types with length = 4.")
                return None
        if isinstance(other, int) or isinstance(other, float):
            raise ValueError("Cross product only defined for floating point vector types with length = 4.")
            return None