diff --git a/include/user/spMcRingBuffer.h b/include/user/spMcRingBuffer.h index afadc9e..f4a350a 100644 --- a/include/user/spMcRingBuffer.h +++ b/include/user/spMcRingBuffer.h @@ -6,7 +6,9 @@ #include #include #include +#include #include +#include #include namespace smo { @@ -24,32 +26,35 @@ class SpMcRingBuffer { public: /** EXPLANATION: - * Constructor initializes the ring buffer with the given constraints and - * number of buffers. Allocates slots vector with properly constructed - * StimulusFrame instances. + * Constructor initializes the ring buffer with FrameAssemblyDesc. + * Allocates frames vector with properly constructed StimulusFrame instances, + * each initialized with a SlotDesc from the FrameAssemblyDesc. */ explicit SpMcRingBuffer( - size_t nBuffers_, - const StagingBuffer::IOEngineConstraints& inputEngineConstraints, - const StagingBuffer::IOEngineConstraints& outputEngineConstraints, - size_t nSlotsPerStimFrame) - : nBuffers(nBuffers_), - // Default-construct all frames - slots(nBuffers) + const std::shared_ptr &frameAssemblyDesc_) + : + nBuffers(frameAssemblyDesc_ ? frameAssemblyDesc_->slots.size() : 0), + frameAssemblyDesc(frameAssemblyDesc_), + slots(nBuffers) // Default-construct all frames { + if (!frameAssemblyDesc) + { + throw std::invalid_argument(std::string(__func__) + + ": SpMcRingBuffer: frameAssemblyDesc must not be null"); + } + if (nBuffers == 0) { throw std::invalid_argument(std::string(__func__) - + ": SpMcRingBuffer: nBuffers must be > 0"); + + ": SpMcRingBuffer: frameAssemblyDesc must have at least one " + "slot"); } // Re-invoke constructors w/placement new on default-constructed frames for (size_t i = 0; i < nBuffers; ++i) { slots[i].~StimulusFrame(); // Destroy default-constructed object - new (&slots[i]) StimulusFrame( - inputEngineConstraints, outputEngineConstraints, - nSlotsPerStimFrame); + new (&slots[i]) StimulusFrame(frameAssemblyDesc->slots[i]); } } @@ -94,7 +99,9 @@ public: size_t nBuffers; private: - // Frames vector: each frame contains a sequence lock and staging buffer + // FrameAssemblyDesc describing the memory layout + std::shared_ptr frameAssemblyDesc; + // Frames vector: each frame contains a sequence lock and SlotDesc std::vector slots; }; diff --git a/include/user/stimulusBuffer.h b/include/user/stimulusBuffer.h index cd898c9..7569954 100644 --- a/include/user/stimulusBuffer.h +++ b/include/user/stimulusBuffer.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "stimulusFrame.h" #include "deviceAttachmentSpec.h" @@ -30,15 +31,15 @@ public: &deviceAttachmentSpec, int histbuffMs, const StagingBuffer::IOEngineConstraints& inputEngineConstraints, - const StagingBuffer::IOEngineConstraints& outputEngineConstraints, - size_t nSlotsPerStimFrame) + const StagingBuffer::IOEngineConstraints& outputEngineConstraints) : parent(parent), deviceAttachmentSpec(deviceAttachmentSpec), histbuffMs(histbuffMs), - ringBuffer( - static_cast(histbuffMs / CONFIG_STIMBUFF_FRAME_PERIOD_MS), - inputEngineConstraints, outputEngineConstraints, - nSlotsPerStimFrame) + stagingBuffer( + inputEngineConstraints, + outputEngineConstraints, + static_cast(histbuffMs / CONFIG_STIMBUFF_FRAME_PERIOD_MS)), + ringBuffer(static_cast>(stagingBuffer)) {} virtual ~StimulusBuffer() = default; @@ -53,6 +54,7 @@ public: StimulusProducer& parent; std::shared_ptr deviceAttachmentSpec; int histbuffMs; + StagingBuffer stagingBuffer; SpMcRingBuffer ringBuffer; }; diff --git a/include/user/stimulusFrame.h b/include/user/stimulusFrame.h index 40e533c..32caea7 100644 --- a/include/user/stimulusFrame.h +++ b/include/user/stimulusFrame.h @@ -2,7 +2,7 @@ #define _ATTACHMENT_SUPPORT_STIMULUS_FRAME_H #include -#include +#include #include namespace smo { @@ -69,12 +69,8 @@ public: */ StimulusFrame() = default; - StimulusFrame( - const StagingBuffer::IOEngineConstraints& inputEngineConstraints, - const StagingBuffer::IOEngineConstraints& outputEngineConstraints, - size_t nSlots) - : stagingBuffer( - inputEngineConstraints, outputEngineConstraints, nSlots) + StimulusFrame(const FrameAssemblyDesc::SlotDesc& slotDesc_) + : slotDesc(slotDesc_) {} ~StimulusFrame() = default; @@ -88,7 +84,7 @@ public: public: SequenceLock lock; SimultaneityStamp simultaneityStamp; - StagingBuffer stagingBuffer; + FrameAssemblyDesc::SlotDesc slotDesc; }; } // namespace stim_buff diff --git a/stimBuffApis/livoxGen1/meshStimulusBuffer.h b/stimBuffApis/livoxGen1/meshStimulusBuffer.h index 67b80fc..f5d4a49 100644 --- a/stimBuffApis/livoxGen1/meshStimulusBuffer.h +++ b/stimBuffApis/livoxGen1/meshStimulusBuffer.h @@ -23,11 +23,10 @@ public: const std::shared_ptr& deviceAttachmentSpec, int histbuffMs, const StagingBuffer::IOEngineConstraints& inputEngineConstraints, - const StagingBuffer::IOEngineConstraints& outputEngineConstraints, - size_t nSlotsPerStimFrame) + const StagingBuffer::IOEngineConstraints& outputEngineConstraints) : StimulusBuffer( parent, deviceAttachmentSpec, histbuffMs, - inputEngineConstraints, outputEngineConstraints, nSlotsPerStimFrame) + inputEngineConstraints, outputEngineConstraints) {} ~MeshStimulusBuffer() = default; diff --git a/stimBuffApis/livoxGen1/pcloudAmbienceStimulusBuffer.h b/stimBuffApis/livoxGen1/pcloudAmbienceStimulusBuffer.h index 564a27f..c10d20d 100644 --- a/stimBuffApis/livoxGen1/pcloudAmbienceStimulusBuffer.h +++ b/stimBuffApis/livoxGen1/pcloudAmbienceStimulusBuffer.h @@ -23,11 +23,10 @@ public: const std::shared_ptr& deviceAttachmentSpec, int histbuffMs, const StagingBuffer::IOEngineConstraints& inputEngineConstraints, - const StagingBuffer::IOEngineConstraints& outputEngineConstraints, - size_t nSlotsPerStimFrame) + const StagingBuffer::IOEngineConstraints& outputEngineConstraints) : StimulusBuffer( parent, deviceAttachmentSpec, histbuffMs, - inputEngineConstraints, outputEngineConstraints, nSlotsPerStimFrame) + inputEngineConstraints, outputEngineConstraints) {} ~PcloudAmbienceStimulusBuffer() = default; diff --git a/stimBuffApis/livoxGen1/pcloudIntensityStimulusBuffer.h b/stimBuffApis/livoxGen1/pcloudIntensityStimulusBuffer.h index 9507a68..8aa10ef 100644 --- a/stimBuffApis/livoxGen1/pcloudIntensityStimulusBuffer.h +++ b/stimBuffApis/livoxGen1/pcloudIntensityStimulusBuffer.h @@ -24,11 +24,10 @@ public: &deviceAttachmentSpec, int histbuffMs, const StagingBuffer::IOEngineConstraints& inputEngineConstraints, - const StagingBuffer::IOEngineConstraints& outputEngineConstraints, - size_t nSlotsPerStimFrame) + const StagingBuffer::IOEngineConstraints& outputEngineConstraints) : StimulusBuffer( parent, deviceAttachmentSpec, histbuffMs, - inputEngineConstraints, outputEngineConstraints, nSlotsPerStimFrame) + inputEngineConstraints, outputEngineConstraints) {} ~PcloudIntensityStimulusBuffer() = default; diff --git a/stimBuffApis/livoxGen1/pcloudStimulusProducer.cpp b/stimBuffApis/livoxGen1/pcloudStimulusProducer.cpp index 50bd404..bb202b5 100644 --- a/stimBuffApis/livoxGen1/pcloudStimulusProducer.cpp +++ b/stimBuffApis/livoxGen1/pcloudStimulusProducer.cpp @@ -18,10 +18,24 @@ extern const SmoCallbacks* smoHooksPtr; // OpenCL kernels are used to collate and produce our StimFrames. static StagingBuffer::IOEngineConstraints openClInputConstraints( + /** FIXME: + * This should eventually be aligned to 4B and padded to 12B. + */ // slotStartAlignmentByteVal (page alignment) - sizeof(float) * 3, + sizeof(float) * 4, // slotPadToNBytes (pointer size) - sizeof(void *), + sizeof(float) * 4, + // frameStartAlignmentByteVal (page alignment) + static_cast(sysconf(_SC_PAGE_SIZE)), + // framePadToNBytes (pointer size) + static_cast(sysconf(_SC_PAGE_SIZE))); + +// OpenCL kernels are used to collate and produce our StimFrames. +static StagingBuffer::IOEngineConstraints openClMeshInputConstraints( + // slotStartAlignmentByteVal (page alignment) + static_cast(sysconf(_SC_PAGE_SIZE)), + // slotPadToNBytes (pointer size) + sizeof(float) * 3, // frameStartAlignmentByteVal (page alignment) static_cast(sysconf(_SC_PAGE_SIZE)), // framePadToNBytes (pointer size) @@ -29,7 +43,7 @@ static StagingBuffer::IOEngineConstraints openClInputConstraints( static StagingBuffer::IOEngineConstraints openClIntensityInputConstraints( // slotStartAlignmentByteVal (page alignment) - sizeof(float), + static_cast(sysconf(_SC_PAGE_SIZE)), // slotPadToNBytes (intensity value size) sizeof(float), // frameStartAlignmentByteVal (page alignment) @@ -39,9 +53,9 @@ static StagingBuffer::IOEngineConstraints openClIntensityInputConstraints( static StagingBuffer::IOEngineConstraints openClAmbienceInputConstraints( // slotStartAlignmentByteVal (page alignment) - sizeof(float), + static_cast(sysconf(_SC_PAGE_SIZE)), // slotPadToNBytes (pointer size) - sizeof(void *), + sizeof(float), // frameStartAlignmentByteVal (page alignment) static_cast(sysconf(_SC_PAGE_SIZE)), // framePadToNBytes (pointer size) @@ -68,10 +82,11 @@ collationBuffer( StagingBuffer::IOEngineConstraints::openClInputConstraints, StagingBuffer::IOEngineConstraints::openClInputConstraints, nDgramsPerStagingBufferFrame), -tempStimulusFrame( - StagingBuffer::IOEngineConstraints::openClInputConstraints, - StagingBuffer::IOEngineConstraints::openClInputConstraints, - nDgramsPerStagingBufferFrame) +tempStimulusFrameMem(0), +tempStimulusFrame(FrameAssemblyDesc::SlotDesc{ + 0, + reinterpret_cast(&tempStimulusFrameMem), + sizeof(tempStimulusFrameMem)}) { if (smoHooksPtr->OptionParser_getOptions().verbose) { @@ -204,19 +219,24 @@ PcloudStimulusProducer::getOrCreateAttachedStimulusBuffer( // Parse qualeIfaceApi to determine buffer type const std::string& qualeIfaceApi = deviceAttachmentSpec->qualeIfaceApi; - // Calculate nPointsPerStimFrame based on return mode + // Calculate nPointsPerDgram based on return mode size_t nPointsPerDgram = livoxProto1::Device::getNPointsPerDgram( static_cast(device->currentReturnMode)); - size_t nPointsPerStimFrame = this->nDgramsPerStagingBufferFrame - * nPointsPerDgram; if (qualeIfaceApi == "mesh") { + /* Calculate slotStrideNBytes: + * nDgramsPerStagingBufferFrame * nPointsPerDgram * sizeof(float) * 3 + */ + size_t slotStrideNBytes = this->nDgramsPerStagingBufferFrame + * nPointsPerDgram * sizeof(float) * 3; + // Reuse openClMeshInputConstraints, only modify slotPadToNBytes + openClMeshInputConstraints.slotPadToNBytes = slotStrideNBytes; + std::cout << __func__ << ": $$$$$$$ Creating MeshStimulusBuffer" << std::endl; auto meshBuffer = std::make_shared( *this, deviceAttachmentSpec, histbuffMs, - openClInputConstraints, openClInputConstraints, - nPointsPerStimFrame); + openClMeshInputConstraints, openClMeshInputConstraints); std::cout << __func__ << ": $$$$$$$ Created MeshStimulusBuffer" << std::endl; meshStimulusBuffer = meshBuffer; @@ -225,11 +245,18 @@ std::cout << __func__ << ": $$$$$$$ Created MeshStimulusBuffer" << std::endl; } else if (qualeIfaceApi == "pcloudIntensity") { + /* Calculate slotStrideNBytes: + * nDgramsPerStagingBufferFrame * nPointsPerDgram * sizeof(float) * 1 + */ + size_t slotStrideNBytes = this->nDgramsPerStagingBufferFrame + * nPointsPerDgram * sizeof(float) * 1; + // Reuse openClIntensityInputConstraints, only modify slotPadToNBytes + openClIntensityInputConstraints.slotPadToNBytes = slotStrideNBytes; + std::cout << __func__ << ": $$$$$$$ Creating PcloudIntensityStimulusBuffer" << std::endl; auto intensityBuffer = std::make_shared( *this, deviceAttachmentSpec, histbuffMs, - openClIntensityInputConstraints, openClIntensityInputConstraints, - nPointsPerStimFrame); + openClIntensityInputConstraints, openClIntensityInputConstraints); std::cout << __func__ << ": $$$$$$$ Created PcloudIntensityStimulusBuffer" << std::endl; intensityStimulusBuffer = intensityBuffer; @@ -238,11 +265,17 @@ std::cout << __func__ << ": $$$$$$$ Created PcloudIntensityStimulusBuffer" << st } else if (qualeIfaceApi == "pcloudAmbience") { -std::cout << __func__ << ": $$$$$$$ Creating PcloudAmbienceStimulusBuffer" << std::endl; + /* Calculate slotStrideNBytes: + * nDgramsPerStagingBufferFrame * sizeof(float) + */ + size_t slotStrideNBytes = this->nDgramsPerStagingBufferFrame + * sizeof(float); + // Reuse openClAmbienceInputConstraints, only modify slotPadToNBytes + openClAmbienceInputConstraints.slotPadToNBytes = slotStrideNBytes; + auto ambienceBuffer = std::make_shared( *this, deviceAttachmentSpec, histbuffMs, - openClAmbienceInputConstraints, openClAmbienceInputConstraints, - nDgramsPerStagingBufferFrame); + openClAmbienceInputConstraints, openClAmbienceInputConstraints); std::cout << __func__ << ": $$$$$$$ Created PcloudAmbienceStimulusBuffer" << std::endl; ambienceStimulusBuffer = ambienceBuffer; diff --git a/stimBuffApis/livoxGen1/pcloudStimulusProducer.h b/stimBuffApis/livoxGen1/pcloudStimulusProducer.h index f761732..f564953 100644 --- a/stimBuffApis/livoxGen1/pcloudStimulusProducer.h +++ b/stimBuffApis/livoxGen1/pcloudStimulusProducer.h @@ -86,6 +86,7 @@ public: StagingBuffer assemblyBuffer; IoUringAssemblyEngine ioUringAssemblyEngine; StagingBuffer collationBuffer; + size_t tempStimulusFrameMem; StimulusFrame tempStimulusFrame; std::shared_ptr meshStimulusBuffer; std::shared_ptr intensityStimulusBuffer;