/// <summary> /// Returns a graph's dependency edges /// </summary> /// <param name="from"></param> /// <param name="to"></param> public void GetEdges(out CUgraphNode[] from, out CUgraphNode[] to) { from = null; to = null; SizeT numNodes = new SizeT(); res = DriverAPINativeMethods.GraphManagment.cuGraphGetEdges(_graph, null, null, ref numNodes); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuGraphGetEdges", res)); if (res != CUResult.Success) { throw new CudaException(res); } if (numNodes > 0) { from = new CUgraphNode[numNodes]; to = new CUgraphNode[numNodes]; res = DriverAPINativeMethods.GraphManagment.cuGraphGetEdges(_graph, from, to, ref numNodes); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuGraphGetNodes", res)); if (res != CUResult.Success) { throw new CudaException(res); } } }
/// <summary> /// Returns a graph's root nodes /// </summary> /// <returns></returns> public CUgraphNode[] GetRootNodes() { SizeT numNodes = new SizeT(); res = DriverAPINativeMethods.GraphManagment.cuGraphGetRootNodes(_graph, null, ref numNodes); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuGraphGetRootNodes", res)); if (res != CUResult.Success) { throw new CudaException(res); } if (numNodes > 0) { CUgraphNode[] nodes = new CUgraphNode[numNodes]; res = DriverAPINativeMethods.GraphManagment.cuGraphGetNodes(_graph, nodes, ref numNodes); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuGraphGetRootNodes", res)); if (res != CUResult.Success) { throw new CudaException(res); } return(nodes); } return(null); }
/// <summary> /// Creates a host execution node and adds it to a graph<para/> /// Creates a new CPU execution node and adds it to the graph with /// dependencies specified via dependencies. /// It is possible for dependencies to be null, in which case the node will be placed /// at the root of the graph. Dependencies may not have any duplicate entries. /// A handle to the new node will be returned.<para/> /// When the graph is launched, the node will invoke the specified CPU function. /// </summary> /// <param name="dependencies">can be null</param> /// <param name="hostFunction">Host function to execute</param> /// <param name="userData">User data for host function. Note that the data object must be pinned by GC!</param> /// <returns>A handle to the new node will be returned.</returns> public CUgraphNode AddHostNode(CUgraphNode[] dependencies, CUhostFn hostFunction, IntPtr userData) { CUgraphNode node = new CUgraphNode(); SizeT numDependencies = 0; if (dependencies != null) { numDependencies = dependencies.Length; } CudaHostNodeParams nodeParams = new CudaHostNodeParams { fn = hostFunction, userData = userData }; res = DriverAPINativeMethods.GraphManagment.cuGraphAddHostNode(ref node, _graph, dependencies, numDependencies, ref nodeParams); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuGraphAddHostNode", res)); if (res != CUResult.Success) { throw new CudaException(res); } return(node); }
/// <summary> /// Sets the event for an event record node in the given graphExec /// Sets the event of an event record node in an executable graph \p hGraphExec. /// The node is identified by the corresponding node \p hNode in the /// non-executable graph, from which the executable graph was instantiated. /// The modifications only affect future launches of \p hGraphExec. Already /// enqueued or running launches of \p hGraphExec are not affected by this call. /// \p hNode is also not modified by this call. /// </summary> public void SetWaitEvent(CUgraphNode hNode, CudaEvent event_) { res = DriverAPINativeMethods.GraphManagment.cuGraphExecEventWaitNodeSetEvent(_graph, hNode, event_.Event); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuGraphExecEventWaitNodeSetEvent", res)); if (res != CUResult.Success) { throw new CudaException(res); } }
/// <summary> /// Sets the parameters for an external semaphore wait node in the given graphExec<para/> /// Sets the parameters of an external semaphore wait node in an executable graph \p hGraphExec.<para/> /// The node is identified by the corresponding node \p hNode in the /// non-executable graph, from which the executable graph was instantiated.<para/> /// hNode must not have been removed from the original graph.<para/> /// The modifications only affect future launches of \p hGraphExec. Already /// enqueued or running launches of \p hGraphExec are not affected by this call. /// hNode is also not modified by this call.<para/> /// Changing \p nodeParams->numExtSems is not supported. /// </summary> public void SetParams(CUgraphNode hNode, CudaExtSemWaitNodeParams nodeParams) { res = DriverAPINativeMethods.GraphManagment.cuGraphExecExternalSemaphoresWaitNodeSetParams(_graph, hNode, nodeParams); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuGraphExecExternalSemaphoresWaitNodeSetParams", res)); if (res != CUResult.Success) { throw new CudaException(res); } }
/// <summary> /// Updates node parameters in the child graph node in the given graphExec. /// Updates the work represented by \p hNode in \p hGraphExec as though the nodes contained /// in \p hNode's graph had the parameters contained in \p childGraph's nodes at instantiation. /// \p hNode must remain in the graph which was used to instantiate \p hGraphExec. /// Changed edges to and from \p hNode are ignored. /// The modifications only affect future launches of \p hGraphExec. Already enqueued /// or running launches of \p hGraphExec are not affected by this call. \p hNode is also /// not modified by this call. /// The topology of \p childGraph, as well as the node insertion order, must match that /// of the graph contained in \p hNode. See::cuGraphExecUpdate() for a list of restrictions /// on what can be updated in an instantiated graph.The update is recursive, so child graph /// nodes contained within the top level child graph will also be updated. /// </summary> public void SetParams(CUgraphNode hNode, CudaGraph childGraph) { res = DriverAPINativeMethods.GraphManagment.cuGraphExecChildGraphNodeSetParams(_graph, hNode, childGraph.Graph); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuGraphExecChildGraphNodeSetParams", res)); if (res != CUResult.Success) { throw new CudaException(res); } }
/// <summary> /// Sets the parameters for a memset node in the given graphExec.<para/> /// Updates the work represented by \p hNode in \p hGraphExec as though \p hNode had /// contained \p memsetParams at instantiation. hNode must remain in the graph which was /// used to instantiate \p hGraphExec. Changed edges to and from hNode are ignored.<para/> /// The destination memory in \p memsetParams must be allocated from the same /// contexts as the original destination memory. Both the instantiation-time /// memory operand and the memory operand in \p memsetParams must be 1-dimensional. /// Zero-length operations are not supported.<para/> /// The modifications only affect future launches of \p hGraphExec. Already enqueued /// or running launches of \p hGraphExec are not affected by this call. hNode is also /// not modified by this call.<para/> /// Returns CUDA_ERROR_INVALID_VALUE if the memory operand's mappings changed or /// either the original or new memory operand are multidimensional. /// </summary> public void SetParams(CUgraphNode hNode, ref CudaMemsetNodeParams memsetParams, CUcontext ctx) { res = DriverAPINativeMethods.GraphManagment.cuGraphExecMemsetNodeSetParams(_graph, hNode, ref memsetParams, ctx); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuGraphExecMemsetNodeSetParams", res)); if (res != CUResult.Success) { throw new CudaException(res); } }
/// <summary> /// Finds a cloned version of a node<para/> /// This function returns the node corresponding to originalNode /// in the original graph.<para/> /// This cloned graph must have been cloned from the original Graph via its Clone() method. /// OriginalNode must have been in that graph at the time of the call to /// Clone(), and the corresponding cloned node in this graph must not have /// been removed. The cloned node is then returned. /// </summary> /// <param name="originalNode"></param> public CUgraphNode NodeFindInClone(CUgraphNode originalNode) { CUgraphNode clone = new CUgraphNode(); res = DriverAPINativeMethods.GraphManagment.cuGraphNodeFindInClone(ref clone, originalNode, _graph); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuGraphNodeFindInClone", res)); if (res != CUResult.Success) { throw new CudaException(res); } return(clone); }
/// <summary> /// Creates an executable graph from a graph<para/> /// Instantiates this Graph as an executable graph. The graph is validated for any /// structural constraints or intra-node constraints which were not previously /// validated. If instantiation is successful, a handle to the instantiated graph /// is returned. /// </summary> public CudaGraphExec Instantiate() { SizeT sizeBuffer = 10000; byte[] logBuffer = new byte[sizeBuffer]; CUgraphExec graphExec = new CUgraphExec(); CUgraphNode errNode = new CUgraphNode(); res = DriverAPINativeMethods.GraphManagment.cuGraphInstantiate(ref graphExec, _graph, ref errNode, logBuffer, sizeBuffer); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuGraphInstantiate", res)); if (res != CUResult.Success) { string message = Encoding.ASCII.GetString(logBuffer); throw new CudaException(res, message, null); } return(new CudaGraphExec(graphExec)); }
/// <summary> /// Creates a memory free node and adds it to a graph<para/> /// Creates a new memory free node and adds it to \p hGraph with \p numDependencies /// dependencies specified via \p dependencies and arguments specified in \p nodeParams. /// It is possible for \p numDependencies to be 0, in which case the node will be placed /// at the root of the graph. \p dependencies may not have any duplicate entries. A handle /// to the new node will be returned in \p phGraphNode. /// </summary> /// <param name="dependencies">Dependencies of the node</param> /// <param name="dptr">Parameters for the node</param> /// <returns>Returns newly created node</returns> public CUgraphNode AddMemFreeNode(CUgraphNode[] dependencies, CUdeviceptr dptr) { CUgraphNode node = new CUgraphNode(); SizeT numDependencies = 0; if (dependencies != null) { numDependencies = dependencies.Length; } res = DriverAPINativeMethods.GraphManagment.cuGraphAddMemFreeNode(ref node, _graph, dependencies, numDependencies, dptr); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuGraphAddMemFreeNode", res)); if (res != CUResult.Success) { throw new CudaException(res); } return(node); }
/// <summary> /// Creates a memcpy node and adds it to a graph<para/> /// Creates a new memcpy node and adds it to graph with /// dependencies specified via dependencies.<para/> /// It is possible for dependencies to be null, in which case the node will be placed /// at the root of the graph. Dependencies may not have any duplicate entries. /// A handle to the new node will be returned.<para/> /// When the graph is launched, the node will perform the memcpy described by copyParams. /// See ::cuMemcpy3D() for a description of the structure and its restrictions.<para/> /// Memcpy nodes have some additional restrictions with regards to managed memory, if the /// system contains at least one device which has a zero value for the device attribute /// ::CU_DEVICE_ATTRIBUTE_CONCURRENT_MANAGED_ACCESS. If one or more of the operands refer /// to managed memory, then using the memory type ::CU_MEMORYTYPE_UNIFIED is disallowed /// for those operand(s). The managed memory will be treated as residing on either the /// host or the device, depending on which memory type is specified. /// </summary> /// <param name="dependencies">can be null</param> /// <param name="copyParams">Parameters for the memory copy</param> /// <param name="ctx">Cuda context used for the operation</param> /// <returns>A handle to the new node will be returned.</returns> public CUgraphNode AddMemcpyNode(CUgraphNode[] dependencies, CUDAMemCpy3D copyParams, CudaContext ctx) { CUgraphNode node = new CUgraphNode(); SizeT numDependencies = 0; if (dependencies != null) { numDependencies = dependencies.Length; } res = DriverAPINativeMethods.GraphManagment.cuGraphAddMemcpyNode(ref node, _graph, dependencies, numDependencies, ref copyParams, ctx.Context); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuGraphAddMemcpyNode", res)); if (res != CUResult.Success) { throw new CudaException(res); } return(node); }
/// <summary> /// Creates a memset node and adds it to a graph<para/> /// Creates a new memset node and adds it to graph with /// dependencies specified via dependencies.<para/> /// It is possible for dependencies to be null, in which case the node will be placed /// at the root of the graph. Dependencies may not have any duplicate entries.<para/> /// The element size must be 1, 2, or 4 bytes.<para/> /// When the graph is launched, the node will perform the memset described by memsetParams. /// </summary> /// <param name="dependencies">can be null</param> /// <param name="deviceVariable">When the graph is launched, the node will perform the memset on deviceVariable.</param> /// <param name="value">Value to set</param> /// <param name="ctx">Cuda context used for the operation</param> /// <returns>A handle to the new node will be returned.</returns> public CUgraphNode AddMemsetNode <T>(CUgraphNode[] dependencies, CudaPitchedDeviceVariable <T> deviceVariable, uint value, CudaContext ctx) where T : struct { CUgraphNode node = new CUgraphNode(); SizeT numDependencies = 0; if (dependencies != null) { numDependencies = dependencies.Length; } CudaMemsetNodeParams memsetParams = CudaMemsetNodeParams.init <T>(deviceVariable, value); res = DriverAPINativeMethods.GraphManagment.cuGraphAddMemsetNode(ref node, _graph, dependencies, numDependencies, ref memsetParams, ctx.Context); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuGraphAddMemsetNode", res)); if (res != CUResult.Success) { throw new CudaException(res); } return(node); }
/// <summary> /// Creates a kernel execution node and adds it to a graph<para/> /// Creates a new kernel execution node and adds it to the graph with /// dependencies specified via dependencies and arguments specified in nodeParams.<para/> /// It is possible for dependencies to be null, in which case the node will be placed /// at the root of the graph. Dependencies may not have any duplicate entries.<para/> /// A handle to the new node will be returned. /// </summary> /// <param name="dependencies">can be null</param> /// <param name="kernel">Kernel to execute</param> /// <param name="parameters">Kernel parameters to pass. An Array of IntPtr each of them pointing to a parameters. Note that the parameters must be pinned by GC!</param> /// <param name="extras">Extra data</param> /// <returns>A handle to the new node will be returned.</returns> public CUgraphNode AddKernelNode(CUgraphNode[] dependencies, CudaKernel kernel, IntPtr parameters, IntPtr extras) { CUgraphNode node = new CUgraphNode(); SizeT numDependencies = 0; if (dependencies != null) { numDependencies = dependencies.Length; } CudaKernelNodeParams nodeParams = new CudaKernelNodeParams { blockDimX = kernel.BlockDimensions.x, blockDimY = kernel.BlockDimensions.y, blockDimZ = kernel.BlockDimensions.z, extra = extras, func = kernel.CUFunction, gridDimX = kernel.GridDimensions.x, gridDimY = kernel.GridDimensions.y, gridDimZ = kernel.GridDimensions.z, kernelParams = parameters, sharedMemBytes = kernel.DynamicSharedMemory }; res = DriverAPINativeMethods.GraphManagment.cuGraphAddKernelNode(ref node, _graph, dependencies, numDependencies, ref nodeParams); Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "cuGraphAddKernelNode", res)); if (res != CUResult.Success) { throw new CudaException(res); } return(node); }