Skip to content

Commit

Permalink
Implement (un)mapArray
Browse files Browse the repository at this point in the history
  • Loading branch information
szellmann authored and jeffamstutz committed Jun 20, 2023
1 parent a702d7a commit fc225a0
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 6 deletions.
58 changes: 55 additions & 3 deletions libs/remote_device/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,42 @@ ANARIArray3D Device::newArray3D(const void *appMemory,
byteStride3);
}

void *Device::mapArray(ANARIArray)
void *Device::mapArray(ANARIArray array)
{
return nullptr;
auto buf = std::make_shared<Buffer>();
buf->write((const char *)&remoteDevice, sizeof(remoteDevice));
buf->write((const char *)&array, sizeof(array));
write(MessageType::MapArray, buf);

std::unique_lock l(syncMapArray.mtx);
std::vector<char> &data = arrays[array];
syncMapArray.cv.wait(l, [&]() { return !data.empty(); });
l.unlock();

LOG(logging::Level::Info) << "Array mapped: " << array;

return data.data();
}

void Device::unmapArray(ANARIArray) {}
void Device::unmapArray(ANARIArray array)
{
auto buf = std::make_shared<Buffer>();
buf->write((const char *)&remoteDevice, sizeof(remoteDevice));
buf->write((const char *)&array, sizeof(array));
uint64_t numBytes = arrays[array].size();
buf->write((const char *)&numBytes, sizeof(numBytes));
buf->write(arrays[array].data(), numBytes);
write(MessageType::UnmapArray, buf);

std::unique_lock l(syncMapArray.mtx);
std::vector<char> &data = arrays[array];
syncMapArray.cv.wait(l, [&]() { return data.empty(); });
l.unlock();

arrays.erase(array);

LOG(logging::Level::Info) << "Array unmapped: " << array;
}

//--- Renderable Objects ------------------------------

Expand Down Expand Up @@ -671,6 +701,28 @@ void Device::handleMessage(async::connection::reason reason,
l.unlock();
syncDeviceHandleRemote.cv.notify_all();
LOG(logging::Level::Info) << "Got remote device handle: " << remoteDevice;
} else if (message->type() == MessageType::ArrayMapped) {
std::unique_lock l(syncMapArray.mtx);

char *msg = message->data();

ANARIArray arr = *(ANARIArray *)message->data();
msg += sizeof(ANARIArray);
uint64_t numBytes = 0;
memcpy(&numBytes, msg, sizeof(numBytes));
msg += sizeof(numBytes);

arrays[arr].resize(numBytes);
memcpy(arrays[arr].data(), msg, numBytes);
l.unlock();
syncMapArray.cv.notify_all();
} else if (message->type() == MessageType::ArrayUnmapped) {
std::unique_lock l(syncUnmapArray.mtx);
char *msg = message->data();
ANARIArray arr = *(ANARIArray *)message->data();
arrays[arr].resize(0);
l.unlock();
syncMapArray.cv.notify_all();
} else if (message->type() == MessageType::FrameIsReady) {
assert(message->size() == sizeof(Handle));
ANARIObject hnd = *(ANARIObject *)message->data();
Expand Down
13 changes: 13 additions & 0 deletions libs/remote_device/Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,18 @@ struct Device : anari::DeviceImpl, helium::ParameterizedObject
std::condition_variable cv;
} syncDeviceHandleRemote;

struct
{
std::mutex mtx;
std::condition_variable cv;
} syncMapArray;

struct
{
std::mutex mtx;
std::condition_variable cv;
} syncUnmapArray;

struct
{
std::mutex mtx;
Expand Down Expand Up @@ -197,6 +209,7 @@ struct Device : anari::DeviceImpl, helium::ParameterizedObject
std::vector<StringListProperty> stringListProperties;

std::map<ANARIObject, Frame> frames;
std::map<ANARIArray, std::vector<char>> arrays;

ANARIObject registerNewObject(ANARIDataType type, std::string subtype = "");
ANARIArray registerNewArray(ANARIDataType type,
Expand Down
115 changes: 112 additions & 3 deletions libs/remote_device/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ static ANARIArray newArray(
info.byteStride3);
}

if (array) {
if (array && data) {
void *ptr = anariMapArray(dev, array);
memcpy(ptr, data, info.getSizeInBytes());
anariUnmapArray(dev, array);
Expand All @@ -147,6 +147,7 @@ struct ResourceManager
size_t newNumHandles = std::max(anariDevices.size(), (size_t)handle + 1);
anariDevices.resize(newNumHandles);
serverObjects.resize(newNumHandles);
serverArrays.resize(newNumHandles);
anariDevices[handle] = dev;
return handle;
}
Expand All @@ -165,6 +166,22 @@ struct ResourceManager
anariDevices[deviceID], anariObj, type};
}

// Like registerObject, but stores array size; so we can later
// send the whole array data back to the client on mapArray()
void registerArray(uint64_t deviceID,
uint64_t objectID,
ANARIObject anariObj,
const ArrayInfo &info)
{
registerObject(deviceID, objectID, anariObj, info.type);

size_t newNumHandles =
std::max(serverArrays[deviceID].size(), (size_t)objectID + 1);

serverArrays[deviceID].resize(newNumHandles);
serverArrays[deviceID][objectID] = info;
}

ANARIDevice getDevice(uint64_t deviceID)
{
if (deviceID >= anariDevices.size())
Expand All @@ -182,12 +199,24 @@ struct ResourceManager
return serverObjects[deviceHandle][objectHandle];
}

ArrayInfo getArrayInfo(Handle deviceHandle, Handle objectHandle)
{
if (deviceHandle >= serverArrays.size()
|| objectHandle >= serverArrays[deviceHandle].size())
return {};

return serverArrays[deviceHandle][objectHandle];
}

Handle nextDeviceHandle = 1;

std::vector<ANARIDevice> anariDevices;

// vector of anari objects per device
std::vector<std::vector<ServerObject>> serverObjects;

// vector of array infos per device
std::vector<std::vector<ArrayInfo>> serverArrays;
};

struct Server
Expand Down Expand Up @@ -389,8 +418,8 @@ struct Server
}

ANARIArray anariArr = newArray(dev, info, arrayData.data());
resourceManager.registerObject(
(uint64_t)deviceHandle, objectID, anariArr, info.type);
resourceManager.registerArray(
(uint64_t)deviceHandle, objectID, anariArr, info);

LOG(logging::Level::Info)
<< "Creating new array, objectID: " << objectID
Expand Down Expand Up @@ -594,6 +623,86 @@ struct Server

LOG(logging::Level::Info)
<< "Retained object. Handle: " << objectHandle;
} else if (message->type() == MessageType::MapArray) {
LOG(logging::Level::Info) << "Message: MapArray, message size: "
<< prettyBytes(message->size());

Buffer buf;
buf.write(message->data(), message->size());
buf.seek(0);

Handle deviceHandle, objectHandle;
buf.read((char *)&deviceHandle, sizeof(deviceHandle));
buf.read((char *)&objectHandle, sizeof(objectHandle));

ANARIDevice dev = resourceManager.getDevice(deviceHandle);

ServerObject serverObj =
resourceManager.getServerObject(deviceHandle, objectHandle);

if (!dev || !serverObj.handle) {
LOG(logging::Level::Error)
<< "Error retaining object. Handle: " << objectHandle;
// manager->stop(); // legal?
return;
}

void *ptr = anariMapArray(dev, (ANARIArray)serverObj.handle);

const ArrayInfo &info = resourceManager.getArrayInfo(deviceHandle, objectHandle);

uint64_t numBytes = info.getSizeInBytes();

auto outbuf = std::make_shared<Buffer>();
outbuf->write((const char *)&objectHandle, sizeof(objectHandle));
outbuf->write((const char *)&numBytes, sizeof(numBytes));
outbuf->write((const char *)ptr, numBytes);
write(MessageType::ArrayMapped, outbuf);

LOG(logging::Level::Info)
<< "Mapped array. Handle: " << objectHandle;
} else if (message->type() == MessageType::UnmapArray) {
LOG(logging::Level::Info) << "Message: UnmapArray, message size: "
<< prettyBytes(message->size());

Buffer buf;
buf.write(message->data(), message->size());
buf.seek(0);

Handle deviceHandle, objectHandle;
buf.read((char *)&deviceHandle, sizeof(deviceHandle));
buf.read((char *)&objectHandle, sizeof(objectHandle));

ANARIDevice dev = resourceManager.getDevice(deviceHandle);

ServerObject serverObj =
resourceManager.getServerObject(deviceHandle, objectHandle);

if (!dev || !serverObj.handle) {
LOG(logging::Level::Error)
<< "Error retaining object. Handle: " << objectHandle;
// manager->stop(); // legal?
return;
}

// Array is currently mapped - unmap
anariUnmapArray(dev, (ANARIArray)serverObj.handle);

// Now map so we can write to it
void *ptr = anariMapArray(dev, (ANARIArray)serverObj.handle);
uint64_t numBytes = 0;
buf.read((char *)&numBytes, sizeof(numBytes));
buf.read((char *)ptr, numBytes);

// Unmap again..
anariUnmapArray(dev, (ANARIArray)serverObj.handle);

auto outbuf = std::make_shared<Buffer>();
outbuf->write((const char *)&objectHandle, sizeof(objectHandle));
write(MessageType::ArrayUnmapped, outbuf);

LOG(logging::Level::Info)
<< "Unmapped array. Handle: " << objectHandle;
} else if (message->type() == MessageType::RenderFrame) {
LOG(logging::Level::Info) << "Message: RenderFrame, message size: "
<< prettyBytes(message->size());
Expand Down
4 changes: 4 additions & 0 deletions libs/remote_device/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ struct MessageType
Release,
Retain,
ArrayData,
MapArray,
ArrayMapped,
UnmapArray,
ArrayUnmapped,
RenderFrame,
FrameReady,
FrameIsReady,
Expand Down

0 comments on commit fc225a0

Please sign in to comment.