e689063a8c
Now each StimFrame knows its index within its parent SpMcRingbuff object.
124 lines
4.7 KiB
C++
124 lines
4.7 KiB
C++
#ifndef _ATTACHMENT_SUPPORT_STIMULUS_FRAME_H
|
|
#define _ATTACHMENT_SUPPORT_STIMULUS_FRAME_H
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <user/frameAssemblyDesc.h>
|
|
#include <user/sequenceLock.h>
|
|
#include <user/compute.h>
|
|
#include <user/senseApiDesc.h>
|
|
#define CL_TARGET_OPENCL_VERSION 120
|
|
#include <CL/cl.h>
|
|
|
|
namespace smo {
|
|
namespace stim_buff {
|
|
|
|
/** EXPLANATION:
|
|
* A simultaneity stamp is a timestamp that is used to determine whether two
|
|
* stimulus frames occured simultaneously. Its purpose is adamantly *NOT* to
|
|
* record or denote the "absolute" time of the stimulus frames. I cannot stress
|
|
* this enough. The simultaneity stamp is NOT used to record "when" the stimulus
|
|
* frame occured. It is used *SOLELY* to record that two or more stimulus frames
|
|
* occured at the same time.
|
|
*
|
|
* The SMO has absolutely no notion of "absolute" time. It only has a notion of
|
|
* simultaneity among stimulus frames. Any notions of "absolute" time are built
|
|
* up consciously and volitionally by the running mind, and not baked into the
|
|
* underlying software (i.e: Salmanoff).
|
|
*
|
|
* We need about 36 bits of unique simultaneity per year, assuming that we only
|
|
* expect to capture 1000 stim frames per second. 1000 is a lot of stim frames
|
|
* per second. If we use a 64 bit integer, that leaves us with 2^28 years
|
|
* before our simultaneity stamps roll over. That's 256 million years.
|
|
*
|
|
* The calculation we used to arrive at 36 bits is as follows:
|
|
* hex(86400 * 400 * 1000) = 0x80befc000
|
|
* * 86400 = seconds per day.
|
|
* * 400 = days per year.
|
|
* * 1000 = stim frames per second.
|
|
* As you can see, our extremely cautious calculation resulted in 36 bits.
|
|
* If we use a UUID (128 bits), we can basically be fairly sure we won't
|
|
* rollover for ...aeons. Now the question is: should we use a UUID or a 64 bit
|
|
* integer?
|
|
*
|
|
* It's important to note that simultaneity stamps are not used in all mental
|
|
* entities. They're only used in raw chronomena recordings, and possibly
|
|
* also in artificed memory chronomena. Among the artificed chronomena, their
|
|
* simultaneity lifetime is usually self-contained. Only the raw, observed
|
|
* chronomena have to retain a lifetime that is basically "the person's
|
|
* lifespan" (though not even necessarily that long).
|
|
*
|
|
* It may not even necessarily need to be lifespan-unique because the purpose of
|
|
* simultaneity stamps is to denote simultaneity among the stim frames that are
|
|
* __actually stored__ in the mind's memories. So if we forgot all stim frames
|
|
* with simultaneity stamps that older than say, 1000, then we can re-use all
|
|
* the simultaneity stamps that are numerically less than 1000. So there's some
|
|
* dynamic recycling, and we can prolly keep track of the oldest simultaneity
|
|
* stamp that we are currently using.
|
|
*
|
|
* Also, since simultaneity stamps are *NOT* used to record "when" the stimulus
|
|
* frame occured, we can also periodically run a reclaiming daemon process on
|
|
* our stored memories, which will try to defragment the simultaneity stamps
|
|
* in use by currently stored chronomena. Or we can silently mutate the
|
|
* simultaneity stamps of chronomena when committing them to backing storage;
|
|
* as well as when loading them from backing storage.
|
|
*/
|
|
typedef uint64_t SimultaneityStamp;
|
|
|
|
class StimulusFrame
|
|
{
|
|
public:
|
|
/** EXPLANATION:
|
|
* Default constructor creates uninitialized frame.
|
|
* Must be properly initialized using placement new with the parameterized constructor.
|
|
*/
|
|
StimulusFrame() = default;
|
|
|
|
StimulusFrame(
|
|
const FrameAssemblyDesc::SlotDesc& slotDesc_,
|
|
const SmoCallbacks& callbacks,
|
|
cl_mem_flags flags,
|
|
size_t ringBufferIndex_)
|
|
: slotDesc(slotDesc_),
|
|
ringBufferIndex(ringBufferIndex_)
|
|
{
|
|
if (!callbacks.ComputeManager_createUseHostPtrBuffer)
|
|
{
|
|
throw std::runtime_error(std::string(__func__)
|
|
+ ": StimulusFrame: ComputeManager_createUseHostPtrBuffer "
|
|
"callback is null");
|
|
}
|
|
|
|
clBuffer = callbacks.ComputeManager_createUseHostPtrBuffer(
|
|
slotDesc.vaddr, slotDesc.nBytes, flags);
|
|
|
|
if (!clBuffer)
|
|
{
|
|
throw std::runtime_error(std::string(__func__)
|
|
+ ": StimulusFrame: failed to create clBuffer");
|
|
}
|
|
|
|
// std::cout << __func__ << ": StimulusFrame: created clBuffer with size " << slotDesc.nBytes << " bytes @ " << (const void*)slotDesc.vaddr << std::endl;
|
|
}
|
|
|
|
~StimulusFrame() = default;
|
|
|
|
// Non-copyable, movable
|
|
StimulusFrame(const StimulusFrame&) = delete;
|
|
StimulusFrame& operator=(const StimulusFrame&) = delete;
|
|
StimulusFrame(StimulusFrame&&) = default;
|
|
StimulusFrame& operator=(StimulusFrame&&) = default;
|
|
|
|
public:
|
|
SequenceLock lock;
|
|
SimultaneityStamp simultaneityStamp;
|
|
FrameAssemblyDesc::SlotDesc slotDesc;
|
|
std::shared_ptr<smo::compute::ClBuffer> clBuffer;
|
|
size_t ringBufferIndex;
|
|
};
|
|
|
|
} // namespace stim_buff
|
|
} // namespace smo
|
|
|
|
#endif // _ATTACHMENT_SUPPORT_STIMULUS_FRAME_H
|