2

I'm trying to build simple dll which uses library UMFPACK.

Here is my file "umfsolver.c":

#include <stdio.h>
#include <stdlib.h>
#include "umfpack.h"
#include "amd.h"

#define MAX(a,b) (((a) > (b)) ? (a) : (b))

#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif

typedef struct problem_struct
{
    double Control [UMFPACK_CONTROL];
    double Info [UMFPACK_INFO];
    int *Ti;
    int *Tj;
    double *Tx;
    int nrow;
    int ncol;
    int nz;
} problem;


EXPORT problem* __stdcall create(int nrows, int ncols, int nnonzero) 
{

    problem *prob;
    prob = (problem*) malloc(sizeof (problem)) ;
    if (!prob) return (NULL);
    prob->nrow = nrows;
    prob->ncol = ncols;
    prob->nz = nnonzero;
    printf("Creating...\n");
    umfpack_di_defaults (prob->Control) ;
    prob->Control [UMFPACK_PRL] = 3 ;
    prob->Control [UMFPACK_BLOCK_SIZE] = 32 ;
    prob->Ti = (int *) malloc (nnonzero * sizeof (int)) ;
    prob->Tj = (int *) malloc (nnonzero * sizeof (int)) ;
    prob->Tx = (double *) malloc (nnonzero * sizeof (double)) ;
    if (!prob->Ti || !prob->Tj || !prob->Tx ) return (NULL);
    return prob;
}

And here is my makefile:

all: libs umfsolver

include ../../SuiteSparse_config/SuiteSparse_config.mk

#-------------------------------------------------------------------------------
# the optional Partition module requires METIS, CAMD, and CCOLAMD
I_WITH_PARTITION = 
LIB_WITH_PARTITION =
CONFIG1 = -DNCHOLMOD
CONFIG2 = -DNPARTITION
ifeq (,$(findstring -DNCHOLMOD, $(UMFPACK_CONFIG)))
    # CHOLMOD is requested.  See if it is available
    ifeq (../../CHOLMOD, $(wildcard ../../CHOLMOD))
        ifeq (../../COLAMD, $(wildcard ../../COLAMD))
            # CHOLMOD and COLAMD are available
            CONFIG1 =
            LIB_WITH_CHOLMOD = ../../CHOLMOD/Lib/libcholmod.a \
                ../../COLAMD/Lib/libcolamd.a
            # check if METIS is requested and available
            ifeq (,$(findstring -DNPARTITION, $(CHOLMOD_CONFIG)))
                # METIS is requested.  See if it is available
                ifeq ($(METIS_PATH), $(wildcard $(METIS_PATH)))
                    ifeq (../../CAMD, $(wildcard ../../CAMD))
                        ifeq (../../CCOLAMD, $(wildcard ../../CCOLAMD))
                            # METIS, CAMD, and CCOLAMD are available
                            LIB_WITH_PARTITION = $(METIS) \
                                ../../CCOLAMD/Lib/libccolamd.a \
                                ../../CAMD/Lib/libcamd.a
                            I_WITH_PARTITION = -I$(METIS_PATH)/Lib \
                                -I../../CCOLAMD/Include -I../../CAMD/Include
                            CONFIG2 =
                        endif
                    endif
                endif
            endif
        endif
    endif
endif
#-------------------------------------------------------------------------------

C = $(CC) $(CF) $(UMFPACK_CONFIG) $(CONFIG1) $(CONFIG2) \
    -I../Include -I../../AMD/Include -I../../SuiteSparse_config

INC = ../Include/umfpack.h ../../AMD/Include/amd.h ../../SuiteSparse_config/SuiteSparse_config.h

LIBS = $(LAPACK) $(BLAS) $(XERBLA) $(LIB) $(LIB_WITH_CHOLMOD) $(LIB_WITH_PARTITION) $(CUBLAS_LIB) $(CUDART_LIB)

../Lib/libumfpack.a:
    ( cd ../Lib ; $(MAKE) )

../../AMD/Lib/libamd.a:
    ( cd ../../AMD ; $(MAKE) library )

../../SuiteSparse_config/libsuitesparseconfig.a:
    ( cd ../../SuiteSparse_config ; $(MAKE) library )

../../CHOLMOD/Lib/libcholmod.a:
    - ( cd ../../CHOLMOD && $(MAKE) library )

../../COLAMD/Lib/libcolamd.a:
    - ( cd ../../COLAMD && $(MAKE) library )


../../CCOLAMD/Lib/libccolamd.a:
    - ( cd ../../CCOLAMD && $(MAKE) library )

../../CAMD/Lib/libcamd.a:
    - ( cd ../../CAMD && $(MAKE) library )

$(METIS):
    ( cd $(METIS_PATH) && $(MAKE) )

UMFPACK = ../Lib/libumfpack.a ../../AMD/Lib/libamd.a \
    ../../SuiteSparse_config/libsuitesparseconfig.a \
    $(LIB_WITH_CHOLMOD) $(LIB_WITH_PARTITION) 

libs: $(UMFPACK)


umfsolver: umfsolver.c $(UMFPACK)
    $(C) -c -DBUILD_DLL umfsolver.c 
    $(C) -shared -o umfsolver.dll umfsolver.o -Wl,--add-stdcall-alias $(UMFPACK) $(LIBS) -lm

I used variables:

CF = -O3 -fexceptions -fPIC
CC = cc
LIB = -lm -lrt
UMFPACK_CONFIG = -DNBLAS -LD:/SuiteSparseBuild/UMFPACK/Lib -lsuitesparseconfig -lrt
MAKE = make
CUBLAS_LIB = 
CUDART_LIB = 
XERBLA = 
BLAS = 
LAPACK = 
METIS_PATH = ../../metis-4.0
METIS = ../../metis-4.0/libmetis.a

It builds with no errors. When I'm calling function create from another program (using static dllimport), it works until some library function need to be called inside create.

It seems like the program goes to infinite loop when either it calls printf("Creating...\n") or umfpack_di_defaults (prob->Control).

When I type make, I get this:

cc    -O3 -fexceptions -fPIC -DNBLAS -LD:/SuiteSparseBuild/UMFPACK/Lib -lsuitesparseconfig -lrt   -I../Include -I../../AMD/Include -I../../SuiteSparse_config -c -DBUILD_DLL umfsolver.c
cc1: warning: fPIC ignored for target (all code is position independent)
cc    -O3 -fexceptions -fPIC -DNBLAS -LD:/SuiteSparseBuild/UMFPACK/Lib -lsuitesparseconfig -lrt   -I../Include -I../../AMD/Include -I../../SuiteSparse_config -shared -o umfsolver.dll umfsolver.o ../Lib/libumfpack.a ../../AMD/Lib/libamd.a ../../SuiteSparse_config/libsuitesparseconfig.a ../../CHOLMOD/Lib/libcholmod.a ../../COLAMD/Lib/libcolamd.a ../../metis-4.0/libmetis.a ../../CCOLAMD/Lib/libccolamd.a ../../CAMD/Lib/libcamd.a     -lm -lrt ../../CHOLMOD/Lib/libcholmod.a ../../COLAMD/Lib/libcolamd.a ../../metis-4.0/libmetis.a ../../CCOLAMD/Lib/libccolamd.a ../../CAMD/Lib/libcamd.a    -Wl,--add-stdcall-alias

I guess that I should somehow change the makefile to put all library files together? How can I do this? Can anyone explain me this?

Thanks!

TKireev
  • 43
  • 7
  • Std warning: do not cast malloc return. – LPs Jun 24 '15 at 12:49
  • 1
    every call to malloc needs to have the returned value checked (!=NULL) to assure the operation was successful. On those conditions where some malloc has been called and the function create() eventually returns NULL, there is a memory leak unless all malloc'd memory is (before returning NULL) passed to free() Note: if all memory pointers are initially set to NULL, then calling free() for each pointer be easy as passing NULL to free() is ok. – user3629249 Jun 24 '15 at 13:16
  • there are a lot of macro definitions being referenced in the posted makefile, but I do not see where those macros are being defined. – user3629249 Jun 24 '15 at 13:17
  • there are some targets in the posted makefile that are not actual files. Those targets need to be part of a '.PHONY: statement, like '.PHONY: libs all – user3629249 Jun 24 '15 at 13:20
  • @LPs, OP is returning with out free'ing the non-failing call(s) to malloc – user3629249 Jun 24 '15 at 13:21
  • @user3629249 You're right. I cancelled. – LPs Jun 24 '15 at 13:44
  • Also I've added shell output when I type command make. – TKireev Jun 25 '15 at 06:54
  • It is very strange. When I just call printf("a") the program dies - stops respond. – TKireev Jun 25 '15 at 07:03

0 Answers0