     ///   - functor: 1-place functor for element transformation
     ///   - forType: type of each element
     /// - Returns: kernel function
-    func kernel<T: KernelDataProtocol>(
-            _ source: BinaryOperationKernelSource, operation: BinaryOperation, forType: T.Type) -> Function {
+    func kernel<T: KernelDataProtocol>(_ source: BinaryOperationKernelSource,
+                                       operation: BinaryOperation,
+                                       forType: T.Type) -> Function {
         /// Get cached function
         let key = ModuleCacheKey(type: T.kernelDataType, source: source.rawValue, operation: operation)
         if let (_, function) = modules[key] {

        self.device = device
    }

    /// Get a compiled functorial kernel, a.k.a. kernel with a transformation functor
    /// such as `log` and `tanh`.
    ///
    /// - Parameters:
    ///   - source: kernel source to be compiled (if not cached) and loaded
    ///   - functor: 1-place functor for element transformation
    ///   - forType: type of each element
    /// - Returns: kernel function
    func kernel<T: KernelDataProtocol & FloatingPoint>(
            _ source: FunctorialKernelSource, transformation: UnaryOperation, forType: T.Type) -> Function {
        /// Get cached function
        let key = ModuleCacheKey(type: T.kernelDataType, source: source.rawValue, functor: transformation)
        if let (_, function) = modules[key] {
            return function
        }
        /// If not cached, compile using NVRTC
        log("Loading CUDA kernel \'\(source) \(transformation)\' for \(T.self)...\n")
        let ptx = try! Compiler.compile(
            source.rawValue,
            options: [
                .computeCapability(device.computeCapability),
                .useFastMath,
                .disableWarnings,
                .defineMacro("KERNEL", as: String(describing: source)),
                .defineMacro("TYPE", as: T.kernelDataType.rawValue),
                .defineMacro("FUNC", as: transformation.source(forType: T.self))
            ]
        )
        var function: Function!
        device.sync {
            let module = try! Module(ptx: ptx)
            function = module.function(named: String(describing: source))!
            modules[key] = (module, function)
        }
        return function
    }


        }
        /// If not cached, compile using NVRTC
        log("Loading CUDA kernel \'\(source) \(operation)\' for \(T.self)...\n")
        let (module, function) = makeKernel(source, extraOptions: [
            .defineMacro("KERNEL", as: String(describing: source)),
            .defineMacro("TYPE", as: T.kernelDataType.rawValue),
            .defineMacro("OP(_x_, _y_)", as: operation.source)
        ])
        modules[key] = (module, function)
        return function
    }

