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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef INLINE
00043 #pragma ident "@(#) libf/fio/dopexfer.c 92.3 06/18/99 10:21:14"
00044 #endif
00045
00046 #include <liberrno.h>
00047 #include <stdlib.h>
00048 #include <string.h>
00049 #include <cray/nassert.h>
00050 #include "fio.h"
00051 #include "f90io.h"
00052
00053
00054
00055
00056
00057
00058 static FILE *_df;
00059 static int _ddope_nest = 0;
00060 static int _ddope = -1;
00061 static unit *_ddcup;
00062
00063 #ifdef _ASSERT_ON
00064
00065 #define DEBUG_90IO \
00066 ((_ddope == -1) ? ( \
00067 (getenv("DEBUG_90IO") != NULL) ? ( \
00068 (_df = fopen(getenv("DEBUG_90IO"), "w")), \
00069 (_ddope = (_df != NULL)) \
00070 ) \
00071 : (\
00072 (_df = fopen("/dev/null", "w")), \
00073 (_ddope = 0) \
00074 ) \
00075 ) \
00076 : \
00077 _ddope \
00078 )
00079
00080 #define DD { \
00081 if (DEBUG_90IO) { \
00082 register int ix; \
00083 fprintf(_df, "unit %lld ", _ddcup->uid); \
00084 for (ix = 0; ix < _ddope_nest; ix++) \
00085 putc(' ', _df); \
00086 } \
00087 }
00088
00089 #else
00090 #define DEBUG_90IO 0
00091 #define DD
00092 #endif
00093
00094
00095
00096
00097
00098
00099 #define MAXDOVAR 7
00100 struct dovarlist {
00101 int nvar;
00102 int *dov[MAXDOVAR];
00103 };
00104
00105
00106 static int _stride_dv(FIOSPTR css, unit *cup, DopeVectorType *dv,
00107 int **dovar, xfer_func *func);
00108
00109 int _map_to_dv(ioimplieddo_entry *impdo, DopeVectorType *dvptr,
00110 int **iarr, struct dovarlist *dovlp);
00111
00112 int _strip_mine(FIOSPTR css, unit *cup, xfer_func *func, ioimplieddo_entry *ie,
00113 int *retp);
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 #ifdef INLINE
00136 static int
00137 _inline_xfer_iolist(
00138 #else
00139 int
00140 _xfer_iolist(
00141 #endif
00142 FIOSPTR css,
00143 unit *cup,
00144 iolist_header *iolist,
00145 xfer_func *func)
00146 {
00147 register short termrec;
00148 int ret;
00149 type_packet tip;
00150 register int ioitems;
00151 ioentry_header *nextioh;
00152 void *nexte;
00153 int **indarray;
00154 register int mode;
00155
00156 ioitems = iolist->icount;
00157 nextioh = (ioentry_header *)(iolist + 1);
00158 termrec = 0;
00159
00160 if (DEBUG_90IO) {
00161 _ddcup = cup;
00162 _ddope_nest++;
00163 if (_ddope_nest == 1) {
00164 char *fnm = "";
00165 if (func == _rdfmt) fnm = "_rdfmt";
00166 else if (func == _wrfmt) fnm = "_wrfmt";
00167 else if (func == _ld_read) fnm = "_ld_read";
00168 else if (func == _ld_write) fnm = "_ld_write";
00169 else if (func == _rdunf) fnm = "_rdunf";
00170 else if (func == _wrunf) fnm = "_wrunf";
00171
00172 DD; putc('\n', _df);
00173 DD; fprintf(_df,"----------------------------------\n");
00174 DD; fprintf(_df,
00175 "Begin iolist for unit %lld func=%s\n",
00176 cup->uid, fnm);
00177
00178 DD; fprintf(_df,"iolist->icount = %d\n",iolist->icount);
00179 }
00180 }
00181
00182 ret = 0;
00183
00184 while (ioitems--) {
00185
00186 if (cup->f_lastiolist) {
00187 if ((void *)((long *)nextioh + nextioh->ioentsize) == cup->f_lastiolist)
00188 termrec = 1;
00189 }
00190
00191 nexte = nextioh + 1;
00192
00193
00194
00195 tip.type77 = -1;
00196 tip.cnvindx = 0;
00197 tip.count = 1;
00198 tip.stride = 1;
00199
00200 switch (nextioh->valtype) {
00201
00202 case IO_SCALAR:
00203
00204 {
00205 ioscalar_entry *se;
00206 void *vaddr;
00207
00208 se = nexte;
00209
00210
00211 assert ( se->tinfo.type == DVTYPE_ASCII ||
00212 se->tinfo.int_len > 0 );
00213
00214 tip.type90 = se->tinfo.type;
00215 tip.intlen = se->tinfo.int_len;
00216 tip.extlen = tip.intlen;
00217 tip.elsize = tip.intlen >> 3;
00218
00219 if (DEBUG_90IO) {
00220 DD; putc('\n',_df);
00221 DD; fprintf(_df,"IO_SCALAR, type90=%d\n",
00222 tip.type90);
00223 DD; fprintf(_df,"address = 0%lo\n",
00224 (long)se->iovar_address.v);
00225 if (tip.type90 == DVTYPE_ASCII) {
00226 DD; fprintf(_df,"character len = %ld\n",
00227 _fcdlen(se->iovar_address.fcd));
00228 }
00229
00230 DD; fprintf(_df,"dpflag = %d\n",
00231 se->tinfo.dpflag);
00232 DD; fprintf(_df,"kind_or_star = %d\n",
00233 se->tinfo.kind_or_star);
00234 DD; fprintf(_df,"int_len = %d\n",
00235 se->tinfo.int_len);
00236 DD; fprintf(_df,"dec_len = %d\n",
00237 se->tinfo.dec_len);
00238 }
00239
00240 if (tip.type90 == DVTYPE_ASCII) {
00241
00242 vaddr = _fcdtocp(se->iovar_address.fcd);
00243 tip.elsize = tip.elsize *
00244 _fcdlen(se->iovar_address.fcd);
00245 }
00246 else
00247 vaddr = se->iovar_address.v;
00248
00249 tip.count = 1;
00250 tip.stride = 1;
00251
00252 #if NUMERIC_DATA_CONVERSION_ENABLED
00253 if ( !(cup->ufmt) &&
00254 (cup->unumcvrt || cup->ucharset) ) {
00255
00256 ret = _get_dc_param(css, cup, se->tinfo,
00257 &tip);
00258 if (ret != 0)
00259 goto done;
00260 }
00261 #endif
00262
00263 mode = termrec ? FULL : PARTIAL;
00264 ret = func(css, cup, vaddr, &tip, mode);
00265
00266 break;
00267 }
00268
00269 case IO_DOPEVEC:
00270 {
00271 ioarray_entry *ae;
00272 DopeVectorType *dv;
00273
00274 ae = nexte;
00275 dv = ae->dv;
00276 tip.type90 = dv->type_lens.type;
00277
00278 if (DEBUG_90IO) {
00279 DD; putc('\n',_df);
00280 DD; fprintf(_df,"IO_DOPEVEC, type90=%d\n",
00281 tip.type90);
00282 }
00283
00284
00285 assert ( ! (ae->indflag && ae->dovar == NULL) );
00286
00287 indarray = NULL;
00288
00289 if (ae->indflag)
00290 indarray = ae->dovar;
00291
00292
00293
00294
00295
00296 if (indarray == NULL && tip.type90 != DVTYPE_ASCII) {
00297
00298 register short n_dim = dv->n_dim;
00299 register long extent = dv->dimension[0].extent;
00300 register long inc;
00301 struct DvDimen *dimen = dv->dimension;
00302
00303 tip.intlen = dv->type_lens.int_len;
00304 tip.extlen = tip.intlen;
00305 tip.elsize = tip.intlen >> 3;
00306
00307
00308
00309
00310
00311
00312 if (n_dim != 1) {
00313 register short nc;
00314
00315 if (n_dim == 2) {
00316 if (dimen[0].stride_mult * extent !=
00317 dimen[1].stride_mult)
00318 goto general_dv_processing;
00319 extent *= dimen[1].extent;
00320 }
00321 else if (n_dim == 0) {
00322 extent = 1;
00323 }
00324 else {
00325 for (nc = 0; nc < (n_dim-1); nc++) {
00326 register long st = dimen[nc].stride_mult;
00327 register long ex = dimen[nc].extent;
00328 if ( (st * ex) !=
00329 dimen[nc+1].stride_mult)
00330 goto general_dv_processing;
00331 extent *= dimen[nc+1].extent;
00332 }
00333 }
00334 }
00335
00336 if (extent > 1) {
00337 register long sm;
00338
00339 sm = dv->dimension[0].stride_mult;
00340
00341 if (DEBUG_90IO) {
00342 DD;fprintf(_df,"elsize=%ld sm=%ld SMSCALE=%d\n",
00343 tip.elsize, sm, SMSCALE(dv));
00344 DD;fprintf(_df,"int_len=%d kind_or_star=%d ext_len=%d\n",
00345 dv->type_lens.int_len,
00346 dv->type_lens.kind_or_star,
00347 dv->type_lens.dec_len);
00348 }
00349 if (sm * (signed)SMSCALE(dv) == tip.elsize)
00350 inc = 1;
00351 else {
00352 register long bpsm;
00353
00354 bpsm = sm * (signed)SMSCALE(dv);
00355 inc = bpsm / tip.elsize;
00356
00357
00358
00359 if (tip.elsize * inc != bpsm)
00360 goto general_dv_processing;
00361 }
00362 }
00363 else
00364 inc = 1;
00365
00366 tip.count = extent;
00367 tip.stride = inc;
00368
00369 #if NUMERIC_DATA_CONVERSION_ENABLED
00370 if ( !(cup->ufmt) &&
00371 (cup->unumcvrt || cup->ucharset) ) {
00372 ret = _get_dc_param(css, cup, dv->type_lens,
00373 &tip);
00374 if (ret != 0)
00375 return(ret);
00376 }
00377 #endif
00378 if (DEBUG_90IO) {
00379 DD; fprintf(_df,"Fold DV to 1-dim, extent=%ld inc=%ld\n",
00380 extent, inc);
00381 }
00382
00383 mode = termrec ? FULL : PARTIAL;
00384 ret = func(css, cup, dv->base_addr.a.ptr,
00385 &tip, mode);
00386 }
00387 else {
00388 general_dv_processing:
00389 ret = _stride_dv(css, cup, ae->dv, indarray,
00390 func);
00391 }
00392
00393 break;
00394 }
00395
00396 case IO_LOOP:
00397 {
00398 register long loopinc;
00399 register long begcnt;
00400 register long endcnt;
00401 int *loopvar;
00402 int *locia[MAXDIM];
00403 DopeVectorType locdv;
00404 ioimplieddo_entry *ie;
00405 struct dovarlist dovl;
00406
00407 ie = nexte;
00408
00409 if (DEBUG_90IO) {
00410 DD; putc('\n',_df);
00411 DD; fprintf(_df,
00412 "IO_LOOP start=%d inc=%d end=%d\n",
00413 *ie->iobegcnt, *ie->ioinccnt,
00414 *ie->ioendcnt);
00415 }
00416
00417 dovl.nvar = 0;
00418
00419 if (_map_to_dv(ie, &locdv, locia, &dovl)) {
00420 if (DEBUG_90IO) {
00421 DD; fprintf(_df,"Mapped to dopevect\n");
00422 }
00423 ret = _stride_dv(css, cup, &locdv, locia,
00424 func);
00425 break;
00426 }
00427
00428
00429
00430
00431
00432
00433 if (_strip_mine(css, cup, func, ie, &ret))
00434 break;
00435
00436 if (DEBUG_90IO) {
00437 DD; fprintf(_df,
00438 "Could not map to dopevector or strip mine \n");
00439 }
00440
00441
00442
00443 assert ( ie->ioinccnt != NULL );
00444 assert ( ie->ioloopvar != NULL );
00445 assert ( ie->iobegcnt != NULL );
00446 assert ( ie->ioendcnt != NULL );
00447
00448 loopinc = *ie->ioinccnt;
00449 loopvar = ie->ioloopvar;
00450 begcnt = *ie->iobegcnt;
00451 endcnt = *ie->ioendcnt;
00452
00453 if (loopinc == 0) {
00454 ret = FEINCZER;
00455 goto done;
00456 }
00457
00458 *loopvar = begcnt;
00459
00460
00461
00462
00463 if (cup->f_lastiolist != NULL)
00464 cup->f_lastiolist = NULL;
00465
00466 for (;;) {
00467
00468 if (DEBUG_90IO) {
00469 DD; fprintf(_df,"loopvar = %d\n",*loopvar);
00470 }
00471
00472 if (loopinc > 0) {
00473 if (*loopvar > endcnt) break;
00474 }
00475 else {
00476 if (*loopvar < endcnt) break;
00477 }
00478
00479 ret = _xfer_iolist(css, cup, (void *)(ie + 1), func);
00480
00481 if (ret != 0)
00482 goto done;
00483
00484 *loopvar += loopinc;
00485 }
00486 break;
00487 }
00488
00489 default:
00490 _ferr(css, FEINTUNK);
00491 }
00492
00493 if (ret != 0)
00494 goto done;
00495
00496 nextioh = (ioentry_header*)((long *)nextioh +
00497 nextioh->ioentsize);
00498 }
00499 done:
00500 if (DEBUG_90IO) {
00501 if (_ddope_nest == 1) {
00502 DD; fprintf(_df,"End iolist for unit %lld\n",cup->uid);
00503 }
00504 _ddope_nest--;
00505 }
00506
00507 return(ret);
00508 }
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531 static int
00532 _stride_dv(
00533 FIOSPTR css,
00534 unit *cup,
00535 DopeVectorType *dv,
00536 int **dovar,
00537 xfer_func *func)
00538 {
00539 register short element_stride;
00540 register short i;
00541 register short nd;
00542 register short newi;
00543 register short nc;
00544 register int id1, id2, id3, id4, id5, id6, id7;
00545 register int ret;
00546 register long badjust;
00547 register long extent;
00548 struct DvDimen *dvdimen;
00549 bcont *addr;
00550 char *baddr;
00551 void *addr2, *addr3, *addr4;
00552 void *addr5, *addr6;
00553 type_packet tip;
00554 struct DvDimen dimen[MAXDIM];
00555
00556
00557
00558
00559 if (DEBUG_90IO) {
00560 register short itmp;
00561 DD; fprintf(_df,"\n");
00562 DD; fprintf(_df,"Enter _stride_dv\n");
00563 DD; fprintf(_df,"dv->base_addr = 0%lo\n",
00564 (long)dv->base_addr.a.ptr);
00565 if (dv->type_lens.type == DVTYPE_ASCII) {
00566 DD; fprintf(_df,"character len = %ld\n",
00567 _fcdlen(dv->base_addr.charptr));
00568 }
00569 DD; fprintf(_df,"dv->base_addr.a.el_len = %ld\n",
00570 dv->base_addr.a.el_len);
00571 DD; fprintf(_df,"dv->assoc = %d\n",dv->assoc);
00572 DD; fprintf(_df,"dv->ptr_alloc = %d\n",dv->ptr_alloc);
00573 DD; fprintf(_df,"dv->p_or_a = %d\n",dv->p_or_a);
00574 DD; fprintf(_df,"dv->n_dim = %d\n",dv->n_dim);
00575
00576 DD; fprintf(_df,"dv->type_lens.dpflag = %d\n",
00577 dv->type_lens.dpflag);
00578 DD; fprintf(_df,"dv->type_lens.kind_or_star = %d\n",
00579 dv->type_lens.kind_or_star);
00580 DD; fprintf(_df,"dv->type_lens.int_len = %d\n",
00581 dv->type_lens.int_len);
00582 DD; fprintf(_df,"dv->type_lens.dec_len = %d\n",
00583 dv->type_lens.dec_len);
00584
00585 DD; fprintf(_df,"dv->orig_base = %p\n",dv->orig_base);
00586 DD; fprintf(_df,"dv->orig_size = %ld\n",dv->orig_size);
00587
00588 for (itmp = 0; itmp < dv->n_dim; itmp++) {
00589 DD; fprintf(_df," Dim %d ", itmp);
00590 fprintf(_df," low=%2ld extent=%2ld stride_mult=%2ld\n",
00591 dv->dimension[itmp].low_bound,
00592 dv->dimension[itmp].extent,
00593 dv->dimension[itmp].stride_mult);
00594 }
00595 if (dovar != NULL) {
00596 DD; fprintf(_df,"Indexes into dopevector:\n");
00597 DD; fprintf(_df," Index Addresses: ");
00598 for (itmp = 0; itmp < dv->n_dim; itmp++) {
00599 if (dovar[itmp] == NULL)
00600 fprintf(_df," NULL");
00601 else
00602 fprintf(_df," 0%lo", (long)dovar[itmp]);
00603 }
00604 fprintf(_df,"\n");
00605 DD; fprintf(_df," Index Values: ");
00606 for (itmp = 0; itmp < dv->n_dim ; itmp++) {
00607 if (dovar[itmp] == NULL)
00608 fprintf(_df," -");
00609 else
00610 fprintf(_df," 0%o", *dovar[itmp]);
00611 }
00612 fprintf(_df,"\n");
00613 }
00614 }
00615
00616
00617
00618 assert ( dv != NULL );
00619 assert ( dv->type_lens.int_len > 0 );
00620
00621 if (dv->p_or_a && (dv->assoc == 0))
00622 return(FEPTRNAS);
00623
00624 tip.type77 = -1;
00625 tip.type90 = dv->type_lens.type;
00626 tip.intlen = dv->type_lens.int_len;
00627 tip.extlen = tip.intlen;
00628 tip.elsize = tip.intlen >> 3;
00629 tip.cnvindx = 0;
00630 tip.count = 1;
00631 tip.stride = 1;
00632
00633
00634
00635
00636
00637 #if NUMERIC_DATA_CONVERSION_ENABLED
00638 if ( !(cup->ufmt) &&
00639 (cup->unumcvrt || cup->ucharset) ) {
00640
00641 ret = _get_dc_param(css, cup, dv->type_lens, &tip);
00642
00643 if (ret != 0)
00644 goto done;
00645 }
00646 #endif
00647
00648 nd = dv->n_dim;
00649 badjust = 0;
00650
00651
00652
00653
00654 for (i = 0; i < nd; i++)
00655 dimen[i] = dv->dimension[i];
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665 newi = 0;
00666 dvdimen = dv->dimension;
00667
00668 for (i = 0; i < nd; i++) {
00669 if (dovar == NULL || dovar[i] == NULL) {
00670
00671
00672
00673 if (dvdimen[i].extent == 0)
00674 return(0);
00675
00676
00677
00678 if (dvdimen[i].extent > 1)
00679 dimen[newi++] = dvdimen[i];
00680 }
00681 else
00682 badjust += (*dovar[i] - dvdimen[i].low_bound) *
00683 dvdimen[i].stride_mult;
00684 }
00685
00686 if (DEBUG_90IO) {
00687 DD; fprintf(_df, "%d indexed or extent-1 dims collapsed\n",
00688 nd - newi);
00689 }
00690
00691 nd = newi;
00692
00693 if (DEBUG_90IO) {
00694 register int i_dim;
00695 DD; fprintf(_df, "%d dimension(s) are left\n", nd);
00696 for (i_dim = 0; i_dim < nd ; i_dim++) {
00697 DD; fprintf(_df," Dim %d ",i_dim);
00698 fprintf(_df," low=%2ld extent=%2ld stride_mult=%2ld\n",
00699 dimen[i_dim].low_bound,
00700 dimen[i_dim].extent,
00701 dimen[i_dim].stride_mult);
00702 }
00703 }
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717 for (nc = 0; nc < (nd-1); nc++) {
00718 register long st = dimen[nc].stride_mult;
00719 register long ex = dimen[nc].extent;
00720 if ((st * ex) != dimen[nc+1].stride_mult)
00721 break;
00722 }
00723
00724 if (DEBUG_90IO) {
00725 DD; fprintf(_df, "%d dimensions removed by collapsing compatibile adjacent dimension(s)\n", nc);
00726 }
00727
00728
00729
00730
00731
00732
00733
00734 if (nc > 0) {
00735 register short j;
00736
00737 for (j = 1; j <= nc; j++)
00738 dimen[0].extent *= dimen[j].extent;
00739
00740 nd = nd - nc;
00741
00742 assert (nd > 0);
00743
00744
00745
00746
00747
00748
00749 for (j = 1; j < nd; j++)
00750 dimen[j] = dimen[j+nc];
00751 }
00752
00753 if (DEBUG_90IO) {
00754 register int i_dim;
00755 DD; fprintf(_df, "%d dimension(s) are left\n", nd);
00756 for (i_dim = 0; i_dim < nd ; i_dim++) {
00757 DD; fprintf(_df," Dim %d ",i_dim);
00758 fprintf(_df," low=%2ld extent=%2ld stride_mult=%2ld\n",
00759 dimen[i_dim].low_bound,
00760 dimen[i_dim].extent,
00761 dimen[i_dim].stride_mult);
00762 }
00763 }
00764
00765
00766
00767
00768
00769 if (nd == 0) {
00770 nd = 1;
00771 dimen[0].extent = 1;
00772 dimen[0].stride_mult = 0;
00773 }
00774
00775 if (tip.type90 == DVTYPE_ASCII) {
00776
00777 tip.elsize = tip.elsize * _fcdlen(dv->base_addr.charptr);
00778 extent = dimen[0].extent;
00779 element_stride = 1;
00780
00781 if (extent > 1) {
00782 register long stm;
00783
00784 stm = dimen[0].stride_mult;
00785 tip.stride = stm / tip.elsize;
00786
00787 if (tip.stride * tip.elsize != stm)
00788 element_stride = 0;
00789 }
00790
00791
00792
00793
00794
00795 baddr = _fcdtocp(dv->base_addr.charptr) + badjust;
00796
00797 switch (nd) {
00798
00799 case 7:
00800 for (id7 = 0; id7 < dimen[6].extent; id7++) {
00801 addr6 = baddr;
00802 case 6:
00803 for (id6 = 0; id6 < dimen[5].extent; id6++) {
00804 addr5 = baddr;
00805 case 5:
00806 for (id5 = 0; id5 < dimen[4].extent; id5++) {
00807 addr4 = baddr;
00808 case 4:
00809 for (id4 = 0; id4 < dimen[3].extent; id4++) {
00810 addr3 = baddr;
00811 case 3:
00812 for (id3 = 0; id3 < dimen[2].extent; id3++) {
00813 addr2 = baddr;
00814 case 2:
00815 for (id2 = 0; id2 < dimen[1].extent; id2++) {
00816 case 1:
00817 if (element_stride) {
00818 tip.count = extent;
00819 ret = func(css, cup, baddr, &tip, PARTIAL);
00820 if (ret != 0) goto done;
00821 }
00822 else {
00823 char *ba;
00824 ba = baddr;
00825 for (id1 = 0; id1 < extent; id1++) {
00826 tip.count = 1;
00827 ret = func(css, cup, ba, &tip, PARTIAL);
00828 if (ret != 0) goto done;
00829 ba = ba + dimen[0].stride_mult;
00830 }
00831 }
00832
00833 if (nd == 1) goto done;
00834 baddr += dimen[1].stride_mult;
00835 }
00836 if (nd == 2) goto done;
00837 baddr = addr2;
00838 baddr += dimen[2].stride_mult;
00839 }
00840 if (nd == 3) goto done;
00841 baddr = addr3;
00842 baddr += dimen[3].stride_mult;
00843 }
00844 if (nd == 4) goto done;
00845 baddr = addr4;
00846 baddr += dimen[4].stride_mult;
00847 }
00848 if (nd == 5) goto done;
00849 baddr = addr5;
00850 baddr += dimen[5].stride_mult;
00851 }
00852 if (nd == 6) goto done;
00853 baddr = addr6;
00854 baddr += dimen[6].stride_mult;
00855 }
00856 }
00857 }
00858 else {
00859
00860 register int bshft;
00861
00862
00863
00864
00865
00866
00867 #if defined(__mips) || defined(_LITTLE_ENDIAN)
00868 assert( SMSCALE(dv) == sizeof(bcont) ||
00869 SMSCALE(dv) == sizeof(_f_int2) ||
00870 SMSCALE(dv) == sizeof(_f_int4) ||
00871 SMSCALE(dv) == sizeof(long) );
00872 #else
00873 assert( SMSCALE(dv) == sizeof(bcont) ||
00874 SMSCALE(dv) == sizeof(long) );
00875 #endif
00876
00877
00878
00879 assert( SMSHIFT(dv) != -1);
00880
00881 element_stride = 1;
00882 extent = dimen[0].extent;
00883 bshft = SMSHIFT(dv);
00884
00885 if (extent > 1) {
00886 register long bpsm;
00887
00888 bpsm = dimen[0].stride_mult * (signed)SMSCALE(dv);
00889 tip.stride = bpsm / tip.elsize;
00890
00891 if (tip.stride * tip.elsize != bpsm)
00892 element_stride = 0;
00893 }
00894
00895 addr = (bcont *)dv->base_addr.a.ptr + (badjust << bshft);
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905 if (nd > 1 && element_stride && (extent * tip.elsize) <= CHBUFSIZE){
00906
00907 if (DEBUG_90IO) {
00908 DD; fprintf(_df, "calling chunk routine\n");
00909 }
00910
00911 ret = _iochunk(css, cup, func, dimen, &tip, nd,
00912 extent, bshft, addr);
00913 return(ret);
00914 }
00915
00916 switch (nd) {
00917
00918 case 7:
00919 for (id7 = 0; id7 < dimen[6].extent; id7++) {
00920 addr6 = addr;
00921 case 6:
00922 for (id6 = 0; id6 < dimen[5].extent; id6++) {
00923 addr5 = addr;
00924 case 5:
00925 for (id5 = 0; id5 < dimen[4].extent; id5++) {
00926 addr4 = addr;
00927 case 4:
00928 for (id4 = 0; id4 < dimen[3].extent; id4++) {
00929 addr3 = addr;
00930 case 3:
00931 for (id3 = 0; id3 < dimen[2].extent; id3++) {
00932 addr2 = addr;
00933 case 2:
00934 for (id2 = 0; id2 < dimen[1].extent; id2++) {
00935 case 1:
00936 if (element_stride) {
00937 tip.count = extent;
00938 ret = func(css, cup, addr, &tip, PARTIAL);
00939 }
00940 else {
00941 bcont *ad;
00942 ad = addr;
00943
00944
00945
00946
00947
00948
00949
00950 for (id1 = 0; id1 < extent; id1++) {
00951 tip.count = 1;
00952 ret = func(css, cup, ad, &tip, PARTIAL);
00953 if (ret != 0) goto done;
00954 ad = ad + dimen[0].stride_mult;
00955 }
00956 }
00957
00958 if (ret != 0) goto done;
00959
00960 if (nd == 1) goto done;
00961 addr += dimen[1].stride_mult << bshft;
00962 }
00963 if (nd == 2) goto done;
00964 addr = addr2;
00965 addr += dimen[2].stride_mult << bshft;
00966 }
00967 if (nd == 3) goto done;
00968 addr = addr3;
00969 addr += dimen[3].stride_mult << bshft;
00970 }
00971 if (nd == 4) goto done;
00972 addr = addr4;
00973 addr += dimen[4].stride_mult << bshft;
00974 }
00975 if (nd == 5) goto done;
00976 addr = addr5;
00977 addr += dimen[5].stride_mult << bshft;
00978 }
00979 if (nd == 6) goto done;
00980 addr = addr6;
00981 addr += dimen[6].stride_mult << bshft;
00982 }
00983 }
00984 }
00985
00986 done:
00987 return(ret);
00988 }
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015 int
01016 _map_to_dv(
01017 ioimplieddo_entry *impdo,
01018 DopeVectorType *dvptr,
01019 int **iarr,
01020 struct dovarlist *dovlp)
01021 {
01022 register short need_to_shift;
01023 register int i;
01024 register int ind_dim;
01025 register int ret;
01026 register long doinc;
01027 register long extent;
01028 register long adjust;
01029 struct DvDimen *dvdimen;
01030 struct DvDimen dvdim_tmp;
01031 iolist_header *nested_iolist;
01032 ioentry_header *nextioh;
01033 ioarray_entry *ae;
01034
01035 long _tripcnt(long beg, long end, long inc);
01036
01037 nested_iolist = (iolist_header *)(impdo + 1);
01038
01039 if (nested_iolist->icount != 1)
01040 return(0);
01041
01042 for (i = 0; i < dovlp->nvar; i++) {
01043
01044 if (DEBUG_90IO) {
01045 DD; fprintf(_df,"compare loopvar addr %lo to %lo %lo %lo\n",
01046 (long)dovlp->dov[i], (long)impdo->iobegcnt,
01047 (long)impdo->ioendcnt, (long)impdo->ioinccnt);
01048 }
01049
01050 if ( (impdo->iobegcnt == dovlp->dov[i]) ||
01051 (impdo->ioendcnt == dovlp->dov[i]) ||
01052 (impdo->ioinccnt == dovlp->dov[i]) )
01053 return(0);
01054 }
01055
01056 if (DEBUG_90IO) {
01057 DD; fprintf(_df,"Making recursive _map_to_dv check\n");
01058 }
01059
01060 nextioh = (ioentry_header *)(nested_iolist + 1);
01061
01062 switch (nextioh->valtype) {
01063
01064 default:
01065 return(0);
01066
01067 case IO_LOOP:
01068
01069
01070
01071
01072
01073
01074
01075 dovlp->nvar++;
01076 if (dovlp->nvar > MAXDOVAR)
01077 return(0);
01078 dovlp->dov[ dovlp->nvar-1 ] = impdo->ioloopvar;
01079
01080
01081 ret = _map_to_dv( (ioimplieddo_entry *)(nextioh + 1),
01082 dvptr,
01083 iarr,
01084 dovlp);
01085 if (ret == 0)
01086 return(0);
01087 break;
01088
01089 case IO_DOPEVEC:
01090 ae = (ioarray_entry *)(nextioh + 1);
01091
01092
01093 *dvptr = *(ae->dv);
01094
01095 if (ae->indflag == 0)
01096 return(0);
01097
01098
01099 for (i = 0; i < dvptr->n_dim; i++)
01100 iarr[i] = ae->dovar[i];
01101
01102 break;
01103 }
01104
01105 dvdimen = dvptr->dimension;
01106
01107
01108
01109 ind_dim = -1;
01110
01111 for (i = 0; i < dvptr->n_dim; i++)
01112 if (iarr[i] == impdo->ioloopvar) {
01113 ind_dim = i;
01114 break;
01115 }
01116
01117 if (ind_dim == -1)
01118 return(0);
01119
01120 if (DEBUG_90IO) {
01121 DD; fprintf(_df,"Dim %d indexed by impdo\n", ind_dim);
01122 }
01123
01124
01125
01126
01127
01128
01129 need_to_shift = 0;
01130
01131 for (i = ind_dim+1; i < dvptr->n_dim; i++) {
01132
01133
01134
01135
01136
01137
01138 if (iarr[i] == impdo->ioloopvar) {
01139
01140 if (DEBUG_90IO) {
01141 DD; fprintf(_df,"Dim %d also indexed by impdo\n",i);
01142 }
01143
01144 if (dvdimen[i].low_bound != dvdimen[ind_dim].low_bound)
01145 return(0);
01146
01147 dvdimen[i].stride_mult += dvdimen[ind_dim].stride_mult;
01148
01149
01150
01151
01152
01153 dvdimen[ind_dim].extent = 1;
01154 iarr[ind_dim] = NULL;
01155
01156 ind_dim = i;
01157 need_to_shift = 0;
01158 }
01159 else if (iarr[i] == NULL && dvdimen[i].extent > 1)
01160 need_to_shift = 1;
01161 }
01162
01163
01164
01165
01166
01167
01168
01169 if (need_to_shift) {
01170 dvdim_tmp = dvdimen[ind_dim];
01171 for (i = ind_dim; i < dvptr->n_dim-1; i++) {
01172 dvdimen[i] = dvdimen[i+1];
01173 iarr[i] = iarr[i+1];
01174 }
01175 ind_dim = i;
01176
01177
01178 dvdimen[ind_dim] = dvdim_tmp;
01179 }
01180
01181
01182
01183
01184 iarr[ind_dim] = NULL;
01185
01186 doinc = *impdo->ioinccnt;
01187
01188 adjust = (*impdo->iobegcnt - dvdimen[ind_dim].low_bound) *
01189 dvdimen[ind_dim].stride_mult;
01190
01191 extent = _tripcnt(*impdo->iobegcnt, *impdo->ioendcnt, doinc);
01192
01193
01194
01195
01196 dvdimen[ind_dim].extent = extent;
01197 dvdimen[ind_dim].stride_mult *= doinc;
01198
01199 if (dvptr->type_lens.type == DVTYPE_ASCII) {
01200 _fcd f;
01201 int flen;
01202
01203 f = dvptr->base_addr.charptr;
01204 flen = _fcdlen(f);
01205 dvptr->base_addr.charptr = _cptofcd(_fcdtocp(f) + adjust, flen);
01206 }
01207 else {
01208
01209
01210 int bshft = SMSHIFT(dvptr);
01211 dvptr->base_addr.a.ptr = (bcont *)dvptr->base_addr.a.ptr +
01212 (adjust << bshft);
01213
01214
01215 assert( SMSHIFT(dvptr) != -1);
01216 }
01217
01218
01219
01220
01221 *impdo->ioloopvar = *impdo->iobegcnt + extent * doinc;
01222
01223 return(1);
01224 }
01225
01226
01227
01228
01229
01230
01231 long
01232 _tripcnt(long beg, long end, long inc)
01233 {
01234 register long tc;
01235
01236 if (inc < 0) {
01237 beg = -beg;
01238 end = -end;
01239 inc = -inc;
01240 }
01241
01242 tc = (end - beg + inc) / inc;
01243
01244 if (tc < 0)
01245 tc = 0;
01246
01247 return(tc);
01248 }
01249
01250 typedef struct strideloop {
01251
01252 void *saddr;
01253
01254 long binc;
01255
01256
01257
01258
01259 long inc;
01260
01261 int elstr;
01262
01263 } strideloop_t;
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282 #define MAXITEMS 32
01283
01284 int
01285 _strip_mine(
01286 FIOSPTR css,
01287 unit *cup,
01288 xfer_func *func,
01289 ioimplieddo_entry *impdo,
01290 int *retp)
01291 {
01292 register short reading;
01293 register short sametp;
01294 register int bshft;
01295 register int ioitems;
01296 register int item;
01297 register long badjust;
01298 register long begcnt;
01299 register long bytes_per_trip;
01300 register long endcnt;
01301 register long dotrips;
01302 register long ib;
01303 register long loopinc;
01304 register long trips_per_buf;
01305 long stride;
01306 long inc;
01307 int *loopvar;
01308 int **indarray;
01309 void *nexte;
01310 bcont *addr;
01311 long locbuf[CHBUFSIZE/sizeof(long)];
01312 char *lbptr;
01313 type_packet tip;
01314 iolist_header *iolist;
01315 strideloop_t slt[MAXITEMS];
01316 struct DvDimen *dimen;
01317 ioentry_header *nextioh;
01318 f90_type_t ts, curts;
01319
01320 *retp = 0;
01321 reading = !(cup->uwrt);
01322
01323 if (DEBUG_90IO) {
01324 DD; putc('\n',_df);
01325 DD; fprintf(_df,"Enter _strip_mine\n");
01326 }
01327
01328
01329
01330
01331
01332 if (func == _ld_read)
01333 return(0);
01334
01335 loopinc = *impdo->ioinccnt;
01336 loopvar = impdo->ioloopvar;
01337 begcnt = *impdo->iobegcnt;
01338 endcnt = *impdo->ioendcnt;
01339
01340 *loopvar = begcnt;
01341
01342 if (loopinc == 0) {
01343 *retp = FEINCZER;
01344 return(1);
01345 }
01346
01347 iolist = (iolist_header *) (impdo + 1);
01348 ioitems = iolist->icount;
01349
01350 if (ioitems > MAXITEMS)
01351 return(0);
01352
01353 sametp = 1;
01354 nextioh = (ioentry_header *)(iolist + 1);
01355
01356 tip.type77 = -1;
01357 tip.cnvindx = 0;
01358 tip.count = 1;
01359 tip.stride = 1;
01360
01361
01362
01363
01364
01365 for (item = 0; item < ioitems; item++) {
01366 register int i;
01367 register short n_dim;
01368 ioscalar_entry *se;
01369 ioarray_entry *ae;
01370 DopeVectorType *dv;
01371
01372 nexte = nextioh + 1;
01373
01374 if (nextioh->valtype == IO_SCALAR) {
01375 se = nexte;
01376 curts = se->tinfo;
01377 }
01378 else if (nextioh->valtype == IO_DOPEVEC) {
01379 ae = nexte;
01380 dv = ae->dv;
01381 curts = dv->type_lens;
01382 }
01383 else
01384 return(0);
01385
01386 tip.type90 = curts.type;
01387
01388 if (DEBUG_90IO) {
01389 DD; putc('\n',_df);
01390 DD; fprintf(_df,"%s, type90=%d\n",
01391 ((nextioh->valtype == IO_SCALAR) ?
01392 "IO_SCALAR" : "IO_DOPEVEC"), tip.type90);
01393 }
01394
01395 if (tip.type90 == DVTYPE_ASCII)
01396 return(0);
01397
01398 if (item == 0) {
01399 ts = curts;
01400 tip.intlen = ts.int_len;
01401 tip.elsize = ts.int_len >> 3;
01402 }
01403 else {
01404 if (curts.int_len != ts.int_len)
01405 return(0);
01406 if (memcmp(&curts, &ts, sizeof(ts)))
01407 sametp = 0;
01408 }
01409
01410
01411
01412
01413 switch (nextioh->valtype) {
01414
01415 case IO_SCALAR:
01416
01417 slt[item].saddr = se->iovar_address.v;
01418 slt[item].binc = 0;
01419 slt[item].inc = 0;
01420 slt[item].elstr = 1;
01421
01422 break;
01423
01424 case IO_DOPEVEC:
01425
01426 indarray = NULL;
01427
01428 if (ae->indflag)
01429 indarray = ae->dovar;
01430
01431 n_dim = dv->n_dim;
01432 dimen = dv->dimension;
01433
01434 badjust = 0;
01435 stride = 0;
01436
01437 for (i = 0; i < n_dim; i++) {
01438 if (indarray != NULL && indarray[i] != NULL) {
01439 badjust += (*indarray[i] - dimen[i].low_bound) *
01440 dimen[i].stride_mult;
01441 if (indarray[i] == loopvar) {
01442 stride += loopinc*dimen[i].stride_mult;
01443 }
01444 }
01445 else {
01446 if (dimen[i].extent > 1)
01447 return(0);
01448 }
01449 }
01450
01451 stride = stride * (signed)SMSCALE(dv);
01452
01453
01454
01455 assert( SMSHIFT(dv) != -1);
01456
01457 bshft = SMSHIFT(dv);
01458 addr = (bcont *)dv->base_addr.a.ptr + (badjust << bshft);
01459
01460 slt[item].saddr = addr;
01461 slt[item].binc = stride;
01462 slt[item].inc = stride / tip.elsize;
01463 slt[item].elstr = (stride % tip.elsize == 0);
01464
01465 break;
01466
01467 default:
01468
01469 return(0);
01470
01471 }
01472
01473 nextioh = (ioentry_header *)((long *)nextioh +
01474 nextioh->ioentsize);
01475 }
01476
01477 dotrips = _tripcnt(begcnt, endcnt, loopinc);
01478 bytes_per_trip = tip.elsize * ioitems;
01479 trips_per_buf = CHBUFSIZE/bytes_per_trip;
01480
01481 if (trips_per_buf > dotrips)
01482 trips_per_buf = dotrips;
01483
01484 if (trips_per_buf == 0)
01485 return(0);
01486
01487 if ( !(cup->ufmt) ) {
01488 #if NUMERIC_DATA_CONVERSION_ENABLED
01489 if (cup->unumcvrt || cup->ucharset) {
01490
01491
01492
01493
01494
01495 if (!sametp)
01496 return(0);
01497
01498 *retp = _get_dc_param(css, cup, ts, &tip);
01499
01500 if (*retp != 0)
01501 return(1);
01502 }
01503 #endif
01504 }
01505 else {
01506
01507
01508
01509
01510 if (!sametp)
01511 return(0);
01512 }
01513
01514
01515
01516
01517
01518
01519 for (ib = 0; ib < dotrips; ib += trips_per_buf) {
01520 register long t;
01521
01522 if (trips_per_buf > dotrips - ib)
01523 trips_per_buf = dotrips - ib;
01524
01525 tip.count = ioitems * trips_per_buf;
01526
01527 if (reading) {
01528
01529
01530
01531
01532
01533
01534
01535 *retp = func(css, cup, locbuf, &tip, PARTIAL);
01536 }
01537
01538
01539
01540
01541
01542 assert ( sizeof(*loopvar) == sizeof(_f_int) );
01543
01544 for (item = 0; item < ioitems; item++) {
01545
01546 if (slt[item].elstr && tip.elsize == sizeof(int)) {
01547
01548 int *wptr;
01549 int *wbuf = (int *)locbuf;
01550
01551 inc = slt[item].inc;
01552 wptr = ((int *)slt[item].saddr) + ib * inc;
01553
01554 if (reading) {
01555 #ifdef _CRAY1
01556 #pragma _CRI ivdep
01557 #endif
01558 for (t = 0; t < trips_per_buf; t++)
01559 wptr[t * inc] = wbuf[item + t*ioitems];
01560 }
01561 else {
01562
01563
01564
01565
01566 if (wptr == (int *)loopvar) {
01567 for (t = 0; t < trips_per_buf; t++) {
01568 wbuf[item + t * ioitems] =
01569 *loopvar + loopinc * t;
01570 }
01571 }
01572 else {
01573 #ifdef _CRAY1
01574 #pragma _CRI ivdep
01575 #endif
01576 for (t = 0; t < trips_per_buf; t++)
01577 wbuf[item + t * ioitems] = wptr[t * inc];
01578 }
01579 }
01580 }
01581 else {
01582 char *dptr;
01583 register long binc;
01584
01585 binc = slt[item].binc;
01586 lbptr = (char *)locbuf + tip.elsize * item;
01587 dptr = ((char *)slt[item].saddr) + ib * slt[item].binc;
01588
01589 for (t = 0; t < trips_per_buf; t++) {
01590
01591 if (reading)
01592 (void) memcpy(dptr, lbptr, tip.elsize);
01593 else
01594 (void) memcpy(lbptr, dptr, tip.elsize);
01595
01596 dptr += binc;
01597 lbptr += ioitems * tip.elsize;
01598 }
01599 }
01600 }
01601
01602 if (!reading) {
01603
01604
01605
01606
01607
01608 *retp = func(css, cup, locbuf, &tip, PARTIAL);
01609 }
01610
01611 *loopvar += loopinc * trips_per_buf;
01612
01613 if (*retp != 0)
01614 return(1);
01615 }
01616
01617 return(1);
01618 }