00001
00014 #include "ck.h"
00015 #include "ckarray.h"
00016 #include "debug-charm.h"
00017
00018 CkRegisteredInfo<EntryInfo> _entryTable;
00019 CkRegisteredInfo<MsgInfo> _msgTable;
00020 CkRegisteredInfo<ChareInfo> _chareTable;
00021 CkRegisteredInfo<MainInfo> _mainTable;
00022 CkRegisteredInfo<ReadonlyInfo> _readonlyTable;
00023 CkRegisteredInfo<ReadonlyMsgInfo> _readonlyMsgs;
00024
00025 static int __registerDone = 0;
00026
00027 void _registerInit(void)
00028 {
00029 if(__registerDone)
00030 return;
00031 }
00032
00033 int CkRegisterMsg(const char *name, CkPackFnPtr pack, CkUnpackFnPtr unpack,
00034 CkDeallocFnPtr dealloc, size_t size)
00035 {
00036 return _msgTable.add(new MsgInfo(name, pack, unpack, dealloc, size));
00037 }
00038
00039 void ckInvalidCallFn(void *msg,void *obj) {
00040 CkAbort("Charm++: Invalid entry method executed. Perhaps there is an unregistered module?");
00041 }
00042
00043 static
00044 int CkRegisterEpInternal(const char *name, CkCallFnPtr call, int msgIdx, int chareIdx,
00045 int ck_ep_flags, bool isTemplated)
00046 {
00047 #if !CMK_CHARMPY // charm4py can support dynamic registration of Chares after program start
00048 if (__registerDone) {
00049 CkPrintf("Charm++: late entry method registration happened after init\nEntry point: %s, addr: %p\n", name, call);
00050 CkAbort("Did you forget to import a module or instantiate a templated entry method in a .ci file?\n");
00051 }
00052 #endif
00053 EntryInfo *e = new EntryInfo(name, call?call:ckInvalidCallFn, msgIdx, chareIdx, isTemplated);
00054 if (ck_ep_flags & CK_EP_NOKEEP) e->noKeep=true;
00055 if (ck_ep_flags & CK_EP_INTRINSIC) e->inCharm=true;
00056 if (ck_ep_flags & CK_EP_TRACEDISABLE) e->traceEnabled=false;
00057 if (ck_ep_flags & CK_EP_APPWORK) e->appWork=true;
00058 if (ck_ep_flags & CK_EP_IMMEDIATE) e->isImmediate=true;
00059 if (ck_ep_flags & CK_EP_INLINE) e->isInline=true;
00060 #if ADAPT_SCHED_MEM
00061 if (ck_ep_flags & CK_EP_MEMCRITICAL){
00062 e->isMemCritical=true;
00063 if (CkMyRank()==0)
00064 numMemCriticalEntries++;
00065 }else{
00066 e->isMemCritical=false;
00067 }
00068 #endif
00069 return _entryTable.add(e);
00070 }
00071
00072 int CkRegisterEp(const char *name, CkCallFnPtr call, int msgIdx, int chareIdx, int ck_ep_flags)
00073 {
00074 return CkRegisterEpInternal(name, call, msgIdx, chareIdx, ck_ep_flags, false );
00075 }
00076
00077 int CkRegisterEpTemplated(const char *name, CkCallFnPtr call, int msgIdx, int chareIdx, int ck_ep_flags)
00078 {
00079 return CkRegisterEpInternal(name, call, msgIdx, chareIdx, ck_ep_flags, true );
00080 }
00081
00082 int CkRegisterChare(const char *name, size_t dataSz, ChareType chareType)
00083 {
00084 return _chareTable.add(new ChareInfo(name, dataSz, chareType));
00085 }
00086
00087 void CkRegisterArrayDimensions(int chareIndex, int ndims) {
00088 _chareTable[chareIndex]->ndims = ndims;
00089 }
00090
00091 void CkRegisterChareInCharm(int chareIndex){
00092 _chareTable[chareIndex]->inCharm = true;
00093 }
00094
00095 void CkRegisterGroupIrr(int chareIndex,int isIrr){
00096 _chareTable[chareIndex]->isIrr = (isIrr!=0);
00097 }
00098
00099
00100 void CkRegisterGroupExt(const char *s, int numEntryMethods, int *chareIdx, int *startEpIdx) {
00101 int __idx = CkRegisterChare(s, sizeof(GroupExt), TypeGroup);
00102 CkRegisterBase(__idx, CkIndex_IrrGroup::__idx);
00103 CkRegisterGroupIrr(__idx, true);
00104
00105 int epIdxCtor = CkRegisterEp(s, GroupExt::__GroupExt, CkMarshallMsg::__idx, __idx, 0+CK_EP_NOKEEP);
00106 CkRegisterDefaultCtor(__idx, epIdxCtor);
00107
00108 for (int i=0; i < numEntryMethods; i++)
00109 int epidx = CkRegisterEp(s, GroupExt::__entryMethod,
00110 CkMarshallMsg::__idx, __idx, 0+CK_EP_NOKEEP);
00111
00112 *chareIdx = __idx;
00113 *startEpIdx = epIdxCtor;
00114 }
00115
00116 void CkRegisterArrayMapExt(const char *s, int numEntryMethods, int *chareIdx, int *startEpIdx) {
00117 int __idx = CkRegisterChare(s, sizeof(ArrayMapExt), TypeGroup);
00118
00119 CkRegisterBase(__idx, CkIndex_IrrGroup::__idx);
00120 CkRegisterGroupIrr(__idx, true);
00121
00122 int epIdxCtor = CkRegisterEp(s, ArrayMapExt::__ArrayMapExt, CkMarshallMsg::__idx, __idx, 0+CK_EP_NOKEEP);
00123 CkRegisterDefaultCtor(__idx, epIdxCtor);
00124
00125 for (int i=0; i < numEntryMethods; i++)
00126 int epidx = CkRegisterEp(s, ArrayMapExt::__entryMethod,
00127 CkMarshallMsg::__idx, __idx, 0+CK_EP_NOKEEP);
00128
00129 *chareIdx = __idx;
00130 *startEpIdx = epIdxCtor;
00131 }
00132
00133
00134 void CkRegisterArrayExt(const char *s, int numEntryMethods, int *chareIdx, int *startEpIdx) {
00135 int __idx = CkRegisterChare(s, sizeof(ArrayElemExt), TypeArray);
00136 CkRegisterBase(__idx, CkIndex_ArrayElement::__idx);
00137
00138 int epIdxCtor = CkRegisterEp(s, ArrayElemExt::__ArrayElemExt, CkMarshallMsg::__idx, __idx, 0+CK_EP_NOKEEP);
00139 CkRegisterDefaultCtor(__idx, epIdxCtor);
00140
00141 int epidx = CkRegisterEp(s, ArrayElemExt::__CkMigrateMessage, 0, __idx, 0);
00142 CkRegisterMigCtor(__idx, epidx);
00143
00144 epidx = CkRegisterEp(s, ArrayElemExt::__AtSyncEntryMethod, 0, __idx, 0);
00145 for (int i=0; i < numEntryMethods; i++)
00146 epidx = CkRegisterEp(s, ArrayElemExt::__entryMethod, CkMarshallMsg::__idx,
00147 __idx, 0+CK_EP_NOKEEP);
00148
00149 *chareIdx = __idx;
00150 *startEpIdx = epIdxCtor;
00151 }
00152
00153 void CkRegisterDefaultCtor(int chareIdx, int ctorEpIdx)
00154 {
00155 _chareTable[chareIdx]->setDefaultCtor(ctorEpIdx);
00156 }
00157 void CkRegisterMigCtor(int chareIdx, int ctorEpIdx)
00158 {
00159 _chareTable[chareIdx]->setMigCtor(ctorEpIdx);
00160 }
00161
00162 int CkRegisterMainChare(int chareIdx, int entryIdx)
00163 {
00164 int mIdx = _mainTable.add(new MainInfo(chareIdx, entryIdx));
00165 _chareTable[chareIdx]->setMainChareType(mIdx);
00166 return mIdx;
00167 }
00168
00169
00170 void CkRegisterMainChareExt(const char *s, int numEntryMethods, int *chareIdx, int *startEpIdx) {
00171 int __idx = CkRegisterChare(s, sizeof(MainchareExt), TypeMainChare);
00172 CkRegisterBase(__idx, CkIndex_Chare::__idx);
00173
00174 int epIdxCtor = CkRegisterEp(s, MainchareExt::__Ctor_CkArgMsg, CMessage_CkArgMsg::__idx, __idx, 0);
00175 CkRegisterMessagePupFn(epIdxCtor, (CkMessagePupFn)CkArgMsg::ckDebugPup);
00176 CkRegisterMainChare(__idx, epIdxCtor);
00177
00178 for (int i=0; i < numEntryMethods; i++)
00179 int epidx = CkRegisterEp(s, MainchareExt::__entryMethod, CkMarshallMsg::__idx,
00180 __idx, 0+CK_EP_NOKEEP);
00181
00182 *chareIdx = __idx;
00183 *startEpIdx = epIdxCtor;
00184 }
00185
00186 void CkRegisterBase(int derivedIdx, int baseIdx)
00187 {
00188 if (baseIdx!=-1)
00189 _chareTable[derivedIdx]->addBase(baseIdx);
00190 }
00191
00192 int CkGetChareIdx(const char *name){
00193 for(int i=0; i<_chareTable.size(); i++){
00194 if(strcmp(name, _chareTable[i]->name)==0)
00195 return i;
00196 }
00197 return -1;
00198 }
00199
00200 void CkRegisterReadonly(const char *name,const char *type,
00201 size_t size, void *ptr,CkPupReadonlyFnPtr pup_fn)
00202 {
00203 _readonlyTable.add(new ReadonlyInfo(name,type,size,ptr,pup_fn));
00204 }
00205
00206 void CkRegisterReadonlyExt(const char *name, const char *type, size_t msgSize, char *msg) {
00207 if (msgSize > 0) ReadOnlyExt::setData(msg, msgSize);
00208 CkRegisterReadonly(name, type, msgSize, ReadOnlyExt::ro_data, ReadOnlyExt::_roPup);
00209 }
00210
00211 void CkRegisterReadonlyMsg(const char *name,const char *type,void **pMsg)
00212 {
00213 _readonlyMsgs.add(new ReadonlyMsgInfo(name,type,pMsg));
00214 }
00215
00216
00217 void CkRegisterMarshallUnpackFn(int epIndex,CkMarshallUnpackFn m)
00218 {
00219 _entryTable[epIndex]->marshallUnpack=m;
00220 }
00221
00222 CkMarshallUnpackFn CkLookupMarshallUnpackFn(int epIndex)
00223 {
00224 return _entryTable[epIndex]->marshallUnpack;
00225 }
00226 void CkRegisterMessagePupFn(int epIndex,CkMessagePupFn m)
00227 {
00228 #if CMK_CHARMDEBUG
00229 _entryTable[epIndex]->messagePup=m;
00230 #endif
00231 }
00232 int CkDisableTracing(int epIdx) {
00233 CmiLock(_smp_mutex);
00234 int oldStatus = _entryTable[epIdx]->traceEnabled;
00235 _entryTable[epIdx]->traceEnabled=false;
00236 CmiUnlock(_smp_mutex);
00237 return oldStatus;
00238 }
00239
00240 void CkEnableTracing(int epIdx) {
00241 CmiLock(_smp_mutex);
00242 _entryTable[epIdx]->traceEnabled=true;
00243 CmiUnlock(_smp_mutex);
00244 }
00245
00246 #if CMK_CHARMDEBUG
00247 static void pupEntry(PUP::er &p,int index)
00248 {
00249 EntryInfo *c=_entryTable[index];
00250 PCOMS(name)
00251 p.comment("index");
00252 p(index);
00253 PCOM(msgIdx)
00254 PCOM(chareIdx)
00255 PCOM(inCharm);
00256 }
00257
00258 static void pupMsg(PUP::er &p,int i)
00259 {
00260 MsgInfo *c=_msgTable[i];
00261 PCOMS(name) PCOM(size)
00262 }
00263 static void pupChare(PUP::er &p,int i)
00264 {
00265 ChareInfo *c=_chareTable[i];
00266 PCOMS(name) PCOM(size)
00267 PCOM(defCtor) PCOM(migCtor)
00268 PCOM(numbases)
00269 PCOM(inCharm)
00270 p.comment("List of base classes:");
00271 p(c->bases,c->numbases);
00272 }
00273 static void pupMain(PUP::er &p,int i)
00274 {
00275 MainInfo *c=_mainTable[i];
00276 PCOMS(name) PCOM(chareIdx) PCOM(entryIdx)
00277 }
00278 static void pupReadonly(PUP::er &p,int i)
00279 {
00280 ReadonlyInfo *c=_readonlyTable[i];
00281 PCOMS(name) PCOMS(type) PCOM(size)
00282 p.comment("value");
00283
00284 p((char *)c->ptr,c->size);
00285 }
00286 static void pupReadonlyMsg(PUP::er &p,int i)
00287 {
00288 ReadonlyMsgInfo *c=_readonlyMsgs[i];
00289 PCOMS(name) PCOMS(type)
00290 p.comment("value");
00291 CkPupMessage(p,c->pMsg,0);
00292 }
00293 #endif
00294 extern void CpdCharmInit(void);
00295
00296 void _registerDone(void)
00297 {
00298 __registerDone = 1;
00299 #if CMK_CHARMDEBUG
00300 if (CkMyRank() == 0) {
00301 CpdListRegister(new CpdSimpleListAccessor<EntryInfo>("charm/entries",&_entryTable,pupEntry));
00302 CpdListRegister(new CpdSimpleListAccessor<MsgInfo>("charm/messages",&_msgTable,pupMsg));
00303 CpdListRegister(new CpdSimpleListAccessor<ChareInfo>("charm/chares",&_chareTable,pupChare));
00304 CpdListRegister(new CpdSimpleListAccessor<MainInfo>("charm/mains",&_mainTable,pupMain));
00305 CpdListRegister(new CpdSimpleListAccessor<ReadonlyInfo>("charm/readonly",&_readonlyTable,pupReadonly));
00306 CpdListRegister(new CpdSimpleListAccessor<ReadonlyMsgInfo>("charm/readonlyMsg",&_readonlyMsgs,pupReadonlyMsg));
00307 CpdCharmInit();
00308 }
00309 #endif
00310 }
00311
00312
00313 void CkPrintEntryMethod(int epIdx) {
00314 if (epIdx<=0 || epIdx>=(int)_entryTable.size())
00315 CkPrintf("INVALID ENTRY METHOD %d!",epIdx);
00316 else {
00317 EntryInfo *e=_entryTable[epIdx];
00318 CkPrintChareName(e->chareIdx);
00319 CkPrintf("::%s",e->name);
00320 }
00321 }
00322
00323
00324 void CkPrintChareName(int chareIdx) {
00325 if (chareIdx<=0 || chareIdx>=(int)_chareTable.size())
00326 CkPrintf("INVALID CHARE INDEX %d!",chareIdx);
00327 else {
00328 ChareInfo *c=_chareTable[chareIdx];
00329 CkPrintf("%s",c->name);
00330 }
00331 }
00332
00333
00334
00335