mirror of
https://github.com/matrix-construct/construct
synced 2025-01-13 16:33:53 +01:00
ircd:🆑 Re-attempt pre-SVM mapping w/ synchronous closure.
This commit is contained in:
parent
d69f8ffb9c
commit
a21589654a
2 changed files with 190 additions and 10 deletions
|
@ -14,9 +14,6 @@
|
|||
/// OpenCL Interface
|
||||
namespace ircd::cl
|
||||
{
|
||||
IRCD_EXCEPTION(ircd::error, error)
|
||||
IRCD_EXCEPTION(error, opencl_error)
|
||||
|
||||
struct init;
|
||||
struct exec;
|
||||
struct kern;
|
||||
|
@ -24,6 +21,12 @@ namespace ircd::cl
|
|||
struct data;
|
||||
struct work;
|
||||
|
||||
IRCD_EXCEPTION(ircd::error, error)
|
||||
IRCD_EXCEPTION(error, opencl_error)
|
||||
|
||||
using read_closure = std::function<void (const_buffer)>;
|
||||
using write_closure = std::function<void (mutable_buffer)>;
|
||||
|
||||
extern const info::versions version_api;
|
||||
extern info::versions version_abi;
|
||||
extern conf::item<bool> enable;
|
||||
|
@ -143,12 +146,18 @@ struct ircd::cl::exec
|
|||
|
||||
static const opts opts_default;
|
||||
|
||||
// Read data from the device into buffer.
|
||||
exec(data &, const mutable_buffer &, const opts & = opts_default);
|
||||
// View data written by the device to the GTT (synchronous closure).
|
||||
exec(data &, const read_closure &, const opts & = opts_default);
|
||||
|
||||
// Write data to the device from buffer.
|
||||
// View buffer in the GTT which the device will read (synchronous closure).
|
||||
exec(data &, const write_closure &, const opts & = opts_default);
|
||||
|
||||
// Copy data from the buffer to the GTT for use by the device.
|
||||
exec(data &, const const_buffer &, const opts & = opts_default);
|
||||
|
||||
// Copy data written by the device to the GTT into our buffer.
|
||||
exec(data &, const mutable_buffer &, const opts & = opts_default);
|
||||
|
||||
// Execute a kernel on a range.
|
||||
exec(kern &, const kern::range &, const opts & = opts_default);
|
||||
|
||||
|
@ -166,8 +175,21 @@ struct ircd::cl::exec::opts
|
|||
/// the default.
|
||||
vector_view<cl::exec> deps;
|
||||
|
||||
/// For operations that have an optional blocking behavior;
|
||||
/// otherwise ignored.
|
||||
/// For operations which have a size; otherwise ignored, or serves as
|
||||
/// sentinel for automatic size.
|
||||
size_t size {0};
|
||||
|
||||
/// For operations which have an offset; otherwise ignored.
|
||||
off_t offset {0};
|
||||
|
||||
/// For operations which plan to both read and write to the GTT, set to
|
||||
/// true and execute the write_closure; otherwise ignored. Can be used
|
||||
/// to de-optimize the write_closure, which is unidirectional by default.
|
||||
bool duplex {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};
|
||||
};
|
||||
|
||||
|
|
162
ircd/cl.cc
162
ircd/cl.cc
|
@ -387,7 +387,7 @@ try
|
|||
q,
|
||||
cl_mem(data.handle),
|
||||
opts.blocking,
|
||||
0UL, //offset,
|
||||
opts.offset,
|
||||
ircd::size(buf),
|
||||
ircd::data(buf),
|
||||
deps.size(),
|
||||
|
@ -421,13 +421,14 @@ try
|
|||
make_deps(this, opts)
|
||||
};
|
||||
|
||||
assert(!this->handle);
|
||||
call
|
||||
(
|
||||
clEnqueueWriteBuffer,
|
||||
q,
|
||||
cl_mem(data.handle),
|
||||
opts.blocking,
|
||||
0UL, //offset,
|
||||
opts.offset,
|
||||
ircd::size(buf),
|
||||
mutable_cast(ircd::data(buf)),
|
||||
deps.size(),
|
||||
|
@ -446,6 +447,163 @@ catch(const std::exception &e)
|
|||
throw;
|
||||
}
|
||||
|
||||
ircd::cl::exec::exec(data &data,
|
||||
const read_closure &closure,
|
||||
const opts &opts)
|
||||
try
|
||||
{
|
||||
auto &q
|
||||
{
|
||||
queue[0][0]
|
||||
};
|
||||
|
||||
const auto deps
|
||||
{
|
||||
make_deps(this, opts)
|
||||
};
|
||||
|
||||
const auto size
|
||||
{
|
||||
opts.size?: data.size()
|
||||
};
|
||||
|
||||
cl_map_flags flags {0};
|
||||
flags |= CL_MAP_READ;
|
||||
|
||||
int err {CL_SUCCESS};
|
||||
assert(!this->handle);
|
||||
void *const ptr
|
||||
{
|
||||
clEnqueueMapBuffer
|
||||
(
|
||||
q,
|
||||
cl_mem(data.handle),
|
||||
opts.blocking,
|
||||
flags,
|
||||
opts.offset,
|
||||
size,
|
||||
deps.size(),
|
||||
deps.size()? deps.data(): nullptr,
|
||||
reinterpret_cast<cl_event *>(&this->handle),
|
||||
&err
|
||||
)
|
||||
};
|
||||
|
||||
throw_on_error(err);
|
||||
assert(this->handle);
|
||||
assert(ptr);
|
||||
|
||||
const unwind unmap{[this, &data, &q, &ptr]
|
||||
{
|
||||
assert(!this->handle);
|
||||
call
|
||||
(
|
||||
clEnqueueUnmapMemObject,
|
||||
q,
|
||||
cl_mem(data.handle),
|
||||
ptr,
|
||||
0, // deps
|
||||
nullptr, // depslist
|
||||
reinterpret_cast<cl_event *>(&this->handle)
|
||||
);
|
||||
}};
|
||||
|
||||
wait();
|
||||
closure(const_buffer
|
||||
{
|
||||
reinterpret_cast<const char *>(ptr), size
|
||||
});
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
log::error
|
||||
{
|
||||
log, "Exec Read Closure :%s",
|
||||
e.what(),
|
||||
};
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
ircd::cl::exec::exec(data &data,
|
||||
const write_closure &closure,
|
||||
const opts &opts)
|
||||
try
|
||||
{
|
||||
auto &q
|
||||
{
|
||||
queue[0][0]
|
||||
};
|
||||
|
||||
const auto deps
|
||||
{
|
||||
make_deps(this, opts)
|
||||
};
|
||||
|
||||
const auto size
|
||||
{
|
||||
opts.size?: data.size()
|
||||
};
|
||||
|
||||
cl_map_flags flags {0};
|
||||
flags |= CL_MAP_WRITE;
|
||||
flags |= opts.duplex? CL_MAP_READ: 0;
|
||||
|
||||
int err {CL_SUCCESS};
|
||||
assert(!this->handle);
|
||||
void *const ptr
|
||||
{
|
||||
clEnqueueMapBuffer
|
||||
(
|
||||
q,
|
||||
cl_mem(data.handle),
|
||||
opts.blocking,
|
||||
flags,
|
||||
opts.offset,
|
||||
size,
|
||||
deps.size(),
|
||||
deps.size()? deps.data(): nullptr,
|
||||
reinterpret_cast<cl_event *>(&this->handle),
|
||||
&err
|
||||
)
|
||||
};
|
||||
|
||||
throw_on_error(err);
|
||||
assert(this->handle);
|
||||
assert(ptr);
|
||||
|
||||
const unwind unmap{[this, &data, &q, &ptr]
|
||||
{
|
||||
assert(!this->handle);
|
||||
call
|
||||
(
|
||||
clEnqueueUnmapMemObject,
|
||||
q,
|
||||
cl_mem(data.handle),
|
||||
ptr,
|
||||
0, // deps
|
||||
nullptr, // depslist
|
||||
reinterpret_cast<cl_event *>(&this->handle)
|
||||
);
|
||||
}};
|
||||
|
||||
wait();
|
||||
closure(mutable_buffer
|
||||
{
|
||||
reinterpret_cast<char *>(ptr), size
|
||||
});
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
log::error
|
||||
{
|
||||
log, "Exec Write Closure :%s",
|
||||
e.what(),
|
||||
};
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
ircd::vector_view<cl_event>
|
||||
ircd::cl::make_deps(cl::work *const &work,
|
||||
const exec::opts &opts)
|
||||
|
|
Loading…
Reference in a new issue