Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5849b71

Browse files
authored
Merge pull request #12283 from pv/odr-ilp64
ENH: odr: ILP64 Blas support in ODR
2 parents 578d889 + 01f300f commit 5849b71

4 files changed

Lines changed: 128 additions & 2340 deletions

File tree

scipy/odr/__odrpack.c

Lines changed: 70 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,36 @@
1313
#include "odrpack.h"
1414

1515

16-
void F_FUNC(dodrc,DODRC)(void (*fcn)(int *n, int *m, int *np, int *nq, int *ldn, int *ldm,
17-
int *ldnp, double *beta, double *xplusd, int *ifixb, int *ifixx,
18-
int *ldifx, int *ideval, double *f, double *fjacb, double *fjacd,
19-
int *istop),
20-
int *n, int *m, int *np, int *nq, double *beta, double *y, int *ldy,
21-
double *x, int *ldx, double *we, int *ldwe, int *ld2we, double *wd,
22-
int *ldwd, int *ld2wd, int *ifixb, int *ifixx, int *ldifx, int *job,
23-
int *ndigit, double *taufac, double *sstol, double *partol,
24-
int *maxit, int *iprint, int *lunerr, int *lunrpt, double *stpb,
25-
double *stpd, int *ldstpd, double *sclb, double *scld, int *ldscld,
26-
double *work, int *lwork, int *iwork, int *liwork, int *info);
27-
void F_FUNC(dwinf,DWINF)(int *n, int *m, int *np, int *nq, int *ldwe, int *ld2we, int *isodr,
28-
int *delta, int *eps, int *xplus, int *fn, int *sd, int *vcv, int *rvar,
29-
int *wss, int *wssde, int *wssep, int *rcond, int *eta, int *olmav,
30-
int *tau, int *alpha, int *actrs, int *pnorm, int *rnors, int *prers,
31-
int *partl, int *sstol, int *taufc, int *apsma, int *betao, int *betac,
32-
int *betas, int *betan, int *s, int *ss, int *ssf, int *qraux, int *u,
33-
int *fs, int *fjacb, int *we1, int *diff, int *delts, int *deltn,
34-
int *t, int *tt, int *omega, int *fjacd, int *wrk1, int *wrk2,
35-
int *wrk3, int *wrk4, int *wrk5, int *wrk6, int *wrk7, int *lwkmn);
36-
void F_FUNC(dluno,DLUNO)(int *lun, char *fn, int fnlen);
37-
void F_FUNC(dlunc,DLUNC)(int *lun);
16+
void F_FUNC(dodrc,DODRC)(void (*fcn)(F_INT *n, F_INT *m, F_INT *np, F_INT *nq, F_INT *ldn, F_INT *ldm,
17+
F_INT *ldnp, double *beta, double *xplusd, F_INT *ifixb, F_INT *ifixx,
18+
F_INT *ldifx, F_INT *ideval, double *f, double *fjacb, double *fjacd,
19+
F_INT *istop),
20+
F_INT *n, F_INT *m, F_INT *np, F_INT *nq, double *beta, double *y, F_INT *ldy,
21+
double *x, F_INT *ldx, double *we, F_INT *ldwe, F_INT *ld2we, double *wd,
22+
F_INT *ldwd, F_INT *ld2wd, F_INT *ifixb, F_INT *ifixx, F_INT *ldifx, F_INT *job,
23+
F_INT *ndigit, double *taufac, double *sstol, double *partol,
24+
F_INT *maxit, F_INT *iprF_INT, F_INT *lunerr, F_INT *lunrpt, double *stpb,
25+
double *stpd, F_INT *ldstpd, double *sclb, double *scld, F_INT *ldscld,
26+
double *work, F_INT *lwork, F_INT *iwork, F_INT *liwork, F_INT *info);
27+
void F_FUNC(dwinf,DWINF)(F_INT *n, F_INT *m, F_INT *np, F_INT *nq, F_INT *ldwe, F_INT *ld2we, F_INT *isodr,
28+
F_INT *delta, F_INT *eps, F_INT *xplus, F_INT *fn, F_INT *sd, F_INT *vcv, F_INT *rvar,
29+
F_INT *wss, F_INT *wssde, F_INT *wssep, F_INT *rcond, F_INT *eta, F_INT *olmav,
30+
F_INT *tau, F_INT *alpha, F_INT *actrs, F_INT *pnorm, F_INT *rnors, F_INT *prers,
31+
F_INT *partl, F_INT *sstol, F_INT *taufc, F_INT *apsma, F_INT *betao, F_INT *betac,
32+
F_INT *betas, F_INT *betan, F_INT *s, F_INT *ss, F_INT *ssf, F_INT *qraux, F_INT *u,
33+
F_INT *fs, F_INT *fjacb, F_INT *we1, F_INT *diff, F_INT *delts, F_INT *deltn,
34+
F_INT *t, F_INT *tt, F_INT *omega, F_INT *fjacd, F_INT *wrk1, F_INT *wrk2,
35+
F_INT *wrk3, F_INT *wrk4, F_INT *wrk5, F_INT *wrk6, F_INT *wrk7, F_INT *lwkmn);
36+
void F_FUNC(dluno,DLUNO)(F_INT *lun, char *fn, int fnlen);
37+
void F_FUNC(dlunc,DLUNC)(F_INT *lun);
3838

3939

4040

4141
/* callback to pass to DODRC; calls the Python function in the global structure |odr_global| */
42-
void fcn_callback(int *n, int *m, int *np, int *nq, int *ldn, int *ldm,
43-
int *ldnp, double *beta, double *xplusd, int *ifixb,
44-
int *ifixx, int *ldfix, int *ideval, double *f,
45-
double *fjacb, double *fjacd, int *istop)
42+
void fcn_callback(F_INT *n, F_INT *m, F_INT *np, F_INT *nq, F_INT *ldn, F_INT *ldm,
43+
F_INT *ldnp, double *beta, double *xplusd, F_INT *ifixb,
44+
F_INT *ifixx, F_INT *ldfix, F_INT *ideval, double *f,
45+
double *fjacb, double *fjacd, F_INT *istop)
4646
{
4747
PyObject *arg01, *arglist;
4848
PyObject *result = NULL;
@@ -269,18 +269,18 @@ void fcn_callback(int *n, int *m, int *np, int *nq, int *ldn, int *ldm,
269269

270270

271271
/* generates Python output from the raw output from DODRC */
272-
PyObject *gen_output(int n, int m, int np, int nq, int ldwe, int ld2we,
272+
PyObject *gen_output(F_INT n, F_INT m, F_INT np, F_INT nq, F_INT ldwe, F_INT ld2we,
273273
PyArrayObject * beta, PyArrayObject * work,
274-
PyArrayObject * iwork, int isodr, int info,
274+
PyArrayObject * iwork, F_INT isodr, F_INT info,
275275
int full_output)
276276
{
277277
PyArrayObject *sd_beta, *cov_beta;
278278

279-
int delta, eps, xplus, fn, sd, vcv, rvar, wss, wssde, wssep, rcond;
280-
int eta, olmav, tau, alpha, actrs, pnorm, rnors, prers, partl, sstol;
281-
int taufc, apsma, betao, betac, betas, betan, s, ss, ssf, qraux, u;
282-
int fs, fjacb, we1, diff, delts, deltn, t, tt, omega, fjacd;
283-
int wrk1, wrk2, wrk3, wrk4, wrk5, wrk6, wrk7, lwkmn;
279+
F_INT delta, eps, xplus, fn, sd, vcv, rvar, wss, wssde, wssep, rcond;
280+
F_INT eta, olmav, tau, alpha, actrs, pnorm, rnors, prers, partl, sstol;
281+
F_INT taufc, apsma, betao, betac, betas, betan, s, ss, ssf, qraux, u;
282+
F_INT fs, fjacb, we1, diff, delts, deltn, t, tt, omega, fjacd;
283+
F_INT wrk1, wrk2, wrk3, wrk4, wrk5, wrk6, wrk7, lwkmn;
284284

285285
PyObject *retobj;
286286

@@ -383,7 +383,19 @@ PyObject *gen_output(int n, int m, int np, int nq, int ldwe, int ld2we,
383383

384384
work_ind =
385385
Py_BuildValue
386-
("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i}",
386+
(("{s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT
387+
",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT
388+
",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT
389+
",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT
390+
",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT
391+
",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT
392+
",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT
393+
",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT
394+
",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT
395+
",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT
396+
",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT
397+
",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT ",s:" F_INT_PYFMT
398+
",s:" F_INT_PYFMT "}"),
387399
"delta", delta, "eps", eps, "xplus", xplus, "fn", fn, "sd", sd, "sd",
388400
vcv, "rvar", rvar, "wss", wss, "wssde", wssde, "wssep", wssep,
389401
"rcond", rcond, "eta", eta, "olmav", olmav, "tau", tau, "alpha",
@@ -446,7 +458,7 @@ PyObject *gen_output(int n, int m, int np, int nq, int ldwe, int ld2we,
446458

447459
retobj =
448460
Py_BuildValue
449-
("OOO{s:O,s:O,s:O,s:O,s:d,s:d,s:d,s:d,s:d,s:d,s:O,s:O,s:O,s:i}",
461+
(("OOO{s:O,s:O,s:O,s:O,s:d,s:d,s:d,s:d,s:d,s:d,s:O,s:O,s:O,s:" F_INT_PYFMT "}"),
450462
PyArray_Return(beta), PyArray_Return(sd_beta),
451463
PyArray_Return(cov_beta), "delta", PyArray_Return(deltaA), "eps",
452464
PyArray_Return(epsA), "xplus", PyArray_Return(xplusA), "y",
@@ -473,7 +485,7 @@ PyObject *odr(PyObject * self, PyObject * args, PyObject * kwds)
473485
PyObject *fjacd = NULL, *pifixb = NULL, *pifixx = NULL;
474486
PyObject *pstpb = NULL, *pstpd = NULL, *psclb = NULL, *pscld = NULL;
475487
PyObject *pwork = NULL, *piwork = NULL, *extra_args = NULL;
476-
int job = 0, ndigit = 0, maxit = -1, iprint = 0;
488+
F_INT job = 0, ndigit = 0, maxit = -1, iprint = 0;
477489
int full_output = 0;
478490
double taufac = 0.0, sstol = -1.0, partol = -1.0;
479491
char *errfile = NULL, *rptfile = NULL;
@@ -482,23 +494,25 @@ PyObject *odr(PyObject * self, PyObject * args, PyObject * kwds)
482494
PyArrayObject *ifixb = NULL, *ifixx = NULL;
483495
PyArrayObject *stpb = NULL, *stpd = NULL, *sclb = NULL, *scld = NULL;
484496
PyArrayObject *work = NULL, *iwork = NULL;
485-
int n, m, np, nq, ldy, ldx, ldwe, ld2we, ldwd, ld2wd, ldifx;
486-
int lunerr = -1, lunrpt = -1, ldstpd, ldscld, lwork, liwork, info = 0;
497+
F_INT n, m, np, nq, ldy, ldx, ldwe, ld2we, ldwd, ld2wd, ldifx;
498+
F_INT lunerr = -1, lunrpt = -1, ldstpd, ldscld, lwork, liwork, info = 0;
487499
static char *kw_list[] = { "fcn", "initbeta", "y", "x", "we", "wd", "fjacb",
488500
"fjacd", "extra_args", "ifixb", "ifixx", "job", "iprint", "errfile",
489501
"rptfile", "ndigit", "taufac", "sstol", "partol",
490502
"maxit", "stpb", "stpd", "sclb", "scld", "work",
491503
"iwork", "full_output", NULL
492504
};
493-
int isodr = 1;
505+
F_INT isodr = 1;
494506
PyObject *result;
495507
npy_intp dim1[1], dim2[2], dim3[3];
496-
int implicit; /* flag for implicit model */
508+
F_INT implicit; /* flag for implicit model */
497509

498510

499511
if (kwds == NULL)
500512
{
501-
if (!PyArg_ParseTuple(args, "OOOO|OOOOOOOiiz#z#idddiOOOOOOi:odr",
513+
if (!PyArg_ParseTuple(args, ("OOOO|OOOOOOO" F_INT_PYFMT F_INT_PYFMT
514+
"z#z#" F_INT_PYFMT "ddd" F_INT_PYFMT
515+
"OOOOOOi:odr"),
502516
&fcn, &initbeta, &py, &px, &pwe, &pwd,
503517
&fjacb, &fjacd, &extra_args, &pifixb, &pifixx,
504518
&job, &iprint, &errfile, &lerrfile, &rptfile,
@@ -512,7 +526,9 @@ PyObject *odr(PyObject * self, PyObject * args, PyObject * kwds)
512526
else
513527
{
514528
if (!PyArg_ParseTupleAndKeywords(args, kwds,
515-
"OOOO|OOOOOOOiiz#z#idddiOOOOOOi:odr",
529+
("OOOO|OOOOOOO" F_INT_PYFMT "" F_INT_PYFMT
530+
"z#z#" F_INT_PYFMT "ddd" F_INT_PYFMT
531+
"OOOOOOi:odr"),
516532
kw_list, &fcn, &initbeta, &py, &px,
517533
&pwe, &pwd, &fjacb, &fjacd,
518534
&extra_args, &pifixb, &pifixx, &job,
@@ -640,7 +656,7 @@ PyObject *odr(PyObject * self, PyObject * args, PyObject * kwds)
640656
else
641657
{ /* we *do* have an implicit model */
642658
ldy = 1;
643-
nq = (int)PyLong_AsLong(py);
659+
nq = (F_INT)PyLong_AsLong(py);
644660
dim1[0] = 1;
645661

646662
/* initialize y to a dummy array; never referenced */
@@ -867,15 +883,15 @@ PyObject *odr(PyObject * self, PyObject * args, PyObject * kwds)
867883
if (pifixb == NULL)
868884
{
869885
dim1[0] = np;
870-
ifixb = (PyArrayObject *) PyArray_SimpleNew(1, dim1, NPY_INT);
871-
*(int *)(PyArray_DATA(ifixb)) = -1; /* set first element negative */
886+
ifixb = (PyArrayObject *) PyArray_SimpleNew(1, dim1, F_INT_NPY);
887+
*(F_INT *)(PyArray_DATA(ifixb)) = -1; /* set first element negative */
872888
}
873889
else
874890
{
875891
/* pifixb is a sequence as checked before */
876892

877893
if ((ifixb =
878-
(PyArrayObject *) PyArray_CopyFromObject(pifixb, NPY_INT, 1,
894+
(PyArrayObject *) PyArray_CopyFromObject(pifixb, F_INT_NPY, 1,
879895
1)) == NULL)
880896
{
881897
PYERR(PyExc_ValueError,
@@ -893,16 +909,16 @@ PyObject *odr(PyObject * self, PyObject * args, PyObject * kwds)
893909
{
894910
dim2[0] = m;
895911
dim2[1] = 1;
896-
ifixx = (PyArrayObject *) PyArray_SimpleNew(2, dim2, NPY_INT);
897-
*(int *)(PyArray_DATA(ifixx)) = -1; /* set first element negative */
912+
ifixx = (PyArrayObject *) PyArray_SimpleNew(2, dim2, F_INT_NPY);
913+
*(F_INT *)(PyArray_DATA(ifixx)) = -1; /* set first element negative */
898914
ldifx = 1;
899915
}
900916
else
901917
{
902918
/* pifixx is a sequence as checked before */
903919

904920
if ((ifixx =
905-
(PyArrayObject *) PyArray_CopyFromObject(pifixx, NPY_INT, 1,
921+
(PyArrayObject *) PyArray_CopyFromObject(pifixx, F_INT_NPY, 1,
906922
2)) == NULL)
907923
{
908924
PYERR(PyExc_ValueError,
@@ -1102,7 +1118,7 @@ PyObject *odr(PyObject * self, PyObject * args, PyObject * kwds)
11021118
}
11031119
if (PyArray_DIMS(work)[0] < lwork)
11041120
{
1105-
printf("%ld %d\n", PyArray_DIMS(work)[0], lwork);
1121+
printf("%ld " F_INT_FMT "\n", PyArray_DIMS(work)[0], lwork);
11061122
PYERR(PyExc_ValueError, "work is too small");
11071123
}
11081124
}
@@ -1116,7 +1132,7 @@ PyObject *odr(PyObject * self, PyObject * args, PyObject * kwds)
11161132
if (piwork != NULL)
11171133
{
11181134
if ((iwork =
1119-
(PyArrayObject *) PyArray_CopyFromObject(piwork, NPY_INT, 1,
1135+
(PyArrayObject *) PyArray_CopyFromObject(piwork, F_INT_NPY, 1,
11201136
1)) == NULL)
11211137
{
11221138
PYERR(PyExc_ValueError,
@@ -1132,7 +1148,7 @@ PyObject *odr(PyObject * self, PyObject * args, PyObject * kwds)
11321148
{
11331149
/* initialize our own iwork array */
11341150
dim1[0] = liwork;
1135-
iwork = (PyArrayObject *) PyArray_SimpleNew(1, dim1, NPY_INT);
1151+
iwork = (PyArrayObject *) PyArray_SimpleNew(1, dim1, F_INT_NPY);
11361152
} /* iwork */
11371153

11381154
/* check if what JOB requests can be done with what the user has
@@ -1165,12 +1181,12 @@ PyObject *odr(PyObject * self, PyObject * args, PyObject * kwds)
11651181
(double *)(PyArray_DATA(y)), &ldy, (double *)(PyArray_DATA(x)), &ldx,
11661182
(double *)(PyArray_DATA(we)), &ldwe, &ld2we,
11671183
(double *)(PyArray_DATA(wd)), &ldwd, &ld2wd,
1168-
(int *)(PyArray_DATA(ifixb)), (int *)(PyArray_DATA(ifixx)), &ldifx,
1184+
(F_INT *)(PyArray_DATA(ifixb)), (F_INT *)(PyArray_DATA(ifixx)), &ldifx,
11691185
&job, &ndigit, &taufac, &sstol, &partol, &maxit,
11701186
&iprint, &lunerr, &lunrpt,
11711187
(double *)(PyArray_DATA(stpb)), (double *)(PyArray_DATA(stpd)), &ldstpd,
11721188
(double *)(PyArray_DATA(sclb)), (double *)(PyArray_DATA(scld)), &ldscld,
1173-
(double *)(PyArray_DATA(work)), &lwork, (int *)(PyArray_DATA(iwork)), &liwork,
1189+
(double *)(PyArray_DATA(work)), &lwork, (F_INT *)(PyArray_DATA(iwork)), &liwork,
11741190
&info);
11751191

11761192
result = gen_output(n, m, np, nq, ldwe, ld2we,

scipy/odr/odrpack.h

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,38 @@
22
#include "Python.h"
33
#include "numpy/arrayobject.h"
44

5+
#ifdef HAVE_BLAS_ILP64
6+
7+
#define F_INT npy_int64
8+
#define F_INT_NPY NPY_INT64
9+
10+
#if NPY_BITSOF_SHORT == 64
11+
#define F_INT_PYFMT "h"
12+
#define F_INT_FMT "%h"
13+
#elif NPY_BITSOF_INT == 64
14+
#define F_INT_PYFMT "i"
15+
#define F_INT_FMT "%d"
16+
#elif NPY_BITSOF_LONG == 64
17+
#define F_INT_PYFMT "l"
18+
#define F_INT_FMT "%ld"
19+
#elif NPY_BITSOF_LONGLONG == 64
20+
#define F_INT_PYFMT "L"
21+
#define F_INT_FMT "%lld"
22+
#else
23+
#error No compatible 64-bit integer size. \
24+
Please contact NumPy maintainers and give detailed information about your \
25+
compiler and platform, or set NPY_USE_BLAS64_=0
26+
#endif
27+
28+
#else
29+
30+
#define F_INT int
31+
#define F_INT_NPY NPY_INT
32+
#define F_INT_FMT NPY_INT_FMT
33+
#define F_INT_PYFMT "i"
34+
35+
#endif
36+
537
#if defined(NO_APPEND_FORTRAN)
638
#if defined(UPPERCASE_FORTRAN)
739
#define F_FUNC(f,F) F
@@ -38,14 +70,14 @@ static ODR_info odr_global;
3870
static PyObject *odr_error=NULL;
3971
static PyObject *odr_stop=NULL;
4072

41-
void fcn_callback(int *n, int *m, int *np, int *nq, int *ldn, int *ldm,
42-
int *ldnp, double *beta, double *xplusd, int *ifixb,
43-
int *ifixx, int *ldfix, int *ideval, double *f,
44-
double *fjacb, double *fjacd, int *istop);
73+
void fcn_callback(F_INT *n, F_INT *m, F_INT *np, F_INT *nq, F_INT *ldn, F_INT *ldm,
74+
F_INT *ldnp, double *beta, double *xplusd, F_INT *ifixb,
75+
F_INT *ifixx, F_INT *ldfix, F_INT *ideval, double *f,
76+
double *fjacb, double *fjacd, F_INT *istop);
4577

46-
PyObject *gen_output(int n, int m, int np, int nq, int ldwe, int ld2we,
78+
PyObject *gen_output(F_INT n, F_INT m, F_INT np, F_INT nq, F_INT ldwe, F_INT ld2we,
4779
PyArrayObject *beta, PyArrayObject *work, PyArrayObject *iwork,
48-
int isodr, int info, int full_output);
80+
F_INT isodr, F_INT info, int full_output);
4981

5082
PyObject *odr(PyObject *self, PyObject *args, PyObject *kwds);
5183

0 commit comments

Comments
 (0)