// The Construct // // Copyright (C) The Construct Developers, Authors & Contributors // Copyright (C) 2016-2022 Jason Volk // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice is present in all copies. The // full license for this software is available in the LICENSE file. #pragma once #define HAVE_IRCD_CL_EXEC_H /// Construction enqueues the task; destruction waits for completion. /// /// clEnqueue* construction with resulting cl_event wrapping. Instances /// represent the full lifecycle of work creation, submission and completion. /// /// Our interface is tied directly to ircd::ctx for intuitive control flow and /// interaction with the device. By default, all constructions are dependent /// on the last construction made on the same ircd::ctx, providing sequential /// consistency for each ircd::ctx, and independence between different ctxs. /// Each instance destructs only when complete, otherwise the ircd::ctx will /// block in the destructor. struct ircd::cl::exec :work { struct opts; static const opts opts_default; // Copy data written by the device to the GTT into our buffer. exec(data &, const std::memory_order, const opts & = opts_default); // Copy data directly between buffers. exec(data &, const data &, const opts & = opts_default); // Execute a kernel on a range. exec(kern &, const kern::range &, const opts & = opts_default); // Execute a kernel on a range. exec(kern &, const opts &, const kern::range &); // Execute a barrier. exec(const opts &); // No-op exec() = default; }; /// Options for an exec. struct ircd::cl::exec::opts { /// Specify a list of dependencies. When provided, this list overrides the /// default sequential behavior; thus can be used to start new dependency /// chains for some task concurrency on the same ircd::ctx. Providing a /// single reference to the last exec on the same stack is equivalent to /// the default. vector_view deps; /// For operations which have a size; otherwise ignored, or serves as /// sentinel for automatic size. size_t size {-1UL}; /// For operations which have an offset (or two); otherwise ignored. off_t offset[2] {0}; /// Tune the intensity of the execution. The value is intended to correlate /// with parallel resource consumption on the device by shaping the work /// groups submitted over the range. The minimum value of 1 will serialize /// execution. Values greater than the number of CU's will not increase /// concurrency but may still partition a large range with multiple command /// submissions to increase niceness. The default of zero will maximize /// intensity and minimize command submissions (to one). uint intensity {0}; /// Starts a new dependency chain; allowing empty deps without implicit /// dependency on the last work item constructed on the ircd::ctx. bool indep {false}; /// For operations that have an optional blocking behavior; otherwise /// ignored. Note that this is a thread-level blocking mechanism and /// does not yield the ircd::ctx; for testing/special use only. bool blocking {false}; /// Perform a flush of the queue directly after submit. bool flush {false}; /// Perform a sync of the queue directly after submit; this will block in /// the ctor; all work will be complete at full construction. bool sync {false}; }; inline ircd::cl::exec::exec(kern &kern, const opts &opts, const kern::range &range) :exec { kern, range, opts } {}