Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:08

0001 #pragma once
0002 /**
0003 QCurandState.h
0004 ===============
0005 
0006 Aims to replace QCurandState.{hh,cc} with more flexible 
0007 chunk based state handling using SCurandState.h 
0008 
0009 Need to enable runtime choice of maxphoton, 
0010 also can partially load chunks to get the desired maxphoton
0011 appropriate for VRAM. 
0012 
0013 The old impl split:
0014 
0015 1. creation of the RNG file with QCurandState.{hh,cc}
0016 2. loading+uploading of RNG file for simulation with QRng.{hh,cc}
0017 
0018 That definitely has advantages, as considerations for the 
0019 install time executables to prepare the RNG and for 
0020 runtime usage of the files are very different. 
0021 
0022 The chunk-centric impl follows the same split:
0023 
0024 1. creation of chunked RNG files with QCurandState.h 
0025 2. loading+uploading of chunked RNG files with QRng.{hh,cc} 
0026 
0027 Related tests::
0028 
0029     ~/o/qudarap/tests/QCurandState_Test.sh
0030     ~/o/sysrap/tests/SCurandState_test.sh
0031     ~/o/qudarap/tests/QRngTest.sh
0032 
0033 **/
0034 
0035 #include "SCurandState.h"
0036 #include "SLaunchSequence.h"
0037 #include "QU.hh"
0038 
0039 #include "qrng.h"
0040 
0041 
0042 extern "C" void QCurandState_curand_init_chunk(SLaunchSequence* lseq, scurandref<XORWOW>* cr, scurandref<XORWOW>* d_cr) ; 
0043 
0044 
0045 struct QCurandState
0046 {
0047     static QCurandState* Create(const char* _dir=nullptr); 
0048 
0049     SCurandState cs = {} ;
0050     QCurandState(const char* _dir); 
0051 
0052     void init(); 
0053     void initChunk(SCurandChunk& c);
0054 
0055     std::string desc() const ; 
0056 }; 
0057 
0058 
0059 inline QCurandState* QCurandState::Create(const char* _dir)
0060 {
0061     std::cerr << "[QCurandState::Create\n" ; 
0062     QCurandState* qcs = new QCurandState(_dir); 
0063     std::cerr << "]QCurandState::Create\n" ; 
0064     return qcs ; 
0065 } 
0066 
0067 inline QCurandState::QCurandState(const char* _dir)
0068     :
0069     cs(_dir)
0070 {
0071     init(); 
0072 }
0073 
0074 
0075 /**
0076 QCurandState::init
0077 --------------------
0078 
0079 Completeness means all the chunk files exist. 
0080 
0081 Outcome of instanciation is a complete set of
0082 chunk files. 
0083 
0084 **/
0085 
0086 inline void QCurandState::init()
0087 {
0088     int num_chunk = cs.chunk.size(); 
0089     bool complete = cs.is_complete() ; 
0090     std::cerr 
0091         << "QCurandState::init"
0092         << " cs.chunk.size " << num_chunk  
0093         << " is_complete " << ( complete ? "YES" : "NO " ) 
0094         << "\n"
0095         ;
0096 
0097     if(complete) return ; 
0098 
0099     for(int i=0 ; i < num_chunk ; i++)
0100     {
0101         SCurandChunk& c = cs.chunk[i]; 
0102         if(SCurandChunk::IsValid(c)) continue ;
0103         initChunk(c);  
0104     }
0105 }
0106 
0107 
0108 /**
0109 QCurandState::initChunk : generates RNG for chunk and saves to file
0110 -------------------------------------------------------------------------------
0111 
0112 1. prep sequence of launches needed for c.ref.num slots
0113 2. allocate + zero space on device for c.ref.num RNG 
0114 3. upload scurandref<XORWOW> metadata struct 
0115 4. launch curand_init kernel on device populating RNG buffer
0116 5. allocate h_states on host 
0117 6. copy device to host 
0118 7. free on device
0119 8. change c.ref.states to host r_states
0120 9. save c.ref.states to file named according to scurandref<XORWOW> chunk metadata values
0121 10. free h_states 
0122 
0123 **/
0124 
0125 
0126 inline void QCurandState::initChunk(SCurandChunk& c)
0127 {
0128     scurandref<XORWOW>* cr = &(c.ref) ; 
0129 
0130     SLaunchSequence lseq(cr->num);
0131 
0132     cr->states = QU::device_alloc_zero<XORWOW>(cr->num,"QCurandState::initChunk") ;
0133  
0134     scurandref<XORWOW>* d_cr = QU::UploadArray<scurandref<XORWOW>>(cr, 1, "QCurandState::initChunk" );    
0135 
0136     QCurandState_curand_init_chunk(&lseq, cr, d_cr); 
0137 
0138     XORWOW* h_states = (XORWOW*)malloc(sizeof(XORWOW)*cr->num);
0139 
0140     QU::copy_device_to_host( h_states, cr->states, cr->num ); 
0141 
0142     QU::device_free<XORWOW>(cr->states); 
0143 
0144     cr->states = h_states ; 
0145 
0146     c.save(cs.dir);
0147 
0148     free(h_states); 
0149 }
0150 
0151 
0152 
0153 inline std::string QCurandState::desc() const 
0154 {
0155     std::stringstream ss ; 
0156     ss << "QCurandState::desc\n"
0157        << cs.desc() 
0158        ; 
0159 
0160     std::string str = ss.str() ; 
0161     return str ;
0162 }
0163 
0164 
0165 
0166