METIS is written in C by using int
and when one uses a solver on a 64-bit system that employs 8-byte integers this must be changed. Recently I have compiled MUMPS with -i8
and this was exactly this case. The newest version of METIS seems have an option to compile METIS with long
but it is still alpha so I have decided to hack METIS 4 by myself. My experience in this respect is written below.
All the METIS code is in the directory metis-4.0/Lib/
and below it is assumed that we are already in this directory.
First thing is to change int
to long
in the code. The simplest solution is to insert somewhere
#define int long
There are several headers in the directory but quick inspection
$ grep #include *.c
$ grep #include *.h
shows us that the c-files includes only metis.h
and the latter includes other headers. This shows that we have to include the statement #define int long
in metis.h
after it includes the standard headers and before it includes other headers in this directory, that is, in the line 31.
If you find the solution with #define int long
too tricky there is another way to do it. It is possible to use sed
to change int
to long
in the code directly. A simple script that does it is changeid. With it
$ changeid int long *.h *.c
does the job.
So far it was an easy job. Now the question is whether the code will work. The problem is that a programmer could assume the length of int
in the code explicitly and in this case we have serious problems.
Quick inspection of memory allocation
$ grep malloc *.c
shows that the author uses its own functions to allocate memory that in turn uses sizeof(int)
. This gives us the hope that this should probably be okay.
Now the compilation with gcc produces a warning in ometis.c
ometis.c: In function `__MMDOrder':
ometis.c:641: warning: left shift count >= width of type
At the first glance the warning looks strange, as the statement is
genmmd(nvtxs, xadj, adjncy, iperm, perm, 1, head, qsize, list, marker, MAXIDX, &nofsub);
However if we recognize that MAXIDX is a macro (a common practice in C is to write macros uppercase), then
$ grep MAXIDX *.h
struct.h:#define MAXIDX (1<<8*sizeof(idxtype)-2)
we find the reason in struct.h. 1
has type int
and we have to change it to long
, that is, to 1l
. This is quite important as otherwise MAXIDX will be defined just wrong.
Then there are problems in minitpart.c
:
minitpart.c:340: error: conflicting types for 'SelectQueueOneWay'
minitpart.c:248: error: previous implicit declaration of 'SelectQueueOneWay' was here
The inspection of these lines shows the reason. In C a function can be declared implicitly (line 248) and here it is implicitly assumed that it returns int
. On the other hand the function by itself (line 340) return long
(do not forget about #define int long
). So we have to add a function declaration before its use at the beginning of the file
int SelectQueueOneWay(int , float *, float *, int , PQueueType queues[MAXNCON][2]);
You see, warnings are very important and it is important to pay attention to them. In gcc
one can obtain all warning with -Wall
. Then we see more warning but most of them are not related to the change at all and
warning: int format, different type arg (arg 8)
is related to printf
and can be ignored.
In my case all the tests have shown that METIS is working just fine and from that I conclude that the fixes described above were enough. Well, MUMPS does not use all the METIS functionality, so you have to run your own tests as well.
Microsoft Visual Studio C++
Please note that in Microsoft Visual Studio C++ sizeof(int) == sizeof(long) == 4. Thereafter in order to declare an 8 Byte integer, one has to use __int64 instead of long.
RSS