File indexing completed on 2026-04-09 07:49:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <sstream>
0015 #include <csignal>
0016
0017 #include <cuda_runtime.h>
0018 #include "OPTICKS_LOG.hh"
0019
0020 #include "SEventConfig.hh"
0021 #include "scuda.h"
0022 #include "squad.h"
0023 #include "ssys.h"
0024 #include "spath.h"
0025
0026 #include "SSim.hh"
0027 #include "SBnd.h"
0028 #include "SPrd.h"
0029
0030 #include "SEvt.hh"
0031 #include "NP.hh"
0032 #include "sstate.h"
0033
0034 #include "QRng.hh"
0035 #include "QBnd.hh"
0036 #include "QProp.hh"
0037 #include "QSim.hh"
0038 #include "QSimLaunch.hh"
0039 #include "QEvt.hh"
0040
0041 #include "QDebug.hh"
0042 #include "qdebug.h"
0043
0044 #include "SEvent.hh"
0045
0046
0047
0048 struct QSimTest
0049 {
0050 static constexpr const unsigned M = 1000000 ;
0051 static const char* FOLD ;
0052 static const plog::Severity LEVEL ;
0053 static unsigned Num(int argc, char** argv);
0054
0055 const SPrd* sprd ;
0056 QSim* qs ;
0057 unsigned type ;
0058 unsigned num ;
0059 const char* subfold ;
0060 int rc ;
0061
0062 QSimTest(unsigned type, unsigned num, const SPrd* sprd );
0063 void main();
0064
0065 static const bool rng_sequence_PRECOOKED ;
0066 void rng_sequence(unsigned ni, int ni_tranche_size);
0067
0068
0069 void boundary_lookup_all();
0070 void boundary_lookup_line(const char* material, float x0, float x1, unsigned nx );
0071
0072 template<typename T>
0073 void prop_lookup( int iprop, T x0, T x1, unsigned nx );
0074
0075 void multifilm_lookup_all();
0076
0077 void wavelength() ;
0078 void RandGaussQ_shoot();
0079
0080 void dbg_gs_generate();
0081
0082
0083 void generate_photon();
0084 void getStateNames(std::vector<std::string>& names, int num_state) const ;
0085
0086 void fill_state(unsigned version);
0087 void save_state( const char* subfold, const float* data, int num_state );
0088
0089 void photon_launch_generate();
0090 void photon_launch_mutate();
0091
0092 static void EventConfig(unsigned type, const SPrd* prd);
0093 void fake_propagate();
0094
0095 void quad_launch_generate();
0096
0097
0098 };
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108 const plog::Severity QSimTest::LEVEL = SLOG::EnvLevel("QSimTest", "INFO");
0109
0110
0111
0112 QSimTest::QSimTest(unsigned type_, unsigned num_, const SPrd* sprd_)
0113 :
0114 sprd(sprd_),
0115 qs(QSim::Create()),
0116 type(type_),
0117 num(num_),
0118 subfold(QSimLaunch::Name(type)),
0119 rc(0)
0120 {
0121 }
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 const bool QSimTest::rng_sequence_PRECOOKED = ssys::getenvbool("QSimTest__rng_sequence_PRECOOKED") ;
0143
0144 void QSimTest::rng_sequence(unsigned ni, int ni_tranche_size_)
0145 {
0146 unsigned nj = 16 ;
0147 unsigned nk = 16 ;
0148 unsigned ni_tranche_size = ni_tranche_size_ > 0 ? ni_tranche_size_ : ni ;
0149
0150 const char* udir = rng_sequence_PRECOOKED ? "$HOME/.opticks/precooked/QSimTest/rng_sequence" : "$FOLD" ;
0151 LOG(info) << " idir " << udir ;
0152
0153
0154 LOG_IF(error, rng_sequence_PRECOOKED)
0155 << " QSimTest__rng_sequence_PRECOOKED envvar triggers directory override " << std::endl
0156 << " default [" << "$FOLD" << "] " << std::endl
0157 << " override [" << udir << "]"
0158 ;
0159
0160 qs->rng_sequence<float>(udir, ni, nj, nk, ni_tranche_size );
0161 }
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174 void QSimTest::boundary_lookup_all()
0175 {
0176 unsigned width = qs->getBoundaryTexWidth();
0177 unsigned height = qs->getBoundaryTexHeight();
0178 const NP* src = qs->getBoundaryTexSrc();
0179
0180
0181 bool height_expect = height % 8 == 0 ;
0182 assert( height_expect );
0183 if(!height_expect) std::raise(SIGINT);
0184
0185 unsigned num_bnd = height/8 ;
0186 NP* l = qs->boundary_lookup_all( width, height );
0187
0188 bool l_expect = l->has_shape( num_bnd, 4, 2, width, 4 ) ;
0189 assert( l_expect );
0190 if(!l_expect ) std::raise(SIGINT) ;
0191
0192 l->save("$FOLD/lookup_all.npy" );
0193 src->save("$FOLD/lookup_all_src.npy" );
0194 }
0195
0196
0197
0198
0199
0200
0201
0202
0203 void QSimTest::boundary_lookup_line(const char* material, float x0 , float x1, unsigned nx )
0204 {
0205 LOG(info);
0206
0207 unsigned line = qs->bnd->sbn->getMaterialLine(material);
0208 if( line == ~0u )
0209 {
0210 LOG(fatal) << " material not in boundary tex " << material ;
0211 assert(0);
0212 }
0213
0214 LOG(info) << " material " << material << " line " << line ;
0215 unsigned k = 0 ;
0216
0217 NP* x = NP::Linspace<float>(x0,x1,nx);
0218 float* xx = x->values<float>();
0219
0220 NP* l = qs->boundary_lookup_line( xx, nx, line, k );
0221
0222 l->save("$FOLD/lookup_line.npy" );
0223 x->save("$FOLD/lookup_line_wavelength.npy");
0224 }
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237 template<typename T>
0238 void QSimTest::prop_lookup( int iprop, T x0, T x1, unsigned nx )
0239 {
0240 unsigned tot_prop = qs->prop->ni ;
0241 const NP* pp = qs->prop->a ;
0242
0243 std::vector<unsigned> pids ;
0244 if( iprop == -1 )
0245 {
0246 for(unsigned i=0 ; i < tot_prop ; i++ ) pids.push_back(i);
0247 }
0248 else
0249 {
0250 pids.push_back(iprop);
0251 }
0252
0253 unsigned num_prop = pids.size() ;
0254
0255 LOG(info)
0256 << " tot_prop " << tot_prop
0257 << " iprop " << iprop
0258 << " pids.size " << pids.size()
0259 << " num_prop " << num_prop
0260 << " pp " << pp->desc()
0261 ;
0262
0263
0264 NP* yy = NP::Make<T>(num_prop, nx) ;
0265 NP* x = NP::Linspace<T>(x0,x1,nx);
0266
0267 qs->prop_lookup_onebyone( yy->values<T>(), x->cvalues<T>(), nx, pids ) ;
0268
0269 const char* reldir = sizeof(T) == 8 ? "double" : "float" ;
0270
0271 pp->save("$FOLD", reldir, "prop_lookup_pp.npy" );
0272 x->save("$FOLD", reldir, "prop_lookup_x.npy" );
0273 yy->save("$FOLD", reldir, "prop_lookup_yy.npy" );
0274 }
0275
0276
0277
0278
0279
0280 void QSimTest::multifilm_lookup_all(){
0281
0282
0283
0284
0285
0286
0287
0288
0289 NP * sample = NP::Load("/tmp/debug_multi_film_table/","test_texture.npy");
0290
0291 assert(sample);
0292 quad2 * h_quad2_sample = (quad2*)sample->values<float>();
0293
0294
0295 unsigned height= sample->shape[0];
0296 unsigned width = sample->shape[1];
0297 unsigned num_sample = height*width;
0298 std::cout<<" width = "<< width
0299 <<" height = "<< height
0300 <<" num_sample ="<< num_sample
0301 <<std::endl;
0302
0303 assert( height*width == num_sample);
0304
0305
0306 quad2 h_quad2_result[num_sample];
0307 qs->multifilm_lookup_all( h_quad2_sample , h_quad2_result , width, height );
0308
0309 assert(h_quad2_result);
0310 NP * result = NP::Make<float>(height,width , 4);
0311 float4* output = (float4*) result->values<float>();
0312
0313
0314 for(unsigned i = 0 ; i < height ; i++){
0315 for(unsigned j = 0 ; j < width ; j++ ){
0316 unsigned index = i*width + j;
0317 output[index].x = h_quad2_result[index].q1.f.x;
0318 output[index].y = h_quad2_result[index].q1.f.y;
0319 output[index].z = h_quad2_result[index].q1.f.z;
0320 output[index].w = h_quad2_result[index].q1.f.w;
0321 }
0322 }
0323 result->save("$FOLD/multifilm_lut_result.npy");
0324 }
0325
0326
0327
0328 void QSimTest::wavelength()
0329 {
0330 NP* w = nullptr ;
0331
0332 std::stringstream ss ;
0333 ss << "wavelength" ; ;
0334 if( type == WAVELENGTH_SCINTILLATION )
0335 {
0336 unsigned hd_factor(~0u) ;
0337 w = qs->scint_wavelength( num, hd_factor );
0338 assert( hd_factor == 0 || hd_factor == 10 || hd_factor == 20 );
0339 ss << "_scint_hd" << hd_factor ;
0340
0341 char scintTexFilterMode = qs->getScintTexFilterMode() ;
0342 if(scintTexFilterMode == 'P') ss << "_cudaFilterModePoint" ;
0343 }
0344 else if( type == WAVELENGTH_CERENKOV )
0345 {
0346
0347 assert(0);
0348 ss << "_cerenkov" ;
0349 }
0350
0351 ss << "_" << num << ".npy" ;
0352 std::string s = ss.str();
0353 const char* name = s.c_str();
0354
0355 float* ww = w->values<float>();
0356 qs->dump_wavelength( ww, num );
0357
0358 LOG(info) << " name " << name ;
0359 w->save("$FOLD", name );
0360 }
0361
0362
0363
0364 void QSimTest::RandGaussQ_shoot()
0365 {
0366 NP* v = qs->RandGaussQ_shoot(num) ;
0367 v->save("$FOLD/RandGaussQ_shoot.npy" );
0368 }
0369
0370
0371
0372 void QSimTest::dbg_gs_generate()
0373 {
0374 NP* p = qs->dbg_gs_generate(num, type);
0375
0376 p->save("$FOLD/p.npy");
0377
0378 if( type == SCINT_GENERATE )
0379 {
0380 qs->dbg->save_scint_gs("$FOLD");
0381 }
0382 else if( type == CERENKOV_GENERATE )
0383 {
0384 qs->dbg->save_cerenkov_gs("$FOLD");
0385 }
0386 else
0387 {
0388 LOG(fatal) << "unexpected type " << type << " subfold " << subfold ;
0389 }
0390 }
0391
0392
0393
0394 void QSimTest::generate_photon()
0395 {
0396 const char* gs_config = ssys::getenvvar("GS_CONFIG", "torch" );
0397
0398 LOG(info) << "[ gs_config " << gs_config ;
0399 const NP* gs = SEvent::MakeDemoGenstep(gs_config);
0400
0401 SEvt* evt = SEvt::Create(SEvt::EGPU) ;
0402 assert(evt);
0403
0404 evt->addGenstep(gs);
0405 unsigned num_photon_after_SEvt__addGenstep = qs->qev->getNumPhoton();
0406
0407
0408 NP* igs = evt->makeGenstepArrayFromVector();
0409 qs->qev->setGenstepUpload_NP(igs);
0410 unsigned num_photon_after_QEvt__setGenstep = qs->qev->getNumPhoton();
0411
0412
0413 LOG(info)
0414 << "\n"
0415 << " gs_config " << gs_config
0416 << " gs " << ( gs ? gs->sstr() : "-" )
0417 << "\n"
0418 << " num_photon_after_SEvt__addGenstep "
0419 << num_photon_after_SEvt__addGenstep
0420 << "\n"
0421 << " num_photon_after_QEvt__setGenstep "
0422 << num_photon_after_QEvt__setGenstep
0423 << "\n"
0424 ;
0425
0426
0427 qs->generate_photon();
0428
0429
0430
0431 NP* p = qs->qev->gatherPhoton();
0432 p->save("$FOLD/p.npy");
0433
0434 LOG(info) << "]" ;
0435 }
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448 void QSimTest::fill_state(unsigned version)
0449 {
0450 LOG(info) << "[" ;
0451
0452 unsigned num_state = qs->bnd->sbn->getNumBoundary() ;
0453
0454 if( version == 0 )
0455 {
0456 std::vector<quad6> s(num_state) ;
0457 qs->fill_state_0( s.data(), s.size() );
0458 save_state("fill_state_0", (float*)s.data(), num_state );
0459 }
0460 else if( version == 1 )
0461 {
0462 std::vector<sstate> s(num_state) ;
0463 qs->fill_state_1( s.data(), s.size() );
0464 save_state("fill_state_1", (float*)s.data(), num_state );
0465 }
0466 LOG(info) << "]" ;
0467 }
0468
0469
0470 void QSimTest::save_state( const char* subfold, const float* data, int num_state )
0471 {
0472 std::vector<std::string> names ;
0473 getStateNames(names, num_state);
0474
0475 NP* a = NP::Make<float>( num_state, 6, 4 );
0476 a->read( data );
0477 a->set_names(names);
0478 a->save("$FOLD/state.npy");
0479 }
0480
0481
0482 void QSimTest::getStateNames(std::vector<std::string>& names, int num_state) const
0483 {
0484 int* idx = new int[num_state] ;
0485 for(int i=0 ; i < num_state ; i++) idx[i] = i ;
0486 qs->bnd->sbn->getBoundarySpec(names, idx, num_state );
0487 delete [] idx ;
0488 }
0489
0490 void QSimTest::photon_launch_generate()
0491 {
0492 assert( QSimLaunch::IsMutate(type)==false );
0493 NP* p = qs->photon_launch_generate(num, type );
0494 p->save("$FOLD/p.npy");
0495 qs->dbg->save("$FOLD");
0496 }
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525 void QSimTest::EventConfig(unsigned type, const SPrd* prd )
0526 {
0527 SEvt* sev = SEvt::Get_EGPU();
0528 LOG_IF(fatal, sev != nullptr ) << "QSimTest::EventConfig must be done prior to instanciating SEvt, eg for fake_propagate bounce consistency " ;
0529 assert(sev == nullptr);
0530
0531 LOG(LEVEL) << "[ " << QSimLaunch::Name(type) ;
0532 if( type == FAKE_PROPAGATE )
0533 {
0534 LOG(LEVEL) << prd->desc() ;
0535 int maxbounce = prd->getNumBounce();
0536
0537 SEventConfig::SetMaxBounce(maxbounce);
0538 SEventConfig::SetEventMode("DebugLite");
0539 SEventConfig::Initialize();
0540
0541 SEventConfig::SetMaxGenstep(1);
0542
0543 unsigned mx = 1000000 ;
0544 SEventConfig::SetMaxPhoton(mx);
0545 SEventConfig::SetMaxSlot(mx);
0546
0547
0548 LOG(LEVEL) << " SEventConfig::Desc " << SEventConfig::Desc() ;
0549 }
0550 LOG(LEVEL) << "] " << QSimLaunch::Name(type) ;
0551 }
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562 void QSimTest::fake_propagate()
0563 {
0564 assert( QSimLaunch::IsMutate(type)==true );
0565 LOG(info) << "[" ;
0566 LOG(info) << " SEventConfig::Desc " << SEventConfig::Desc() ;
0567
0568 NP* p = sphoton::make_ephoton_array(num);
0569
0570 SEvt* sev = SEvt::Get_EGPU();
0571 assert( sev );
0572 sev->setInputPhoton(p);
0573 sev->setFramePlaceholder() ;
0574
0575 int bounce_max = SEventConfig::MaxBounce();
0576 NP* prd = sprd->fake_prd(num, bounce_max);
0577
0578 LOG(info)
0579 << " num " << num
0580 << " p " << ( p ? p->sstr() : "-" )
0581 << " bounce_max " << bounce_max
0582 << " prd " << ( prd ? prd->sstr() : "-" )
0583 ;
0584
0585
0586
0587
0588
0589 int eventID = 0 ;
0590
0591 sev->beginOfEvent(eventID) ;
0592
0593 qs->fake_propagate( prd, type );
0594
0595 sev->endOfEvent(eventID) ;
0596
0597 LOG(info) << "]" ;
0598 }
0599
0600
0601
0602
0603
0604
0605
0606 void QSimTest::quad_launch_generate()
0607 {
0608 assert( QSimLaunch::IsMutate(type)==false );
0609 NP* q = qs->quad_launch_generate(num, type );
0610 q->set_meta<std::string>("source", "QSimTest.sh");
0611 q->save("$FOLD/q.npy");
0612 }
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624 void QSimTest::photon_launch_mutate()
0625 {
0626 assert( QSimLaunch::IsMutate(type)==true );
0627
0628 unsigned src = QSimLaunch::MutateSource(type);
0629 const char* src_subfold = QSimLaunch::Name(src);
0630 assert( src_subfold );
0631
0632 unsigned num_photon = num ;
0633 NP* a = NP::Load("$BASE", src_subfold, "p.npy" );
0634
0635
0636
0637
0638 if( a == nullptr )
0639 {
0640 const char* a_path = U::Resolve("$BASE", src_subfold, "p.npy" );
0641 LOG(fatal)
0642 << "failed to NP::Load photons from "
0643 << " src_subfold [" << ( src_subfold ? src_subfold : "-" ) << "]"
0644 << " a_path [" << ( a_path ? a_path : "-" ) << "]"
0645 << std::endl
0646 << " YOU PROBABLY NEED TO RUN ANOTHER TEST FIRST TO GENERATE THE PHOTONS "
0647 ;
0648 rc = 101 ;
0649 return ;
0650 }
0651
0652 unsigned num_photon_loaded = a->shape[0] ;
0653 bool num_photon_consistent = num_photon_loaded == num_photon ;
0654
0655 LOG(info)
0656 << "\n"
0657 << " a.sstr " << a->sstr() << "\n"
0658 << " from src_subfold " << src_subfold << "\n"
0659 << " a.lpath " << a->get_lpath() << "\n"
0660 << " num_photon_loaded " << num_photon_loaded << "\n"
0661 << " num_photon_loaded/M " << num_photon_loaded/M << "\n"
0662 << " num_photon " << num_photon << "\n"
0663 << " num_photon/M " << num_photon/M << "\n"
0664 << " num_photon_consistent " << ( num_photon_consistent ? "YES" : "NO " ) << "\n"
0665 ;
0666
0667 assert( num_photon_consistent );
0668 if(!num_photon_consistent) std::raise(SIGINT);
0669
0670 sphoton* photons = (sphoton*)a->bytes() ;
0671 qs->photon_launch_mutate( photons, num_photon, type );
0672
0673
0674
0675 a->save("$FOLD/p.npy");
0676
0677 qs->dbg->save("$FOLD");
0678 }
0679
0680
0681 unsigned QSimTest::Num(int argc, char** argv)
0682 {
0683 unsigned M1 = 1000000u ;
0684 unsigned num_default = ssys::getenvunsigned("NUM", M1 ) ;
0685 unsigned num = argc > 1 ? std::atoi(argv[1]) : num_default ;
0686 return num ;
0687 }
0688
0689 void QSimTest::main()
0690 {
0691 unsigned K100 = 100000u ;
0692 int ni_tranche_size = ssys::getenvint("NI_TRANCHE_SIZE", K100 );
0693 int print_id = ssys::getenvint("PINDEX", -1 );
0694 const char* subfold = QSimLaunch::Name(type) ;
0695 assert( subfold );
0696
0697 LOG(info)
0698 << " num " << num
0699 << " type " << type
0700 << " subfold " << subfold
0701 << " ni_tranche_size " << ni_tranche_size
0702 << " print_id " << print_id
0703 ;
0704
0705 switch(type)
0706 {
0707 case RNG_SEQUENCE: rng_sequence(num, ni_tranche_size) ; break ;
0708
0709 case WAVELENGTH_SCINTILLATION:
0710 case WAVELENGTH_CERENKOV:
0711 wavelength() ; break ;
0712
0713 case RANDGAUSSQ_SHOOT:
0714 RandGaussQ_shoot() ; break ;
0715
0716 case SCINT_GENERATE:
0717 case CERENKOV_GENERATE:
0718 dbg_gs_generate() ; break ;
0719
0720 case CERENKOV_GENERATE_ENPROP_FLOAT:
0721 case CERENKOV_GENERATE_ENPROP_DOUBLE:
0722 case CERENKOV_GENERATE_EXPT :
0723 assert(0) ; break ;
0724
0725 case GENERATE_PHOTON_G:
0726 case GENTORCH:
0727 generate_photon(); ; break ;
0728
0729 case BOUNDARY_LOOKUP_ALL: boundary_lookup_all() ; break ;
0730 case BOUNDARY_LOOKUP_WATER: boundary_lookup_line("Water", 80., 800., 721) ; break ;
0731 case BOUNDARY_LOOKUP_LS: boundary_lookup_line("LS", 80., 800., 721) ; break ;
0732
0733 case PROP_LOOKUP_Y: prop_lookup(-1, -1.f,16.f,1701) ; break ;
0734 case MULTIFILM_LOOKUP: multifilm_lookup_all() ; break ;
0735
0736 case FILL_STATE_0: fill_state(0) ; break ;
0737 case FILL_STATE_1: fill_state(1) ; break ;
0738
0739
0740
0741 case PROPAGATE_TO_BOUNDARY: num=8 ; photon_launch_generate() ; break ;
0742 case PROPAGATE_AT_SURFACE: num=8 ; photon_launch_generate() ; break ;
0743
0744 case RAYLEIGH_SCATTER_ALIGN:
0745 case PROPAGATE_AT_BOUNDARY:
0746 case PROPAGATE_AT_BOUNDARY_NORMAL_INCIDENCE:
0747 assert(0) ; break ;
0748 case REFLECT_DIFFUSE:
0749 case REFLECT_SPECULAR:
0750 photon_launch_generate() ; break ;
0751 case HEMISPHERE_S_POLARIZED:
0752 case HEMISPHERE_P_POLARIZED:
0753 case HEMISPHERE_X_POLARIZED:
0754 photon_launch_generate() ; break ;
0755 case PROPAGATE_AT_BOUNDARY_S_POLARIZED:
0756 case PROPAGATE_AT_BOUNDARY_P_POLARIZED:
0757 case PROPAGATE_AT_BOUNDARY_X_POLARIZED:
0758 case PROPAGATE_AT_MULTIFILM_S_POLARIZED:
0759 case PROPAGATE_AT_MULTIFILM_P_POLARIZED:
0760 case PROPAGATE_AT_MULTIFILM_X_POLARIZED:
0761 photon_launch_mutate() ; break ;
0762 case QGEN_RANDOM_DIRECTION_MARSAGLIA:
0763 case QGEN_LAMBERTIAN_DIRECTION:
0764 case QGEN_SMEAR_NORMAL_SIGMA_ALPHA:
0765 case QGEN_SMEAR_NORMAL_POLISH:
0766 quad_launch_generate() ; break ;
0767 case FAKE_PROPAGATE:
0768 fake_propagate() ; break ;
0769
0770 default :
0771 LOG(fatal) << "unimplemented" << std::endl ; break ;
0772 }
0773 }
0774
0775
0776
0777 int main(int argc, char** argv)
0778 {
0779 OPTICKS_LOG(argc, argv);
0780
0781 const char* TEST = ssys::getenvvar("TEST", "hemisphere_s_polarized");
0782 LOG(info) << "[ TEST " << TEST ;
0783
0784
0785 int type = QSimLaunch::Type(TEST);
0786 unsigned num = QSimTest::Num(argc, argv);
0787
0788 LOG(info) << "[SSim::Load" ;
0789 SSim* sim = SSim::Load();
0790 LOG(info) << "]SSim::Load" ;
0791 assert(sim);
0792
0793
0794 QSim::UploadComponents(sim);
0795 const SPrd* prd = sim->get_sprd() ;
0796
0797 LOG_IF(error, prd->rc != 0 )
0798 << " SPrd::rc NON-ZERO " << prd->rc
0799 << " NOT ALL CONFIGURED BOUNDARIES ARE IN THE GEOMETRY "
0800 << "\nprd.desc\n"
0801 << prd->desc()
0802 << "\nsim.desc\n"
0803 << sim->desc()
0804 ;
0805 if(prd->rc != 0 ) return 0 ;
0806
0807
0808 QSimTest::EventConfig(type, prd );
0809
0810 [[maybe_unused]] SEvt* ev = SEvt::Create_EGPU() ;
0811 assert(ev);
0812
0813
0814 QSimTest qst(type, num, prd) ;
0815 qst.main();
0816
0817 cudaDeviceSynchronize();
0818
0819 LOG(info) << "] TEST " << TEST << " qst.rc " << qst.rc ;
0820 return qst.rc ;
0821 }