/** Return a binary string containing the JPEG-compressed data of this raster image, which is wid x ht pixels, and each pixel bpp bytes (must be either 1, for greyscale; or 3, for RGB). quality controls the compression rate, from quality == 0, tiny compressed image, very low quality quality == 100, huge compressed image, very high quality This code derived from the "example.c" that ships with libjpeg; see that file for comments. */ std::string JPEGcompressImage(int wid,int ht,int bpp, const byte *image_data, int quality) { struct jpeg_compress_struct cinfo; JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ int row_stride; /* physical row width in image buffer */ struct jpeg_error_mgr jerr; cinfo.err = jpeg_std_error(&jerr); /* Now we can initialize the JPEG compression object. */ jpeg_create_compress(&cinfo); std::string ret; jpeg_stl_dest(&cinfo,&ret); cinfo.image_width = wid; /* image width and height, in pixels */ cinfo.image_height = ht; while (cinfo.image_height>65000) { /* FUNKY HACK: JPEG library can't support images over 64K pixels. But we want tall-skinny images for 3D volume impostors. So we just *lie* to the JPEG library, and it'll interpret the image data as several side-by-side interleaved scanlines. The decompressor doesn't (necessarily!) need to change either... */ if (cinfo.image_height&1) { CkError("liveViz0 JPEGlib WARNING: cannot shrink odd image height %d\n",cinfo.image_height); } cinfo.image_height/=2; cinfo.image_width*=2; } switch (bpp) { case 1: cinfo.input_components = 1; /* # of color components per pixel */ cinfo.in_color_space = JCS_GRAYSCALE; /* colorspace of input image */ break; case 3: cinfo.input_components = 3; /* # of color components per pixel */ cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ break; default: CkError("liveViz0's JPEGcompressImage: JPEGlib can only handle 1 or 3 bytes per pixel, not %d bpp\n",bpp); CkAbort("liveViz0's JPEGcompressImage: JPEGlib can only handle 1 or 3 bytes per pixel"); break; } jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); jpeg_start_compress(&cinfo, TRUE); row_stride = cinfo.image_width * bpp; /* JSAMPLEs per row in image_buffer */ while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = (JSAMPLE *)(& image_data[cinfo.next_scanline * row_stride]); (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); return ret; }
void FEMchunk::readField(int fid, void *nodes, const char *fname) { const IDXL_Layout &dt = IDXL_Layout_List::get().get(fid,"FEM_Read_field"); int type = dt.type; int width = dt.width; int offset = dt.offset; int distance = dt.distance; int skew = dt.skew; FILE *fp = fopen(fname, "r"); if(fp==0) { CkError("Cannot open file %s for reading.\n", fname); CkAbort("Exiting"); } char str[80]; char* pos; const char* fmt; int i, j, curline; #if FEM_FORTRAN curline = 1; #else curline = 0; #endif switch(type) { case FEM_INT: fmt = "%d%n"; break; case FEM_REAL: fmt = "%f%n"; break; case FEM_DOUBLE: fmt = "%lf%n"; break; default: CkAbort("FEM_Read_field doesn't support that data type"); } FEM_Mesh *cur_mesh=getMesh("FEM_Read_field"); int nNodes=cur_mesh->node.size(); for(i=0;i<nNodes;i++) { // skip lines to the next local node // (FIXME: assumes nodes are in ascending global order, which they ain't) int target=cur_mesh->node.getGlobalno(i); for(j=curline;j<target;j++) fgets(str,80,fp); curline = target+1; fgets(str,80,fp); int curnode, numchars; sscanf(str,"%d%n",&curnode,&numchars); pos = str + numchars; if(curnode != target) { CkError("Expecting info for node %d, got %d\n", target, curnode); CkAbort("Exiting"); } for(j=0;j<width;j++) { sscanf(pos, fmt, &IDXL_LAYOUT_DEREF(unsigned char,nodes,i,j), &numchars); pos += numchars; } } fclose(fp); }
// Check the quality of triangle i void checkTriangle(myGlobals &g, int i) { double area=calcArea(g,i); if (area<0) { CkError("Triangle %d of chunk %d is inverted! (area=%g)\n", i,FEM_My_partition(),area); CkAbort("Inverted triangle"); } if (area<1.0e-15) { CkError("Triangle %d of chunk %d is a sliver!\n",i,FEM_My_partition()); CkAbort("Sliver triangle"); } }
/** Create a stencil with this number of elements, and these adjacent elements. In C, userEnds[i] is the 0-based one-past-last element; in F90, userEnds[i] is the 1-based last element, which amounts to the same thing! In C, userAdj is 0-based; in F90, the even elType fields are 0-based, and the odd elemNum fields are 1-based. */ FEM_Ghost_Stencil::FEM_Ghost_Stencil(int elType_, int n_,bool addNodes_, const int *userEnds, const int *userAdj, int idxBase) :elType(elType_), n(n_), addNodes(addNodes_), ends(new int[n]), adj(new int[2*userEnds[n-1]]) { int i; int lastEnd=0; for (i=0;i<n;i++) { ends[i]=userEnds[i]; if (ends[i]<lastEnd) { CkError("FEM_Ghost_Stencil> ends array not monotonic!\n" " ends[%d]=%d < previous value %d\n", i,ends[i],lastEnd); CkAbort("FEM_Ghost_Stencil> ends array not monotonic"); } lastEnd=ends[i]; } int m=ends[n-1]; for (i=0;i<m;i++) { adj[2*i+0]=userAdj[2*i+0]; adj[2*i+1]=userAdj[2*i+1]-idxBase; } }
/// /// Feedback main method /// void Main::StellarFeedback(double dTime, double dDelta) { if(verbosity) CkPrintf("Stellar Feedback ... \n"); double startTime = CkWallTimer(); CkReductionMsg *msgFeedback; treeProxy.Feedback(*(param.feedback), dTime, dDelta, CkCallbackResumeThread((void*&)msgFeedback)); double *dFeedback = (double *)msgFeedback->getData(); if(verbosity) { CkPrintf("Feedback totals: mass, energy, metalicity\n"); for(int i = 0; i < NFEEDBACKS; i++){ CkPrintf("feedback %d: %g %g %g\n", i, dFeedback[i*3], dFeedback[i*3 + 1], dFeedback[i*3] != 0.0 ? dFeedback[i*3 + 2]/dFeedback[i*3] : 0.0); } } delete msgFeedback; CkReductionMsg *msgChk; treeProxy.massMetalsEnergyCheck(1, CkCallbackResumeThread((void*&)msgChk)); if(verbosity) CkPrintf("Distribute Stellar Feedback ... "); // Need to build tree since we just did addDelParticle. // treeProxy.buildTree(bucketSize, CkCallbackResumeThread()); DistStellarFeedbackSmoothParams pDSFB(TYPE_GAS, 0, param.csm, dTime, param.dConstGamma, param.feedback); double dfBall2OverSoft2 = 4.0*param.dhMinOverSoft*param.dhMinOverSoft; treeProxy.startSmooth(&pDSFB, 0, param.feedback->nSmoothFeedback, dfBall2OverSoft2, CkCallbackResumeThread()); treeProxy.finishNodeCache(CkCallbackResumeThread()); CkPrintf("Stellar Feedback Calculated, Wallclock %f secs\n", CkWallTimer() - startTime); CkReductionMsg *msgChk2; treeProxy.massMetalsEnergyCheck(0, CkCallbackResumeThread((void*&)msgChk2)); double *dTotals = (double *)msgChk->getData(); double *dTotals2 = (double *)msgChk2->getData(); int i; for(i = 0; i < 5; i++) { std::string labels[5] = {"Mass", "Metals", "Oxygen", "Iron", "Energy"}; if(verbosity > 1) CkPrintf("Total %s: %g\n", labels[i].c_str(), dTotals[i]); if(fabs(dTotals[i] - dTotals2[i]) > 1e-12*(dTotals[i])) { CkError("ERROR: %s not conserved: %.15e != %.15e!\n", labels[i].c_str(), dTotals[i], dTotals2[i]); } } delete msgChk; delete msgChk2; }
void varsizetest_init(void) { if(CkNumPes()<2) { CkError("varsize: requires at least 2 processors\n"); megatest_finish(); } else CProxy_varsizetest_main::ckNew(0); }
void migration_init(void) { const int numElements = 10 + (CkNumPes() * 2); if(CkNumPes() < 2) { CkError("migration: requires at least 2 processors.\n"); megatest_finish(); } else CProxy_mig_Element::ckNew(numElements); }
int findChunk(int paneID,const int *paneFmChunk) { for (int c=0;paneFmChunk[c]>0;c++) if (paneFmChunk[c]==paneID) return c; CkError("Can't find chunk for pconn paneID %d!\n",paneID); CmiAbort("Bad pconn array"); return -1; }
void done(int objectType,int paramVal) { if (objectType!=expectType || paramVal!=expectParam) { CkError("Callback step %d: expected object %d, got %d; expected param %d, got %d\n", state,expectType,objectType, expectParam,paramVal); CkAbort("Unexpected callback object or parameter"); } expectCount--; if (expectCount==0) next(); }
inline int globalElem2elType(const FEM_Mesh *m,int globalElem) { int curStart=0; for (int t=0;t<m->elem.size();t++) if (m->elem.has(t)) { int n=m->elem[t].size(); if (globalElem>=curStart && globalElem<curStart+n) return t; curStart+=n; } CkError("FEM> Invalid global element number %d!\n",globalElem); CkAbort("FEM> Invalid global element number!"); return 0; }
void pong(int callee, int order) { CkPrintf("[chare=%d,pe=%d]: %d: pong #%d called by %d\n", getuChareSet()->getId(), getuChareSet()->getPe(), getId(), order, callee); //doPong(callee); if ((pongCounters[callee] + 1) != order) { CkError("Pong order failure: callee = %d, counter = %d, order = %d\n", callee, pongCounters[callee], order); CkAbort("Pong order failure"); } else pongCounters[callee]++; }
static void checkArr(int *arr,int tryNo,int n) { randGen g(tryNo+257*n); for (int i=0;i<n;i++) { int expected=(int)g.next(); if (arr[i]!=expected) { CkError("Array marshalling error: try %d," " index %d of %d (got 0x%08x; should be 0x%08x) \n", tryNo,i,n,arr[i],expected); CkAbort("Marshalling error"); } } }
void liveViz0Deposit(const liveVizRequest &req,byte * imageData) { int len=req.wid*req.ht*config.getNetworkBytesPerPixel(); if (config.getVerbose(2)) CmiPrintf("CCS getImage> Reply for (%d x %d) pixel or %d byte image.\n", req.wid,req.ht,len); switch (req.compressionType) { case liveVizRequest::compressionNone: /* send uncompressed pixels */ CcsSendDelayedReply(req.replyToken, len, imageData); break; #if CMK_USE_LIBJPEG && !defined(__CYGWIN__) case liveVizRequest::compressionJPEG: { /* JPEG-compress the data */ std::string data=JPEGcompressImage(req.wid,req.ht, config.getNetworkBytesPerPixel(),imageData, req.compressionQuality); CcsSendDelayedReply(req.replyToken, data.size(), &data[0]); break; } #endif case liveVizRequest::compressionRunLength: { std::string data; for(int i=0; i<req.ht*req.wid;) { int j=i; while(imageData[j]==imageData[i]&&i-j<255&&i<req.ht*req.wid) i++; data.push_back((char)((i-j)&0xff)); data.push_back(imageData[j]); } CcsSendDelayedReply(req.replyToken, data.size(), &data[0]); } break; default: CkError("liveViz0.C WARNING: Ignoring liveViz client's unrecognized compressionType %d\n",req.compressionType); CcsSendDelayedReply(req.replyToken, 0, 0); }; }
/* These non "_type" routines describe element adjacencies using one big array, instead of one array per element type. This one-piece format is more convenient for most users. */ CDECL void FEM_Add_ghost_stencil(int nElts,int addNodes, const int *ends,const int *adj) { FEMAPI("FEM_Add_ghost_stencil"); const FEM_Mesh *m=setMesh(); int adjSrc=0, endsSrc=0; for (int t=0;t<m->elem.size();t++) if (m->elem.has(t)) { const FEM_Elem &el=m->elem[t]; int n=el.size(); int nAdjLocal=ends[endsSrc+n-1]-adjSrc; int *adjLocal=new int[2*nAdjLocal]; int *endsLocal=new int[n]; int adjDest=0, endsDest=0; while (endsDest<n) { while (adjSrc<ends[endsSrc]) { /* Make adj array into elType, elNum pairs */ int et=globalElem2elType(m,adj[adjSrc]); adjLocal[2*adjDest+0]=et; adjLocal[2*adjDest+1]=adj[adjSrc]-m->nElems(et); adjDest++; adjSrc++; } /* Use local end numbers in adjLocal array */ endsLocal[endsDest]=adjDest; endsDest++; endsSrc++; } if (adjDest!=nAdjLocal) CkAbort("FEM_Add_ghost_stencil adjacency count mismatch!"); FEM_Add_ghost_stencil_type(t,n,addNodes,endsLocal,adjLocal); delete []endsLocal; delete []adjLocal; } if (endsSrc!=nElts) { CkError("FEM_Add_ghost_stencil: FEM thinks there are %d elements, but nElts is %d!\n",endsSrc,nElts); CkAbort("FEM_Add_ghost_stencil elements mismatch!"); } FEM_curPartition().markGhostStencilLayer(); }
void immRing_group::start(immMessage *msg) { const int maxRings = 50; //CkPrintf("[%d] start %d\n", thisIndex, msg->iter); if(!msg->check()) { CkError("Message corrupted!\n"); megatest_finish(); return; } if(CkMyPe()==0) msg->iter++; if (msg->iter < maxRings) { thisProxy[(CkMyPe()+1) % CkNumPes()].start(msg); } else { delete msg; //megatest_finish(); int size=CmiMsgHeaderSizeBytes; void *msg=CmiAlloc(size); CmiSetHandler(msg,immediatering_finishHandlerIdx); CmiSyncSendAndFree(0,size,(char *)msg); } }
void DistStellarFeedbackSmoothParams::DistFBMME(GravityParticle *p,int nSmooth, pqSmoothNode *nList) { GravityParticle *q; double fNorm,ih2,r2,rs,rstot,fNorm_u,fNorm_Pres,fAveDens; int i,counter; int nHeavy = 0; if ( p->fMSN() == 0.0 ){return;} /* Is there any feedback mass? */ CkAssert(TYPETest(p, TYPE_STAR)); CkAssert(nSmooth > 0); ih2 = invH2(p); rstot = 0.0; fNorm_u = 0.0; fNorm_Pres = 0.0; fAveDens = 0.0; fNorm = 0.5*M_1_PI*sqrt(ih2)*ih2; for (i=0;i<nSmooth;++i) { double fDist2 = nList[i].fKey; r2 = fDist2*ih2; rs = KERNEL(r2); q = nList[i].p; if(q->mass > fb.dMaxGasMass) { nHeavy++; continue; /* Skip heavy particles */ } fNorm_u += q->mass*rs; CkAssert(TYPETest(q, TYPE_GAS)); rs *= fNorm; fAveDens += q->mass*rs; fNorm_Pres += q->mass*q->uPred()*rs; } if(fNorm_u == 0.0) { CkError("Got %d heavies: no feedback\n", nHeavy); } CkAssert(fNorm_u > 0.0); /* be sure we have at least one neighbor */ fNorm_Pres *= (gamma-1.0); fNorm_u = 1./fNorm_u; counter=0; for (i=0;i<nSmooth;++i) { double weight; q = nList[i].p; if(q->mass > fb.dMaxGasMass) { continue; /* Skip heavy particles */ } double fDist2 = nList[i].fKey; r2 = fDist2*ih2; rs = KERNEL(r2); /* Remember: We are dealing with total energy rate and total metal * mass, not energy/gram or metals per gram. * q->mass is in product to make units work for fNorm_u. */ #ifdef VOLUMEFEEDBACK weight = rs*fNorm_u*q->mass/q->fDensity; #else weight = rs*fNorm_u*q->mass; #endif if (p->fNSN() == 0.0) q->fESNrate() += weight*p->fStarESNrate(); q->fMetals() += weight*p->fSNMetals(); q->fMFracOxygen() += weight*p->fMOxygenOut(); q->fMFracIron() += weight*p->fMIronOut(); q->mass += weight*p->fMSN(); } }
static void die(const char *str) { CkError("Fatal error: %s\n",str); CkExit(); }