00001 
00002 
00003 
00004 
00005 
00006 
00007 #include "lv3d0_server.h"
00008 #include "pup_toNetwork.h"
00009 #include <vector>
00010 #include <map>
00011 #include <algorithm>
00012 #include "stats.h"
00013 #include "LBDatabase.h" 
00014 
00015 #include "lv3d0.decl.h" 
00016 void _registerlv3d1(void);
00017 void _registerliveViz(void);
00018 
00019 
00020 static  CProxy_LV3D0_Manager mgrProxy;
00021 static  int LV3D_dosave_views=0; 
00022 static  int LV3D_disable_ship_prio=0; 
00023 static  int LV3D_disable_ship_replace=0; 
00024 static  int LV3D_disable_ship_throttle=0; 
00025 static  int LV3D_disable_ship=0;  
00026 #define masterProcessor 0
00027 
00033 class LV3D0_ViewMsg : public CMessage_LV3D0_ViewMsg {
00034 public:
00035 
00037     CkViewableID id;
00038     
00041     int prio;
00042     
00044     int pixels;
00045     
00047     int clientID;
00048     
00050     int view_size;
00052     unsigned char *view;
00053     
00055     static LV3D0_ViewMsg *new_(CkView *view);
00056     static void delete_(LV3D0_ViewMsg *m);
00057 };
00058 
00060 LV3D0_ViewMsg *LV3D0_ViewMsg::new_(CkView *vp) {
00061     PUP_toNetwork_sizer ps; ps|vp;
00062     int view_size=ps.size();
00063     
00064     LV3D0_ViewMsg *m=new (view_size,0) LV3D0_ViewMsg;
00065     m->id=vp->id;
00066     m->prio=vp->prio;
00067     m->pixels=vp->pixels;
00068     m->view_size=view_size;
00069     PUP_toNetwork_pack pp(m->view); pp|vp;
00070     return m;
00071 }
00072 void LV3D0_ViewMsg::delete_(LV3D0_ViewMsg *m) {
00073     delete m;
00074 }
00075 
00076 
00077 
00078 
00080 class CkViewPrioHolder {
00081 public:
00082     LV3D0_ViewMsg *v;
00083     
00084     CkViewPrioHolder(LV3D0_ViewMsg *v_) :v(v_) {}
00085     
00086     
00087     
00088     bool operator<(const CkViewPrioHolder &h) const {
00089         if (v->prio<h.v->prio) return true;
00090         if (v->prio>h.v->prio) return false;
00091         
00092         int i;
00093         for (i=0;i<4;i++) {
00094             if (v->id.id[i]<h.v->id.id[i]) return true;
00095             if (v->id.id[i]>h.v->id.id[i]) return false;
00096         }
00097         
00098         return v < h.v;
00099     }
00100 };
00101 
00107 class CkViewPrioSorter {
00108 
00109     
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118     
00119     
00120     CkHashtableT<CkViewableID,CkViewPrioHolder> id2view;
00121 
00122     
00123     
00124     typedef std::map<CkViewPrioHolder,char> prio2view_t;
00125     prio2view_t prio2view;
00126     
00127 public:
00128     CkViewPrioSorter() 
00129         :id2view(129,0.2)
00130     {
00131     }
00132     ~CkViewPrioSorter() {
00133         for (iterator it=begin();it!=end();++it)
00134             delete (*it).first.v;
00135     }
00136     
00138     bool isEmpty(void) const {return prio2view.size()==0;}
00139     
00141     void add(LV3D0_ViewMsg *v)
00142     {
00143         if (LV3D_disable_ship_prio) v->prio=0;
00144         CkViewPrioHolder old=id2view.get(v->id);
00146         if (old.v!=0 && !LV3D_disable_ship_replace) 
00147         { 
00148 
00149             
00150             if (v->prio>old.v->prio)  
00151                 v->prio=old.v->prio;
00152             prio2view.erase(prio2view.find(old));
00153             delete old.v;
00154         }
00155         else {
00156             
00157         }
00158         id2view.put(v->id)=CkViewPrioHolder(v);
00159         prio2view.insert(std::make_pair(CkViewPrioHolder(v),(char)1));
00160     }
00161     
00164     typedef prio2view_t::iterator iterator;
00165     iterator begin(void) {return prio2view.begin();}
00166     iterator end(void) {return prio2view.end();}
00167     
00170     LV3D0_ViewMsg *extract(const iterator &doomed) {
00171         LV3D0_ViewMsg *v=(*doomed).first.v;
00172         prio2view.erase(doomed);
00173         id2view.remove(v->id);
00174         return v;
00175     }
00176 };
00177 
00179 class LV3D0_ClientManager : public CkViewPrioSorter {
00180 public:
00181     virtual ~LV3D0_ClientManager() {}
00182     virtual void add(LV3D0_ViewMsg *v) =0;
00183     virtual void getViews(void) {}
00184     virtual void whenEmptyCallback(const CkCallback &cb) {}
00185 };
00186 
00187 
00190 int LV3D0_toMaster_bytesPer=100*1024;
00192 int LV3D0_toMaster_bytesMax=2*LV3D0_toMaster_bytesPer;
00193 
00194 static void toMaster_fillBucket(void *ptr,double timer);
00195 
00196 static stats::op_t op_master_count=stats::count_op("master.count","Number of final master impostors","count");
00197 static stats::op_t op_master_bytes=stats::count_op("master.bytes","Number of final master bytes","bytes");
00198 static stats::op_t op_master_pixels=stats::count_op("master.pixels","Number of final master pixels","pixels");
00199 
00206 class LV3D0_ClientManager_toMaster : public LV3D0_ClientManager {
00208     int bucket_bytes;
00209     int cidx;
00210 public:
00211     LV3D0_ClientManager_toMaster() {
00212         bucket_bytes=LV3D0_toMaster_bytesMax;
00213         cidx=CcdCallOnConditionKeep(CcdPERIODIC_10ms,toMaster_fillBucket,this);
00214     }
00215     ~LV3D0_ClientManager_toMaster() {
00216         CcdCancelCallOnConditionKeep(CcdPERIODIC_10ms,cidx);
00217     }
00218     
00220     virtual void add(LV3D0_ViewMsg *v) {
00221         CkViewPrioSorter::add(v);
00222         progress();
00223     }
00225     void progress(void) {
00226         
00227         if (CmiLongSendQueue(CmiNodeOf(masterProcessor),LV3D0_toMaster_bytesMax))
00228             return; 
00229         while ((!isEmpty()) && (bucket_bytes>0 || LV3D_disable_ship_throttle)) 
00230         {
00231             LV3D0_ViewMsg *v=extract(begin());
00232             bucket_bytes-=v->view_size;
00233             stats::get()->add(1.0,op_master_count);
00234             stats::get()->add(v->view_size,op_master_bytes);
00235             stats::get()->add(v->pixels,op_master_pixels);
00236             mgrProxy[masterProcessor].addView(v);
00237         }
00238     }
00241     void fillBucket(void) {
00242         bucket_bytes+=LV3D0_toMaster_bytesPer;
00243         if (bucket_bytes>LV3D0_toMaster_bytesMax) 
00244             bucket_bytes=LV3D0_toMaster_bytesMax;
00245         progress();
00246     }
00247 };
00249 static void toMaster_fillBucket(void *ptr,double timer) {
00250     LV3D0_ClientManager_toMaster *p=(LV3D0_ClientManager_toMaster *)ptr;
00251     p->fillBucket();
00252 }
00253 
00254 
00256 int LV3D0_toClient_bytesPer=100*1024;
00257 
00258 static stats::op_t op_client_pack=stats::time_op("client.pack","Time spent packing final client impostors");
00259 static stats::op_t op_client_count=stats::count_op("client.count","Number of final client impostors","count");
00260 static stats::op_t op_client_bytes=stats::count_op("client.bytes","Number of final client bytes","bytes");
00261 static stats::op_t op_client_pixels=stats::count_op("client.pixels","Final client impostor pixels","pixels");
00262 
00267 class LV3D0_ClientManager_toClient : public LV3D0_ClientManager
00268 {
00269     typedef CkViewPrioSorter super;
00270     bool hasDelayed;
00271     CcsDelayedReply delayedReply;
00272     
00274     CkVec<CkCallback> emptyCallbacks;
00275     void checkEmpty(void) {
00276         if (isEmpty()) { 
00277             for (int i=0;i<emptyCallbacks.size();i++)
00278                 emptyCallbacks[i].send();
00279             emptyCallbacks.resize(0);
00280         }
00281     }
00282     
00284     void sendReply(CcsDelayedReply repl) {
00285         stats::op_sentry stats_sentry(op_client_pack);
00286         
00287     
00288         int len=4; 
00289         int n=0;
00290         iterator it=begin();
00291         while (it!=end() && (len<LV3D0_toClient_bytesPer || LV3D_disable_ship_throttle)) {
00292             LV3D0_ViewMsg *v=(*it++).first.v;
00293             len+=v->view_size;
00294             n++;
00295         }
00296     
00297     
00298         
00299         
00300         
00301         char *retMsg=new char[len];
00302         PUP_toNetwork_pack pp(retMsg);
00303         pp|n;
00304         for (int i=0;i<n;i++) {
00305             LV3D0_ViewMsg *v=extract(begin());
00306             pp(v->view,v->view_size);
00307             stats::get()->add(v->pixels,op_client_pixels);
00308             delete v;
00309         }
00310         
00311         if (len!=pp.size()) {
00312             CkError("Sizing pup was %d bytes; packing pup was %d!\n",
00313                 len,pp.size());
00314             CkAbort("Pup size mismatch (logic error) in LV3D0_!\n");
00315         }
00316 
00317         stats::get()->add(1.0,op_client_count);
00318         stats::get()->add(len,op_client_bytes);
00319         CcsSendDelayedReply(repl,len,retMsg);
00320         delete[] retMsg;
00321         
00322         
00323         checkEmpty();
00324     }
00325     
00326 public:
00327     LV3D0_ClientManager_toClient() 
00328     {
00329         hasDelayed=false;
00330     }
00331     
00334     virtual void add(LV3D0_ViewMsg *v) {
00335         super::add(v);
00336         
00337         if (hasDelayed) { 
00338             hasDelayed=false;
00339             sendReply(delayedReply);
00340         }
00341     }
00342     
00345     virtual void getViews(void) {
00346         if (isEmpty()) { 
00347             
00348             hasDelayed=true;
00349             delayedReply=CcsDelayReply();
00350         }
00351         else 
00352         {
00353             sendReply(CcsDelayReply());
00354         }   
00355     }
00356     
00358     virtual void whenEmptyCallback(const CkCallback &cb) {
00359         emptyCallbacks.push_back(cb);
00360         checkEmpty();
00361     }
00362 };
00363 
00368 class LV3D0_Manager : public CBase_LV3D0_Manager {
00370     CkHashtableT<CkHashtableAdaptorT<int>,LV3D0_ClientManager *> clientTable;
00371     
00373     int nextClientID;
00374 public:
00375     LV3D0_Manager(void);
00376     
00379     int newClient(void);
00380     
00382     LV3D0_ClientManager *getClient(int clientID);
00383     
00387     void getViews(int clientID) {
00388         getClient(clientID)->getViews();
00389     }
00390     
00392     inline void addView(LV3D0_ViewMsg *m) {
00393         getClient(m->clientID)->add(m);
00394     }
00395 };
00396 
00397 
00398 LV3D0_Manager::LV3D0_Manager(void)
00399 {
00400     mgrProxy=thisgroup;
00401     nextClientID=1;
00402 }
00403 
00404 int LV3D0_Manager::newClient(void)
00405 {
00406     return nextClientID++;
00407 }
00408 
00410 LV3D0_ClientManager *LV3D0_Manager::getClient(int clientID)
00411 {
00412     LV3D0_ClientManager *m=clientTable.get(clientID);
00413     if (m==NULL) {
00414         if (CkMyPe()==masterProcessor) 
00415             m=new LV3D0_ClientManager_toClient;
00416         else
00417             m=new LV3D0_ClientManager_toMaster;
00418         clientTable.put(clientID)=m;
00419     }
00420     return m;
00421 }
00422 
00423 static stats::op_t op_deposit_views=stats::count_op("deposit.views","CkView count","CkViews");
00424 static stats::op_t op_deposit_bytes=stats::count_op("deposit.bytes","CkView sizes","bytes");
00425 static stats::op_t op_deposit_pixels=stats::count_op("deposit.pixels","CkView pixels","pixels");
00426 
00427 
00429 CkpvStaticDeclare(FILE *,LV3D_save_views);
00430 static double LV3D_save_viewStart=0; 
00431 static char *LV3D_copy_view_src=0, *LV3D_copy_view_dest=0;
00432 static stats::op_t op_save=stats::time_op("save.time","Time spent saving views to disk");
00433 
00434 static void LV3D_save_init(void) {
00435     if (LV3D_copy_view_src==0) return;
00436     if (CkpvAccess(LV3D_save_views)) { 
00437         fclose(CkpvAccess(LV3D_save_views));
00438     }
00439     
00440     char fName[1024];
00441     sprintf(fName,LV3D_copy_view_src,CkMyPe());
00442     FILE *f=fopen(fName,"wb");
00443     if (f==NULL) CmiAbort("Couldn't create save view file!\n");
00444     CkpvAccess(LV3D_save_views)=f;
00445     CkPrintf("Created views file %s\n",fName);
00446 }
00447 
00448 static void LV3D_save_start(void)
00449 {
00450     if (!LV3D_dosave_views) return;
00451     LV3D_save_init();
00452     LV3D_save_viewStart=CkWallTimer(); 
00453 }
00454 
00455 struct savedViewRecord {
00456 public:
00457     double t; 
00458     int view_size; 
00459     void pup(PUP::er &p) {
00460         p|t;
00461         p|view_size;
00462     }
00463 };
00464 
00465 static int LV3D_save_view(LV3D0_ViewMsg *v) {
00466     if (!LV3D_dosave_views) return 0;
00467     if (!CkpvAccess(LV3D_save_views)) return 0;
00468     stats::op_sentry stats_sentry(op_save);
00469     savedViewRecord rec;
00470     rec.t=CkWallTimer()-LV3D_save_viewStart;
00471     rec.view_size=v->view_size;
00472     enum {bufLen=sizeof(rec)};
00473     char buf[bufLen];
00474     PUP_toNetwork_pack p(buf); p|rec;
00475     FILE *f=CkpvAccess(LV3D_save_views);
00476     if (1!=fwrite(buf,p.size(),1,f)) CmiAbort("Can't write header to saved view file!\n");
00477     if (1!=fwrite(v->view,v->view_size,1,f)) CmiAbort("Can't write view to saved view file!\n");
00478     delete v;
00479     return 1;
00480 }
00481 
00482 static void LV3D_save_finish(void) {
00483     if (!LV3D_dosave_views) return;
00484     if (!CkpvAccess(LV3D_save_views)) return;
00485     fclose(CkpvAccess(LV3D_save_views));
00486     CkpvAccess(LV3D_save_views)=0;
00487     if (LV3D_copy_view_dest) { 
00488         char fSrc[1024], fDest[1024], cmd[2048];
00489         sprintf(fSrc,LV3D_copy_view_src,CkMyPe());
00490         sprintf(fDest,LV3D_copy_view_dest,CkMyPe());
00491         sprintf(cmd,"cp '%s' '%s' && rm '%s'", fSrc,fDest, fSrc);
00492         CkPrintf("Copying views file from %s to %s\n",fSrc,fDest);
00493         system(cmd);
00494         CkPrintf("Views file copied.\n");
00495     }
00496 }
00497 
00498 
00503 void LV3D0_Deposit(CkView *v,int clientID) {
00504     stats::stats *s=stats::get();
00505     s->add(1.0,op_deposit_views);
00506     s->add(v->pixels,op_deposit_pixels);
00507     LV3D0_ViewMsg *vm=LV3D0_ViewMsg::new_(v);
00508     if (LV3D_save_view(vm)) return;
00509     s->add(vm->view_size,op_deposit_bytes);
00510     if (LV3D_disable_ship) {delete vm; return;}
00511     vm->clientID=clientID;
00512     mgrProxy.ckLocalBranch()->addView(vm);
00513 }
00514 
00515 
00516 
00517 
00518 static stats::op_t op_pes=stats::count_op("cmi.pes","Processors","pes");
00519 static stats::op_t op_time=stats::time_op("cmi.time","Elapsed wall-clock time");
00520 static stats::op_t op_unknown=stats::time_op("cmi.unknown","Unaccounted-for time");
00521 static stats::op_t op_idle=stats::time_op("cmi.idle","Time spent waiting for data");
00522 
00523 
00524 static CcsDelayedReply statsReply;
00525 
00527 static void printStats(void *rednMsg) {
00528     CkReductionMsg *m=(CkReductionMsg *)rednMsg;
00529     
00530     
00531     
00532     
00533     char tmpFileName[100];
00534     sprintf(tmpFileName,"/tmp/stats.%d.%d",CkMyPe(),(int)getpid());
00535     FILE *f=fopen(tmpFileName,"w");
00536     int len=0; void *buf=0;
00537     if (f!=NULL) {
00538         
00539         const stats::stats *s=(const stats::stats *)m->getData();
00540         s->print(f,"total",1.0);
00541         s->print(f,"per_second",1.0/s->get(op_time));
00542         s->print(f,"per_pe-second",1.0/(CkNumPes()*s->get(op_time)));
00543         fclose(f);
00544         
00545         
00546         f=fopen(tmpFileName,"r");
00547         fseek(f,0,SEEK_END);
00548         len=ftell(f);
00549         buf=malloc(len);
00550         fseek(f,0,SEEK_SET);
00551         fread(buf,1,len,f);
00552         fclose(f);
00553         
00554         
00555         write(1,buf,len);
00556         printf("\n");
00557     
00558     }
00559     unlink(tmpFileName);
00560     CcsSendDelayedReply(statsReply,len,buf);
00561     free(buf);
00562     delete m;
00563 }
00564 
00566 static void perfmanager_stats_idle(void *ptr,double timer)
00567 {
00568     stats::swap(op_idle);
00569 }
00570 
00571 class LV3D_PerfManager : public CBase_LV3D_PerfManager {
00572     double startTime;
00573 public:
00574     LV3D_PerfManager(void) {
00575         zero();
00576         CcdCallOnConditionKeep(CcdPROCESSOR_BEGIN_IDLE,perfmanager_stats_idle,0);
00577         CcdCallOnConditionKeep(CcdPROCESSOR_END_IDLE,perfmanager_stats_idle,0);
00578         
00579         
00580         char *bitmap=new char[CkNumPes()];
00581         for (int i=0;i<CkNumPes();i++)
00582             bitmap[i]=(i!=masterProcessor);
00583         set_avail_vector(bitmap);
00584     }
00587     void zero(void) { 
00588         stats::stats *s=stats::get();
00589         stats::swap(op_unknown); 
00590         s->zero();
00591         s->add(1.0,op_pes);
00592         startTime=stats::time();
00593         stats::swap(op_unknown);
00594         LV3D_save_start();
00595     }
00598     void collect(void) { 
00599         stats::stats *s=stats::get();
00600         if (CkMyPe()==0) s->set(stats::time()-startTime,op_time);
00601         else s->set(0,op_time);
00602         stats::swap(op_unknown);
00603         contribute(sizeof(double)*stats::op_len,&s->t[0],CkReduction::sum_double,
00604             CkCallback(printStats));
00605         LV3D_save_finish();
00606         zero();
00607     }
00608     void traceOn(void) {
00609         traceBegin();
00610     }
00611     void startBalance(void) {
00612         LBClearLoads();
00613         LBTurnInstrumentOn();
00614     }
00615     void doneBalance(void) {
00616         LBTurnInstrumentOff();
00617     }
00618     void throttle(int throttleOn) { LV3D_disable_ship_throttle=!throttleOn; }
00619 };
00620 
00621 
00622 
00623 
00624 static LV3D_Universe *theUniverse=0;
00625 static LV3D_ServerMgr *theMgr=0;
00626 static CProxy_LV3D_PerfManager perfMgr;
00627 
00628 LV3D_ServerMgr::~LV3D_ServerMgr() {}
00629 
00637 extern "C" void LV3D0_setup(char *msg) {
00638     CmiFree(msg);
00639     int clientID=mgrProxy.ckLocalBranch()->newClient();
00640     PUP_toNetwork_sizer sp;
00641     sp|clientID;
00642     sp|theUniverse;
00643     unsigned char *buf=new unsigned char[sp.size()];
00644     PUP_toNetwork_pack pp(buf);
00645     pp|clientID;
00646     pp|theUniverse;
00647     CcsSendReply(sp.size(),buf);
00648     theMgr->newClient(clientID);
00649     CmiPrintf("Registered (client %d)\n",clientID);
00650     delete[] buf;
00651     perfMgr.zero(); 
00652 }
00653 
00654 
00655 static stats::op_t op_view_count=stats::count_op("client.views","New viewpoints","Views");
00656 
00665 extern "C" void LV3D0_newViewpoint(char *msg) {
00666     PUP_toNetwork_unpack p(&msg[CmiMsgHeaderSizeBytes]);
00667     LV3D_ViewpointMsg *m=new LV3D_ViewpointMsg;
00668     p|m->clientID;
00669     p|m->frameID;
00670     m->viewpoint.pup(p);
00671     
00672     theMgr->newViewpoint(m);
00673     stats::get()->add(1.0,op_view_count);
00674 }
00675 
00686 extern "C" void LV3D0_getViews(char *msg) {
00687     PUP_toNetwork_unpack p(&msg[CmiMsgHeaderSizeBytes]);
00688     int clientID=0; p|clientID; CmiFree(msg);
00689     mgrProxy.ckLocalBranch()->getViews(clientID);
00690 }
00691 
00692 
00693 
00694 
00695 
00696 
00697 struct lv3d_qdState {
00699     int clientID;
00700     
00702     CcsDelayedReply reply;
00703 };
00704 
00705 static void qdDoneFn(void *param,void *msg);
00706 static void emptyDoneFn(void *param,void *msg);
00707 
00708 extern "C" void LV3D0_qd(char *msg) 
00709 {
00710     lv3d_qdState *s=new lv3d_qdState;
00711     PUP_toNetwork_unpack p(&msg[CmiMsgHeaderSizeBytes]);
00712     p|s->clientID;
00713     s->reply=CcsDelayReply();
00714     CmiFree(msg);
00715     CkCallback cb(qdDoneFn,s);
00716     CkStartQD(cb); 
00717 }
00718 static void qdDoneFn(void *param,void *msg)  
00719 {
00720     lv3d_qdState *s=(lv3d_qdState *)param;
00721     mgrProxy.ckLocalBranch()->getClient(s->clientID)->whenEmptyCallback(
00722         CkCallback(emptyDoneFn,s));
00723 }
00724 static void emptyDoneFn(void *param,void *msg) 
00725 {
00726     lv3d_qdState *s=(lv3d_qdState *)param;
00727     CcsSendDelayedReply(s->reply,0,0);
00728     delete s;
00729 }
00730 
00737 extern "C" void LV3D0_flush(char *msg) {
00738     int clientID=0;
00739     PUP_toNetwork_unpack p(&msg[CmiMsgHeaderSizeBytes]);
00740     p|clientID;
00741     CmiFree(msg);
00742     theMgr->newClient(clientID);
00743 }
00744 
00745 
00746 
00747 
00748 
00749 
00750 extern "C" void LV3D0_startbalance(char *msg) 
00751 {
00752     CkPrintf("CCS call to LV3D0_startbalance\n");
00753     perfMgr.startBalance();
00754     CmiFree(msg);
00755 }
00756 
00757 
00758 
00759 
00760 
00761 extern "C" void LV3D0_endbalance(char *msg) 
00762 {
00763     CkPrintf("CCS call to LV3D0_endbalance\n");
00764     theMgr->doBalance();
00765     perfMgr.doneBalance();
00766     LV3D0_qd(msg); 
00767 }
00768 
00769 
00770 
00771 
00772 
00773 extern "C" void LV3D0_quit(char *msg) 
00774 {
00775     CkPrintf("Exiting: CCS call to LV3D0_quit\n");
00776     CcsSendReply(0,0);
00777     CmiFree(msg);
00778     CkExit();
00779 }
00781 extern "C" void LV3D0_zero(char *msg) 
00782 {
00783     CkPrintf("Zeroing statistics\n");
00784     perfMgr.zero();
00785     CmiFree(msg);
00786 }
00788 extern "C" void LV3D0_stats(char *msg) 
00789 {
00790     CkPrintf("Printing statistics\n");
00791     statsReply=CcsDelayReply();
00792     perfMgr.collect();
00793     CmiFree(msg);
00794 }
00796 extern "C" void LV3D0_trace(char *msg) 
00797 {
00798     CkPrintf("Tracing turned on\n");
00799     perfMgr.traceOn();
00800     CmiFree(msg);
00801 }
00802 extern "C" void LV3D0_throttle0(char *msg) { perfMgr.throttle(0); CmiFree(msg); }
00803 extern "C" void LV3D0_throttle1(char *msg) { perfMgr.throttle(1); CmiFree(msg); }
00804 
00809 void LV3D0_Init(LV3D_Universe *clientUniverse,LV3D_ServerMgr *mgr)
00810 {
00811     if (clientUniverse==0)
00812         clientUniverse=new LV3D_Universe();
00813     theUniverse=clientUniverse;
00814     theMgr=mgr;
00815     CcsRegisterHandler("lv3d_setup",(CmiHandler)LV3D0_setup);
00816     CcsRegisterHandler("lv3d_flush",(CmiHandler)LV3D0_flush);
00817     CcsRegisterHandler("lv3d_newViewpoint",(CmiHandler)LV3D0_newViewpoint);
00818     CcsRegisterHandler("lv3d_getViews",(CmiHandler)LV3D0_getViews);
00819     CcsRegisterHandler("lv3d_qd",(CmiHandler)LV3D0_qd);
00820     CcsRegisterHandler("lv3d_startbal",(CmiHandler)LV3D0_startbalance);
00821     CcsRegisterHandler("lv3d_endbal",(CmiHandler)LV3D0_endbalance);
00822     CcsRegisterHandler("lv3d_quit",(CmiHandler)LV3D0_quit);
00823     CcsRegisterHandler("lv3d_zero",(CmiHandler)LV3D0_zero);
00824     CcsRegisterHandler("lv3d_stats",(CmiHandler)LV3D0_stats);
00825     CcsRegisterHandler("lv3d_trace",(CmiHandler)LV3D0_trace);
00826     CcsRegisterHandler("lv3d_throttle0",(CmiHandler)LV3D0_throttle0);
00827     CcsRegisterHandler("lv3d_throttle1",(CmiHandler)LV3D0_throttle1);
00828     CProxy_LV3D0_Manager::ckNew();
00829     perfMgr=CProxy_LV3D_PerfManager::ckNew();
00830 }
00831 
00835 void LV3D0_ProcInit(void) {
00836     CkpvInitialize(FILE *,LV3D_save_views);
00837     CkpvAccess(LV3D_save_views)=0;
00838     CmiGetArgStringDesc(CkGetArgv(),"+LV3D_save_views",&LV3D_copy_view_src,"Save rendered views to a file with this pattern.  Use like '/tmp/views.%d.pe'");
00839     CmiGetArgStringDesc(CkGetArgv(),"+LV3D_copy_views",&LV3D_copy_view_dest,"Copy view files to this pattern.  Use like 'views.%d.pe'");
00840     LV3D0_toMaster_bytesPer=LV3D0_toMaster_bytesPer/CkNumPes();
00841     LV3D0_toMaster_bytesMax=LV3D0_toMaster_bytesMax/CkNumPes();
00842 }
00843 void LV3D0_NodeInit(void) {
00844     CkViewNodeInit();
00845 }
00846 
00847 
00848 #include "lv3d0.def.h"
00849 #include "liveViz3d.def.h"
00850