'Perform Compliation
The valid compiler options are
*   - -g (enable generation of debugging information)
*   - -opt=
*     - 0 (disable optimizations)
*     - 3 (default, enable optimizations)
*   - -arch=
*     - compute_20 (default)
*     - compute_30
*     - compute_35
*   - -ftz=
*     - 0 (default, preserve denormal values, when performing
*          single-precision floating-point operations)
*     - 1 (flush denormal values to zero, when performing
*          single-precision floating-point operations)
*   - -prec-sqrt=
*     - 0 (use a faster approximation for single-precision
*          floating-point square root)
*     - 1 (default, use IEEE round-to-nearest mode for
*          single-precision floating-point square root)
*   - -prec-div=
*     - 0 (use a faster approximation for single-precision
*          floating-point division and reciprocals)
*     - 1 (default, use IEEE round-to-nearest mode for
*          single-precision floating-point division and reciprocals)
*   - -fma=
*     - 0 (disable FMA contraction)
*     - 1 (default, enable FMA contraction)'

def compile(self, **options):

    opts = []
    if ('debug' in options):
        if options.pop('debug'):
            opts.append('-g')
    if options.get('opt'):
        opts.append(('-opt=%d' % options.pop('opt')))
    if options.get('arch'):
        opts.append(('-arch=%s' % options.pop('arch')))
    other_options = ('ftz', 'prec_sqrt', 'prec_div', 'fma')
    for k in other_options:
        if (k in options):
            v = int(bool(options.pop(k)))
            opts.append(('-%s=%d' % (k.replace('_', '-'), v)))
    if options:
        optstr = ',    '.join(map(repr, options.keys()))
        raise NvvmError('unsupported    option    {0}'.format(optstr))
    c_opts = (c_char_p * len(opts))(*[c_char_p(x.encode('utf8')) for x in opts])
    err = self.driver.nvvmCompileProgram(self._handle, len(opts), c_opts)
    self._try_error(err, 'Failed    to    compile\n')
    reslen = c_size_t()
    err = self.driver.nvvmGetCompiledResultSize(self._handle, byref(reslen))
    self._try_error(err, 'Failed    to    get    size    of    compiled    result.')
    ptxbuf = (c_char * reslen.value)()
    err = self.driver.nvvmGetCompiledResult(self._handle, ptxbuf)
    self._try_error(err, 'Failed    to    get    compiled    result.')
    self.log = self.get_log()
    return ptxbuf[:]
