 
 import CCUDARuntime
 import struct CUDADriver.Function
-import class CUDADriver.Stream
-import enum CUDADriver.SharedMemoryBankSize
-import struct CUDADriver.GridSize
-import struct CUDADriver.BlockSize
-import enum CUDADriver.CachePreference
-import struct CUDADriver.KernelArgument
-
+@_exported import enum CUDADriver.SharedMemoryBankSize
+@_exported import struct CUDADriver.GridSize
+@_exported import struct CUDADriver.BlockSize
+@_exported import enum CUDADriver.CachePreference
+@_exported import struct CUDADriver.KernelArgument
 
 public struct Function {
 
-    fileprivate let address: UnsafeRawPointer
+    let address: UnsafeRawPointer
 
     fileprivate let attributes: cudaFuncAttributes
 
+    public init(_ driverFunction: CUDADriver.Function) {
+        address = UnsafeRawPointer(driverFunction.withUnsafeHandle{$0})
+        var attr = cudaFuncAttributes()
+        !!cudaFuncGetAttributes(&attr, address)
+        attributes = attr
+    }
+
     public var cachePreference: CachePreference = .none {
         didSet {
-            cudaFuncSetCacheConfig(address, cudaFuncCache(cachePreference.rawValue))
+            !!cudaFuncSetCacheConfig(address, cudaFuncCache(cachePreference.rawValue))
         }
     }
 
     public var sharedMemoryBankSize: SharedMemoryBankSize = .default {
         didSet {
-            cudaFuncSetSharedMemConfig(address, cudaSharedMemConfig(sharedMemoryBankSize.rawValue))
+            !!cudaFuncSetSharedMemConfig(address, cudaSharedMemConfig(sharedMemoryBankSize.rawValue))
         }
     }
 

    }

}

                             blockSize.memory, stream?.handle)
        )
    }

    public func launch(with arguments: [KernelArgument],
                       blockCount: Int, threadCount: Int,
                       memory: Int, stream: Stream?) throws {
