cuda 0.12.8.0 → 0.13.0.0
raw patch · 27 files changed
+371/−2020 lines, 27 filessetup-changedPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Foreign.CUDA.Analysis.Device: instance Text.Show.Describe.Describe Foreign.CUDA.Analysis.Device.ComputeMode
- Foreign.CUDA.Driver: OnlyPartialNativeAtomicSupported :: PeerAttribute
- Foreign.CUDA.Driver.Context.Peer: OnlyPartialNativeAtomicSupported :: PeerAttribute
- Foreign.CUDA.Driver.Error: instance Text.Show.Describe.Describe Foreign.CUDA.Driver.Error.Status
- Foreign.CUDA.Runtime.Device: BlockingSync :: DeviceFlag
- Foreign.CUDA.Runtime.Device: Compute :: !Int -> !Int -> Compute
- Foreign.CUDA.Runtime.Device: Default :: ComputeMode
- Foreign.CUDA.Runtime.Device: DeviceProperties :: !String -> !Compute -> !Int64 -> !Int64 -> !Int64 -> !Int -> !Int -> !Int -> !Int -> !(Int, Int, Int) -> !(Int, Int, Int) -> !Int -> !(Int, Int) -> !(Int, Int, Int) -> !Int -> !Int -> !Int64 -> !Int -> !Int -> !Int64 -> !ComputeMode -> !Bool -> !Bool -> !Bool -> !Int -> !Int -> !PCI -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Int -> !Bool -> !Int -> !Bool -> !Bool -> DeviceProperties
- Foreign.CUDA.Runtime.Device: Devruntimependinglaunchcount :: Limit
- Foreign.CUDA.Runtime.Device: Devruntimesyncdepth :: Limit
- Foreign.CUDA.Runtime.Device: ExclusiveProcess :: ComputeMode
- Foreign.CUDA.Runtime.Device: LMemResizeToMax :: DeviceFlag
- Foreign.CUDA.Runtime.Device: Mallocheapsize :: Limit
- Foreign.CUDA.Runtime.Device: MapHost :: DeviceFlag
- Foreign.CUDA.Runtime.Device: Maxl2fetchgranularity :: Limit
- Foreign.CUDA.Runtime.Device: Persistingl2cachesize :: Limit
- Foreign.CUDA.Runtime.Device: Printffifosize :: Limit
- Foreign.CUDA.Runtime.Device: Prohibited :: ComputeMode
- Foreign.CUDA.Runtime.Device: ScheduleAuto :: DeviceFlag
- Foreign.CUDA.Runtime.Device: ScheduleSpin :: DeviceFlag
- Foreign.CUDA.Runtime.Device: ScheduleYield :: DeviceFlag
- Foreign.CUDA.Runtime.Device: Stacksize :: Limit
- Foreign.CUDA.Runtime.Device: [asyncEngineCount] :: DeviceProperties -> !Int
- Foreign.CUDA.Runtime.Device: [cacheMemL2] :: DeviceProperties -> !Int
- Foreign.CUDA.Runtime.Device: [canMapHostMemory] :: DeviceProperties -> !Bool
- Foreign.CUDA.Runtime.Device: [clockRate] :: DeviceProperties -> !Int
- Foreign.CUDA.Runtime.Device: [computeCapability] :: DeviceProperties -> !Compute
- Foreign.CUDA.Runtime.Device: [computeMode] :: DeviceProperties -> !ComputeMode
- Foreign.CUDA.Runtime.Device: [concurrentKernels] :: DeviceProperties -> !Bool
- Foreign.CUDA.Runtime.Device: [cooperativeLaunchMultiDevice] :: DeviceProperties -> !Bool
- Foreign.CUDA.Runtime.Device: [cooperativeLaunch] :: DeviceProperties -> !Bool
- Foreign.CUDA.Runtime.Device: [deviceName] :: DeviceProperties -> !String
- Foreign.CUDA.Runtime.Device: [deviceOverlap] :: DeviceProperties -> !Bool
- Foreign.CUDA.Runtime.Device: [eccEnabled] :: DeviceProperties -> !Bool
- Foreign.CUDA.Runtime.Device: [globalL1Cache] :: DeviceProperties -> !Bool
- Foreign.CUDA.Runtime.Device: [integrated] :: DeviceProperties -> !Bool
- Foreign.CUDA.Runtime.Device: [kernelExecTimeoutEnabled] :: DeviceProperties -> !Bool
- Foreign.CUDA.Runtime.Device: [localL1Cache] :: DeviceProperties -> !Bool
- Foreign.CUDA.Runtime.Device: [managedMemory] :: DeviceProperties -> !Bool
- Foreign.CUDA.Runtime.Device: [maxBlockSize] :: DeviceProperties -> !(Int, Int, Int)
- Foreign.CUDA.Runtime.Device: [maxGridSize] :: DeviceProperties -> !(Int, Int, Int)
- Foreign.CUDA.Runtime.Device: [maxTextureDim1D] :: DeviceProperties -> !Int
- Foreign.CUDA.Runtime.Device: [maxTextureDim2D] :: DeviceProperties -> !(Int, Int)
- Foreign.CUDA.Runtime.Device: [maxTextureDim3D] :: DeviceProperties -> !(Int, Int, Int)
- Foreign.CUDA.Runtime.Device: [maxThreadsPerBlock] :: DeviceProperties -> !Int
- Foreign.CUDA.Runtime.Device: [maxThreadsPerMultiProcessor] :: DeviceProperties -> !Int
- Foreign.CUDA.Runtime.Device: [memBusWidth] :: DeviceProperties -> !Int
- Foreign.CUDA.Runtime.Device: [memClockRate] :: DeviceProperties -> !Int
- Foreign.CUDA.Runtime.Device: [memPitch] :: DeviceProperties -> !Int64
- Foreign.CUDA.Runtime.Device: [multiGPUBoardGroupID] :: DeviceProperties -> !Int
- Foreign.CUDA.Runtime.Device: [multiGPUBoard] :: DeviceProperties -> !Bool
- Foreign.CUDA.Runtime.Device: [multiProcessorCount] :: DeviceProperties -> !Int
- Foreign.CUDA.Runtime.Device: [pciInfo] :: DeviceProperties -> !PCI
- Foreign.CUDA.Runtime.Device: [preemption] :: DeviceProperties -> !Bool
- Foreign.CUDA.Runtime.Device: [regsPerBlock] :: DeviceProperties -> !Int
- Foreign.CUDA.Runtime.Device: [sharedMemPerBlock] :: DeviceProperties -> !Int64
- Foreign.CUDA.Runtime.Device: [singleToDoublePerfRatio] :: DeviceProperties -> !Int
- Foreign.CUDA.Runtime.Device: [streamPriorities] :: DeviceProperties -> !Bool
- Foreign.CUDA.Runtime.Device: [tccDriverEnabled] :: DeviceProperties -> !Bool
- Foreign.CUDA.Runtime.Device: [textureAlignment] :: DeviceProperties -> !Int64
- Foreign.CUDA.Runtime.Device: [totalConstMem] :: DeviceProperties -> !Int64
- Foreign.CUDA.Runtime.Device: [totalGlobalMem] :: DeviceProperties -> !Int64
- Foreign.CUDA.Runtime.Device: [unifiedAddressing] :: DeviceProperties -> !Bool
- Foreign.CUDA.Runtime.Device: [warpSize] :: DeviceProperties -> !Int
- Foreign.CUDA.Runtime.Device: accessible :: Device -> Device -> IO Bool
- Foreign.CUDA.Runtime.Device: add :: Device -> [PeerFlag] -> IO ()
- Foreign.CUDA.Runtime.Device: choose :: DeviceProperties -> IO Device
- Foreign.CUDA.Runtime.Device: count :: IO Int
- Foreign.CUDA.Runtime.Device: data Compute
- Foreign.CUDA.Runtime.Device: data ComputeMode
- Foreign.CUDA.Runtime.Device: data DeviceFlag
- Foreign.CUDA.Runtime.Device: data DeviceProperties
- Foreign.CUDA.Runtime.Device: data Limit
- Foreign.CUDA.Runtime.Device: data PeerFlag
- Foreign.CUDA.Runtime.Device: get :: IO Device
- Foreign.CUDA.Runtime.Device: getLimit :: Limit -> IO Int
- Foreign.CUDA.Runtime.Device: instance Foreign.Storable.Storable Foreign.CUDA.Analysis.Device.DeviceProperties
- Foreign.CUDA.Runtime.Device: instance GHC.Classes.Eq Foreign.CUDA.Runtime.Device.DeviceFlag
- Foreign.CUDA.Runtime.Device: instance GHC.Classes.Eq Foreign.CUDA.Runtime.Device.Limit
- Foreign.CUDA.Runtime.Device: instance GHC.Enum.Bounded Foreign.CUDA.Runtime.Device.DeviceFlag
- Foreign.CUDA.Runtime.Device: instance GHC.Enum.Enum Foreign.CUDA.Runtime.Device.DeviceFlag
- Foreign.CUDA.Runtime.Device: instance GHC.Enum.Enum Foreign.CUDA.Runtime.Device.Limit
- Foreign.CUDA.Runtime.Device: instance GHC.Enum.Enum Foreign.CUDA.Runtime.Device.PeerFlag
- Foreign.CUDA.Runtime.Device: instance GHC.Show.Show Foreign.CUDA.Runtime.Device.DeviceFlag
- Foreign.CUDA.Runtime.Device: instance GHC.Show.Show Foreign.CUDA.Runtime.Device.Limit
- Foreign.CUDA.Runtime.Device: props :: Device -> IO DeviceProperties
- Foreign.CUDA.Runtime.Device: remove :: Device -> IO ()
- Foreign.CUDA.Runtime.Device: reset :: IO ()
- Foreign.CUDA.Runtime.Device: set :: Device -> IO ()
- Foreign.CUDA.Runtime.Device: setFlags :: [DeviceFlag] -> IO ()
- Foreign.CUDA.Runtime.Device: setLimit :: Limit -> Int -> IO ()
- Foreign.CUDA.Runtime.Device: setOrder :: [Device] -> IO ()
- Foreign.CUDA.Runtime.Device: sync :: IO ()
- Foreign.CUDA.Runtime.Device: type Device = Int
- Foreign.CUDA.Runtime.Error: AddressOfConstant :: Status
- Foreign.CUDA.Runtime.Error: AlreadyAcquired :: Status
- Foreign.CUDA.Runtime.Error: AlreadyMapped :: Status
- Foreign.CUDA.Runtime.Error: ApiFailureBase :: Status
- Foreign.CUDA.Runtime.Error: ArrayIsMapped :: Status
- Foreign.CUDA.Runtime.Error: Assert :: Status
- Foreign.CUDA.Runtime.Error: CallRequiresNewerDriver :: Status
- Foreign.CUDA.Runtime.Error: CapturedEvent :: Status
- Foreign.CUDA.Runtime.Error: CdpNotSupported :: Status
- Foreign.CUDA.Runtime.Error: CdpVersionMismatch :: Status
- Foreign.CUDA.Runtime.Error: CompatNotSupportedOnDevice :: Status
- Foreign.CUDA.Runtime.Error: Contained :: Status
- Foreign.CUDA.Runtime.Error: ContextIsDestroyed :: Status
- Foreign.CUDA.Runtime.Error: CooperativeLaunchTooLarge :: Status
- Foreign.CUDA.Runtime.Error: CudartUnloading :: Status
- Foreign.CUDA.Runtime.Error: DeviceAlreadyInUse :: Status
- Foreign.CUDA.Runtime.Error: DeviceNotLicensed :: Status
- Foreign.CUDA.Runtime.Error: DeviceUninitialized :: Status
- Foreign.CUDA.Runtime.Error: DevicesUnavailable :: Status
- Foreign.CUDA.Runtime.Error: DuplicateSurfaceName :: Status
- Foreign.CUDA.Runtime.Error: DuplicateTextureName :: Status
- Foreign.CUDA.Runtime.Error: DuplicateVariableName :: Status
- Foreign.CUDA.Runtime.Error: ECCUncorrectable :: Status
- Foreign.CUDA.Runtime.Error: ExitCode :: Status -> CUDAException
- Foreign.CUDA.Runtime.Error: ExternalDevice :: Status
- Foreign.CUDA.Runtime.Error: FileNotFound :: Status
- Foreign.CUDA.Runtime.Error: FunctionNotLoaded :: Status
- Foreign.CUDA.Runtime.Error: GraphExecUpdateFailure :: Status
- Foreign.CUDA.Runtime.Error: HardwareStackError :: Status
- Foreign.CUDA.Runtime.Error: HostMemoryAlreadyRegistered :: Status
- Foreign.CUDA.Runtime.Error: HostMemoryNotRegistered :: Status
- Foreign.CUDA.Runtime.Error: IllegalAddress :: Status
- Foreign.CUDA.Runtime.Error: IllegalInstruction :: Status
- Foreign.CUDA.Runtime.Error: IllegalState :: Status
- Foreign.CUDA.Runtime.Error: IncompatibleDriverContext :: Status
- Foreign.CUDA.Runtime.Error: InitializationError :: Status
- Foreign.CUDA.Runtime.Error: InsufficientDriver :: Status
- Foreign.CUDA.Runtime.Error: InvalidAddressSpace :: Status
- Foreign.CUDA.Runtime.Error: InvalidChannelDescriptor :: Status
- Foreign.CUDA.Runtime.Error: InvalidClusterSize :: Status
- Foreign.CUDA.Runtime.Error: InvalidConfiguration :: Status
- Foreign.CUDA.Runtime.Error: InvalidDevice :: Status
- Foreign.CUDA.Runtime.Error: InvalidDeviceFunction :: Status
- Foreign.CUDA.Runtime.Error: InvalidDevicePointer :: Status
- Foreign.CUDA.Runtime.Error: InvalidFilterSetting :: Status
- Foreign.CUDA.Runtime.Error: InvalidGraphicsContext :: Status
- Foreign.CUDA.Runtime.Error: InvalidHostPointer :: Status
- Foreign.CUDA.Runtime.Error: InvalidKernelImage :: Status
- Foreign.CUDA.Runtime.Error: InvalidMemcpyDirection :: Status
- Foreign.CUDA.Runtime.Error: InvalidNormSetting :: Status
- Foreign.CUDA.Runtime.Error: InvalidPc :: Status
- Foreign.CUDA.Runtime.Error: InvalidPitchValue :: Status
- Foreign.CUDA.Runtime.Error: InvalidPtx :: Status
- Foreign.CUDA.Runtime.Error: InvalidResourceConfiguration :: Status
- Foreign.CUDA.Runtime.Error: InvalidResourceHandle :: Status
- Foreign.CUDA.Runtime.Error: InvalidResourceType :: Status
- Foreign.CUDA.Runtime.Error: InvalidSource :: Status
- Foreign.CUDA.Runtime.Error: InvalidSurface :: Status
- Foreign.CUDA.Runtime.Error: InvalidSymbol :: Status
- Foreign.CUDA.Runtime.Error: InvalidTexture :: Status
- Foreign.CUDA.Runtime.Error: InvalidTextureBinding :: Status
- Foreign.CUDA.Runtime.Error: InvalidValue :: Status
- Foreign.CUDA.Runtime.Error: JitCompilationDisabled :: Status
- Foreign.CUDA.Runtime.Error: JitCompilerNotFound :: Status
- Foreign.CUDA.Runtime.Error: LaunchFailure :: Status
- Foreign.CUDA.Runtime.Error: LaunchFileScopedSurf :: Status
- Foreign.CUDA.Runtime.Error: LaunchFileScopedTex :: Status
- Foreign.CUDA.Runtime.Error: LaunchIncompatibleTexturing :: Status
- Foreign.CUDA.Runtime.Error: LaunchMaxDepthExceeded :: Status
- Foreign.CUDA.Runtime.Error: LaunchOutOfResources :: Status
- Foreign.CUDA.Runtime.Error: LaunchPendingCountExceeded :: Status
- Foreign.CUDA.Runtime.Error: LaunchTimeout :: Status
- Foreign.CUDA.Runtime.Error: LossyQuery :: Status
- Foreign.CUDA.Runtime.Error: MapBufferObjectFailed :: Status
- Foreign.CUDA.Runtime.Error: MemoryAllocation :: Status
- Foreign.CUDA.Runtime.Error: MemoryValueTooLarge :: Status
- Foreign.CUDA.Runtime.Error: MisalignedAddress :: Status
- Foreign.CUDA.Runtime.Error: MissingConfiguration :: Status
- Foreign.CUDA.Runtime.Error: MixedDeviceExecution :: Status
- Foreign.CUDA.Runtime.Error: MpsClientTerminated :: Status
- Foreign.CUDA.Runtime.Error: MpsConnectionFailed :: Status
- Foreign.CUDA.Runtime.Error: MpsMaxClientsReached :: Status
- Foreign.CUDA.Runtime.Error: MpsMaxConnectionsReached :: Status
- Foreign.CUDA.Runtime.Error: MpsRpcFailure :: Status
- Foreign.CUDA.Runtime.Error: MpsServerNotReady :: Status
- Foreign.CUDA.Runtime.Error: NoDevice :: Status
- Foreign.CUDA.Runtime.Error: NoKernelImageForDevice :: Status
- Foreign.CUDA.Runtime.Error: NotMapped :: Status
- Foreign.CUDA.Runtime.Error: NotMappedAsArray :: Status
- Foreign.CUDA.Runtime.Error: NotMappedAsPointer :: Status
- Foreign.CUDA.Runtime.Error: NotPermitted :: Status
- Foreign.CUDA.Runtime.Error: NotReady :: Status
- Foreign.CUDA.Runtime.Error: NotSupported :: Status
- Foreign.CUDA.Runtime.Error: NotYetImplemented :: Status
- Foreign.CUDA.Runtime.Error: NvlinkUncorrectable :: Status
- Foreign.CUDA.Runtime.Error: OperatingSystem :: Status
- Foreign.CUDA.Runtime.Error: PeerAccessAlreadyEnabled :: Status
- Foreign.CUDA.Runtime.Error: PeerAccessNotEnabled :: Status
- Foreign.CUDA.Runtime.Error: PeerAccessUnsupported :: Status
- Foreign.CUDA.Runtime.Error: PriorLaunchFailure :: Status
- Foreign.CUDA.Runtime.Error: ProfilerAlreadyStarted :: Status
- Foreign.CUDA.Runtime.Error: ProfilerAlreadyStopped :: Status
- Foreign.CUDA.Runtime.Error: ProfilerDisabled :: Status
- Foreign.CUDA.Runtime.Error: ProfilerNotInitialized :: Status
- Foreign.CUDA.Runtime.Error: SetOnActiveProcess :: Status
- Foreign.CUDA.Runtime.Error: SharedObjectInitFailed :: Status
- Foreign.CUDA.Runtime.Error: SharedObjectSymbolNotFound :: Status
- Foreign.CUDA.Runtime.Error: SoftwareValidityNotEstablished :: Status
- Foreign.CUDA.Runtime.Error: StartupFailure :: Status
- Foreign.CUDA.Runtime.Error: StreamCaptureImplicit :: Status
- Foreign.CUDA.Runtime.Error: StreamCaptureInvalidated :: Status
- Foreign.CUDA.Runtime.Error: StreamCaptureIsolation :: Status
- Foreign.CUDA.Runtime.Error: StreamCaptureMerge :: Status
- Foreign.CUDA.Runtime.Error: StreamCaptureUnjoined :: Status
- Foreign.CUDA.Runtime.Error: StreamCaptureUnmatched :: Status
- Foreign.CUDA.Runtime.Error: StreamCaptureUnsupported :: Status
- Foreign.CUDA.Runtime.Error: StreamCaptureWrongThread :: Status
- Foreign.CUDA.Runtime.Error: StubLibrary :: Status
- Foreign.CUDA.Runtime.Error: Success :: Status
- Foreign.CUDA.Runtime.Error: SymbolNotFound :: Status
- Foreign.CUDA.Runtime.Error: SyncDepthExceeded :: Status
- Foreign.CUDA.Runtime.Error: SynchronizationError :: Status
- Foreign.CUDA.Runtime.Error: SystemDriverMismatch :: Status
- Foreign.CUDA.Runtime.Error: SystemNotReady :: Status
- Foreign.CUDA.Runtime.Error: TensorMemoryLeak :: Status
- Foreign.CUDA.Runtime.Error: TextureFetchFailed :: Status
- Foreign.CUDA.Runtime.Error: TextureNotBound :: Status
- Foreign.CUDA.Runtime.Error: Timeout :: Status
- Foreign.CUDA.Runtime.Error: TooManyPeers :: Status
- Foreign.CUDA.Runtime.Error: Unknown :: Status
- Foreign.CUDA.Runtime.Error: UnmapBufferObjectFailed :: Status
- Foreign.CUDA.Runtime.Error: UnsupportedDevSideSync :: Status
- Foreign.CUDA.Runtime.Error: UnsupportedExecAffinity :: Status
- Foreign.CUDA.Runtime.Error: UnsupportedLimit :: Status
- Foreign.CUDA.Runtime.Error: UnsupportedPtxVersion :: Status
- Foreign.CUDA.Runtime.Error: UserError :: String -> CUDAException
- Foreign.CUDA.Runtime.Error: checkStatus :: CInt -> IO ()
- Foreign.CUDA.Runtime.Error: cudaError :: String -> IO a
- Foreign.CUDA.Runtime.Error: data CUDAException
- Foreign.CUDA.Runtime.Error: data Status
- Foreign.CUDA.Runtime.Error: describe :: Describe a => a -> String
- Foreign.CUDA.Runtime.Error: instance GHC.Classes.Eq Foreign.CUDA.Runtime.Error.Status
- Foreign.CUDA.Runtime.Error: instance GHC.Enum.Enum Foreign.CUDA.Runtime.Error.Status
- Foreign.CUDA.Runtime.Error: instance GHC.Exception.Type.Exception Foreign.CUDA.Runtime.Error.CUDAException
- Foreign.CUDA.Runtime.Error: instance GHC.Show.Show Foreign.CUDA.Runtime.Error.CUDAException
- Foreign.CUDA.Runtime.Error: instance GHC.Show.Show Foreign.CUDA.Runtime.Error.Status
- Foreign.CUDA.Runtime.Error: instance Text.Show.Describe.Describe Foreign.CUDA.Runtime.Error.Status
- Foreign.CUDA.Runtime.Error: nothingIfOk :: Status -> IO ()
- Foreign.CUDA.Runtime.Error: requireSDK :: Name -> Double -> IO a
- Foreign.CUDA.Runtime.Error: resultIfOk :: (Status, a) -> IO a
- Foreign.CUDA.Runtime.Event: BlockingSync :: EventFlag
- Foreign.CUDA.Runtime.Event: Default :: EventFlag
- Foreign.CUDA.Runtime.Event: DisableTiming :: EventFlag
- Foreign.CUDA.Runtime.Event: Interprocess :: EventFlag
- Foreign.CUDA.Runtime.Event: block :: Event -> IO ()
- Foreign.CUDA.Runtime.Event: create :: [EventFlag] -> IO Event
- Foreign.CUDA.Runtime.Event: data Event
- Foreign.CUDA.Runtime.Event: data EventFlag
- Foreign.CUDA.Runtime.Event: data WaitFlag
- Foreign.CUDA.Runtime.Event: destroy :: Event -> IO ()
- Foreign.CUDA.Runtime.Event: elapsedTime :: Event -> Event -> IO Float
- Foreign.CUDA.Runtime.Event: query :: Event -> IO Bool
- Foreign.CUDA.Runtime.Event: record :: Event -> Maybe Stream -> IO ()
- Foreign.CUDA.Runtime.Event: wait :: Event -> Maybe Stream -> [WaitFlag] -> IO ()
- Foreign.CUDA.Runtime.Exec: Equal :: CacheConfig
- Foreign.CUDA.Runtime.Exec: FunAttributes :: !Int64 -> !Int64 -> !Int64 -> !Int -> !Int -> FunAttributes
- Foreign.CUDA.Runtime.Exec: L1 :: CacheConfig
- Foreign.CUDA.Runtime.Exec: None :: CacheConfig
- Foreign.CUDA.Runtime.Exec: Shared :: CacheConfig
- Foreign.CUDA.Runtime.Exec: [DArg] :: !Double -> FunParam
- Foreign.CUDA.Runtime.Exec: [FArg] :: !Float -> FunParam
- Foreign.CUDA.Runtime.Exec: [IArg] :: !Int -> FunParam
- Foreign.CUDA.Runtime.Exec: [VArg] :: Storable a => !a -> FunParam
- Foreign.CUDA.Runtime.Exec: [constSizeBytes] :: FunAttributes -> !Int64
- Foreign.CUDA.Runtime.Exec: [localSizeBytes] :: FunAttributes -> !Int64
- Foreign.CUDA.Runtime.Exec: [maxKernelThreadsPerBlock] :: FunAttributes -> !Int
- Foreign.CUDA.Runtime.Exec: [numRegs] :: FunAttributes -> !Int
- Foreign.CUDA.Runtime.Exec: [sharedSizeBytes] :: FunAttributes -> !Int64
- Foreign.CUDA.Runtime.Exec: attributes :: Fun -> IO FunAttributes
- Foreign.CUDA.Runtime.Exec: data CacheConfig
- Foreign.CUDA.Runtime.Exec: data FunAttributes
- Foreign.CUDA.Runtime.Exec: data FunParam
- Foreign.CUDA.Runtime.Exec: instance Foreign.Storable.Storable Foreign.CUDA.Runtime.Exec.FunAttributes
- Foreign.CUDA.Runtime.Exec: instance GHC.Classes.Eq Foreign.CUDA.Runtime.Exec.CacheConfig
- Foreign.CUDA.Runtime.Exec: instance GHC.Enum.Enum Foreign.CUDA.Runtime.Exec.CacheConfig
- Foreign.CUDA.Runtime.Exec: instance GHC.Show.Show Foreign.CUDA.Runtime.Exec.CacheConfig
- Foreign.CUDA.Runtime.Exec: instance GHC.Show.Show Foreign.CUDA.Runtime.Exec.FunAttributes
- Foreign.CUDA.Runtime.Exec: launchKernel :: Fun -> (Int, Int) -> (Int, Int, Int) -> Int64 -> Maybe Stream -> [FunParam] -> IO ()
- Foreign.CUDA.Runtime.Exec: setCacheConfig :: Fun -> CacheConfig -> IO ()
- Foreign.CUDA.Runtime.Exec: type Fun = FunPtr ()
- Foreign.CUDA.Runtime.Marshal: DeviceMapped :: AllocFlag
- Foreign.CUDA.Runtime.Marshal: Global :: AttachFlag
- Foreign.CUDA.Runtime.Marshal: Host :: AttachFlag
- Foreign.CUDA.Runtime.Marshal: Portable :: AllocFlag
- Foreign.CUDA.Runtime.Marshal: Single :: AttachFlag
- Foreign.CUDA.Runtime.Marshal: WriteCombined :: AllocFlag
- Foreign.CUDA.Runtime.Marshal: allocaArray :: Storable a => Int -> (DevicePtr a -> IO b) -> IO b
- Foreign.CUDA.Runtime.Marshal: copyArray :: Storable a => Int -> DevicePtr a -> DevicePtr a -> IO ()
- Foreign.CUDA.Runtime.Marshal: copyArray2D :: Storable a => Int -> Int -> DevicePtr a -> Int -> DevicePtr a -> Int -> IO ()
- Foreign.CUDA.Runtime.Marshal: copyArray2DAsync :: Storable a => Int -> Int -> DevicePtr a -> Int -> DevicePtr a -> Int -> Maybe Stream -> IO ()
- Foreign.CUDA.Runtime.Marshal: copyArrayAsync :: Storable a => Int -> DevicePtr a -> DevicePtr a -> Maybe Stream -> IO ()
- Foreign.CUDA.Runtime.Marshal: data AllocFlag
- Foreign.CUDA.Runtime.Marshal: data AttachFlag
- Foreign.CUDA.Runtime.Marshal: free :: DevicePtr a -> IO ()
- Foreign.CUDA.Runtime.Marshal: freeHost :: HostPtr a -> IO ()
- Foreign.CUDA.Runtime.Marshal: instance GHC.Classes.Eq Foreign.CUDA.Runtime.Marshal.AllocFlag
- Foreign.CUDA.Runtime.Marshal: instance GHC.Classes.Eq Foreign.CUDA.Runtime.Marshal.AttachFlag
- Foreign.CUDA.Runtime.Marshal: instance GHC.Classes.Eq Foreign.CUDA.Runtime.Marshal.CopyDirection
- Foreign.CUDA.Runtime.Marshal: instance GHC.Enum.Bounded Foreign.CUDA.Runtime.Marshal.AllocFlag
- Foreign.CUDA.Runtime.Marshal: instance GHC.Enum.Bounded Foreign.CUDA.Runtime.Marshal.AttachFlag
- Foreign.CUDA.Runtime.Marshal: instance GHC.Enum.Enum Foreign.CUDA.Runtime.Marshal.AllocFlag
- Foreign.CUDA.Runtime.Marshal: instance GHC.Enum.Enum Foreign.CUDA.Runtime.Marshal.AttachFlag
- Foreign.CUDA.Runtime.Marshal: instance GHC.Enum.Enum Foreign.CUDA.Runtime.Marshal.CopyDirection
- Foreign.CUDA.Runtime.Marshal: instance GHC.Show.Show Foreign.CUDA.Runtime.Marshal.AllocFlag
- Foreign.CUDA.Runtime.Marshal: instance GHC.Show.Show Foreign.CUDA.Runtime.Marshal.AttachFlag
- Foreign.CUDA.Runtime.Marshal: instance GHC.Show.Show Foreign.CUDA.Runtime.Marshal.CopyDirection
- Foreign.CUDA.Runtime.Marshal: mallocArray :: Storable a => Int -> IO (DevicePtr a)
- Foreign.CUDA.Runtime.Marshal: mallocHostArray :: Storable a => [AllocFlag] -> Int -> IO (HostPtr a)
- Foreign.CUDA.Runtime.Marshal: mallocManagedArray :: Storable a => [AttachFlag] -> Int -> IO (DevicePtr a)
- Foreign.CUDA.Runtime.Marshal: memset :: DevicePtr a -> Int64 -> Int8 -> IO ()
- Foreign.CUDA.Runtime.Marshal: newListArray :: Storable a => [a] -> IO (DevicePtr a)
- Foreign.CUDA.Runtime.Marshal: newListArrayLen :: Storable a => [a] -> IO (DevicePtr a, Int)
- Foreign.CUDA.Runtime.Marshal: peekArray :: Storable a => Int -> DevicePtr a -> Ptr a -> IO ()
- Foreign.CUDA.Runtime.Marshal: peekArray2D :: Storable a => Int -> Int -> DevicePtr a -> Int -> Ptr a -> Int -> IO ()
- Foreign.CUDA.Runtime.Marshal: peekArray2DAsync :: Storable a => Int -> Int -> DevicePtr a -> Int -> HostPtr a -> Int -> Maybe Stream -> IO ()
- Foreign.CUDA.Runtime.Marshal: peekArrayAsync :: Storable a => Int -> DevicePtr a -> HostPtr a -> Maybe Stream -> IO ()
- Foreign.CUDA.Runtime.Marshal: peekListArray :: Storable a => Int -> DevicePtr a -> IO [a]
- Foreign.CUDA.Runtime.Marshal: pokeArray :: Storable a => Int -> Ptr a -> DevicePtr a -> IO ()
- Foreign.CUDA.Runtime.Marshal: pokeArray2D :: Storable a => Int -> Int -> Ptr a -> Int -> DevicePtr a -> Int -> IO ()
- Foreign.CUDA.Runtime.Marshal: pokeArray2DAsync :: Storable a => Int -> Int -> HostPtr a -> Int -> DevicePtr a -> Int -> Maybe Stream -> IO ()
- Foreign.CUDA.Runtime.Marshal: pokeArrayAsync :: Storable a => Int -> HostPtr a -> DevicePtr a -> Maybe Stream -> IO ()
- Foreign.CUDA.Runtime.Marshal: pokeListArray :: Storable a => [a] -> DevicePtr a -> IO ()
- Foreign.CUDA.Runtime.Marshal: withListArray :: Storable a => [a] -> (DevicePtr a -> IO b) -> IO b
- Foreign.CUDA.Runtime.Marshal: withListArrayLen :: Storable a => [a] -> (Int -> DevicePtr a -> IO b) -> IO b
- Foreign.CUDA.Runtime.Stream: Stream :: Ptr () -> Stream
- Foreign.CUDA.Runtime.Stream: [useStream] :: Stream -> Ptr ()
- Foreign.CUDA.Runtime.Stream: block :: Stream -> IO ()
- Foreign.CUDA.Runtime.Stream: create :: IO Stream
- Foreign.CUDA.Runtime.Stream: defaultStream :: Stream
- Foreign.CUDA.Runtime.Stream: defaultStreamLegacy :: Stream
- Foreign.CUDA.Runtime.Stream: defaultStreamPerThread :: Stream
- Foreign.CUDA.Runtime.Stream: destroy :: Stream -> IO ()
- Foreign.CUDA.Runtime.Stream: finished :: Stream -> IO Bool
- Foreign.CUDA.Runtime.Stream: newtype Stream
- Foreign.CUDA.Runtime.Utils: driverVersion :: IO Int
- Foreign.CUDA.Runtime.Utils: libraryVersion :: Int
- Foreign.CUDA.Runtime.Utils: runtimeVersion :: IO Int
+ Foreign.CUDA.Analysis.Device: instance Foreign.CUDA.Internal.Describe.Describe Foreign.CUDA.Analysis.Device.ComputeMode
+ Foreign.CUDA.Driver.Error: instance Foreign.CUDA.Internal.Describe.Describe Foreign.CUDA.Driver.Error.Status
+ Foreign.CUDA.Internal.C2HS: cFloatConv :: (RealFloat a, RealFloat b) => a -> b
+ Foreign.CUDA.Internal.C2HS: cFromBool :: Num a => Bool -> a
+ Foreign.CUDA.Internal.C2HS: cFromEnum :: (Enum e, Integral i) => e -> i
+ Foreign.CUDA.Internal.C2HS: cIntConv :: (Integral a, Integral b) => a -> b
+ Foreign.CUDA.Internal.C2HS: cToBool :: (Eq a, Num a) => a -> Bool
+ Foreign.CUDA.Internal.C2HS: cToEnum :: (Integral i, Enum e) => i -> e
+ Foreign.CUDA.Internal.C2HS: combineBitMasks :: (Enum a, Num b, Bits b) => [a] -> b
+ Foreign.CUDA.Internal.C2HS: containsBitMask :: (Num a, Bits a, Enum b) => a -> b -> Bool
+ Foreign.CUDA.Internal.C2HS: extractBitMasks :: (Num a, Bits a, Enum b, Bounded b) => a -> [b]
+ Foreign.CUDA.Internal.C2HS: nothingIf :: (a -> Bool) -> (a -> b) -> a -> Maybe b
+ Foreign.CUDA.Internal.C2HS: nothingIfNull :: (Ptr a -> b) -> Ptr a -> Maybe b
+ Foreign.CUDA.Internal.C2HS: peekArrayWith :: Storable a => (a -> b) -> Int -> Ptr a -> IO [b]
+ Foreign.CUDA.Internal.C2HS: peekBool :: (Integral a, Storable a) => Ptr a -> IO Bool
+ Foreign.CUDA.Internal.C2HS: peekCStringLenIntConv :: CStringLen -> IO String
+ Foreign.CUDA.Internal.C2HS: peekEnum :: (Enum a, Integral b, Storable b) => Ptr b -> IO a
+ Foreign.CUDA.Internal.C2HS: peekFloatConv :: (Storable a, RealFloat a, RealFloat b) => Ptr a -> IO b
+ Foreign.CUDA.Internal.C2HS: peekIntConv :: (Storable a, Integral a, Integral b) => Ptr a -> IO b
+ Foreign.CUDA.Internal.C2HS: withBool :: (Integral a, Storable a) => Bool -> (Ptr a -> IO b) -> IO b
+ Foreign.CUDA.Internal.C2HS: withCStringLenIntConv :: String -> (CStringLen -> IO a) -> IO a
+ Foreign.CUDA.Internal.C2HS: withEnum :: (Enum a, Integral b, Storable b) => a -> (Ptr b -> IO c) -> IO c
+ Foreign.CUDA.Internal.C2HS: withFloatConv :: (Storable b, RealFloat a, RealFloat b) => a -> (Ptr b -> IO c) -> IO c
+ Foreign.CUDA.Internal.C2HS: withIntConv :: (Storable b, Integral a, Integral b) => a -> (Ptr b -> IO c) -> IO c
+ Foreign.CUDA.Internal.Describe: class Describe a
+ Foreign.CUDA.Internal.Describe: describe :: Describe a => a -> String
Files
- CHANGELOG.md +11/−2
- README.md +8/−5
- Setup.hs +125/−32
- cbits/stubs.c +21/−18
- cbits/stubs.h +5/−6
- cuda.cabal +19/−37
- examples/src/deviceQueryDrv/DeviceQuery.hs +22/−9
- src/Foreign/CUDA.hs +0/−19
- src/Foreign/CUDA/Analysis/Device.chs +15/−3
- src/Foreign/CUDA/Driver.hs +1/−1
- src/Foreign/CUDA/Driver/Device.chs +11/−1
- src/Foreign/CUDA/Driver/Error.chs +1/−1
- src/Foreign/CUDA/Driver/Event.chs +7/−0
- src/Foreign/CUDA/Driver/Graph/Build.chs +62/−0
- src/Foreign/CUDA/Driver/Graph/Capture.chs +25/−5
- src/Foreign/CUDA/Driver/Marshal.chs +10/−0
- src/Foreign/CUDA/Driver/Unified.chs +10/−1
- src/Foreign/CUDA/Internal/Describe.hs +18/−0
- src/Foreign/CUDA/Runtime.hs +0/−28
- src/Foreign/CUDA/Runtime/Device.chs +0/−440
- src/Foreign/CUDA/Runtime/Error.chs +0/−123
- src/Foreign/CUDA/Runtime/Event.chs +0/−149
- src/Foreign/CUDA/Runtime/Exec.chs +0/−294
- src/Foreign/CUDA/Runtime/Marshal.chs +0/−648
- src/Foreign/CUDA/Runtime/Stream.chs +0/−117
- src/Foreign/CUDA/Runtime/Utils.chs +0/−63
- src/Text/Show/Describe.hs +0/−18
CHANGELOG.md view
@@ -5,12 +5,21 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). **NOTE:** The version numbers of this package roughly align to the latest-version of the CUDA API this package is built against This means that this+version of the CUDA API this package is built against. This means that this package _DOES NOT_ follow the PVP, or indeed any sensible version scheme, because NVIDIA are A-OK introducing breaking changes in minor updates. -## [0.12.8.0] - ???+## [0.13.0.0] - 2026-03-30+### Added+ * Support for CUDA-13++### Removed+ * Support for the runtime API (`Foreign.CUDA.RUntime`). There is an+ experimental cuda-runtime package in the Git repository; contact us if you+ depend on this.++## [0.12.8.0] - 2025-08-21 ### Added * Support for CUDA-12 - Thanks to @noahmartinwilliams on GitHub for helping out!
README.md view
@@ -25,10 +25,10 @@ ## Missing functionality -_This library is currently in **maintenance mode**. While we plan to release-updates to keep the existing interface working with newer CUDA versions (as-long as the underlying APIs remain available), no binding of new features is-planned at the moment. Get in touch if you want to contribute._+This library is currently in **maintenance mode**. While we are happy to+release updates to keep the existing interface working with newer CUDA versions+(as long as the underlying APIs remain available), no binding of new features+is planned at the moment. Get in touch if you want to contribute. Here is an incomplete historical list of missing bindings. Pull requests welcome! @@ -150,9 +150,12 @@ - cuGraphMemAllocNodeGetParams - cuGraphMemFreeNodeGetParams -### CUDA-12+### CUDA >= 12 A lot. PRs welcome.++- CUDA-12.3+ - Edge data in the driver Graph API (`cuGraphAddDependencies_v2` etc.) # Old compatibility notes
Setup.hs view
@@ -1,13 +1,22 @@+-- Decouple from GHC's default language setting, so that it's easier+-- to maintain compatibility with old GHCs.+{-# LANGUAGE Haskell2010 #-}+{-# OPTIONS_GHC -Wall #-}++{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE CPP #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE KindSignatures #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TupleSections #-} -- The MIN_VERSION_Cabal macro was introduced with Cabal-1.24 (??) #ifndef MIN_VERSION_Cabal #define MIN_VERSION_Cabal(major1,major2,minor) 0 #endif -import Distribution.PackageDescription+import Distribution.PackageDescription hiding ( Flag ) import Distribution.Simple import Distribution.Simple.BuildPaths import Distribution.Simple.Command@@ -33,6 +42,18 @@ #if MIN_VERSION_Cabal(3,8,0) import Distribution.Simple.PackageDescription #endif+#if MIN_VERSION_Cabal(3,14,0)+-- Note [Cabal 3.14]+--+-- If you change any path stuff, either test that the package still works with+-- Cabal 3.12 or stop declaring support for it in cuda.cabal. (If you do the+-- latter, also remove all of the other conditionals in this file.)+-- Note that supporting old versions of Cabal is useful for being able to run+-- e.g. Accelerate on old GPU clusters, which is nice.+import Distribution.Utils.Path (SymbolicPath, FileOrDir(File, Dir), Lib, Include, Pkg, CWD, makeSymbolicPath, interpretSymbolicPath, makeRelativePathEx)+import qualified Distribution.Types.LocalBuildConfig as LBC+#else+#endif import Control.Exception import Control.Monad@@ -40,6 +61,7 @@ import Data.Function import Data.List import Data.Maybe+import Data.String (fromString) import System.Directory import System.Environment import System.FilePath@@ -67,8 +89,9 @@ main :: IO () main = defaultMainWithHooks customHooks where+ -- Be careful changing flags/paths stuff here; see Note [Cabal 3.14]. readHook get_verbosity a flags = do- getHookedBuildInfo (fromFlag (get_verbosity flags))+ getHookedBuildInfo (flagToMaybe (workingDirFlag flags)) (fromFlag (get_verbosity flags)) preprocessors = hookedPreProcessors simpleUserHooks @@ -87,14 +110,16 @@ , preReg = readHook regVerbosity , preUnreg = readHook regVerbosity , postConf = postConfHook- , hookedPreProcessors = ("chs", ppC2hs) : filter (\x -> fst x /= "chs") preprocessors+ , hookedPreProcessors = (fromString "chs", ppC2hs) : filter (\x -> fst x /= fromString "chs") preprocessors } -- The hook just loads the HookedBuildInfo generated by postConfHook, -- unless there is user-provided info that overwrites it. -- preBuildHook :: Args -> BuildFlags -> IO HookedBuildInfo- preBuildHook _ flags = getHookedBuildInfo $ fromFlag $ buildVerbosity flags+ preBuildHook _ flags = getHookedBuildInfo cwd verbosity+ where cwd = flagToMaybe (workingDirFlag flags)+ verbosity = fromFlag (buildVerbosity flags) -- The hook scans system in search for CUDA Toolkit. If the toolkit is not -- found, an error is raised. Otherwise the toolkit location is used to@@ -103,12 +128,14 @@ postConfHook :: Args -> ConfigFlags -> PackageDescription -> LocalBuildInfo -> IO () postConfHook args flags pkg_descr lbi = do let+ cwd = flagToMaybe (workingDirFlag flags) verbosity = fromFlagOrDefault normal (configVerbosity flags) profile = fromFlagOrDefault False (configProfLib flags) currentPlatform = hostPlatform lbi compilerId_ = compilerId (compiler lbi) -- generateAndStoreBuildInfo+ cwd verbosity profile currentPlatform@@ -118,7 +145,7 @@ generatedBuildInfoFilePath validateLinker verbosity currentPlatform $ withPrograms lbi --- actualBuildInfoToUse <- getHookedBuildInfo verbosity+ actualBuildInfoToUse <- getHookedBuildInfo cwd verbosity let pkg_descr' = updatePackageDescription actualBuildInfoToUse pkg_descr postConf simpleUserHooks args flags pkg_descr' lbi @@ -131,27 +158,29 @@ -- visible to underlying build tools. -- libraryBuildInfo- :: Verbosity+ :: Maybe CWDPath+ -> Verbosity -> Bool -> FilePath -> Platform -> Version- -> [FilePath]- -> [FilePath]+ -> [ExtraLibsPath]+ -> [ExtraIncludesPath] -> IO HookedBuildInfo-libraryBuildInfo verbosity profile installPath platform@(Platform arch os) ghcVersion extraLibs extraIncludes = do+libraryBuildInfo cwd verbosity profile installPath platform@(Platform arch os) ghcVersion extraLibs extraIncludes = do let- libraryPaths = cudaLibraryPaths platform installPath ++ extraLibs- includePaths = cudaIncludePath platform installPath : extraIncludes+ -- Be careful changing flags/paths stuff here; see Note [Cabal 3.14].+ libraryPaths = map makeSymbolicPath (cudaLibraryPaths platform installPath) ++ extraLibs+ includePaths = makeSymbolicPath (cudaIncludePath platform installPath) : extraIncludes takeFirstExisting paths = do- existing <- filterM doesDirectoryExist libraryPaths+ existing <- filterM (doesDirectoryExist . interpretSymbolicPath cwd) libraryPaths case existing of (p0:_) -> return p0 _ -> die' verbosity $ "Could not find path: " ++ show paths -- This can only be defined once, so take the first path which exists- canonicalLibraryPath <- takeFirstExisting libraryPaths+ canonicalLibraryPath <- interpretSymbolicPath cwd <$> takeFirstExisting libraryPaths let -- OS-specific escaping for -D path defines@@ -163,16 +192,16 @@ extraLibDirs' = libraryPaths ccOptions' = [ "-DCUDA_INSTALL_PATH=\"" ++ escDefPath installPath ++ "\"" , "-DCUDA_LIBRARY_PATH=\"" ++ escDefPath canonicalLibraryPath ++ "\""- ] ++ map ("-I" ++) includePaths- ldOptions' = map ("-L" ++) libraryPaths+ ] ++ map (("-I" ++) . interpretSymbolicPath cwd) includePaths+ ldOptions' = map (("-L" ++) . interpretSymbolicPath cwd) libraryPaths ghcOptions = map ("-optc"++) ccOptions' ++ map ("-optl"++) ldOptions' ++ if os /= Windows && not profile- then map ("-optl-Wl,-rpath,"++) extraLibDirs'+ then map (("-optl-Wl,-rpath," ++) . interpretSymbolicPath cwd) extraLibDirs' else [] extraLibs' = cudaLibraries platform- frameworks' = [ "CUDA" | os == OSX ]- frameworkDirs' = [ "/Library/Frameworks" | os == OSX ]+ frameworks' = [ makeRelativePathEx "CUDA" | os == OSX ]+ frameworkDirs' = [ makeSymbolicPath "/Library/Frameworks" | os == OSX ] -- options or c2hs archFlag = case arch of@@ -227,7 +256,9 @@ (Windows, X86_64) -> ["lib/x64"] (OSX, _) -> ["lib"] -- MacOS does not distinguish 32- vs. 64-bit paths (_, X86_64) -> ["lib64", "lib"] -- prefer lib64 for 64-bit systems+#if MIN_VERSION_Cabal(2,4,0) (_, AArch64) -> ["lib64", "lib"]+#endif _ -> ["lib"] -- otherwise @@ -238,7 +269,7 @@ cudaLibraries (Platform _ os) = case os of OSX -> ["cudadevrt", "cudart_static"]- _ -> ["cudart", "cuda"]+ _ -> ["cuda"] cudaGHCiLibraries :: Platform@@ -248,7 +279,7 @@ cudaGHCiLibraries platform@(Platform _ os) installPath libraries = case os of Windows -> cudaGhciLibrariesWindows platform installPath libraries- OSX -> return ["cudart"]+ OSX -> return ["cuda"] _ -> return [] -- Windows compatibility function.@@ -398,7 +429,7 @@ windowsHelpPage :: String-windowsHelpPage = "https://github.com/tmcdonell/cuda/blob/master/WINDOWS.markdown"+windowsHelpPage = "https://github.com/tmcdonell/cuda/blob/master/cuda/WINDOWS.md" windowsLinkerBugMsg :: FilePath -> String windowsLinkerBugMsg ldPath = printf (unlines msg) windowsHelpPage ldPath@@ -427,17 +458,18 @@ -- Runs CUDA detection procedure and stores .buildinfo to a file. -- generateAndStoreBuildInfo- :: Verbosity+ :: Maybe CWDPath+ -> Verbosity -> Bool -> Platform -> CompilerId- -> [FilePath]- -> [FilePath]+ -> [ExtraLibsPath]+ -> [ExtraIncludesPath] -> FilePath -> IO ()-generateAndStoreBuildInfo verbosity profile platform (CompilerId _ghcFlavor ghcVersion) extraLibs extraIncludes path = do+generateAndStoreBuildInfo cwd verbosity profile platform (CompilerId _ghcFlavor ghcVersion) extraLibs extraIncludes path = do installPath <- findCUDAInstallPath verbosity platform- hbi <- libraryBuildInfo verbosity profile installPath platform ghcVersion extraLibs extraIncludes+ hbi <- libraryBuildInfo cwd verbosity profile installPath platform ghcVersion extraLibs extraIncludes storeHookedBuildInfo verbosity path hbi storeHookedBuildInfo@@ -622,21 +654,22 @@ -- (generated one should be always present, as it is created in the post-conf step) -- getHookedBuildInfo- :: Verbosity+ :: Maybe CWDPath+ -> Verbosity -> IO HookedBuildInfo-getHookedBuildInfo verbosity = do- doesCustomBuildInfoExists <- doesFileExist customBuildInfoFilePath+getHookedBuildInfo cwd verbosity = do+ doesCustomBuildInfoExists <- doesFileExist (customBuildInfoFilePath) if doesCustomBuildInfoExists then do notice verbosity $ printf "The user-provided buildinfo from file %s will be used. To use default settings, delete this file.\n" customBuildInfoFilePath- readHookedBuildInfo verbosity customBuildInfoFilePath+ readHookedBuildInfoWithCWD verbosity cwd (makeSymbolicPath customBuildInfoFilePath) else do doesGeneratedBuildInfoExists <- doesFileExist generatedBuildInfoFilePath if doesGeneratedBuildInfoExists then do notice verbosity $ printf "Using build information from '%s'.\n" generatedBuildInfoFilePath notice verbosity $ printf "Provide a '%s' file to override this behaviour.\n" customBuildInfoFilePath- readHookedBuildInfo verbosity generatedBuildInfoFilePath+ readHookedBuildInfoWithCWD verbosity cwd (makeSymbolicPath generatedBuildInfoFilePath) else die' verbosity $ printf "Unexpected failure. Neither the default %s nor custom %s exist.\n" generatedBuildInfoFilePath customBuildInfoFilePath @@ -672,7 +705,7 @@ getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] getCppOptions bi lbi = hcDefines (compiler lbi)- ++ ["-I" ++ dir | dir <- includeDirs bi]+ ++ ["-I" ++ interpretSymbolicPath (lbiCWD lbi) dir | dir <- includeDirs bi] ++ [opt | opt@('-':c:_) <- ccOptions bi, c `elem` "DIU"] hcDefines :: Compiler -> [String]@@ -704,5 +737,65 @@ #if !MIN_VERSION_Cabal(2,0,0) die' :: Verbosity -> String -> IO a die' _ = die+#endif+++-- Compatibility across Cabal 3.14 symbolic paths.+-- If we want to drop pre-Cabal-3.14 compatibility at some point, this should all be merged in above.++lbiCWD :: LocalBuildInfo -> Maybe CWDPath++#if MIN_VERSION_Cabal(3,14,0)+type ExtraLibsPath = SymbolicPath Pkg ('Dir Lib)+type ExtraIncludesPath = SymbolicPath Pkg ('Dir Include)+type CWDPath = SymbolicPath CWD ('Dir Pkg)++regVerbosity :: RegisterFlags -> Flag Verbosity+regVerbosity = setupVerbosity . registerCommonFlags++workingDirFlag :: HasCommonFlags flags => flags -> Flag CWDPath+workingDirFlag = setupWorkingDir . getCommonFlags++lbiCWD = flagToMaybe . setupWorkingDir . configCommonFlags . LBC.configFlags . LBC.packageBuildDescr . localBuildDescr++-- makeSymbolicPath is an actual useful function in Cabal 3.14+-- makeRelativePathEx is an actual useful function in Cabal 3.14+-- interpretSymbolicPath is an actual useful function in Cabal 3.14++class HasCommonFlags flags where getCommonFlags :: flags -> CommonSetupFlags+instance HasCommonFlags BuildFlags where getCommonFlags = buildCommonFlags+instance HasCommonFlags CleanFlags where getCommonFlags = cleanCommonFlags+instance HasCommonFlags ConfigFlags where getCommonFlags = configCommonFlags+instance HasCommonFlags CopyFlags where getCommonFlags = copyCommonFlags+instance HasCommonFlags InstallFlags where getCommonFlags = installCommonFlags+instance HasCommonFlags HscolourFlags where getCommonFlags = hscolourCommonFlags+instance HasCommonFlags HaddockFlags where getCommonFlags = haddockCommonFlags+instance HasCommonFlags RegisterFlags where getCommonFlags = registerCommonFlags++readHookedBuildInfoWithCWD :: Verbosity -> Maybe CWDPath -> SymbolicPath Pkg 'File -> IO HookedBuildInfo+readHookedBuildInfoWithCWD = readHookedBuildInfo+#else+type ExtraLibsPath = FilePath+type ExtraIncludesPath = FilePath+type CWDPath = ()++-- regVerbosity is still present as an actual field in Cabal 3.12++workingDirFlag :: flags -> Flag CWDPath+workingDirFlag _ = NoFlag++lbiCWD _ = Nothing++makeSymbolicPath :: FilePath -> FilePath+makeSymbolicPath = id++makeRelativePathEx :: FilePath -> FilePath+makeRelativePathEx = id++interpretSymbolicPath :: Maybe CWDPath -> FilePath -> FilePath+interpretSymbolicPath _ = id++readHookedBuildInfoWithCWD :: Verbosity -> Maybe CWDPath -> FilePath -> IO HookedBuildInfo+readHookedBuildInfoWithCWD verb _ path = readHookedBuildInfo verb path #endif
cbits/stubs.c view
@@ -3,24 +3,7 @@ */ #include "cbits/stubs.h"--#if CUDART_VERSION >= 7000-cudaError_t cudaLaunchKernel_simple(const void *func, unsigned int gridX, unsigned int gridY, unsigned int gridZ, unsigned int blockX, unsigned int blockY, unsigned int blockZ, void **args, size_t sharedMem, cudaStream_t stream)-{- dim3 gridDim = {gridX, gridY, gridZ};- dim3 blockDim = {blockX, blockY, blockZ};-- return cudaLaunchKernel(func, gridDim, blockDim, args, sharedMem, stream);-}-#else-cudaError_t cudaConfigureCall_simple(unsigned int gridX, unsigned int gridY, unsigned int blockX, unsigned int blockY, unsigned int blockZ, size_t sharedMem, cudaStream_t stream)-{- dim3 gridDim = {gridX, gridY, 1};- dim3 blockDim = {blockX,blockY,blockZ};-- return cudaConfigureCall(gridDim, blockDim, sharedMem, stream);-}-#endif+#include <string.h> // memset CUresult cuMemcpy2DHtoD(CUdeviceptr dstDevice, unsigned int dstPitch, unsigned int dstXInBytes, unsigned int dstY, void* srcHost, unsigned int srcPitch, unsigned int srcXInBytes, unsigned int srcY, unsigned int widthInBytes, unsigned int height) {@@ -196,7 +179,13 @@ CUresult CUDAAPI cuCtxCreate(CUcontext *pctx, unsigned int flags, CUdevice dev) {+#if CUDA_VERSION >= 13000+ CUctxCreateParams params;+ memset(¶ms, 0, sizeof params);+ return cuCtxCreate_v4(pctx, ¶ms, flags, dev);+#else return cuCtxCreate_v2(pctx, flags, dev);+#endif } CUresult CUDAAPI cuModuleGetGlobal(CUdeviceptr *dptr, size_t *bytes, CUmodule hmod, const char *name)@@ -424,3 +413,17 @@ } #endif +#if CUDA_VERSION >= 13000+// This is the signature of the CUDA <=12 version; much easier to shim here than in Haskell.+CUresult cuMemAdvise_device(CUdeviceptr dptr, size_t count, CUmem_advise advice, CUdevice device)+{+ return cuMemAdvise(dptr, count, advice, (CUmemLocation){.id = device, .type = CU_MEM_LOCATION_TYPE_DEVICE});+}++// This is the signature of the CUDA <=12 version; much easier to shim here than in Haskell.+CUresult cuMemPrefetchAsync_device(CUdeviceptr dptr, size_t count, CUdevice device, CUstream hStream)+{+ // flags is reserved and must be 0 in CUDA 13+ return cuMemPrefetchAsync(dptr, count, (CUmemLocation){.id = device, .type = CU_MEM_LOCATION_TYPE_DEVICE}, 0, hStream);+}+#endif
cbits/stubs.h view
@@ -21,12 +21,6 @@ void enable_constructors(); -#if CUDART_VERSION >= 7000-cudaError_t cudaLaunchKernel_simple(const void *func, unsigned int gridX, unsigned int gridY, unsigned int gridZ, unsigned int blockX, unsigned int blockY, unsigned int blockZ, void **args, size_t sharedMem, cudaStream_t stream);-#else-cudaError_t cudaConfigureCall_simple(unsigned int gridX, unsigned int gridY, unsigned int blockX, unsigned int blockY, unsigned int blockZ, size_t sharedMem, cudaStream_t stream);-#endif- CUresult cuTexRefSetAddress2D_simple(CUtexref tex, CUarray_format format, unsigned int numChannels, CUdeviceptr dptr, size_t width, size_t height, size_t pitch); CUresult cuMemcpy2DHtoD(CUdeviceptr dstDevice, unsigned int dstPitch, unsigned int dstXInBytes, unsigned int dstY, void* srcHost, unsigned int srcPitch, unsigned int srcXInBytes, unsigned int srcY, unsigned int widthInBytes, unsigned int height); CUresult cuMemcpy2DHtoDAsync(CUdeviceptr dstDevice, unsigned int dstPitch, unsigned int dstXInBytes, unsigned int dstY, void* srcHost, unsigned int srcPitch, unsigned int srcXInBytes, unsigned int srcY, unsigned int widthInBytes, unsigned int height, CUstream hStream);@@ -182,6 +176,11 @@ #if CUDA_VERSION >= 11010 #undef cuIpcOpenMemHandle CUresult CUDAAPI cuIpcOpenMemHandle(CUdeviceptr *pdptr, CUipcMemHandle handle, unsigned int Flags);+#endif++#if CUDA_VERSION >= 13000+CUresult cuMemAdvise_device(CUdeviceptr dptr, size_t count, CUmem_advise advice, CUdevice device);+CUresult cuMemPrefetchAsync_device(CUdeviceptr dptr, size_t count, CUdevice device, CUstream hStream); #endif #ifdef __cplusplus
cuda.cabal view
@@ -1,8 +1,8 @@ cabal-version: 1.24 Name: cuda-Version: 0.12.8.0-Synopsis: FFI binding to the CUDA interface for programming NVIDIA GPUs+Version: 0.13.0.0+Synopsis: FFI binding to the CUDA driver interface for programming NVIDIA GPUs Description: The CUDA library provides a direct, general purpose C-like SPMD programming model for NVIDIA graphics cards (G8x series onwards). This is a collection@@ -21,18 +21,13 @@ . 3. Checking at @\/usr\/local\/cuda@ .- 4. @CUDA_PATH_Vx_y@ environment variable, for recent CUDA toolkit versions x.y- .- This library provides bindings to both the CUDA Driver and Runtime APIs. To- get started, see one of:- .- * "Foreign.CUDA.Driver" (a short tutorial is available here)+ 4. Environment variables of the form @CUDA_PATH_Vx_y@ (deprecated) .- * "Foreign.CUDA.Runtime"+ This library provides bindings to the CUDA Driver API, not the Runtime API.+ To get started, see "Foreign.CUDA.Driver"; a short tutorial is available+ there. .- Tested with library versions up to CUDA-12.8. See also the- <https://travis-ci.org/tmcdonell/cuda travis-ci.org> build matrix for- version compatibility.+ Tested with library versions up to and including CUDA-13.0. . [/NOTES:/] .@@ -40,16 +35,18 @@ . * <https://github.com/tmcdonell/cuda/blob/master/WINDOWS.md> .- This library is currently in __maintenance mode__. While we plan to release- updates to keep the existing interface working with newer CUDA versions (as- long as the underlying APIs remain available), no binding of new features is- planned at the moment. Get in touch if you want to contribute.+ This library is currently in __maintenance mode__. While we are happy to+ release updates to keep the existing interface working with newer CUDA+ versions (as long as the underlying APIs remain available), no binding of+ new features is planned at the moment. Get in touch if you want to+ contribute. License: BSD3 License-file: LICENSE Copyright: Copyright (c) [2009..2023]. Trevor L. McDonell <trevor.mcdonell@gmail.com> Author: Trevor L. McDonell <trevor.mcdonell@gmail.com>-Maintainer: Trevor L. McDonell <trevor.mcdonell@gmail.com>+Maintainer: Trevor L. McDonell <trevor.mcdonell@gmail.com>,+ Tom Smeding <tom@tomsmeding.com> Homepage: https://github.com/tmcdonell/cuda Bug-reports: https://github.com/tmcdonell/cuda/issues Category: Foreign@@ -61,6 +58,8 @@ Extra-source-files: cbits/stubs.h++Extra-doc-files: CHANGELOG.md README.md WINDOWS.md@@ -68,14 +67,13 @@ custom-setup setup-depends: base >= 4.7 && < 5- , Cabal >= 1.24 && < 3.11+ , Cabal >= 1.24 && < 3.17 , directory >= 1.0 , filepath >= 1.0 Library hs-source-dirs: src exposed-modules:- Foreign.CUDA Foreign.CUDA.Path Foreign.CUDA.Ptr @@ -111,22 +109,10 @@ Foreign.CUDA.Driver.Unified Foreign.CUDA.Driver.Utils - -- Runtime API- Foreign.CUDA.Runtime- Foreign.CUDA.Runtime.Device- Foreign.CUDA.Runtime.Error- Foreign.CUDA.Runtime.Event- Foreign.CUDA.Runtime.Exec- Foreign.CUDA.Runtime.Marshal- Foreign.CUDA.Runtime.Stream- Foreign.CUDA.Runtime.Utils- -- Extras Foreign.C.Extra-- other-modules: Foreign.CUDA.Internal.C2HS- Text.Show.Describe+ Foreign.CUDA.Internal.Describe include-dirs: . c-sources: cbits/stubs.c@@ -150,10 +136,6 @@ -fwarn-tabs -fno-warn-unused-imports - ghc-prof-options:- -fprof-auto- -fprof-cafs- if impl(ghc == 8.0.1) cpp-options: -DCUDA_PRELOAD @@ -177,6 +159,6 @@ source-repository this type: git location: https://github.com/tmcdonell/cuda- tag: v0.12.8.0+ tag: v0.13.0.0 -- vim: nospell
examples/src/deviceQueryDrv/DeviceQuery.hs view
@@ -5,6 +5,7 @@ module Main where import Control.Monad+import Foreign.Marshal.Utils ( toBool ) import Numeric import Prelude hiding ( (<>) ) import Text.PrettyPrint@@ -69,22 +70,34 @@ ,(" 2D:", grid maxTextureDim2D) ,(" 3D:", cube maxTextureDim3D) ,("Texture alignment:", text $ showBytes textureAlignment)- ,("Maximum memory pitch:", text $ showBytes memPitch)- ,("Concurrent kernel execution:", bool concurrentKernels)- ,("Concurrent copy and execution:", bool deviceOverlap <> text (printf ", with %d copy engine%s" asyncEngineCount (if asyncEngineCount > 1 then "s" else "")))- ,("Runtime limit on kernel execution:", bool kernelExecTimeoutEnabled)+ ,("Maximum memory pitch:", text $ showBytes memPitch)]++++ $(if CUDA.libraryVersion >= 13000 then [|+ [("Concurrent copy and kernel execution:", bool concurrentKernels <> text (printf " with %d copy engine%s" asyncEngineCount (if asyncEngineCount > 1 then "s" else "")))]+ |] else [|+ [("Concurrent kernel execution:", bool concurrentKernels)+ ,("Concurrent copy and execution:", bool deviceOverlap <> text (printf ", with %d copy engine%s" asyncEngineCount (if asyncEngineCount > 1 then "s" else "")))]+ |])++++ [("Runtime limit on kernel execution:", bool kernelExecTimeoutEnabled) ,("Integrated GPU sharing host memory:", bool integrated) ,("Host page-locked memory mapping:", bool canMapHostMemory) ,("ECC memory support:", bool eccEnabled) ,("Unified addressing (UVA):", bool unifiedAddressing)]++-#if __GLASGOW_HASKELL__ > 710+ $(if CUDA.libraryVersion >= 8000 then [| [("Single to double precision performance:", text $ printf "%d : 1" singleToDoublePerfRatio)- ,("Supports compute pre-emption:", bool preemption)]|] else [|[]|])+++ ,("Supports compute pre-emption:", bool preemption)]+ |] else [|[]|])+++ $(if CUDA.libraryVersion >= 9000 then [|- [("Supports cooperative launch:", bool cooperativeLaunch)- ,("Supports multi-device cooperative launch:", bool cooperativeLaunchMultiDevice)]|] else [|[]|])++-#endif+ [("Supports cooperative launch:", bool cooperativeLaunch)]+ |] else [|[]|])++++ $(if CUDA.libraryVersion >= 9000 && CUDA.libraryVersion < 13000 then [|+ [("Supports multi-device cooperative launch:", bool cooperativeLaunchMultiDevice)]+ |] else [|[]|])+++ [("PCI bus/location:", int (busID pciInfo) <> char '/' <> int (deviceID pciInfo)) ,("Compute mode:", text (show computeMode)) ]
− src/Foreign/CUDA.hs
@@ -1,19 +0,0 @@------------------------------------------------------------------------------------ |--- Module : Foreign.CUDA--- Copyright : [2009..2023] Trevor L. McDonell--- License : BSD------ Top level bindings. By default, expose the C-for-CUDA runtime API bindings,--- as they are slightly more user friendly.--------------------------------------------------------------------------------------module Foreign.CUDA (-- module Foreign.CUDA.Runtime--) where--import Foreign.CUDA.Runtime-
src/Foreign/CUDA/Analysis/Device.chs view
@@ -23,7 +23,7 @@ import Data.Set (Set) import Data.Int import Data.IORef-import Text.Show.Describe+import Foreign.CUDA.Internal.Describe import System.IO.Unsafe import Debug.Trace@@ -32,13 +32,19 @@ -- | -- The compute mode the device is currently in --+#if CUDA_VERSION < 13000 {# enum CUcomputemode as ComputeMode { underscoreToCase } with prefix="CU_COMPUTEMODE" deriving (Eq, Show) #}+#else+{# enum cudaComputeMode as ComputeMode+ { }+ with prefix="cudaComputeMode" deriving (Eq, Show) #}+#endif instance Describe ComputeMode where describe Default = "Multiple contexts are allowed on the device simultaneously"-#if CUDA_VERSION < 8000+#if CUDA_VERSION < 8000 || CUDA_VERSION >= 13000 describe Exclusive = "Only one context used by a single thread can be present on this device at a time" #endif describe Prohibited = "No contexts can be created on this device at this time"@@ -69,7 +75,13 @@ --} -- |--- The properties of a compute device+-- Some properties of a compute device. Originally, this mirrored+-- @struct cudaDeviceProp@ in CUDA, but since CUDA 13 some fields have been+-- removed from that struct, and this data type keeps them for backwards+-- compatibility.+--+-- There are more device "properties" than those listed in this data type; use+-- 'Foreign.CUDA.Driver.Device.attribute' to query them. -- data DeviceProperties = DeviceProperties {
src/Foreign/CUDA/Driver.hs view
@@ -31,7 +31,7 @@ -- Next, we must select a GPU that we will execute operations on. Each GPU -- is assigned a unique identifier (beginning at zero). We can get a handle -- to a compute device at a given ordinal using the 'device' operation.--- Given a device handle, we can query the properties of that device using+-- Given a device handle, we can query some properties of that device using -- 'props'. The number of available CUDA-capable devices is given via -- 'count'. For example: --
src/Foreign/CUDA/Driver/Device.chs view
@@ -246,8 +246,11 @@ peekS s _ = peekCString s --- | Returns a UUID for the device+-- | Returns a UUID for the device. --+-- Since CUDA-13: If the device is in MIG mode, this function returns its MIG+-- UUID which uniquely identifies the subscribed MIG compute instance.+-- -- Requires CUDA-9.2 -- -- <https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__DEVICE.html#group__CUDA__DEVICE_1g987b46b884c101ed5be414ab4d9e60e4>@@ -265,10 +268,17 @@ unpack ptr where {-# INLINE cuDeviceGetUuid #-}+#if CUDA_VERSION < 13000 {# fun unsafe cuDeviceGetUuid { `Ptr ()' , useDevice `Device' } -> `()' checkStatus*- #}+#else+ {# fun unsafe cuDeviceGetUuid_v2 as cuDeviceGetUuid+ { `Ptr ()'+ , useDevice `Device'+ } -> `()' checkStatus*- #}+#endif {-# INLINE unpack #-} unpack :: Ptr () -> IO UUID
src/Foreign/CUDA/Driver/Error.chs view
@@ -23,7 +23,7 @@ -- Friends import Foreign.CUDA.Internal.C2HS-import Text.Show.Describe+import Foreign.CUDA.Internal.Describe -- System import Control.Exception
src/Foreign/CUDA/Driver/Event.chs view
@@ -114,10 +114,17 @@ elapsedTime !ev1 !ev2 = resultIfOk =<< cuEventElapsedTime ev1 ev2 {-# INLINE cuEventElapsedTime #-}+#if CUDA_VERSION < 13000 {# fun unsafe cuEventElapsedTime { alloca- `Float' peekFloatConv* , useEvent `Event' , useEvent `Event' } -> `Status' cToEnum #}+#else+{# fun unsafe cuEventElapsedTime_v2 as cuEventElapsedTime+ { alloca- `Float' peekFloatConv*+ , useEvent `Event'+ , useEvent `Event' } -> `Status' cToEnum #}+#endif -- |
src/Foreign/CUDA/Driver/Graph/Build.chs view
@@ -204,13 +204,24 @@ where (from, to) = unzip deps +#if CUDA_VERSION < 13000 {# fun unsafe cuGraphAddDependencies { useGraph `Graph' , withNodeArray* `[Node]' , withNodeArrayLen* `[Node]'& } -> `()' checkStatus*- #}+#else+ cuGraphAddDependencies g' from' to' = cuGraphAddDependencies_v2 g' from' to' (length deps)+ {# fun unsafe cuGraphAddDependencies_v2+ { useGraph `Graph'+ , withNodeArray* `[Node]'+ , withNodeArray* `[Node]'+ , withNullEdgeDataLen* `Int'&+ }+ -> `()' checkStatus*- #} #endif+#endif -- | Remove dependency edges from the graph@@ -230,13 +241,24 @@ where (from, to) = unzip deps +#if CUDA_VERSION < 13000 {# fun unsafe cuGraphRemoveDependencies { useGraph `Graph' , withNodeArray* `[Node]' , withNodeArrayLen* `[Node]'& } -> `()' checkStatus*- #}+#else+ cuGraphRemoveDependencies g' from' to' = cuGraphRemoveDependencies_v2 g' from' to' (length deps)+ {# fun unsafe cuGraphRemoveDependencies_v2+ { useGraph `Graph'+ , withNodeArray* `[Node]'+ , withNodeArray* `[Node]'+ , withNullEdgeDataLen* `Int'&+ }+ -> `()' checkStatus*- #} #endif+#endif -- | Create an empty node and add it to the graph.@@ -507,6 +529,7 @@ to <- peekArray count p_to return $ zip from to where+#if CUDA_VERSION < 13000 {# fun unsafe cuGraphGetEdges { useGraph `Graph' , castPtr `Ptr Node'@@ -514,7 +537,18 @@ , id `Ptr CULong' } -> `()' checkStatus*- #}+#else+ cuGraphGetEdges g' f t c = cuGraphGetEdges_v2 g' f t nullPtr c+ {# fun unsafe cuGraphGetEdges_v2+ { useGraph `Graph'+ , castPtr `Ptr Node'+ , castPtr `Ptr Node'+ , castPtr `Ptr edgeData'+ , id `Ptr CULong'+ }+ -> `()' checkStatus*- #} #endif+#endif -- | Return a graph's nodes@@ -598,13 +632,24 @@ cuGraphNodeGetDependencies n p_deps p_count peekArray count p_deps where+#if CUDA_VERSION < 13000 {# fun unsafe cuGraphNodeGetDependencies { useNode `Node' , castPtr `Ptr Node' , id `Ptr CULong' } -> `()' checkStatus*- #}+#else+ cuGraphNodeGetDependencies n' d c = cuGraphNodeGetDependencies_v2 n' d nullPtr c+ {# fun unsafe cuGraphNodeGetDependencies_v2+ { useNode `Node'+ , castPtr `Ptr Node'+ , castPtr `Ptr edgeData'+ , id `Ptr CULong'+ }+ -> `()' checkStatus*- #} #endif+#endif -- | Return a node's dependent nodes@@ -628,13 +673,24 @@ cuGraphNodeGetDependentNodes n p_deps p_count peekArray count p_deps where+#if CUDA_VERSION < 13000 {# fun unsafe cuGraphNodeGetDependentNodes { useNode `Node' , castPtr `Ptr Node' , id `Ptr CULong' } -> `()' checkStatus*- #}+#else+ cuGraphNodeGetDependentNodes n' d c = cuGraphNodeGetDependentNodes_v2 n' d nullPtr c+ {# fun unsafe cuGraphNodeGetDependentNodes_v2+ { useNode `Node'+ , castPtr `Ptr Node'+ , castPtr `Ptr edgeData'+ , id `Ptr CULong'+ }+ -> `()' checkStatus*- #} #endif+#endif -- | Find a cloned version of a node@@ -679,5 +735,11 @@ {-# INLINE withNodeArrayLen #-} withNodeArrayLen :: [Node] -> ((Ptr {# type CUgraphNode #}, CULong) -> IO a) -> IO a withNodeArrayLen ns f = withArrayLen ns $ \i p -> f (castPtr p, cIntConv i)+#endif++#if CUDA_VERSION >= 13000+{-# INLINE withNullEdgeDataLen #-}+withNullEdgeDataLen :: Int -> ((Ptr (), CULong) -> IO a) -> IO a+withNullEdgeDataLen len f = f (nullPtr, cIntConv len) #endif
src/Foreign/CUDA/Driver/Graph/Capture.chs view
@@ -143,6 +143,10 @@ -- | Query the capture status of a stream and get an id for the capture -- sequence, which is unique over the lifetime of the process. --+-- Since CUDA-13, "edge data" can be associated with an edge in the graph. This+-- function assumes no such data is present (if there is, a CUDA error+-- (@CUDA_ERROR_LOSSY_QUERY@) will be raised).+-- -- Requires CUDA-10.1 -- -- <https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__STREAM.html#group__CUDA__STREAM_1g13145ece1d79a1d79a1d22abb9663216>@@ -152,24 +156,38 @@ #if CUDA_VERSION < 10010 info :: Stream -> IO (Status, Int64) info = requireSDK 'info 10.1-#elif CUDA_VERSION < 12000+-- Not another elif because c2hs seems to be buggy+#else+#if CUDA_VERSION < 12000 {# fun unsafe cuStreamGetCaptureInfo as info { useStream `Stream' , alloca- `Status' peekEnum* , alloca- `Int64' peekIntConv* } -> `()' checkStatus*- #}-#else+#elif CUDA_VERSION < 13000 {# fun unsafe cuStreamGetCaptureInfo_v2 as info { useStream `Stream' , alloca- `Status' peekEnum* , alloca- `Int64' peekIntConv*- , alloca- `Graph'- , alloca- `Node'- , alloca- `CSize'+ , withNullPtr- `Graph'+ , withNullPtr- `Node'+ , withNullPtr- `CSize' } -> `()' checkStatus*- #}+#else+{# fun unsafe cuStreamGetCaptureInfo_v3 as info+ { useStream `Stream'+ , alloca- `Status' peekEnum*+ , alloca- `Int64' peekIntConv*+ , withNullPtr- `Graph'+ , withNullPtr- `()'+ , withNullPtr- `Node'+ , withNullPtr- `CSize'+ }+ -> `()' checkStatus*- #} #endif+#endif -- | Set the stream capture interaction mode for this thread. Return the previous value.@@ -201,3 +219,5 @@ peekGraph = liftM Graph . peek #endif +withNullPtr :: (Ptr a -> r) -> r+withNullPtr f = f nullPtr
src/Foreign/CUDA/Driver/Marshal.chs view
@@ -358,6 +358,7 @@ go x _ = nothingIfOk =<< cuMemPrefetchAsync ptr (n * sizeOf x) (maybe (-1) useDevice mdev) (fromMaybe defaultStream mst) {-# INLINE cuMemPrefetchAsync #-}+#if CUDA_VERSION < 13000 {# fun unsafe cuMemPrefetchAsync { useDeviceHandle `DevicePtr a' , `Int'@@ -365,6 +366,15 @@ , useStream `Stream' } -> `Status' cToEnum #}+#else+{# fun unsafe cuMemPrefetchAsync_device as cuMemPrefetchAsync+ { useDeviceHandle `DevicePtr a'+ , `Int'+ , id `CInt'+ , useStream `Stream'+ }+ -> `Status' cToEnum #}+#endif #endif
src/Foreign/CUDA/Driver/Unified.chs view
@@ -258,6 +258,7 @@ go x _ = nothingIfOk =<< cuMemAdvise ptr (n * sizeOf x) a (maybe (-1) useDevice mdev) {-# INLINE cuMemAdvise #-}+#if CUDA_VERSION < 13000 {# fun unsafe cuMemAdvise { useHandle `Ptr a' , `Int'@@ -265,7 +266,15 @@ , `CInt' } -> `Status' cToEnum #}+#else+{# fun unsafe cuMemAdvise_device as cuMemAdvise+ { useHandle `Ptr a'+ , `Int'+ , cFromEnum `Advice'+ , `CInt'+ }+ -> `Status' cToEnum #}+#endif where useHandle = fromIntegral . ptrToIntPtr #endif-
+ src/Foreign/CUDA/Internal/Describe.hs view
@@ -0,0 +1,18 @@+--------------------------------------------------------------------------------+-- |+-- Module : Foreign.CUDA.Internal.Describe+-- Copyright : [2016..2023] Trevor L. McDonell+-- License : BSD+--+--------------------------------------------------------------------------------++module Foreign.CUDA.Internal.Describe+ where+++-- | Like 'Text.Show.Show', but focuses on providing a more detailed description+-- of the value rather than a 'Text.Read.read'able representation.+--+class Describe a where+ describe :: a -> String+
− src/Foreign/CUDA/Runtime.hs
@@ -1,28 +0,0 @@------------------------------------------------------------------------------------ |--- Module : Foreign.CUDA.Runtime--- Copyright : [2009..2023] Trevor L. McDonell--- License : BSD------ Top level bindings to the C-for-CUDA runtime API--------------------------------------------------------------------------------------module Foreign.CUDA.Runtime (-- module Foreign.CUDA.Ptr,- module Foreign.CUDA.Runtime.Device,- module Foreign.CUDA.Runtime.Error,- module Foreign.CUDA.Runtime.Exec,- module Foreign.CUDA.Runtime.Marshal,- module Foreign.CUDA.Runtime.Utils--) where--import Foreign.CUDA.Ptr-import Foreign.CUDA.Runtime.Device-import Foreign.CUDA.Runtime.Error-import Foreign.CUDA.Runtime.Exec-import Foreign.CUDA.Runtime.Marshal-import Foreign.CUDA.Runtime.Utils-
− src/Foreign/CUDA/Runtime/Device.chs
@@ -1,440 +0,0 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE EmptyDataDecls #-}-{-# LANGUAGE ForeignFunctionInterface #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE TemplateHaskell #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}-#ifdef USE_EMPTY_CASE-{-# LANGUAGE EmptyCase #-}-#endif------------------------------------------------------------------------------------ |--- Module : Foreign.CUDA.Runtime.Device--- Copyright : [2009..2023] Trevor L. McDonell--- License : BSD------ Device management routines--------------------------------------------------------------------------------------module Foreign.CUDA.Runtime.Device (-- -- * Device Management- Device, DeviceFlag(..), DeviceProperties(..), Compute(..), ComputeMode(..),- choose, get, count, props, set, setFlags, setOrder, reset, sync,-- -- * Peer Access- PeerFlag,- accessible, add, remove,-- -- * Cache Configuration- Limit(..),- getLimit, setLimit--) where--#include "cbits/stubs.h"-{# context lib="cudart" #}---- Friends-import Foreign.CUDA.Analysis.Device-import Foreign.CUDA.Runtime.Error-import Foreign.CUDA.Internal.C2HS---- System-import Control.Applicative-import Foreign-import Foreign.C-import Prelude--#c-typedef struct cudaDeviceProp cudaDeviceProp;--typedef enum-{- cudaDeviceFlagScheduleAuto = cudaDeviceScheduleAuto,- cudaDeviceFlagScheduleSpin = cudaDeviceScheduleSpin,- cudaDeviceFlagScheduleYield = cudaDeviceScheduleYield,- cudaDeviceFlagBlockingSync = cudaDeviceBlockingSync,- cudaDeviceFlagMapHost = cudaDeviceMapHost,-#if CUDART_VERSION >= 3000- cudaDeviceFlagLMemResizeToMax = cudaDeviceLmemResizeToMax-#endif-} cudaDeviceFlags;-#endc-------------------------------------------------------------------------------------- Data Types------------------------------------------------------------------------------------- |--- A device identifier----type Device = Int--{# pointer *cudaDeviceProp as ^ foreign -> DeviceProperties nocode #}---- |--- Device execution flags----{# enum cudaDeviceFlags as DeviceFlag { }- with prefix="cudaDeviceFlag" deriving (Eq, Show, Bounded) #}---instance Storable DeviceProperties where- sizeOf _ = {#sizeof cudaDeviceProp#}- alignment _ = alignment (undefined :: Ptr ())-- poke _ _ = error "no instance for Foreign.Storable.poke DeviceProperties"- peek p = do- deviceName <- peekCString =<< {#get cudaDeviceProp.name#} p- computeCapability <- Compute <$> (fromIntegral <$> {#get cudaDeviceProp.major#} p)- <*> (fromIntegral <$> {#get cudaDeviceProp.minor#} p)- totalGlobalMem <- cIntConv <$> {#get cudaDeviceProp.totalGlobalMem#} p- sharedMemPerBlock <- cIntConv <$> {#get cudaDeviceProp.sharedMemPerBlock#} p- regsPerBlock <- cIntConv <$> {#get cudaDeviceProp.regsPerBlock#} p- warpSize <- cIntConv <$> {#get cudaDeviceProp.warpSize#} p- memPitch <- cIntConv <$> {#get cudaDeviceProp.memPitch#} p- maxThreadsPerBlock <- cIntConv <$> {#get cudaDeviceProp.maxThreadsPerBlock#} p- clockRate <- cIntConv <$> {#get cudaDeviceProp.clockRate#} p- totalConstMem <- cIntConv <$> {#get cudaDeviceProp.totalConstMem#} p- textureAlignment <- cIntConv <$> {#get cudaDeviceProp.textureAlignment#} p- deviceOverlap <- cToBool <$> {#get cudaDeviceProp.deviceOverlap#} p- multiProcessorCount <- cIntConv <$> {#get cudaDeviceProp.multiProcessorCount#} p- kernelExecTimeoutEnabled <- cToBool <$> {#get cudaDeviceProp.kernelExecTimeoutEnabled#} p- integrated <- cToBool <$> {#get cudaDeviceProp.integrated#} p- canMapHostMemory <- cToBool <$> {#get cudaDeviceProp.canMapHostMemory#} p- computeMode <- cToEnum <$> {#get cudaDeviceProp.computeMode#} p-#if CUDART_VERSION >= 3000- concurrentKernels <- cToBool <$> {#get cudaDeviceProp.concurrentKernels#} p- maxTextureDim1D <- cIntConv <$> {#get cudaDeviceProp.maxTexture1D#} p-#endif-#if CUDART_VERSION >= 3000 && CUDART_VERSION < 3010- -- XXX: not visible from CUDA runtime API 3.0 (only accessible from the driver API)- let eccEnabled = False-#endif-#if CUDART_VERSION >= 3010- eccEnabled <- cToBool <$> {#get cudaDeviceProp.ECCEnabled#} p-#endif-#if CUDART_VERSION >= 4000- asyncEngineCount <- cIntConv <$> {#get cudaDeviceProp.asyncEngineCount#} p- cacheMemL2 <- cIntConv <$> {#get cudaDeviceProp.l2CacheSize#} p- maxThreadsPerMultiProcessor <- cIntConv <$> {#get cudaDeviceProp.maxThreadsPerMultiProcessor#} p- memBusWidth <- cIntConv <$> {#get cudaDeviceProp.memoryBusWidth#} p- memClockRate <- cIntConv <$> {#get cudaDeviceProp.memoryClockRate#} p- pciInfo <- PCI <$> (cIntConv <$> {#get cudaDeviceProp.pciBusID#} p)- <*> (cIntConv <$> {#get cudaDeviceProp.pciDeviceID#} p)- <*> (cIntConv <$> {#get cudaDeviceProp.pciDomainID#} p)- tccDriverEnabled <- cToBool <$> {#get cudaDeviceProp.tccDriver#} p- unifiedAddressing <- cToBool <$> {#get cudaDeviceProp.unifiedAddressing#} p-#endif- [t1,t2,t3] <- peekArrayWith cIntConv 3 =<< {#get cudaDeviceProp.maxThreadsDim#} p- [g1,g2,g3] <- peekArrayWith cIntConv 3 =<< {#get cudaDeviceProp.maxGridSize#} p- let maxBlockSize = (t1,t2,t3)- maxGridSize = (g1,g2,g3)-#if CUDART_VERSION >= 3000- [u21,u22] <- peekArrayWith cIntConv 2 =<< {#get cudaDeviceProp.maxTexture2D#} p- [u31,u32,u33] <- peekArrayWith cIntConv 3 =<< {#get cudaDeviceProp.maxTexture3D#} p- let maxTextureDim2D = (u21,u22)- maxTextureDim3D = (u31,u32,u33)-#endif-#if CUDART_VERSION >= 5050- streamPriorities <- cToBool <$> {#get cudaDeviceProp.streamPrioritiesSupported#} p-#endif-#if CUDART_VERSION >= 6000- globalL1Cache <- cToBool <$> {#get cudaDeviceProp.globalL1CacheSupported#} p- localL1Cache <- cToBool <$> {#get cudaDeviceProp.localL1CacheSupported#} p- managedMemory <- cToBool <$> {#get cudaDeviceProp.managedMemory#} p- multiGPUBoard <- cToBool <$> {#get cudaDeviceProp.isMultiGpuBoard#} p- multiGPUBoardGroupID <- cIntConv <$> {#get cudaDeviceProp.multiGpuBoardGroupID#} p-#endif-#if CUDART_VERSION >= 8000-#if CUDART_VERSION == 8000- -- XXX: Not visible from the CUDA runtime API 8.0 (only accessible from the driver API)- let preemption = False-#else- preemption <- cToBool <$> {#get cudaDeviceProp.computePreemptionSupported#} p-#endif- singleToDoublePerfRatio <- cIntConv <$> {#get cudaDeviceProp.singleToDoublePrecisionPerfRatio#} p-#endif-#if CUDART_VERSION >= 9000- cooperativeLaunch <- cToBool <$> {#get cudaDeviceProp.cooperativeLaunch#} p- cooperativeLaunchMultiDevice <- cToBool <$> {#get cudaDeviceProp.cooperativeMultiDeviceLaunch#} p-#endif-- return DeviceProperties{..}-------------------------------------------------------------------------------------- Device Management------------------------------------------------------------------------------------- |--- Select the compute device which best matches the given criteria----{-# INLINEABLE choose #-}-choose :: DeviceProperties -> IO Device-choose !dev = resultIfOk =<< cudaChooseDevice dev--{-# INLINE cudaChooseDevice #-}-{# fun unsafe cudaChooseDevice- { alloca- `Int' peekIntConv*- , withDevProp* `DeviceProperties' } -> `Status' cToEnum #}- where- withDevProp = with----- |--- Returns which device is currently being used----{-# INLINEABLE get #-}-get :: IO Device-get = resultIfOk =<< cudaGetDevice--{-# INLINE cudaGetDevice #-}-{# fun unsafe cudaGetDevice- { alloca- `Int' peekIntConv* } -> `Status' cToEnum #}----- |--- Returns the number of devices available for execution, with compute--- capability >= 1.0----{-# INLINEABLE count #-}-count :: IO Int-count = resultIfOk =<< cudaGetDeviceCount--{-# INLINE cudaGetDeviceCount #-}-{# fun unsafe cudaGetDeviceCount- { alloca- `Int' peekIntConv* } -> `Status' cToEnum #}----- |--- Return information about the selected compute device----{-# INLINEABLE props #-}-props :: Device -> IO DeviceProperties-props !n = resultIfOk =<< cudaGetDeviceProperties n--{-# INLINE cudaGetDeviceProperties #-}-#if CUDA_VERSION < 12000-{# fun unsafe cudaGetDeviceProperties- { alloca- `DeviceProperties' peek*- , `Int' } -> `Status' cToEnum #}-#else-{# fun unsafe cudaGetDeviceProperties_v2 as cudaGetDeviceProperties- { alloca- `DeviceProperties' peek*- , `Int' } -> `Status' cToEnum #}-#endif----- |--- Set device to be used for GPU execution----{-# INLINEABLE set #-}-set :: Device -> IO ()-set !n = nothingIfOk =<< cudaSetDevice n--{-# INLINE cudaSetDevice #-}-{# fun unsafe cudaSetDevice- { `Int' } -> `Status' cToEnum #}----- |--- Set flags to be used for device executions----{-# INLINEABLE setFlags #-}-setFlags :: [DeviceFlag] -> IO ()-setFlags !f = nothingIfOk =<< cudaSetDeviceFlags (combineBitMasks f)--{-# INLINE cudaSetDeviceFlags #-}-{# fun unsafe cudaSetDeviceFlags- { `Int' } -> `Status' cToEnum #}----- |--- Set list of devices for CUDA execution in priority order----{-# INLINEABLE setOrder #-}-setOrder :: [Device] -> IO ()-setOrder !l = nothingIfOk =<< cudaSetValidDevices l (length l)--{-# INLINE cudaSetValidDevices #-}-{# fun unsafe cudaSetValidDevices- { withArrayIntConv* `[Int]'- , `Int' } -> `Status' cToEnum #}- where- withArrayIntConv = withArray . map cIntConv---- |--- Block until the device has completed all preceding requested tasks. Returns--- an error if one of the tasks fails.----{-# INLINEABLE sync #-}-sync :: IO ()-#if CUDART_VERSION < 4000-{-# INLINE cudaThreadSynchronize #-}-sync = nothingIfOk =<< cudaThreadSynchronize-{# fun cudaThreadSynchronize { } -> `Status' cToEnum #}-#else-{-# INLINE cudaDeviceSynchronize #-}-sync = nothingIfOk =<< cudaDeviceSynchronize-{# fun cudaDeviceSynchronize { } -> `Status' cToEnum #}-#endif---- |--- Explicitly destroys and cleans up all runtime resources associated with the--- current device in the current process. Any subsequent API call will--- reinitialise the device.------ Note that this function will reset the device immediately. It is the caller’s--- responsibility to ensure that the device is not being accessed by any other--- host threads from the process when this function is called.----{-# INLINEABLE reset #-}-reset :: IO ()-#if CUDART_VERSION >= 4000-{-# INLINE cudaDeviceReset #-}-reset = nothingIfOk =<< cudaDeviceReset-{# fun unsafe cudaDeviceReset { } -> `Status' cToEnum #}-#else-{-# INLINE cudaThreadExit #-}-reset = nothingIfOk =<< cudaThreadExit-{# fun unsafe cudaThreadExit { } -> `Status' cToEnum #}-#endif-------------------------------------------------------------------------------------- Peer Access------------------------------------------------------------------------------------- |--- Possible option values for direct peer memory access----data PeerFlag-instance Enum PeerFlag where-#ifdef USE_EMPTY_CASE- toEnum x = error ("PeerFlag.toEnum: Cannot match " ++ show x)- fromEnum x = case x of {}-#endif---- |--- Queries if the first device can directly access the memory of the second. If--- direct access is possible, it can then be enabled with 'add'. Requires--- cuda-4.0.----{-# INLINEABLE accessible #-}-accessible :: Device -> Device -> IO Bool-#if CUDART_VERSION < 4000-accessible _ _ = requireSDK 'accessible 4.0-#else-accessible !dev !peer = resultIfOk =<< cudaDeviceCanAccessPeer dev peer--{-# INLINE cudaDeviceCanAccessPeer #-}-{# fun unsafe cudaDeviceCanAccessPeer- { alloca- `Bool' peekBool*- , cIntConv `Device'- , cIntConv `Device' } -> `Status' cToEnum #}-#endif---- |--- If the devices of both the current and supplied contexts support unified--- addressing, then enable allocations in the supplied context to be accessible--- by the current context. Requires cuda-4.0.----{-# INLINEABLE add #-}-add :: Device -> [PeerFlag] -> IO ()-#if CUDART_VERSION < 4000-add _ _ = requireSDK 'add 4.0-#else-add !dev !flags = nothingIfOk =<< cudaDeviceEnablePeerAccess dev flags--{-# INLINE cudaDeviceEnablePeerAccess #-}-{# fun unsafe cudaDeviceEnablePeerAccess- { cIntConv `Device'- , combineBitMasks `[PeerFlag]' } -> `Status' cToEnum #}-#endif----- |--- Disable direct memory access from the current context to the supplied--- context. Requires cuda-4.0.----{-# INLINEABLE remove #-}-remove :: Device -> IO ()-#if CUDART_VERSION < 4000-remove _ = requireSDK 'remove 4.0-#else-remove !dev = nothingIfOk =<< cudaDeviceDisablePeerAccess dev--{-# INLINE cudaDeviceDisablePeerAccess #-}-{# fun unsafe cudaDeviceDisablePeerAccess- { cIntConv `Device' } -> `Status' cToEnum #}-#endif-------------------------------------------------------------------------------------- Cache Configuration------------------------------------------------------------------------------------- |--- Device limit flags----#if CUDART_VERSION < 3010-data Limit-#else-{# enum cudaLimit as Limit- { underscoreToCase }- with prefix="cudaLimit" deriving (Eq, Show) #}-#endif----- |--- Query compute 2.0 call stack limits. Requires cuda-3.1.----{-# INLINEABLE getLimit #-}-getLimit :: Limit -> IO Int-#if CUDART_VERSION < 3010-getLimit _ = requireSDK 'getLimit 3.1-#elif CUDART_VERSION < 4000-getLimit !l = resultIfOk =<< cudaThreadGetLimit l--{-# INLINE cudaThreadGetLimit #-}-{# fun unsafe cudaThreadGetLimit- { alloca- `Int' peekIntConv*- , cFromEnum `Limit' } -> `Status' cToEnum #}-#else-getLimit !l = resultIfOk =<< cudaDeviceGetLimit l--{-# INLINE cudaDeviceGetLimit #-}-{# fun unsafe cudaDeviceGetLimit- { alloca- `Int' peekIntConv*- , cFromEnum `Limit' } -> `Status' cToEnum #}-#endif----- |--- Set compute 2.0 call stack limits. Requires cuda-3.1.----{-# INLINEABLE setLimit #-}-setLimit :: Limit -> Int -> IO ()-#if CUDART_VERSION < 3010-setLimit _ _ = requireSDK 'setLimit 3.1-#elif CUDART_VERSION < 4000-setLimit !l !n = nothingIfOk =<< cudaThreadSetLimit l n--{-# INLINE cudaThreadSetLimit #-}-{# fun unsafe cudaThreadSetLimit- { cFromEnum `Limit'- , cIntConv `Int' } -> `Status' cToEnum #}-#else-setLimit !l !n = nothingIfOk =<< cudaDeviceSetLimit l n--{-# INLINE cudaDeviceSetLimit #-}-{# fun unsafe cudaDeviceSetLimit- { cFromEnum `Limit'- , cIntConv `Int' } -> `Status' cToEnum #}-#endif-
− src/Foreign/CUDA/Runtime/Error.chs
@@ -1,123 +0,0 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE ForeignFunctionInterface #-}------------------------------------------------------------------------------------ |--- Module : Foreign.CUDA.Runtime.Error--- Copyright : [2009..2023] Trevor L. McDonell--- License : BSD------ Error handling functions--------------------------------------------------------------------------------------module Foreign.CUDA.Runtime.Error (-- Status(..), CUDAException(..),-- cudaError, describe, requireSDK,- resultIfOk, nothingIfOk, checkStatus,--) where---- Friends-import Foreign.CUDA.Internal.C2HS-import Text.Show.Describe---- System-import Control.Exception-import Data.Typeable-import Foreign.C-import Foreign.Ptr-import Language.Haskell.TH-import System.IO.Unsafe-import Text.Printf--#include "cbits/stubs.h"-{# context lib="cudart" #}-------------------------------------------------------------------------------------- Return Status------------------------------------------------------------------------------------- |--- Return codes from API functions----{# enum cudaError as Status- { cudaSuccess as Success }- with prefix="cudaError" deriving (Eq, Show) #}------------------------------------------------------------------------------------- Exceptions-----------------------------------------------------------------------------------data CUDAException- = ExitCode Status- | UserError String- deriving Typeable--instance Exception CUDAException--instance Show CUDAException where- showsPrec _ (ExitCode s) = showString ("CUDA Exception: " ++ describe s)- showsPrec _ (UserError s) = showString ("CUDA Exception: " ++ s)----- |--- Raise a 'CUDAException' in the IO Monad----cudaError :: String -> IO a-cudaError s = throwIO (UserError s)---- |--- A specially formatted error message----requireSDK :: Name -> Double -> IO a-requireSDK n v = cudaError $ printf "'%s' requires at least cuda-%3.1f\n" (show n) v-------------------------------------------------------------------------------------- Helper Functions------------------------------------------------------------------------------------- |--- Return the descriptive string associated with a particular error code----instance Describe Status where- describe = cudaGetErrorString---- Logically, this must be a pure function, returning a pointer to a statically--- defined string constant.----{# fun pure unsafe cudaGetErrorString- { cFromEnum `Status' } -> `String' #}----- |--- Return the results of a function on successful execution, otherwise return--- the error string associated with the return code----{-# INLINE resultIfOk #-}-resultIfOk :: (Status, a) -> IO a-resultIfOk (status, !result) =- case status of- Success -> return result- _ -> throwIO (ExitCode status)----- |--- Return the error string associated with an unsuccessful return code,--- otherwise Nothing----{-# INLINE nothingIfOk #-}-nothingIfOk :: Status -> IO ()-nothingIfOk status =- case status of- Success -> return ()- _ -> throwIO (ExitCode status)--{-# INLINE checkStatus #-}-checkStatus :: CInt -> IO ()-checkStatus = nothingIfOk . cToEnum-
− src/Foreign/CUDA/Runtime/Event.chs
@@ -1,149 +0,0 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE EmptyDataDecls #-}-{-# LANGUAGE ForeignFunctionInterface #-}-{-# LANGUAGE TemplateHaskell #-}------------------------------------------------------------------------------------ |--- Module : Foreign.CUDA.Driver.Event--- Copyright : [2009..2023] Trevor L. McDonell--- License : BSD------ Event management for C-for-CUDA runtime environment--------------------------------------------------------------------------------------module Foreign.CUDA.Runtime.Event (-- -- * Event Management- Event, EventFlag(..), WaitFlag,- create, destroy, elapsedTime, query, record, wait, block--) where--#include "cbits/stubs.h"-{# context lib="cudart" #}---- Friends-import Foreign.CUDA.Driver.Event ( Event(..), EventFlag(..), WaitFlag )-import Foreign.CUDA.Driver.Stream ( Stream(..), defaultStream )-import Foreign.CUDA.Internal.C2HS-import Foreign.CUDA.Runtime.Error---- System-import Foreign-import Foreign.C-import Control.Monad ( liftM )-import Control.Exception ( throwIO )-import Data.Maybe ( fromMaybe )-------------------------------------------------------------------------------------- Event management------------------------------------------------------------------------------------- |--- Create a new event----{-# INLINEABLE create #-}-create :: [EventFlag] -> IO Event-create !flags = resultIfOk =<< cudaEventCreateWithFlags flags--{-# INLINE cudaEventCreateWithFlags #-}-{# fun unsafe cudaEventCreateWithFlags- { alloca- `Event' peekEvt*- , combineBitMasks `[EventFlag]' } -> `Status' cToEnum #}- where peekEvt = liftM Event . peek----- |--- Destroy an event----{-# INLINEABLE destroy #-}-destroy :: Event -> IO ()-destroy !ev = nothingIfOk =<< cudaEventDestroy ev--{-# INLINE cudaEventDestroy #-}-{# fun unsafe cudaEventDestroy- { useEvent `Event' } -> `Status' cToEnum #}----- |--- Determine the elapsed time (in milliseconds) between two events----{-# INLINEABLE elapsedTime #-}-elapsedTime :: Event -> Event -> IO Float-elapsedTime !ev1 !ev2 = resultIfOk =<< cudaEventElapsedTime ev1 ev2--{-# INLINE cudaEventElapsedTime #-}-{# fun unsafe cudaEventElapsedTime- { alloca- `Float' peekFloatConv*- , useEvent `Event'- , useEvent `Event' } -> `Status' cToEnum #}----- |--- Determines if a event has actually been recorded----{-# INLINEABLE query #-}-query :: Event -> IO Bool-query !ev =- cudaEventQuery ev >>= \rv ->- case rv of- Success -> return True- NotReady -> return False- _ -> throwIO (ExitCode rv)--{-# INLINE cudaEventQuery #-}-{# fun unsafe cudaEventQuery- { useEvent `Event' } -> `Status' cToEnum #}----- |--- Record an event once all operations in the current context (or optionally--- specified stream) have completed. This operation is asynchronous.----{-# INLINEABLE record #-}-record :: Event -> Maybe Stream -> IO ()-record !ev !mst =- nothingIfOk =<< cudaEventRecord ev (maybe defaultStream id mst)--{-# INLINE cudaEventRecord #-}-{# fun unsafe cudaEventRecord- { useEvent `Event'- , useStream `Stream' } -> `Status' cToEnum #}----- |--- Makes all future work submitted to the (optional) stream wait until the given--- event reports completion before beginning execution. Synchronisation is--- performed on the device, including when the event and stream are from--- different device contexts. Requires cuda-3.2.----{-# INLINEABLE wait #-}-wait :: Event -> Maybe Stream -> [WaitFlag] -> IO ()-#if CUDART_VERSION < 3020-wait _ _ _ = requireSDK 'wait 3.2-#else-wait !ev !mst !flags =- let st = fromMaybe defaultStream mst- in nothingIfOk =<< cudaStreamWaitEvent st ev flags--{-# INLINE cudaStreamWaitEvent #-}-{# fun unsafe cudaStreamWaitEvent- { useStream `Stream'- , useEvent `Event'- , combineBitMasks `[WaitFlag]' } -> `Status' cToEnum #}-#endif---- |--- Wait until the event has been recorded----{-# INLINEABLE block #-}-block :: Event -> IO ()-block !ev = nothingIfOk =<< cudaEventSynchronize ev--{-# INLINE cudaEventSynchronize #-}-{# fun cudaEventSynchronize- { useEvent `Event' } -> `Status' cToEnum #}-
− src/Foreign/CUDA/Runtime/Exec.chs
@@ -1,294 +0,0 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE ForeignFunctionInterface #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE TemplateHaskell #-}------------------------------------------------------------------------------------ |--- Module : Foreign.CUDA.Runtime.Exec--- Copyright : [2009..2023] Trevor L. McDonell--- License : BSD------ Kernel execution control for C-for-CUDA runtime interface--------------------------------------------------------------------------------------module Foreign.CUDA.Runtime.Exec (-- -- * Kernel Execution- Fun, FunAttributes(..), FunParam(..), CacheConfig(..),- attributes, setCacheConfig, launchKernel,--) where--#include "cbits/stubs.h"-{# context lib="cudart" #}---- Friends-import Foreign.CUDA.Runtime.Stream ( Stream(..), defaultStream )-import Foreign.CUDA.Runtime.Error-import Foreign.CUDA.Internal.C2HS---- System-import Foreign-import Foreign.C-import Control.Monad-import Data.Maybe--#c-typedef struct cudaFuncAttributes cudaFuncAttributes;-#endc-------------------------------------------------------------------------------------- Data Types------------------------------------------------------------------------------------- |--- A @__global__@ device function.------ Note that the use of a string naming a function was deprecated in CUDA 4.1--- and removed in CUDA 5.0.----#if CUDART_VERSION >= 5000-type Fun = FunPtr ()-#else-type Fun = String-#endif-------- Function Attributes----{# pointer *cudaFuncAttributes as ^ foreign -> FunAttributes nocode #}--data FunAttributes = FunAttributes- {- constSizeBytes :: !Int64,- localSizeBytes :: !Int64,- sharedSizeBytes :: !Int64,- maxKernelThreadsPerBlock :: !Int, -- ^ maximum block size that can be successively launched (based on register usage)- numRegs :: !Int -- ^ number of registers required for each thread- }- deriving (Show)--instance Storable FunAttributes where- sizeOf _ = {# sizeof cudaFuncAttributes #}- alignment _ = alignment (undefined :: Ptr ())-- poke _ _ = error "Can not poke Foreign.CUDA.Runtime.FunAttributes"- peek p = do- cs <- cIntConv `fmap` {#get cudaFuncAttributes.constSizeBytes#} p- ls <- cIntConv `fmap` {#get cudaFuncAttributes.localSizeBytes#} p- ss <- cIntConv `fmap` {#get cudaFuncAttributes.sharedSizeBytes#} p- tb <- cIntConv `fmap` {#get cudaFuncAttributes.maxThreadsPerBlock#} p- nr <- cIntConv `fmap` {#get cudaFuncAttributes.numRegs#} p-- return FunAttributes- {- constSizeBytes = cs,- localSizeBytes = ls,- sharedSizeBytes = ss,- maxKernelThreadsPerBlock = tb,- numRegs = nr- }--#if CUDART_VERSION < 3000-data CacheConfig-#else--- |--- Cache configuration preference----{# enum cudaFuncCache as CacheConfig- { }- with prefix="cudaFuncCachePrefer" deriving (Eq, Show) #}-#endif---- |--- Kernel function parameters. Doubles will be converted to an internal float--- representation on devices that do not support doubles natively.----data FunParam where- IArg :: !Int -> FunParam- FArg :: !Float -> FunParam- DArg :: !Double -> FunParam- VArg :: Storable a => !a -> FunParam-------------------------------------------------------------------------------------- Execution Control------------------------------------------------------------------------------------- |--- Obtain the attributes of the named @__global__@ device function. This--- itemises the requirements to successfully launch the given kernel.----{-# INLINEABLE attributes #-}-attributes :: Fun -> IO FunAttributes-attributes !fn = resultIfOk =<< cudaFuncGetAttributes fn--{-# INLINE cudaFuncGetAttributes #-}-{# fun unsafe cudaFuncGetAttributes- { alloca- `FunAttributes' peek*- , withFun* `Fun' } -> `Status' cToEnum #}----- |--- On devices where the L1 cache and shared memory use the same hardware--- resources, this sets the preferred cache configuration for the given device--- function. This is only a preference; the driver is free to choose a different--- configuration as required to execute the function.------ Switching between configuration modes may insert a device-side--- synchronisation point for streamed kernel launches----{-# INLINEABLE setCacheConfig #-}-setCacheConfig :: Fun -> CacheConfig -> IO ()-#if CUDART_VERSION < 3000-setCacheConfig _ _ = requireSDK 'setCacheConfig 3.0-#else-setCacheConfig !fn !pref = nothingIfOk =<< cudaFuncSetCacheConfig fn pref--{-# INLINE cudaFuncSetCacheConfig #-}-{# fun unsafe cudaFuncSetCacheConfig- { withFun* `Fun'- , cFromEnum `CacheConfig' } -> `Status' cToEnum #}-#endif----- |--- Invoke a kernel on a @(gx * gy)@ grid of blocks, where each block contains--- @(tx * ty * tz)@ threads and has access to a given number of bytes of shared--- memory. The launch may also be associated with a specific 'Stream'.----{-# INLINEABLE launchKernel #-}-launchKernel- :: Fun -- ^ Device function symbol- -> (Int,Int) -- ^ grid dimensions- -> (Int,Int,Int) -- ^ thread block shape- -> Int64 -- ^ shared memory per block (bytes)- -> Maybe Stream -- ^ (optional) execution stream- -> [FunParam]- -> IO ()-#if CUDART_VERSION >= 7000-launchKernel !fn (!gx,!gy) (!bx,!by,!bz) !sm !mst !args- = (=<<) nothingIfOk- $ withMany withFP args- $ \pa -> withArray pa- $ \pp -> cudaLaunchKernel_simple fn gx gy 1 bx by bz pp sm (fromMaybe defaultStream mst)- where- withFP :: FunParam -> (Ptr FunParam -> IO b) -> IO b- withFP p f = case p of- IArg v -> with' v (f . castPtr)- FArg v -> with' v (f . castPtr)- DArg v -> with' v (f . castPtr)- VArg v -> with' v (f . castPtr)-- with' :: Storable a => a -> (Ptr a -> IO b) -> IO b- with' !val !f =- allocaBytes (sizeOf val) $ \ptr -> do- poke ptr val- f ptr--{-# INLINE cudaLaunchKernel_simple #-}-{# fun unsafe cudaLaunchKernel_simple- { withFun* `Fun'- , `Int', `Int', `Int'- , `Int', `Int', `Int'- , castPtr `Ptr (Ptr FunParam)'- , `Int64'- , useStream `Stream'- }- -> `Status' cToEnum #}--#else-launchKernel !fn (!gx,!gy) (!bx,!by,!bz) !sm !mst !args = do- setConfig gx gy bx by bz sm (fromMaybe defaultStream mst)- setParams args- launch fn----- Invoke the @__global__@ kernel function on the device. This must be preceded--- by a call to 'setConfig' and (if appropriate) 'setParams'.----{-# INLINE launch #-}-{# fun unsafe cudaLaunch as launch- { withFun* `Fun' } -> `()' checkStatus*- #}----- Specify the grid and block dimensions for a device call. Used in conjunction--- with 'setParams', this pushes data onto the execution stack that will be--- popped when a function is 'launch'ed.------ The FFI does not support passing deferenced structures to C functions, as--- this is highly platform/compiler dependent. Wrap our own function stub--- accepting plain integers.----{-# INLINE setConfig #-}-{# fun unsafe cudaConfigureCall_simple as setConfig- { `Int', `Int'- , `Int', `Int', `Int'- , cIntConv `Int64'- , useStream `Stream'- }- -> `()' checkStatus*- #}---- |--- Set the argument parameters that will be passed to the next kernel--- invocation. This is used in conjunction with 'setConfig' to control kernel--- execution.----{-# INLINEABLE setParams #-}-setParams :: [FunParam] -> IO ()-setParams = foldM_ k 0- where- k !offset !arg = do- let s = size arg- set arg s offset- return (offset + s)-- size (IArg _) = sizeOf (undefined :: Int)- size (FArg _) = sizeOf (undefined :: Float)- size (DArg _) = sizeOf (undefined :: Double)- size (VArg a) = sizeOf a-- set (IArg v) s o = cudaSetupArgument v s o- set (FArg v) s o = cudaSetupArgument v s o- set (VArg v) s o = cudaSetupArgument v s o- set (DArg v) s o = do- d <- cudaSetDoubleForDevice v- cudaSetupArgument d s o--{-# INLINE cudaSetupArgument #-}-{# fun unsafe cudaSetupArgument- `Storable a' =>- { with'* `a'- , `Int'- , `Int'- }- -> `()' checkStatus*- #}- where- with' v a = with v $ \p -> a (castPtr p)--{-# INLINE cudaSetDoubleForDevice #-}-{# fun unsafe cudaSetDoubleForDevice- { with'* `Double' peek'* } -> `()' checkStatus*- #}- where- with' v a = with v $ \p -> a (castPtr p)- peek' = peek . castPtr-#endif------------------------------------------------------------------------------------- Internals------------------------------------------------------------------------------------- CUDA 5.0 changed the type of a kernel function from char* to void*----#if CUDART_VERSION >= 5000-withFun :: Fun -> (Ptr a -> IO b) -> IO b-withFun fn action = action (castFunPtrToPtr fn)-#else-withFun :: Fun -> (Ptr CChar -> IO a) -> IO a-withFun = withCString-#endif-
− src/Foreign/CUDA/Runtime/Marshal.chs
@@ -1,648 +0,0 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE EmptyDataDecls #-}-{-# LANGUAGE ForeignFunctionInterface #-}-{-# LANGUAGE TemplateHaskell #-}------------------------------------------------------------------------------------ |--- Module : Foreign.CUDA.Runtime.Marshal--- Copyright : [2009..2023] Trevor L. McDonell--- License : BSD------ Memory management for CUDA devices--------------------------------------------------------------------------------------module Foreign.CUDA.Runtime.Marshal (-- -- * Host Allocation- AllocFlag(..),- mallocHostArray, freeHost,-- -- * Device Allocation- mallocArray, allocaArray, free,-- -- * Unified Memory Allocation- AttachFlag(..),- mallocManagedArray,-- -- * Marshalling- peekArray, peekArrayAsync, peekArray2D, peekArray2DAsync, peekListArray,- pokeArray, pokeArrayAsync, pokeArray2D, pokeArray2DAsync, pokeListArray,- copyArray, copyArrayAsync, copyArray2D, copyArray2DAsync,-- -- * Combined Allocation and Marshalling- newListArray, newListArrayLen,- withListArray, withListArrayLen,-- -- * Utility- memset--) where--#include "cbits/stubs.h"-{# context lib="cudart" #}---- Friends-import Foreign.CUDA.Ptr-import Foreign.CUDA.Runtime.Error-import Foreign.CUDA.Runtime.Stream-import Foreign.CUDA.Internal.C2HS---- System-import Data.Int-import Data.Maybe-import Control.Exception--import Foreign.C-import Foreign.Ptr-import Foreign.Storable-import qualified Foreign.Marshal as F--#c-typedef enum cudaMemHostAlloc_option_enum {-// CUDA_MEMHOSTALLOC_OPTION_DEFAULT = cudaHostAllocDefault,- CUDA_MEMHOSTALLOC_OPTION_DEVICE_MAPPED = cudaHostAllocMapped,- CUDA_MEMHOSTALLOC_OPTION_PORTABLE = cudaHostAllocPortable,- CUDA_MEMHOSTALLOC_OPTION_WRITE_COMBINED = cudaHostAllocWriteCombined-} cudaMemHostAlloc_option;-#endc--#if CUDART_VERSION >= 6000-#c-typedef enum cudaMemAttachFlags_option_enum {- CUDA_MEM_ATTACH_OPTION_GLOBAL = cudaMemAttachGlobal,- CUDA_MEM_ATTACH_OPTION_HOST = cudaMemAttachHost,- CUDA_MEM_ATTACH_OPTION_SINGLE = cudaMemAttachSingle-} cudaMemAttachFlags_option;-#endc-#endif-------------------------------------------------------------------------------------- Host Allocation------------------------------------------------------------------------------------- |--- Options for host allocation----{# enum cudaMemHostAlloc_option as AllocFlag- { underscoreToCase }- with prefix="CUDA_MEMHOSTALLOC_OPTION" deriving (Eq, Show, Bounded) #}----- |--- Allocate a section of linear memory on the host which is page-locked and--- directly accessible from the device. The storage is sufficient to hold the--- given number of elements of a storable type. The runtime system automatically--- accelerates calls to functions such as 'peekArrayAsync' and 'pokeArrayAsync'--- that refer to page-locked memory.------ Note that since the amount of pageable memory is thusly reduced, overall--- system performance may suffer. This is best used sparingly to allocate--- staging areas for data exchange----{-# INLINEABLE mallocHostArray #-}-mallocHostArray :: Storable a => [AllocFlag] -> Int -> IO (HostPtr a)-mallocHostArray !flags = doMalloc undefined- where- doMalloc :: Storable a' => a' -> Int -> IO (HostPtr a')- doMalloc x !n = resultIfOk =<< cudaHostAlloc (fromIntegral n * fromIntegral (sizeOf x)) flags--{-# INLINE cudaHostAlloc #-}-{# fun unsafe cudaHostAlloc- { alloca'- `HostPtr a' hptr*- , cIntConv `Int64'- , combineBitMasks `[AllocFlag]' } -> `Status' cToEnum #}- where- alloca' !f = F.alloca $ \ !p -> poke p nullPtr >> f (castPtr p)- hptr !p = (HostPtr . castPtr) `fmap` peek p----- |--- Free page-locked host memory previously allocated with 'mallecHost'----{-# INLINEABLE freeHost #-}-freeHost :: HostPtr a -> IO ()-freeHost !p = nothingIfOk =<< cudaFreeHost p--{-# INLINE cudaFreeHost #-}-{# fun unsafe cudaFreeHost- { hptr `HostPtr a' } -> `Status' cToEnum #}- where hptr = castPtr . useHostPtr-------------------------------------------------------------------------------------- Device Allocation------------------------------------------------------------------------------------- |--- Allocate a section of linear memory on the device, and return a reference to--- it. The memory is sufficient to hold the given number of elements of storable--- type. It is suitable aligned, and not cleared.----{-# INLINEABLE mallocArray #-}-mallocArray :: Storable a => Int -> IO (DevicePtr a)-mallocArray = doMalloc undefined- where- doMalloc :: Storable a' => a' -> Int -> IO (DevicePtr a')- doMalloc x !n = resultIfOk =<< cudaMalloc (fromIntegral n * fromIntegral (sizeOf x))--{-# INLINE cudaMalloc #-}-{# fun unsafe cudaMalloc- { alloca'- `DevicePtr a' dptr*- , cIntConv `Int64' } -> `Status' cToEnum #}- where- -- C-> Haskell doesn't like qualified imports in marshaller specifications- alloca' !f = F.alloca $ \ !p -> poke p nullPtr >> f (castPtr p)- dptr !p = (castDevPtr . DevicePtr) `fmap` peek p----- |--- Execute a computation, passing a pointer to a temporarily allocated block of--- memory sufficient to hold the given number of elements of storable type. The--- memory is freed when the computation terminates (normally or via an--- exception), so the pointer must not be used after this.------ Note that kernel launches can be asynchronous, so you may need to add a--- synchronisation point at the end of the computation.----{-# INLINEABLE allocaArray #-}-allocaArray :: Storable a => Int -> (DevicePtr a -> IO b) -> IO b-allocaArray n = bracket (mallocArray n) free----- |--- Free previously allocated memory on the device----{-# INLINEABLE free #-}-free :: DevicePtr a -> IO ()-free !p = nothingIfOk =<< cudaFree p--{-# INLINE cudaFree #-}-{# fun unsafe cudaFree- { dptr `DevicePtr a' } -> `Status' cToEnum #}- where- dptr = useDevicePtr . castDevPtr-------------------------------------------------------------------------------------- Unified memory allocation------------------------------------------------------------------------------------- |--- Options for unified memory allocations----#if CUDART_VERSION >= 6000-{# enum cudaMemAttachFlags_option as AttachFlag- { underscoreToCase }- with prefix="CUDA_MEM_ATTACH_OPTION" deriving (Eq, Show, Bounded) #}-#else-data AttachFlag-#endif---- |--- Allocates memory that will be automatically managed by the Unified Memory--- system----{-# INLINEABLE mallocManagedArray #-}-mallocManagedArray :: Storable a => [AttachFlag] -> Int -> IO (DevicePtr a)-#if CUDART_VERSION < 6000-mallocManagedArray _ _ = requireSDK 'mallocManagedArray 6.0-#else-mallocManagedArray !flags = doMalloc undefined- where- doMalloc :: Storable a' => a' -> Int -> IO (DevicePtr a')- doMalloc x !n = resultIfOk =<< cudaMallocManaged (fromIntegral n * fromIntegral (sizeOf x)) flags--{-# INLINE cudaMallocManaged #-}-{# fun unsafe cudaMallocManaged- { alloca'- `DevicePtr a' dptr*- , cIntConv `Int64'- , combineBitMasks `[AttachFlag]' } -> `Status' cToEnum #}- where- alloca' !f = F.alloca $ \ !p -> poke p nullPtr >> f (castPtr p)- dptr !p = (castDevPtr . DevicePtr) `fmap` peek p-#endif-------------------------------------------------------------------------------------- Marshalling------------------------------------------------------------------------------------- |--- Copy a number of elements from the device to host memory. This is a--- synchronous operation.----{-# INLINEABLE peekArray #-}-peekArray :: Storable a => Int -> DevicePtr a -> Ptr a -> IO ()-peekArray !n !dptr !hptr = memcpy hptr (useDevicePtr dptr) n DeviceToHost----- |--- Copy memory from the device asynchronously, possibly associated with a--- particular stream. The destination memory must be page locked.----{-# INLINEABLE peekArrayAsync #-}-peekArrayAsync :: Storable a => Int -> DevicePtr a -> HostPtr a -> Maybe Stream -> IO ()-peekArrayAsync !n !dptr !hptr !mst =- memcpyAsync (useHostPtr hptr) (useDevicePtr dptr) n DeviceToHost mst----- |--- Copy a 2D memory area from the device to the host. This is a synchronous--- operation.----{-# INLINEABLE peekArray2D #-}-peekArray2D- :: Storable a- => Int -- ^ width to copy (elements)- -> Int -- ^ height to copy (elements)- -> DevicePtr a -- ^ source array- -> Int -- ^ source array width- -> Ptr a -- ^ destination array- -> Int -- ^ destination array width- -> IO ()-peekArray2D !w !h !dptr !dw !hptr !hw =- memcpy2D hptr hw (useDevicePtr dptr) dw w h DeviceToHost----- |--- Copy a 2D memory area from the device to the host asynchronously, possibly--- associated with a particular stream. The destination array must be page--- locked.----{-# INLINEABLE peekArray2DAsync #-}-peekArray2DAsync- :: Storable a- => Int -- ^ width to copy (elements)- -> Int -- ^ height to copy (elements)- -> DevicePtr a -- ^ source array- -> Int -- ^ source array width- -> HostPtr a -- ^ destination array- -> Int -- ^ destination array width- -> Maybe Stream- -> IO ()-peekArray2DAsync !w !h !dptr !dw !hptr !hw !mst =- memcpy2DAsync (useHostPtr hptr) hw (useDevicePtr dptr) dw w h DeviceToHost mst----- |--- Copy a number of elements from the device into a new Haskell list. Note that--- this requires two memory copies: firstly from the device into a heap--- allocated array, and from there marshalled into a list----{-# INLINEABLE peekListArray #-}-peekListArray :: Storable a => Int -> DevicePtr a -> IO [a]-peekListArray !n !dptr =- F.allocaArray n $ \p -> do- peekArray n dptr p- F.peekArray n p----- |--- Copy a number of elements onto the device. This is a synchronous operation.----{-# INLINEABLE pokeArray #-}-pokeArray :: Storable a => Int -> Ptr a -> DevicePtr a -> IO ()-pokeArray !n !hptr !dptr = memcpy (useDevicePtr dptr) hptr n HostToDevice----- |--- Copy memory onto the device asynchronously, possibly associated with a--- particular stream. The source memory must be page-locked.----{-# INLINEABLE pokeArrayAsync #-}-pokeArrayAsync :: Storable a => Int -> HostPtr a -> DevicePtr a -> Maybe Stream -> IO ()-pokeArrayAsync !n !hptr !dptr !mst =- memcpyAsync (useDevicePtr dptr) (useHostPtr hptr) n HostToDevice mst----- |--- Copy a 2D memory area onto the device. This is a synchronous operation.----{-# INLINEABLE pokeArray2D #-}-pokeArray2D- :: Storable a- => Int -- ^ width to copy (elements)- -> Int -- ^ height to copy (elements)- -> Ptr a -- ^ source array- -> Int -- ^ source array width- -> DevicePtr a -- ^ destination array- -> Int -- ^ destination array width- -> IO ()-pokeArray2D !w !h !hptr !dw !dptr !hw =- memcpy2D (useDevicePtr dptr) dw hptr hw w h HostToDevice----- |--- Copy a 2D memory area onto the device asynchronously, possibly associated--- with a particular stream. The source array must be page locked.----{-# INLINEABLE pokeArray2DAsync #-}-pokeArray2DAsync- :: Storable a- => Int -- ^ width to copy (elements)- -> Int -- ^ height to copy (elements)- -> HostPtr a -- ^ source array- -> Int -- ^ source array width- -> DevicePtr a -- ^ destination array- -> Int -- ^ destination array width- -> Maybe Stream- -> IO ()-pokeArray2DAsync !w !h !hptr !hw !dptr !dw !mst =- memcpy2DAsync (useDevicePtr dptr) dw (useHostPtr hptr) hw w h HostToDevice mst---- |--- Write a list of storable elements into a device array. The array must be--- sufficiently large to hold the entire list. This requires two marshalling--- operations----{-# INLINEABLE pokeListArray #-}-pokeListArray :: Storable a => [a] -> DevicePtr a -> IO ()-pokeListArray !xs !dptr = F.withArrayLen xs $ \len p -> pokeArray len p dptr----- |--- Copy the given number of elements from the first device array (source) to the--- second (destination). The copied areas may not overlap. This operation is--- asynchronous with respect to host, but will not overlap other device--- operations.----{-# INLINEABLE copyArray #-}-copyArray :: Storable a => Int -> DevicePtr a -> DevicePtr a -> IO ()-copyArray !n !src !dst = memcpy (useDevicePtr dst) (useDevicePtr src) n DeviceToDevice----- |--- Copy the given number of elements from the first device array (source) to the--- second (destination). The copied areas may not overlap. This operation is--- asynchronous with respect to the host, and may be associated with a--- particular stream.----{-# INLINEABLE copyArrayAsync #-}-copyArrayAsync :: Storable a => Int -> DevicePtr a -> DevicePtr a -> Maybe Stream -> IO ()-copyArrayAsync !n !src !dst !mst =- memcpyAsync (useDevicePtr dst) (useDevicePtr src) n DeviceToDevice mst----- |--- Copy a 2D memory area from the first device array (source) to the second--- (destination). The copied areas may not overlap. This operation is--- asynchronous with respect to the host, but will not overlap other device--- operations.----{-# INLINEABLE copyArray2D #-}-copyArray2D- :: Storable a- => Int -- ^ width to copy (elements)- -> Int -- ^ height to copy (elements)- -> DevicePtr a -- ^ source array- -> Int -- ^ source array width- -> DevicePtr a -- ^ destination array- -> Int -- ^ destination array width- -> IO ()-copyArray2D !w !h !src !sw !dst !dw =- memcpy2D (useDevicePtr dst) dw (useDevicePtr src) sw w h DeviceToDevice----- |--- Copy a 2D memory area from the first device array (source) to the second--- device array (destination). The copied areas may not overlay. This operation--- is asynchronous with respect to the host, and may be associated with a--- particular stream.----{-# INLINEABLE copyArray2DAsync #-}-copyArray2DAsync- :: Storable a- => Int -- ^ width to copy (elements)- -> Int -- ^ height to copy (elements)- -> DevicePtr a -- ^ source array- -> Int -- ^ source array width- -> DevicePtr a -- ^ destination array- -> Int -- ^ destination array width- -> Maybe Stream- -> IO ()-copyArray2DAsync !w !h !src !sw !dst !dw !mst =- memcpy2DAsync (useDevicePtr dst) dw (useDevicePtr src) sw w h DeviceToDevice mst-------- Memory copy kind----{# enum cudaMemcpyKind as CopyDirection {}- with prefix="cudaMemcpy" deriving (Eq, Show) #}---- |--- Copy data between host and device. This is a synchronous operation.----{-# INLINEABLE memcpy #-}-memcpy :: Storable a- => Ptr a -- ^ destination- -> Ptr a -- ^ source- -> Int -- ^ number of elements- -> CopyDirection- -> IO ()-memcpy !dst !src !n !dir = doMemcpy undefined dst- where- doMemcpy :: Storable a' => a' -> Ptr a' -> IO ()- doMemcpy x _ =- nothingIfOk =<< cudaMemcpy dst src (fromIntegral n * fromIntegral (sizeOf x)) dir--{-# INLINE cudaMemcpy #-}-{# fun cudaMemcpy- { castPtr `Ptr a'- , castPtr `Ptr a'- , cIntConv `Int64'- , cFromEnum `CopyDirection' } -> `Status' cToEnum #}----- |--- Copy data between the host and device asynchronously, possibly associated--- with a particular stream. The host-side memory must be page-locked (allocated--- with 'mallocHostArray').----{-# INLINEABLE memcpyAsync #-}-memcpyAsync :: Storable a- => Ptr a -- ^ destination- -> Ptr a -- ^ source- -> Int -- ^ number of elements- -> CopyDirection- -> Maybe Stream- -> IO ()-memcpyAsync !dst !src !n !kind !mst = doMemcpy undefined dst- where- doMemcpy :: Storable a' => a' -> Ptr a' -> IO ()- doMemcpy x _ =- let bytes = fromIntegral n * fromIntegral (sizeOf x) in- nothingIfOk =<< cudaMemcpyAsync dst src bytes kind (fromMaybe defaultStream mst)--{-# INLINE cudaMemcpyAsync #-}-{# fun cudaMemcpyAsync- { castPtr `Ptr a'- , castPtr `Ptr a'- , cIntConv `Int64'- , cFromEnum `CopyDirection'- , useStream `Stream' } -> `Status' cToEnum #}----- |--- Copy a 2D memory area between the host and device. This is a synchronous--- operation.----{-# INLINEABLE memcpy2D #-}-memcpy2D :: Storable a- => Ptr a -- ^ destination- -> Int -- ^ width of destination array- -> Ptr a -- ^ source- -> Int -- ^ width of source array- -> Int -- ^ width to copy- -> Int -- ^ height to copy- -> CopyDirection- -> IO ()-memcpy2D !dst !dw !src !sw !w !h !kind = doCopy undefined dst- where- doCopy :: Storable a' => a' -> Ptr a' -> IO ()- doCopy x _ =- let bytes = fromIntegral (sizeOf x)- dw' = fromIntegral dw * bytes- sw' = fromIntegral sw * bytes- w' = fromIntegral w * bytes- h' = fromIntegral h- in- nothingIfOk =<< cudaMemcpy2D dst dw' src sw' w' h' kind--{-# INLINE cudaMemcpy2D #-}-{# fun cudaMemcpy2D- { castPtr `Ptr a'- , `Int64'- , castPtr `Ptr a'- , `Int64'- , `Int64'- , `Int64'- , cFromEnum `CopyDirection'- }- -> `Status' cToEnum #}----- |--- Copy a 2D memory area between the host and device asynchronously, possibly--- associated with a particular stream. The host-side memory must be--- page-locked.----{-# INLINEABLE memcpy2DAsync #-}-memcpy2DAsync :: Storable a- => Ptr a -- ^ destination- -> Int -- ^ width of destination array- -> Ptr a -- ^ source- -> Int -- ^ width of source array- -> Int -- ^ width to copy- -> Int -- ^ height to copy- -> CopyDirection- -> Maybe Stream- -> IO ()-memcpy2DAsync !dst !dw !src !sw !w !h !kind !mst = doCopy undefined dst- where- doCopy :: Storable a' => a' -> Ptr a' -> IO ()- doCopy x _ =- let bytes = fromIntegral (sizeOf x)- dw' = fromIntegral dw * bytes- sw' = fromIntegral sw * bytes- w' = fromIntegral w * bytes- h' = fromIntegral h- st = fromMaybe defaultStream mst- in- nothingIfOk =<< cudaMemcpy2DAsync dst dw' src sw' w' h' kind st--{-# INLINE cudaMemcpy2DAsync #-}-{# fun cudaMemcpy2DAsync- { castPtr `Ptr a'- , `Int64'- , castPtr `Ptr a'- , `Int64'- , `Int64'- , `Int64'- , cFromEnum `CopyDirection'- , useStream `Stream'- }- -> `Status' cToEnum #}-------------------------------------------------------------------------------------- Combined Allocation and Marshalling------------------------------------------------------------------------------------- |--- Write a list of storable elements into a newly allocated device array,--- returning the device pointer together with the number of elements that were--- written. Note that this requires two copy operations: firstly from a Haskell--- list into a heap-allocated array, and from there into device memory. The--- array should be 'free'd when no longer required.----{-# INLINEABLE newListArrayLen #-}-newListArrayLen :: Storable a => [a] -> IO (DevicePtr a, Int)-newListArrayLen !xs =- F.withArrayLen xs $ \len p ->- bracketOnError (mallocArray len) free $ \d_xs -> do- pokeArray len p d_xs- return (d_xs, len)----- |--- Write a list of storable elements into a newly allocated device array. This--- is 'newListArrayLen' composed with 'fst'.----{-# INLINEABLE newListArray #-}-newListArray :: Storable a => [a] -> IO (DevicePtr a)-newListArray !xs = fst `fmap` newListArrayLen xs----- |--- Temporarily store a list of elements into a newly allocated device array. An--- IO action is applied to the array, the result of which is returned. Similar--- to 'newListArray', this requires two marshalling operations of the data.------ As with 'allocaArray', the memory is freed once the action completes, so you--- should not return the pointer from the action, and be sure that any--- asynchronous operations (such as kernel execution) have completed.----{-# INLINEABLE withListArray #-}-withListArray :: Storable a => [a] -> (DevicePtr a -> IO b) -> IO b-withListArray !xs = withListArrayLen xs . const----- |--- A variant of 'withListArray' which also supplies the number of elements in--- the array to the applied function----{-# INLINEABLE withListArrayLen #-}-withListArrayLen :: Storable a => [a] -> (Int -> DevicePtr a -> IO b) -> IO b-withListArrayLen !xs !f =- bracket (newListArrayLen xs) (free . fst) (uncurry . flip $ f)------ XXX: Will this attempt to double-free the device array on error (together--- with newListArrayLen)?----------------------------------------------------------------------------------------- Utility------------------------------------------------------------------------------------- |--- Initialise device memory to a given 8-bit value----{-# INLINEABLE memset #-}-memset :: DevicePtr a -- ^ The device memory- -> Int64 -- ^ Number of bytes- -> Int8 -- ^ Value to set for each byte- -> IO ()-memset !dptr !bytes !symbol = nothingIfOk =<< cudaMemset dptr symbol bytes--{-# INLINE cudaMemset #-}-{# fun unsafe cudaMemset- { dptr `DevicePtr a'- , cIntConv `Int8'- , cIntConv `Int64' } -> `Status' cToEnum #}- where- dptr = useDevicePtr . castDevPtr-
− src/Foreign/CUDA/Runtime/Stream.chs
@@ -1,117 +0,0 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE ForeignFunctionInterface #-}------------------------------------------------------------------------------------ |--- Module : Foreign.CUDA.Runtime.Stream--- Copyright : [2009..2023] Trevor L. McDonell--- License : BSD------ Stream management routines--------------------------------------------------------------------------------------module Foreign.CUDA.Runtime.Stream (-- -- * Stream Management- Stream(..),- create, destroy, finished, block,-- defaultStream, defaultStreamLegacy, defaultStreamPerThread,--) where--#include "cbits/stubs.h"-{# context lib="cudart" #}---- Friends-import Foreign.CUDA.Driver.Stream ( Stream(..), defaultStream, defaultStreamLegacy, defaultStreamPerThread )-import Foreign.CUDA.Internal.C2HS-import Foreign.CUDA.Runtime.Error---- System-import Foreign-import Foreign.C-import Control.Monad ( liftM )-import Control.Exception ( throwIO )-------------------------------------------------------------------------------------- Functions------------------------------------------------------------------------------------- |--- Create a new asynchronous stream----{-# INLINEABLE create #-}-create :: IO Stream-create = resultIfOk =<< cudaStreamCreate--{-# INLINE cudaStreamCreate #-}-{# fun unsafe cudaStreamCreate- { alloca- `Stream' peekStream* } -> `Status' cToEnum #}----- |--- Destroy and clean up an asynchronous stream----{-# INLINEABLE destroy #-}-destroy :: Stream -> IO ()-destroy !s = nothingIfOk =<< cudaStreamDestroy s--{-# INLINE cudaStreamDestroy #-}-{# fun unsafe cudaStreamDestroy- { useStream `Stream' } -> `Status' cToEnum #}----- |--- Determine if all operations in a stream have completed----{-# INLINEABLE finished #-}-finished :: Stream -> IO Bool-finished !s =- cudaStreamQuery s >>= \rv -> do- case rv of- Success -> return True- NotReady -> return False- _ -> throwIO (ExitCode rv)--{-# INLINE cudaStreamQuery #-}-{# fun unsafe cudaStreamQuery- { useStream `Stream' } -> `Status' cToEnum #}----- |--- Block until all operations in a Stream have been completed----{-# INLINEABLE block #-}-block :: Stream -> IO ()-block !s = nothingIfOk =<< cudaStreamSynchronize s--{-# INLINE cudaStreamSynchronize #-}-{# fun cudaStreamSynchronize- { useStream `Stream' } -> `Status' cToEnum #}----- |--- The main execution stream (0)------ {-# INLINE defaultStream #-}--- defaultStream :: Stream--- #if CUDART_VERSION < 3010--- defaultStream = Stream 0--- #else--- defaultStream = Stream nullPtr--- #endif------------------------------------------------------------------------------------- Internal-----------------------------------------------------------------------------------{-# INLINE peekStream #-}-peekStream :: Ptr {#type cudaStream_t#} -> IO Stream-#if CUDART_VERSION < 3010-peekStream = liftM Stream . peekIntConv-#else-peekStream = liftM Stream . peek-#endif-
− src/Foreign/CUDA/Runtime/Utils.chs
@@ -1,63 +0,0 @@-{-# LANGUAGE ForeignFunctionInterface #-}------------------------------------------------------------------------------------ |--- Module : Foreign.CUDA.Runtime.Utils--- Copyright : [2009..2023] Trevor L. McDonell--- License : BSD------ Utility functions--------------------------------------------------------------------------------------module Foreign.CUDA.Runtime.Utils (-- runtimeVersion,- driverVersion,- libraryVersion,--) where--#include "cbits/stubs.h"-{# context lib="cudart" #}---- Friends-import Foreign.CUDA.Runtime.Error-import Foreign.CUDA.Internal.C2HS---- System-import Foreign-import Foreign.C----- |--- Return the version number of the installed CUDA driver----{-# INLINEABLE runtimeVersion #-}-runtimeVersion :: IO Int-runtimeVersion = resultIfOk =<< cudaRuntimeGetVersion--{-# INLINE cudaRuntimeGetVersion #-}-{# fun unsafe cudaRuntimeGetVersion- { alloca- `Int' peekIntConv* } -> `Status' cToEnum #}----- |--- Return the version number of the installed CUDA runtime----{-# INLINEABLE driverVersion #-}-driverVersion :: IO Int-driverVersion = resultIfOk =<< cudaDriverGetVersion--{-# INLINE cudaDriverGetVersion #-}-{# fun unsafe cudaDriverGetVersion- { alloca- `Int' peekIntConv* } -> `Status' cToEnum #}----- |--- Return the version number of the CUDA library (API) that this package was--- compiled against.----{-# INLINEABLE libraryVersion #-}-libraryVersion :: Int-libraryVersion = {#const CUDART_VERSION #}-
− src/Text/Show/Describe.hs
@@ -1,18 +0,0 @@------------------------------------------------------------------------------------ |--- Module : Text.Show.Describe--- Copyright : [2016..2023] Trevor L. McDonell--- License : BSD--------------------------------------------------------------------------------------module Text.Show.Describe- where----- | Like 'Text.Show.Show', but focuses on providing a more detailed description--- of the value rather than a 'Text.Read.read'able representation.----class Describe a where- describe :: a -> String-