void default_actor_addressing::write(serializer* sink, const actor_ptr& ptr) { CPPA_REQUIRE(sink != nullptr); if (ptr == nullptr) { CPPA_LOGMF(CPPA_DEBUG, self, "serialized nullptr"); sink->begin_object("@0"); sink->end_object(); } else { // local actor? if (!ptr->is_proxy()) { get_actor_registry()->put(ptr->id(), ptr); } auto pinf = m_pinf; if (ptr->is_proxy()) { auto dptr = ptr.downcast<default_actor_proxy>(); if (dptr) pinf = dptr->process_info(); else CPPA_LOGMF(CPPA_ERROR, self, "downcast failed"); } sink->begin_object("@actor"); sink->write_value(ptr->id()); sink->write_value(pinf->process_id()); sink->write_raw(process_information::node_id_size, pinf->node_id().data()); sink->end_object(); } }
void add_arguments_to_kernel_rec(evnt_vec& events, args_vec& arguments, T0& arg0, Ts&... args) { cl_int err{0}; size_t buffer_size = sizeof(typename T0::value_type) * arg0.size(); auto buffer = clCreateBuffer(m_context.get(), CL_MEM_READ_ONLY, buffer_size, nullptr, &err); if (err != CL_SUCCESS) { CPPA_LOGMF(CPPA_ERROR, "clCreateBuffer: " << get_opencl_error(err)); return; } cl_event event; err = clEnqueueWriteBuffer(m_queue.get(), buffer, CL_FALSE, 0, buffer_size, arg0.data(), 0, nullptr, &event); if (err != CL_SUCCESS) { CPPA_LOGMF(CPPA_ERROR, "clEnqueueWriteBuffer: " << get_opencl_error(err)); return; } events.push_back(std::move(event)); mem_ptr tmp; tmp.adopt(std::move(buffer)); arguments.push_back(tmp); add_arguments_to_kernel_rec(events, arguments, args...); }
actor_ptr default_actor_addressing::read(deserializer* source) { CPPA_REQUIRE(source != nullptr); auto cname = source->seek_object(); if (cname == "@0") { CPPA_LOGMF(CPPA_DEBUG, self, "deserialized nullptr"); source->begin_object("@0"); source->end_object(); return nullptr; } else if (cname == "@actor") { process_information::node_id_type nid; source->begin_object(cname); auto aid = source->read<uint32_t>(); auto pid = source->read<uint32_t>(); source->read_raw(process_information::node_id_size, nid.data()); source->end_object(); // local actor? auto pinf = process_information::get(); if (pid == pinf->process_id() && nid == pinf->node_id()) { return get_actor_registry()->get(aid); } else { process_information tmp(pid, nid); return get_or_put(tmp, aid); } } else throw runtime_error("expected type name \"@0\" or \"@actor\"; " "found: " + cname); }
void default_actor_addressing::erase(process_information& inf, actor_id aid) { CPPA_LOGMF(CPPA_TRACE, self, CPPA_TARG(inf, to_string) << ", " << CPPA_ARG(aid)); auto i = m_proxies.find(inf); if (i != m_proxies.end()) { i->second.erase(aid); } }
~command() { cl_int err{0}; for(auto& e : m_events) { err = clReleaseEvent(e); if (err != CL_SUCCESS) { CPPA_LOGMF(CPPA_ERROR, "clReleaseEvent: " << get_opencl_error(err)); } } }
actor_ptr default_actor_addressing::get_or_put(const process_information& inf, actor_id aid) { auto result = get(inf, aid); if (result == nullptr) { CPPA_LOGMF(CPPA_INFO, self, "created new proxy instance; " << CPPA_TARG(inf, to_string) << ", " << CPPA_ARG(aid)); auto ptr = make_counted<default_actor_proxy>(aid, new process_information(inf), m_parent); put(inf, aid, ptr); result = ptr; } return result; }
void add_arguments_to_kernel(evnt_vec& events, args_vec& arguments, size_t ret_size, Ts&&... args) { arguments.clear(); cl_int err{ 0 }; auto buf = clCreateBuffer(m_context.get(), CL_MEM_WRITE_ONLY, sizeof(typename R::value_type) * ret_size, nullptr, &err); if (err != CL_SUCCESS) { CPPA_LOGMF(CPPA_ERROR, "clCreateBuffer: " << get_opencl_error(err)); return; } mem_ptr tmp; tmp.adopt(std::move(buf)); arguments.push_back(tmp); add_arguments_to_kernel_rec(events, arguments, std::forward<Ts>(args)...); }
void default_actor_addressing::put(const process_information& node, actor_id aid, const actor_proxy_ptr& proxy) { auto& submap = m_proxies[node]; auto i = submap.find(aid); if (i == submap.end()) { submap.insert(make_pair(aid, proxy)); m_parent->enqueue(node, {nullptr, nullptr}, make_any_tuple(atom("MONITOR"), process_information::get(), aid)); } else { CPPA_LOGMF(CPPA_ERROR, self, "proxy for " << aid << ":" << to_string(node) << " already exists"); } }
void enqueue_impl(const actor_addr& sender, any_tuple msg, message_id id, util::int_list<Is...>) { auto opt = m_map_args(std::move(msg)); if (opt) { response_promise handle{this->address(), sender, id.response_id()}; evnt_vec events; args_vec arguments; add_arguments_to_kernel<Ret>(events, arguments, m_result_size, get_ref<Is>(*opt)...); auto cmd = make_counted<command<actor_facade, Ret>>( handle, this, std::move(events), std::move(arguments), m_result_size, *opt ); cmd->enqueue(); } else { CPPA_LOGMF(CPPA_ERROR, "actor_facade::enqueue() tuple_cast failed."); } }
void default_actor_addressing::erase(process_information& inf) { CPPA_LOGMF(CPPA_TRACE, self, CPPA_TARG(inf, to_string)); m_proxies.erase(inf); }
void enqueue () { CPPA_LOG_TRACE("command::enqueue()"); this->ref(); // reference held by the OpenCL comand queue cl_int err{0}; cl_event event_k; auto data_or_nullptr = [](const dim_vec& vec) { return vec.empty() ? nullptr : vec.data(); }; err = clEnqueueNDRangeKernel(m_queue.get(), m_actor_facade->m_kernel.get(), m_actor_facade->m_global_dimensions.size(), data_or_nullptr(m_actor_facade->m_global_offsets), data_or_nullptr(m_actor_facade->m_global_dimensions), data_or_nullptr(m_actor_facade->m_local_dimensions), m_events.size(), (m_events.empty() ? nullptr : m_events.data()), &event_k); if (err != CL_SUCCESS) { CPPA_LOGMF(CPPA_ERROR, "clEnqueueNDRangeKernel: " << get_opencl_error(err)); this->deref(); // or can anything actually happen? return; } else { cl_event event_r; err = clEnqueueReadBuffer(m_queue.get(), m_arguments.back().get(), CL_FALSE, 0, sizeof(typename R::value_type) * m_result_size, m_result.data(), 1, &event_k, &event_r); if (err != CL_SUCCESS) { throw std::runtime_error("clEnqueueReadBuffer: " + get_opencl_error(err)); this->deref(); // failed to enqueue command return; } err = clSetEventCallback(event_r, CL_COMPLETE, [](cl_event, cl_int, void* data) { auto cmd = reinterpret_cast<command*>(data); cmd->handle_results(); cmd->deref(); }, this); if (err != CL_SUCCESS) { CPPA_LOGMF(CPPA_ERROR, "clSetEventCallback: " << get_opencl_error(err)); this->deref(); // callback is not set return; } err = clFlush(m_queue.get()); if (err != CL_SUCCESS) { CPPA_LOGMF(CPPA_ERROR, "clFlush: " << get_opencl_error(err)); } m_events.push_back(std::move(event_k)); m_events.push_back(std::move(event_r)); } }