Skip to content

Commit

Permalink
WIP: Towards SVM memory pool
Browse files Browse the repository at this point in the history
  • Loading branch information
inducer committed Jul 25, 2022
1 parent 0dcd53e commit 1f4f769
Show file tree
Hide file tree
Showing 5 changed files with 312 additions and 85 deletions.
15 changes: 12 additions & 3 deletions pyopencl/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

import numpy as np
from pytools import memoize, memoize_method
from pyopencl._cl import bitlog2 # noqa: F401
from pyopencl._cl import bitlog2, get_cl_header_version # noqa: F401
from pytools.persistent_dict import KeyBuilder as KeyBuilderBase

import re
Expand All @@ -59,10 +59,19 @@ def _register_types():
# {{{ imported names

from pyopencl._cl import ( # noqa
PooledBuffer as PooledBuffer,
_tools_PooledBuffer as PooledBuffer,
_tools_DeferredAllocator as DeferredAllocator,
_tools_ImmediateAllocator as ImmediateAllocator,
MemoryPool as MemoryPool)
_tools_MemoryPool as MemoryPool,
)


if get_cl_header_version() >= (2, 0):
from pyopencl._cl import ( # noqa
_tools_SVMemoryPool as SVMemoryPool,
_tools_PooledSVM as PooledSVM,
_tools_SVMAllocator as SVMAllocator,
)

# }}}

Expand Down
30 changes: 12 additions & 18 deletions src/mempool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ namespace PYGPU_PACKAGE
std::cout
<< "[pool] allocation of size " << size << " served from bin " << bin_nr
<< " which contained " << bin.size() << " entries" << std::endl;
return pop_block_from_bin(bin, size);
return m_allocator->hand_out_existing_block(
pop_block_from_bin(bin, size));
}

size_type alloc_sz = alloc_size(bin_nr);
Expand All @@ -256,7 +257,8 @@ namespace PYGPU_PACKAGE

m_allocator->try_release_blocks();
if (bin.size())
return pop_block_from_bin(bin, size);
return m_allocator->hand_out_existing_block(
pop_block_from_bin(bin, size));

if (m_trace)
std::cout << "[pool] allocation still OOM after GC" << std::endl;
Expand All @@ -282,7 +284,7 @@ namespace PYGPU_PACKAGE
"failed to free memory for allocation");
}

void free(pointer_type p, size_type size)
void free(pointer_type &&p, size_type size)
{
--m_active_blocks;
m_active_bytes -= size;
Expand All @@ -291,7 +293,7 @@ namespace PYGPU_PACKAGE
if (!m_stop_holding)
{
inc_held_blocks();
get_bin(bin_nr).push_back(p);
get_bin(bin_nr).push_back(std::move(p));

if (m_trace)
std::cout << "[pool] block of size " << size << " returned to bin "
Expand All @@ -300,7 +302,7 @@ namespace PYGPU_PACKAGE
}
else
{
m_allocator->free(p);
m_allocator->free(std::move(p));
m_managed_bytes -= alloc_size(bin_nr);
}
}
Expand All @@ -313,7 +315,7 @@ namespace PYGPU_PACKAGE

while (bin.size())
{
m_allocator->free(bin.back());
m_allocator->free(std::move(bin.back()));
m_managed_bytes -= alloc_size(bin_pair.first);
bin.pop_back();

Expand Down Expand Up @@ -353,7 +355,7 @@ namespace PYGPU_PACKAGE

if (bin.size())
{
m_allocator->free(bin.back());
m_allocator->free(std::move(bin.back()));
m_managed_bytes -= alloc_size(bin_pair.first);
bin.pop_back();

Expand All @@ -379,7 +381,7 @@ namespace PYGPU_PACKAGE

pointer_type pop_block_from_bin(bin_t &bin, size_type size)
{
pointer_type result = bin.back();
pointer_type result(std::move(bin.back()));
bin.pop_back();

dec_held_blocks();
Expand All @@ -399,7 +401,7 @@ namespace PYGPU_PACKAGE
typedef typename Pool::pointer_type pointer_type;
typedef typename Pool::size_type size_type;

private:
protected:
PYGPU_SHARED_PTR<pool_type> m_pool;

pointer_type m_ptr;
Expand All @@ -421,7 +423,7 @@ namespace PYGPU_PACKAGE
{
if (m_valid)
{
m_pool->free(m_ptr, m_size);
m_pool->free(std::move(m_ptr), m_size);
m_valid = false;
}
else
Expand All @@ -435,16 +437,8 @@ namespace PYGPU_PACKAGE
#endif
);
}

pointer_type ptr() const
{ return m_ptr; }

size_type size() const
{ return m_size; }
};
}




#endif
28 changes: 17 additions & 11 deletions src/wrap_cl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1708,7 +1708,13 @@ namespace pyopencl
src.m_valid = false;
}

command_queue_ref(const command_queue_ref &) = delete;
command_queue_ref(const command_queue_ref &)
{
throw error("command_queue_ref", CL_INVALID_VALUE,
"command_queue_ref copy constructor is never supposed to be called; "
"all notional invocations should be eliminated because of NRVO");
}

command_queue_ref &operator=(const command_queue_ref &) = delete;

~command_queue_ref()
Expand Down Expand Up @@ -3545,7 +3551,7 @@ namespace pyopencl
class svm_pointer
{
public:
virtual void *ptr() const = 0;
virtual void *svm_ptr() const = 0;
// may throw size_not_available
virtual size_t size() const = 0;
};
Expand Down Expand Up @@ -3578,7 +3584,7 @@ namespace pyopencl
m_size = ward->m_buf.len;
}

void *ptr() const
void *svm_ptr() const
{
return m_ptr;
}
Expand Down Expand Up @@ -3674,7 +3680,7 @@ namespace pyopencl
m_allocation = nullptr;
}

void *ptr() const
void *svm_ptr() const
{
return m_allocation;
}
Expand All @@ -3701,7 +3707,7 @@ namespace pyopencl

void bind_to_queue(command_queue const &queue)
{
if (is_queue_out_of_order(m_queue.data()))
if (is_queue_out_of_order(queue.data()))
throw error("SVMAllocation.bind_to_queue", CL_INVALID_VALUE,
"supplying an out-of-order queue to SVMAllocation is invalid");

Expand Down Expand Up @@ -3794,7 +3800,7 @@ namespace pyopencl
(
cq.data(),
is_blocking,
dst.ptr(), src.ptr(),
dst.svm_ptr(), src.svm_ptr(),
size,
PYOPENCL_WAITLIST_ARGS,
&evt
Expand Down Expand Up @@ -3856,7 +3862,7 @@ namespace pyopencl
clEnqueueSVMMemFill,
(
cq.data(),
dst.ptr(), pattern_ptr,
dst.svm_ptr(), pattern_ptr,
pattern_len,
size,
PYOPENCL_WAITLIST_ARGS,
Expand Down Expand Up @@ -3913,7 +3919,7 @@ namespace pyopencl
cq.data(),
is_blocking,
flags,
svm.ptr(), size,
svm.svm_ptr(), size,
PYOPENCL_WAITLIST_ARGS,
&evt
));
Expand All @@ -3936,7 +3942,7 @@ namespace pyopencl
clEnqueueSVMUnmap,
(
cq.data(),
svm.ptr(),
svm.svm_ptr(),
PYOPENCL_WAITLIST_ARGS,
&evt
));
Expand Down Expand Up @@ -3964,7 +3970,7 @@ namespace pyopencl
{
svm_pointer &svm(py::cast<svm_pointer &>(py_svm));

svm_pointers.push_back(svm.ptr());
svm_pointers.push_back(svm.svm_ptr());
sizes.push_back(svm.size());
}

Expand Down Expand Up @@ -4760,7 +4766,7 @@ namespace pyopencl
void set_arg_svm(cl_uint arg_index, svm_pointer const &wrp)
{
PYOPENCL_CALL_GUARDED(clSetKernelArgSVMPointer,
(m_kernel, arg_index, wrp.ptr()));
(m_kernel, arg_index, wrp.svm_ptr()));
}
#endif

Expand Down
4 changes: 2 additions & 2 deletions src/wrap_cl_part_2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ void pyopencl_expose_part_2(py::module &m)
{
typedef svm_pointer cls;
py::class_<cls>(m, "SVMPointer", py::dynamic_attr())
.def("_ptr_as_int", [](cls &self) { return (intptr_t) self.ptr(); })
.def("_ptr_as_int", [](cls &self) { return (intptr_t) self.svm_ptr(); })
.def("_size", [](cls &self) -> py::object
{
try
Expand Down Expand Up @@ -336,7 +336,7 @@ void pyopencl_expose_part_2(py::module &m)
"|std-enqueue-blurb|")
.def(py::self == py::self)
.def(py::self != py::self)
.def("__hash__", [](cls &self) { return (intptr_t) self.ptr(); })
.def("__hash__", [](cls &self) { return (intptr_t) self.svm_ptr(); })
.DEF_SIMPLE_METHOD(bind_to_queue)
.DEF_SIMPLE_METHOD(unbind_from_queue)
;
Expand Down
Loading

0 comments on commit 1f4f769

Please sign in to comment.