00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <iostream>
00028 #include <limits>
00029
00030 #if defined(BL_OLD_STL)
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #else
00034 #include <cstdlib>
00035 #include <cstring>
00036 #endif
00037
00038 #include <BoxLib.H>
00039 #include <FabConv.H>
00040 #include <FArrayBox.H>
00041 #include <FPC.H>
00042 #include <REAL.H>
00043
00044
00045
00046
00047 #if defined(BL_ARCH_CRAY)
00048 #define FORT_IEG2CRAY IEG2CRAY
00049 #define FORT_CRAY2IEG CRAY2IEG
00050 extern "C"
00051 {
00052 void FORT_IEG2CRAY(int& type, int& num, char* forn, int& bitoff,
00053 char* cry, int& stride, char& craych);
00054 void FORT_CRAY2IEG(int& type, int& num, char* forn, int& bitoff,
00055 char* cry, int& stride, char& craych);
00056 }
00057 #endif
00058
00059 RealDescriptor::~RealDescriptor() {}
00060
00061 bool RealDescriptor::bAlwaysFixDenormals(false);
00062
00063 IntDescriptor::IntDescriptor ()
00064 {}
00065
00066 IntDescriptor::IntDescriptor (long nb,
00067 Ordering o)
00068 : numbytes(nb),
00069 ord(o)
00070 {}
00071
00072 IntDescriptor::Ordering
00073 IntDescriptor::order () const
00074 {
00075 return ord;
00076 }
00077
00078 int
00079 IntDescriptor::numBytes () const
00080 {
00081 return numbytes;
00082 }
00083
00084 bool
00085 IntDescriptor::operator== (const IntDescriptor& id) const
00086 {
00087 return ord == id.ord && numbytes == id.numbytes;
00088 }
00089
00090 bool
00091 IntDescriptor::operator!= (const IntDescriptor& id) const
00092 {
00093 return !operator==(id);
00094 }
00095
00096 RealDescriptor::RealDescriptor ()
00097 {}
00098
00099 RealDescriptor::RealDescriptor (const long* fr_,
00100 const int* ord_,
00101 int ordl_)
00102 : fr(fr_, 8),
00103 ord(ord_, ordl_)
00104 {}
00105
00106 RealDescriptor::RealDescriptor (const RealDescriptor& rhs)
00107 : fr(rhs.fr),
00108 ord(rhs.ord)
00109 {}
00110
00111 RealDescriptor&
00112 RealDescriptor::operator= (const RealDescriptor& rhs)
00113 {
00114 fr = rhs.fr;
00115 ord = rhs.ord;
00116 return *this;
00117 }
00118
00119 const long*
00120 RealDescriptor::format () const
00121 {
00122 BL_ASSERT(fr.size() != 0);
00123 return fr.dataPtr();
00124 }
00125
00126 const Array<long>&
00127 RealDescriptor::formatarray () const
00128 {
00129 BL_ASSERT(fr.size() != 0);
00130 return fr;
00131 }
00132
00133 const int*
00134 RealDescriptor::order () const
00135 {
00136 BL_ASSERT(ord.size() != 0);
00137 return ord.dataPtr();
00138 }
00139
00140 const Array<int>&
00141 RealDescriptor::orderarray () const
00142 {
00143 BL_ASSERT(ord.size() != 0);
00144 return ord;
00145 }
00146
00147 int
00148 RealDescriptor::numBytes () const
00149 {
00150 BL_ASSERT(fr.size() != 0);
00151 return (fr[0] + 7 ) >> 3;
00152 }
00153
00154 bool
00155 RealDescriptor::operator== (const RealDescriptor& rd) const
00156 {
00157 return fr == rd.fr && ord == rd.ord;
00158 }
00159
00160 bool
00161 RealDescriptor::operator != (const RealDescriptor& rd) const
00162 {
00163 return !operator==(rd);
00164 }
00165
00166 void
00167 RealDescriptor::SetFixDenormals()
00168 {
00169 bAlwaysFixDenormals = true;
00170 }
00171
00172
00173
00174
00175 RealDescriptor*
00176 RealDescriptor::clone () const
00177 {
00178 RealDescriptor* rd = new RealDescriptor(*this);
00179 return rd;
00180 }
00181
00182
00183
00184
00185
00186 static
00187 const int*
00188 selectOrdering (int prec,
00189 int ordering)
00190 {
00191 switch (prec)
00192 {
00193 case FABio::FAB_FLOAT:
00194 switch (ordering)
00195 {
00196 case FABio::FAB_NORMAL_ORDER:
00197 return FPC::normal_float_order;
00198 case FABio::FAB_REVERSE_ORDER:
00199 return FPC::reverse_float_order;
00200 case FABio::FAB_REVERSE_ORDER_2:
00201 return FPC::reverse_float_order_2;
00202 default:
00203 BoxLib::Error("selectOrdering(): Crazy ordering");
00204 }
00205 break;
00206 case FABio::FAB_DOUBLE:
00207 switch (ordering)
00208 {
00209 case FABio::FAB_NORMAL_ORDER:
00210 return FPC::normal_double_order;
00211 case FABio::FAB_REVERSE_ORDER:
00212 return FPC::reverse_double_order;
00213 case FABio::FAB_REVERSE_ORDER_2:
00214 return FPC::reverse_double_order_2;
00215 default:
00216 BoxLib::Error("selectOrdering(): Crazy ordering");
00217 }
00218 break;
00219 default:
00220 BoxLib::Error("selectOrdering(): Crazy precision");
00221 }
00222 return 0;
00223 }
00224
00225
00226
00227
00228
00229 RealDescriptor*
00230 RealDescriptor::newRealDescriptor (int iot,
00231 int prec,
00232 const char* sys,
00233 int ordering)
00234 {
00235 RealDescriptor* rd = 0;
00236
00237 switch (iot)
00238 {
00239 case FABio::FAB_IEEE:
00240 {
00241 const int* ord = selectOrdering(prec, ordering);
00242 switch (prec)
00243 {
00244 case FABio::FAB_FLOAT:
00245 if(strcmp(sys, "CRAY") == 0) {
00246 rd = new RealDescriptor(FPC::ieee_double, ord, 8);
00247 } else {
00248 rd = new RealDescriptor(FPC::ieee_float, ord, 4);
00249 }
00250 return rd;
00251 case FABio::FAB_DOUBLE:
00252 rd = new RealDescriptor(FPC::ieee_double, ord, 8);
00253 return rd;
00254 }
00255 }
00256 case FABio::FAB_NATIVE:
00257 if (sys != 0 && strncmp(sys, "CRAY", 4) == 0)
00258 {
00259 rd = new RealDescriptor(FPC::cray_float, FPC::cray_float_order, 8);
00260 return rd;
00261 }
00262 default:
00263 BoxLib::Error("RealDescriptor::newRealDescriptor(): Crazy precision");
00264 }
00265 rd = new RealDescriptor;
00266 return rd;
00267 }
00268
00269 inline
00270 void
00271 ONES_COMP_NEG (long& n,
00272 int nb,
00273 long incr)
00274 {
00275 if (nb == 8*sizeof(long))
00276 n = ~n + incr;
00277 else
00278 {
00279 const long MSK = (1L << nb) - 1L;
00280 n = (~n + incr) & MSK;
00281 }
00282 }
00283
00284
00285
00286
00287
00288 inline
00289 int
00290 _PD_get_bit (char* base,
00291 int offs,
00292 int nby,
00293 const int* ord)
00294 {
00295 int n = offs >> 3;
00296 int nbytes = n % nby;
00297 n -= nbytes;
00298 offs = offs % 8;
00299
00300 if (ord == NULL)
00301 base += (n + nbytes);
00302 else
00303 base += (n + (ord[nbytes] - 1));
00304
00305 int mask = (1 << (7 - offs));
00306
00307 return (*base & mask) != 0;
00308 }
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 static
00319 long
00320 _PD_extract_field (char* in,
00321 int offs,
00322 int nbi,
00323 int nby,
00324 const int* ord)
00325 {
00326 int ind;
00327 long bit_field = 0L;
00328
00329
00330
00331
00332
00333 long n = offs >> 3;
00334 int offy = int(n % nby);
00335 n -= offy;
00336 offs = offs % 8;
00337
00338
00339
00340 in += n;
00341 unsigned char bpb = 8 - offs;
00342
00343 if (ord == NULL)
00344 ind = offy++;
00345 else
00346 {
00347 if (offy >= nby)
00348 {
00349 offy -= nby;
00350 in += nby;
00351 }
00352 ind = (ord[offy++] - 1);
00353 }
00354
00355 int tgt = in[ind];
00356 unsigned char mask = (1 << bpb) - 1;
00357 bit_field = ((bit_field << bpb) | (tgt & mask));
00358 nbi -= bpb;
00359 if (nbi < 0)
00360 bit_field = bit_field >> (-nbi);
00361 else
00362 {
00363 for (; nbi > 0; nbi -= bpb)
00364 {
00365
00366
00367
00368 if (ord == NULL)
00369 ind = offy++;
00370 else
00371 {
00372 if (offy >= nby)
00373 {
00374 offy -= nby;
00375 in += nby;
00376 }
00377 ind = (ord[offy++] - 1);
00378 }
00379
00380 tgt = in[ind];
00381 bpb = nbi > 8 ? 8 : nbi;
00382 mask = (1 << bpb) - 1;
00383 bit_field = ((bit_field << bpb) | ((tgt >> (8 - bpb)) & mask));
00384 }
00385 }
00386
00387 return bit_field;
00388 }
00389
00390
00391
00392
00393
00394 static
00395 void
00396 _PD_btrvout (char* out,
00397 long nb,
00398 long nitems)
00399 {
00400 for (long jl = 0, nbo2 = nb >> 1; jl < nbo2; jl++)
00401 {
00402 long jh = nb - jl - 1;
00403 char* p1 = out + jh;
00404 char* p2 = out + jl;
00405 for (long i = 0L; i < nitems; i++)
00406 {
00407 char tmp = *p1;
00408 *p1 = *p2;
00409 *p2 = tmp;
00410 p1 += nb;
00411 p2 += nb;
00412 }
00413 }
00414 }
00415
00416 const int BitsMax = 8*sizeof(long);
00417 const int REVERSE_ORDER = 2;
00418
00419
00420
00421
00422
00423
00424
00425
00426 inline
00427 void
00428 _PD_insert_field (long in_long,
00429 int nb,
00430 char* out,
00431 int offs,
00432 int l_order,
00433 int l_bytes)
00434 {
00435 int dm;
00436 long longmask;
00437
00438 char* in = (char *) &in_long;
00439
00440
00441
00442
00443 if (offs > 7)
00444 {
00445 out += (offs >> 3);
00446 offs %= 8;
00447 }
00448
00449
00450
00451
00452 int mi = BitsMax - nb;
00453 if (mi < offs)
00454 {
00455 dm = BitsMax - (8 - offs);
00456 if (nb == BitsMax)
00457 longmask = ~((1L << dm) - 1L);
00458 else
00459 longmask = ((1L << nb) - 1L) ^ ((1L << dm) - 1L);
00460
00461 unsigned char fb = ((in_long&longmask)>>dm)&((1L<<(nb-dm))-1L);
00462 *(out++) |= fb;
00463
00464 mi += 8 - offs;
00465 offs = 0;
00466 }
00467
00468
00469
00470
00471 dm = mi - offs;
00472 longmask = ~((1L << dm) - 1L);
00473 in_long = (in_long << dm) & longmask;
00474
00475
00476
00477 if (l_order == REVERSE_ORDER)
00478 _PD_btrvout(in, l_bytes, 1L);
00479
00480
00481
00482 for (int n = (offs+nb+7)/8; n > 0; n--, *(out++) |= *(in++))
00483 ;
00484 }
00485
00486
00487
00488
00489
00490 inline
00491 void
00492 _PD_set_bit (char* base, int offs)
00493 {
00494 int nbytes = offs >> 3;
00495
00496 base += nbytes;
00497 offs -= 8*nbytes;
00498
00499 int mask = (1 << (7 - offs));
00500
00501 *base |= mask;
00502 }
00503
00504
00505
00506
00507
00508
00509
00510 static
00511 void
00512 _PD_reorder (char* arr,
00513 long nitems,
00514 int nbytes,
00515 const int* ord)
00516 {
00517 const int MAXLINE = 16;
00518 char local[MAXLINE];
00519
00520 for (int j; nitems > 0; nitems--)
00521 {
00522 arr--;
00523 for (j = 0; j < nbytes; local[j] = arr[ord[j]], j++);
00524 arr++;
00525 for (j = 0; j < nbytes; *(arr++) = local[j++]);
00526 }
00527 }
00528
00529
00530
00531
00532
00533
00534
00535 static
00536 void
00537 permute_real_word_order (void* out,
00538 const void* in,
00539 long nitems,
00540 const int* outord,
00541 const int* inord)
00542 {
00543 const int REALSIZE = sizeof(Real);
00544
00545 char* pin = (char*) in;
00546 char* pout = (char*) out;
00547
00548 pin--; pout--;
00549
00550 for (; nitems > 0; nitems--, pin += REALSIZE, pout += REALSIZE)
00551 {
00552 for (int i = 0; i < REALSIZE; i++)
00553 pout[outord[i]] = pin[inord[i]];
00554 }
00555 }
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626 void
00627 PD_fconvert (void* out,
00628 const void* in,
00629 long nitems,
00630 int boffs,
00631 const long* outfor,
00632 const int* outord,
00633 const long* infor,
00634 const int* inord,
00635 int l_order,
00636 int l_bytes,
00637 int onescmp)
00638 {
00639 long i, expn, expn_max, hexpn, mant, DeltaBias, hmbo, hmbi;
00640 int nbits, inbytes, outbytes, sign;
00641 int indxin, indxout, inrem, outrem, dindx;
00642 int bi_sign, bo_sign, bi_exp, bo_exp, bi_mant, bo_mant;
00643 int nbi_exp, nbo_exp, nbi, nbo;
00644 char *lout, *lin;
00645 unsigned char *rout;
00646
00647 nbi = int(infor[0]);
00648 nbo = int(outfor[0]);
00649 nbi_exp = int(infor[1]);
00650 nbo_exp = int(outfor[1]);
00651 bi_sign = int(infor[3] + boffs);
00652 bo_sign = int(outfor[3]);
00653 bi_exp = int(infor[4] + boffs);
00654 bo_exp = int(outfor[4]);
00655 bi_mant = int(infor[5] + boffs);
00656 bo_mant = int(outfor[5]);
00657
00658 hmbo = (outfor[6] & 1L);
00659 hmbi = (infor[6] & 1L);
00660
00661 inbytes = (nbi + 7) >> 3;
00662 outbytes = (nbo + 7) >> 3;
00663 DeltaBias = outfor[7] + hmbo - infor[7] - hmbi;
00664 hexpn = 1L << (outfor[1] - 1L);
00665 expn_max = (1L << outfor[1]) - 1L;
00666
00667 size_t number = size_t(nitems);
00668 BL_ASSERT(int(number) == nitems);
00669 memset(out, 0, number*outbytes);
00670
00671 lout = (char*)out;
00672 lin = (char*)in;
00673
00674 for (i = 0L; i < nitems; i++)
00675 {
00676
00677
00678
00679 expn = _PD_extract_field(lin, bi_exp, nbi_exp, inbytes, inord);
00680 sign = _PD_get_bit(lin, bi_sign, inbytes, inord);
00681
00682
00683
00684
00685
00686 if (onescmp)
00687 {
00688 if (sign)
00689 {
00690 ONES_COMP_NEG(expn, nbi_exp, 1L);
00691 }
00692 else
00693 expn += (expn < hexpn);
00694 }
00695 if (expn != 0)
00696 expn += DeltaBias;
00697 if ((0 <= expn) && (expn < expn_max))
00698 {
00699 _PD_insert_field(expn, nbo_exp, lout, bo_exp, l_order, l_bytes);
00700
00701 if (sign)
00702 _PD_set_bit(lout, bo_sign);
00703
00704 indxin = bi_mant;
00705 inrem = int(infor[2]);
00706 indxout = bo_mant;
00707 outrem = int(outfor[2]);
00708
00709
00710
00711
00712
00713 dindx = int(hmbo - hmbi);
00714 if (dindx > 0)
00715 {
00716 _PD_set_bit(lout, indxout);
00717 indxout += dindx;
00718 outrem -= dindx;
00719 }
00720
00721
00722
00723
00724
00725 else if (dindx < 0)
00726 {
00727 indxin -= dindx;
00728 inrem += dindx;
00729 }
00730
00731
00732
00733 while ((inrem > 0) && (outrem > 0))
00734 {
00735 nbits = BitsMax > inrem ? inrem : BitsMax;
00736 nbits = nbits > outrem ? outrem : nbits;
00737 mant = _PD_extract_field(lin, indxin, nbits, inbytes, inord);
00738
00739
00740
00741 if (onescmp && sign)
00742 ONES_COMP_NEG(mant, nbits, 0L);
00743
00744 _PD_insert_field(mant, nbits, lout, indxout, l_order, l_bytes);
00745
00746 indxin += nbits;
00747 indxout += nbits;
00748 inrem -= nbits;
00749 outrem -= nbits;
00750 }
00751 }
00752
00753
00754
00755 else if (expn_max <= expn)
00756 {
00757 _PD_insert_field(expn_max, nbo_exp, lout, bo_exp, l_order, l_bytes);
00758
00759 if (_PD_get_bit(lin, bi_sign, inbytes, inord))
00760 _PD_set_bit(lout, bo_sign);
00761 }
00762 bi_sign += nbi;
00763 bi_exp += nbi;
00764 bi_mant += nbi;
00765 bo_sign += nbo;
00766 bo_exp += nbo;
00767 bo_mant += nbo;
00768 }
00769
00770
00771
00772
00773
00774 if (hmbo)
00775 {
00776 int j, mask = (1 << (7 - bo_mant % 8));
00777
00778 indxout = int(outfor[5]/8);
00779 rout = (unsigned char *) out;
00780 for (i = 0L; i < nitems; i++, rout += outbytes)
00781 {
00782 for (j = 0; j < outbytes; j++)
00783 if ((j == indxout) ? (rout[j] != mask) : rout[j])
00784 break;
00785 if (j == outbytes)
00786 rout[indxout] = 0;
00787 }
00788 }
00789
00790
00791
00792 _PD_reorder((char*)out, nitems, outbytes, outord);
00793 }
00794
00795
00796
00797
00798
00799
00800
00801 #if defined(__alpha) && !defined(BL_USE_FLOAT)
00802 static
00803 void
00804 cray64toalpha64_fconvert (void* out,
00805 const void* in,
00806 long nitems)
00807 {
00808 const long DeltaBias = 0x3FFL - 0x4000L - 1L;
00809 const long expn_max = (1L << 11L) - 1L;
00810
00811 memset(out, 0, nitems*8);
00812
00813 long *lin = (long *)in;
00814 long *lout = (long *)out;
00815
00816 for (long i = 0; i < nitems; i++)
00817 {
00818
00819
00820
00821 long ordinp = 0, input = *lin;
00822 for (size_t j = 0; j < sizeof(long); j++)
00823 {
00824 ordinp <<= 8;
00825 ordinp |= (input & 0xff);
00826 input >>= 8;
00827 }
00828
00829
00830
00831 long sign = (ordinp>>63) & 1;
00832 long expn = (ordinp>>48) & 0x7FFF;
00833 long ordout = 0;
00834
00835
00836
00837 if (expn != 0)
00838 expn += DeltaBias;
00839 if (0 <= expn && expn < expn_max)
00840 {
00841 ordout |= (sign<<63);
00842 ordout |= (expn<<52);
00843
00844
00845
00846 long mant = (ordinp) & 0x7FFFFFFFFFFF;
00847 mant <<= 5;
00848 ordout |= mant;
00849 }
00850 else if (expn_max <= expn)
00851 {
00852
00853
00854
00855 ordout = 0x7ff0000000000000L;
00856 ordout |= (sign<<63);
00857 }
00858 else
00859
00860
00861
00862 ordout = 0;
00863
00864
00865
00866 lin++;
00867 *lout++ = ordout;
00868 }
00869 }
00870 #endif
00871
00872 #if defined(__alpha) && defined(BL_USE_FLOAT)
00873 static
00874 void
00875 ieee32toalpha32_fconvert (void* out,
00876 const void* in,
00877 long nitems)
00878 {
00879 const long expn_max = (1L << 8L) - 1L;
00880
00881 memset(out, 0, nitems*4);
00882
00883 int* iin = (int*)in;
00884 int* iout = (int*)out;
00885
00886 for (long i = 0; i < nitems; i++)
00887 {
00888
00889
00890
00891 int ordinp = 0;
00892 for (int j = 0, input = *iin; j < sizeof(int); j++)
00893 {
00894 ordinp <<= 8;
00895 ordinp |= (input & 0xff);
00896 input >>= 8;
00897 }
00898
00899
00900
00901 long expn = (ordinp>>23) & 0xFF;
00902 if (expn_max <= expn)
00903 {
00904
00905
00906
00907 int sign = ordinp & 0x80000000;
00908 ordinp = 0x7f800000;
00909 ordinp |= sign;
00910 }
00911 else if (expn <= 0)
00912
00913
00914
00915 ordinp = 0;
00916
00917
00918
00919 iin++;
00920 *iout++ = ordinp;
00921 }
00922 }
00923 #endif
00924
00925 static
00926 void
00927 PD_fixdenormals (void* out,
00928 long nitems,
00929 const long* outfor,
00930 const int* outord)
00931 {
00932 const int nbo = int(outfor[0]);
00933
00934 int nbo_exp = int(outfor[1]);
00935 int bo_exp = int(outfor[4]);
00936 int outbytes = (nbo + 7) >> 3;
00937
00938 char* lout = (char*) out;
00939
00940 for (long i = 0L; i < nitems; i++)
00941 {
00942 if (_PD_extract_field(lout, bo_exp, nbo_exp, outbytes, outord) == 0)
00943 {
00944
00945
00946
00947 char* loutoffset = lout+(i*outbytes);
00948 memset(loutoffset, '\0', outbytes);
00949 }
00950 bo_exp += nbo;
00951 }
00952 }
00953
00954
00955
00956
00957
00958 #undef GETARRAY
00959 #define GETARRAY(TYPE) \
00960 static \
00961 void \
00962 getarray (std::istream& is, \
00963 Array< TYPE >& ar) \
00964 { \
00965 char c; \
00966 is >> c; \
00967 if (c != '(') \
00968 BoxLib::Error("getarray(istream&): expected a \'(\'"); \
00969 int size; \
00970 is >> size; \
00971 is >> c; \
00972 if ( c != ',') \
00973 BoxLib::Error("getarray(istream&): expected a \',\'"); \
00974 is >> c; \
00975 if (c != '(') \
00976 BoxLib::Error("getarray(istream&): expected a \'(\'"); \
00977 ar.resize(size); \
00978 for(int i = 0; i < size; ++i) \
00979 is >> ar[i]; \
00980 is >> c; \
00981 if (c != ')') \
00982 BoxLib::Error("getarray(istream&): expected a \')\'"); \
00983 is >> c; \
00984 if (c != ')') \
00985 BoxLib::Error("getarray(istream&): expected a \')\'"); \
00986 }
00987 GETARRAY(int)
00988 GETARRAY(long)
00989 #undef GETARRAY
00990
00991 #undef PUTARRAY
00992 #define PUTARRAY(TYPE) \
00993 static \
00994 void \
00995 putarray (std::ostream& os, \
00996 const Array< TYPE >& ar) \
00997 { \
00998 int i; \
00999 os << '('; \
01000 os << ar.size() << ", ("; \
01001 for (i = 0; i < ar.size(); ++i) \
01002 { \
01003 os << ar[i]; \
01004 if (i != ar.size() - 1) \
01005 os << ' '; \
01006 } \
01007 os << "))"; \
01008 }
01009 PUTARRAY(int)
01010 PUTARRAY(long)
01011 #undef PUTARRAY
01012
01013 std::ostream&
01014 operator<< (std::ostream& os,
01015 const RealDescriptor& id)
01016 {
01017 os << "(";
01018 putarray(os, id.formatarray());
01019 os << ',';
01020 putarray(os, id.orderarray());
01021 os << ")";
01022 if (os.fail())
01023 BoxLib::Error("operator<<(ostream&,RealDescriptor&) failed");
01024 return os;
01025 }
01026
01027 std::istream&
01028 operator>> (std::istream& is,
01029 RealDescriptor& rd)
01030 {
01031 char c;
01032 is >> c;
01033 if (c != '(')
01034 BoxLib::Error("operator>>(istream&,RealDescriptor&): expected a \'(\'");
01035 Array<long> fmt;
01036 getarray(is, fmt);
01037 is >> c;
01038 if (c != ',')
01039 BoxLib::Error("operator>>(istream&,RealDescriptor&): expected a \',\'");
01040 Array<int> ord;
01041 getarray(is, ord);
01042 is >> c;
01043 if (c != ')')
01044 BoxLib::Error("operator>>(istream&,RealDescriptor&): expected a \')\'");
01045 rd = RealDescriptor(fmt.dataPtr(),ord.dataPtr(),ord.size());
01046 return is;
01047 }
01048
01049 static
01050 void
01051 PD_convert (void* out,
01052 const void* in,
01053 long nitems,
01054 int boffs,
01055 const RealDescriptor& od,
01056 const RealDescriptor& id,
01057 const IntDescriptor& ld,
01058 int onescmp = 0)
01059 {
01060 #if defined(__alpha) && !defined(BL_USE_FLOAT)
01061 if (id == FPC::CrayRealDescriptor() && od == FPC::NativeRealDescriptor())
01062 cray64toalpha64_fconvert(out, in, nitems);
01063 else
01064 #endif
01065
01066 #if defined(__alpha) & defined( BL_USE_FLOAT)
01067 if (id==FPC::Ieee32NormalRealDescriptor() && od==FPC::NativeRealDescriptor())
01068 ieee32toalpha32_fconvert(out, in, nitems);
01069 else
01070 #endif
01071
01072 #if defined(BL_ARCH_CRAY)
01073 if (id==FPC::NativeRealDescriptor() && od==FPC::Ieee32NormalRealDescriptor())
01074 {
01075 char craych;
01076 int wdsize = 4, conv_typ = 2, stride = 1, offset = 0, len = nitems;
01077 BL_ASSERT(len == nitems);
01078 FORT_CRAY2IEG(conv_typ,len,(char*)out,offset,(char*)in,stride,craych);
01079 }
01080 else
01081 if (id==FPC::NativeRealDescriptor() && od==FPC::Ieee64NormalRealDescriptor())
01082 {
01083
01084
01085
01086
01087
01088
01089
01090 char craych;
01091 int wdsize = 8, conv_typ = 8, stride = 1, offset = 0, len = nitems;
01092 BL_ASSERT(len == nitems);
01093 FORT_CRAY2IEG(conv_typ,len,(char*)out,offset,(char*)in,stride,craych);
01094 }
01095 else
01096 if (id==FPC::Ieee32NormalRealDescriptor() && od==FPC::NativeRealDescriptor())
01097 {
01098 char craych;
01099 int wdsize = 4, conv_typ = 2, stride = 1, offset = 0, len = nitems;
01100 BL_ASSERT(len == nitems);
01101 FORT_IEG2CRAY(conv_typ,len,(char*)in,offset,(char*)out,stride,craych);
01102 }
01103 else
01104 if (id==FPC::Ieee64NormalRealDescriptor() && od==FPC::NativeRealDescriptor())
01105 {
01106 char craych;
01107 int wdsize = 8, conv_typ = 8, stride = 1, offset = 0, len = nitems;
01108 BL_ASSERT(len == nitems);
01109 FORT_IEG2CRAY(conv_typ,len,(char*)in,offset,(char*)out,stride,craych);
01110 }
01111 else
01112 #endif
01113
01114 if (od == id && boffs == 0)
01115 {
01116 size_t n = size_t(nitems);
01117 BL_ASSERT(int(n) == nitems);
01118 memcpy(out, in, n*od.numBytes());
01119 }
01120 else if (od.formatarray() == id.formatarray() && boffs == 0 && !onescmp)
01121 permute_real_word_order(out, in, nitems, od.order(), id.order());
01122 else
01123 {
01124 PD_fconvert(out, in, nitems, boffs, od.format(), od.order(),
01125 id.format(), id.order(), ld.order(), ld.numBytes(),
01126 onescmp);
01127 PD_fixdenormals(out, nitems, od.format(), od.order());
01128 }
01129 }
01130
01131
01132
01133
01134
01135
01136 #if 0
01137
01138
01139
01140
01141
01142
01143 static
01144 void
01145 _PD_ones_complement (char* out,
01146 long nitems,
01147 int nbo)
01148 {
01149
01150
01151
01152
01153
01154 void* vout = out;
01155 signed char* lout = (signed char *) vout;
01156
01157 for (int i = 0L; i < nitems; i++)
01158 {
01159 if (*lout < 0)
01160 {
01161 unsigned int carry = 1;
01162 for (int j = nbo-1; (j >= 0) && (carry > 0); j--)
01163 {
01164 carry += lout[j];
01165 lout[j] = carry & 0xFF;
01166 carry = (carry > 0xFF);
01167 }
01168 }
01169 lout += nbo;
01170 }
01171 }
01172
01173
01174
01175
01176
01177
01178 static
01179 void
01180 PD_iconvert (void* out,
01181 void* in,
01182 long nitems,
01183 long nbo,
01184 int ordo,
01185 long nbi,
01186 int ordi,
01187 int onescmp = 0)
01188 {
01189 long i;
01190 int j;
01191 char *lout, *lin, *po, *pi;
01192
01193 lin = (char*) in;
01194 lout = (char*) out;
01195
01196
01197
01198
01199 if (nbi < nbo)
01200 {
01201 if (ordi == REVERSE_ORDER)
01202 {
01203 for (j = nbi; j < nbo; j++)
01204 {
01205 po = lout + j - nbi;
01206 pi = lin + nbi - 1;
01207 for (i = 0L; i < nitems; i++)
01208 {
01209 *po = (*pi & 0x80) ? 0xff : 0;
01210 po += nbo;
01211 pi += nbi;
01212 }
01213 }
01214 for (j = nbi; j > 0; j--)
01215 {
01216 po = lout + nbo - j;
01217 pi = lin + j - 1;
01218 for (i = 0L; i < nitems; i++)
01219 {
01220 *po = *pi;
01221 po += nbo;
01222 pi += nbi;
01223 }
01224 }
01225 }
01226 else
01227 {
01228 for (j = nbi; j < nbo; j++)
01229 {
01230 po = lout + j - nbi;
01231 pi = lin;
01232 for (i = 0L; i < nitems; i++)
01233 {
01234 *po = (*pi & 0x80) ? 0xff : 0;
01235 po += nbo;
01236 pi += nbi;
01237 }
01238 }
01239 for (j = 0; j < nbi; j++)
01240 {
01241 po = lout + j + nbo - nbi;
01242 pi = lin + j;
01243 for (i = 0L; i < nitems; i++)
01244 {
01245 *po = *pi;
01246 po += nbo;
01247 pi += nbi;
01248 }
01249 }
01250 }
01251 }
01252 else if (nbi >= nbo)
01253 {
01254 if (ordi == REVERSE_ORDER)
01255 {
01256 for (j = nbo; j > 0; j--)
01257 {
01258 po = lout + nbo - j;
01259 pi = lin + j - 1;
01260 for (i = 0L; i < nitems; i++)
01261 {
01262 *po = *pi;
01263 po += nbo;
01264 pi += nbi;
01265 }
01266 }
01267 }
01268 else
01269 {
01270 for (j = nbi - nbo; j < nbi; j++)
01271 {
01272 po = lout + j - nbi + nbo;
01273 pi = lin + j;
01274 for (i = 0L; i < nitems; i++)
01275 {
01276 *po = *pi;
01277 po += nbo;
01278 pi += nbi;
01279 }
01280 }
01281 }
01282 }
01283
01284
01285
01286 if (onescmp)
01287 _PD_ones_complement((char*)out, nitems, nbo);
01288
01289 if (ordo == REVERSE_ORDER)
01290 _PD_btrvout((char*)out, nbo, nitems);
01291 }
01292
01293 static
01294 void
01295 PD_convert (void* out,
01296 void* in,
01297 long nitems,
01298 const IntDescriptor& od,
01299 const IntDescriptor& id,
01300 int onescmp = 0)
01301 {
01302 if (od == id)
01303 memcpy(out, in, nitems*od.numBytes());
01304 else
01305 {
01306 PD_iconvert(out,
01307 in,
01308 nitems,
01309 od.numBytes(),
01310 od.order(),
01311 id.numBytes(),
01312 id.order(),
01313 onescmp);
01314 }
01315 }
01316 #endif
01317
01318
01319
01320
01321
01322 void
01323 RealDescriptor::convertToNativeFormat (Real* out,
01324 long nitems,
01325 void* in,
01326 const RealDescriptor& id)
01327 {
01328
01329 PD_convert(out,
01330 in,
01331 nitems,
01332 0,
01333 FPC::NativeRealDescriptor(),
01334 id,
01335 FPC::NativeLongDescriptor());
01336
01337 if(bAlwaysFixDenormals) {
01338 PD_fixdenormals(out, nitems, FPC::NativeRealDescriptor().format(),
01339 FPC::NativeRealDescriptor().order());
01340 }
01341 }
01342
01343
01344
01345
01346
01347 void
01348 RealDescriptor::convertToNativeFormat (Real* out,
01349 long nitems,
01350 std::istream& is,
01351 const RealDescriptor& id)
01352 {
01353 const int SHOULDREAD = 8192;
01354
01355 char* bufr = new char[SHOULDREAD * id.numBytes()];
01356
01357 while (nitems > 0)
01358 {
01359 int get = int(nitems) > SHOULDREAD ? SHOULDREAD : int(nitems);
01360 is.read(bufr, id.numBytes()*get);
01361 PD_convert(out,
01362 bufr,
01363 get,
01364 0,
01365 FPC::NativeRealDescriptor(),
01366 id,
01367 FPC::NativeLongDescriptor());
01368
01369 if(bAlwaysFixDenormals) {
01370 PD_fixdenormals(out, get, FPC::NativeRealDescriptor().format(),
01371 FPC::NativeRealDescriptor().order());
01372 }
01373 nitems -= get;
01374 out += get;
01375 }
01376
01377 if (is.fail())
01378 BoxLib::Error("convert(Real*,long,istream&,RealDescriptor&) failed");
01379
01380 delete [] bufr;
01381 }
01382
01383
01384
01385
01386
01387 void
01388 RealDescriptor::convertFromNativeFormat (void* out,
01389 long nitems,
01390 Real* in,
01391 const RealDescriptor& od)
01392 {
01393 PD_convert(out,
01394 in,
01395 nitems,
01396 0,
01397 od,
01398 FPC::NativeRealDescriptor(),
01399 FPC::NativeLongDescriptor());
01400 }
01401
01402
01403
01404
01405
01406
01407 void
01408 RealDescriptor::convertFromNativeFormat (std::ostream& os,
01409 long nitems,
01410 const Real* in,
01411 const RealDescriptor& od)
01412 {
01413 const int SHOULDWRITE = 8192;
01414
01415 char* bufr = new char[SHOULDWRITE * od.numBytes()];
01416
01417 while (nitems > 0)
01418 {
01419 int put = int(nitems) > SHOULDWRITE ? SHOULDWRITE : int(nitems);
01420 PD_convert(bufr,
01421 in,
01422 put,
01423 0,
01424 od,
01425 FPC::NativeRealDescriptor(),
01426 FPC::NativeLongDescriptor());
01427 os.write(bufr, od.numBytes()*put);
01428 nitems -= put;
01429 in += put;
01430 }
01431
01432 if (os.fail())
01433 BoxLib::Error("convert(ostream&,long,Real*,RealDescriptor&): failed");
01434
01435 delete [] bufr;
01436 }
01437