Problem in compilation of MINPACK library with CUDA code - c++

I need to solve a nonlinear system of equations and I found the MINPACK library to do the job.
But I need the code to work with CUDA and I'm not able to compile the code.
I'm facing this problem:
nvcc -arch sm_61 -Iinc -I/usr/local/include obj/main.o -o oi -L/usr/local/lib64 -lcuminpack
nvlink error : Undefined reference to 'dpmpar' in 'obj/main.o'
make: *** [makefile:55: oi] Erro 255
My main file is:
main.cu
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define __cminpack_double__
#include <cminpack-1/cminpack.h>
#define real __cminpack_real__
typedef struct{
real fnorm1, fnorm2;
int info;
real solution[2];
} ResultType;
__cminpack_attr__ int fcn(void *p, int n, const real *x, real *fvec, int iflag){
--fvec;
--x;
fvec[0] = x[0] + x[0]*x[1] - 4.0;
fvec[1] = x[0] + x[1] -3.0;
return 0;
}
__global__ void SolvingSystem(ResultType *pResults){
int info;
real fnorm1, fnorm2, tol;
int n = 2;
real fvec[2];
real x[2];
const int lwa = (n*(3*n + 13))/2;
real wa[50];
tol = sqrt(dpmpar(1));
x[0] = 1.98;
x[1] = 1.02;
printf("Initial Guess: %g, %g\n", x[0], x[1]);
}
int main(int argc, char const *argv[]){
cudaSetDevice(0);
ResultType *reuslt_GPU, *reuslt_CPU;
cudaMalloc((void**)&reuslt_GPU, sizeof(ResultType));
cudaMallocHost((void**)&reuslt_CPU, sizeof(ResultType));
printf("Solving System...\n");
dim3 grid(1, 1, 1);
dim3 block(1, 1, 1);
SolvingSystem<<< grid, block>>>(reuslt_GPU);
cudaDeviceSynchronize();
printf("Done!\n");
return 0;
}
And my makefile is:
makefile
# MakeFile
# Program Name
EXE = oi
# Compilers
NVCC := nvcc
ALL_LIBRARIES := cuminpack
LIBDIR := /usr/local/lib64
# Directories
SRCDIR := src
OBJDIR := obj
INCDIR := inc /usr/local/include
#Flags
NVCCARCHFLAG := -arch sm_61
NVCCFLAGS := -std=c++11
LDFLAGS := $(addprefix -L, $(LIBDIR))
INCLUDES := $(addprefix -I, $(INCDIR))
LIBRARIES := $(addprefix -l, $(ALL_LIBRARIES))
LIBRARIES +=
ALL_CPFLAGS := -MMD
ALL_CPFLAGS += $(NVCCARCHFLAG)
ALL_CPFLAGS += $(NVCCFLAGS)
ALL_LDFLAGS := $(LDFLAGS)
# Files
C_FILES := $(wildcard $(SRCDIR)/*.c)
CU_FILES := $(wildcard $(SRCDIR)/*.cu)
C_OBJ := $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(C_FILES))
CU_OBJ := $(patsubst $(SRCDIR)/%.cu, $(OBJDIR)/%.o, $(CU_FILES))
C_DEP := $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.d, $(C_FILES))
CU_DEP := $(patsubst $(SRCDIR)/%.cu, $(OBJDIR)/%.d, $(CU_FILES))
SRC := $(C_FILES) $(CU_FILES)
OBJ := $(C_OBJ) $(CU_OBJ)
DEP := $(C_DEP) $(CU_DEP)
COMPILE.c := $(NVCC) -MMD -g $(INCLUDES) -c
COMPILE.cu := $(NVCC) $(ALL_CPFLAGS) $(INCLUDES) -dc
.PHONY: all clean
all:$(EXE)
$(EXE): $(OBJ)
$(NVCC) $(NVCCARCHFLAG) $(INCLUDES) $^ -o $# $(ALL_LDFLAGS) $(LIBRARIES)
$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR)
$(COMPILE.c) $< -o $#
$(OBJDIR)/%.o: $(SRCDIR)/%.cu | $(OBJDIR)
$(COMPILE.cu) $< -o $#
$(OBJDIR):
#mkdir -p $#
# Cleaning up
clean:
#echo Cleaning up...
#rm -f -r $(OBJDIR)
#rm $(EXE)
# Including dependency
-include $(DEP)
The main file needs to be finished and that's the reason to some unused variables.
I just can't figure out what is causing this error, I think the problem is in cuminpack library, but I don't now how to fix it.
I'm using cminpack-1.3.8 from this website: http://devernay.free.fr/hacks/cminpack/
I installed the library using cmake then make and make install. Then I went to source folder and did make cuda. This last command generated libcuminpack.a file in cuda directory, then I copied this .a file to /usr/local/lib64 where cmake installed the other libraries files.
If anyone could help me I would be very thankful
EDIT
Files from the cminpack library
cminpack.h
...
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
...
#if defined(__CUDA_ARCH__) || defined(__CUDACC__)
#define __cminpack_attr__ __device__
#ifndef __cminpack_real__
#define __cminpack_float__
#define __cminpack_real__ float
#endif
#define __cminpack_type_fcn_nn__ __cminpack_attr__ int fcn_nn
#define __cminpack_type_fcnder_nn__ __cminpack_attr__ int fcnder_nn
#define __cminpack_type_fcn_mn__ __cminpack_attr__ int fcn_mn
#define __cminpack_type_fcnder_mn__ __cminpack_attr__ int fcnder_mn
#define __cminpack_type_fcnderstr_mn__ __cminpack_attr__ int fcnderstr_mn
#define __cminpack_decl_fcn_nn__
#define __cminpack_decl_fcnder_nn__
#define __cminpack_decl_fcn_mn__
#define __cminpack_decl_fcnder_mn__
#define __cminpack_decl_fcnderstr_mn__
#define __cminpack_param_fcn_nn__
#define __cminpack_param_fcnder_nn__
#define __cminpack_param_fcn_mn__
#define __cminpack_param_fcnder_mn__
#define __cminpack_param_fcnderstr_mn__
...
__cminpack_attr__
__cminpack_real__ CMINPACK_EXPORT __cminpack_func__(dpmpar)( int i );
dpmpar.c
#include "cminpack.h"
#include <float.h>
#include "cminpackP.h"
#define DPMPAR(type,X) _DPMPAR(type,X)
#define _DPMPAR(type,X) type ## _ ## X
__cminpack_attr__
real __cminpack_func__(dpmpar)(int i)
{
/* ********** */
/* Function dpmpar */
...

Based on talonmies's comment I was able to compile the code defining the __device__ function dpmpar in main.cu file.
Then I found this post https://forums.developer.nvidia.com/t/external-calls-to-device-functions/17737 where the guy answered that CUDA doesn't have a linker on the device side, so it's not possible to call a __device__ function from a different .cu file.
With this in mind, I copied only the files that I needed from the library and made some modifications, like changing __cminpack_attr__ to __device__ and I rewrote the header file too. So basically I made my own device library (thank's again to talonmies's).
The last thing I did was move all this new files to the same folder where my main.cu and my makefile lives and I rewrote the makefile.
Now the code compile fine!!

Related

Using makefile to link cimgui to project?

I have a c project and I'm trying to link the C binding for imgui to it using Makefiles but I'm having some trouble. I've already generated the .dll using cmake in a build folder, these are the contents of it:
C:\path\to\cimgui\build:
-CMakefiles
-cimgui.dll
-cmake_install.txt
-CMakeCache.txt
-libcimgui.dll.a
-Makefile
and this is my makefile
PROJ := proj
TARGET := $(PROJ)
OBJ := sub.o main.o
INCLUDE_PATH := -IC:\path\to\SDL2 -IC:\path\to\cimgui
LIB_PATH := -LC:\path\to\SDL2\lib -LC:\path\to\cimgui\build
LINKER_FLAGS := -lSDL2 -lopengl32 -lcimgui -lcimgui.dll
CFLAGS := $(INCLUDE_PATH)
.PHONY : build clean
build : $(TARGET).exe
$(TARGET).exe: $(OBJ)
gcc $^ $(LIB_PATH) $(LINKER_FLAGS) -o $#
sub.o: sub.c sub.h
gcc -c $(CFLAGS) $< -o $#
main.o: main.c sub.h
$(CC) $(CFLAGS) $< -o $#
clean :
#rm -fv *.o
#rm -fv *.exe
and this is my main.c project
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS
#include "cimgui.h"
#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#include <SDL_opengl.h>
int main(int argc, char ** argv)
{
return 0;
}
This is the error I get when i try to compile my makefile:
c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: cannot find -lcimgui.dll

Makefile that only recompiles changed objects?

Alright, new user here, and I've got a problem. I'm a new c++ student, and I have no prior experience in this language (before about 3 months ago). My assignment is as follows:
Write a program that declares an array darray of 50 elements of type double. Initialize the array so that the first 25 elements are equal to the square of the index variable, and the last 25 elements are equal to three times the index variable. Output the array so that 10 elements per line are printed.
The program should have two functions: a function, initArray(), which initializes the array elements, and a function, prArray(), which prints the elements.
I have that, it's as follows
#include "printArray.h"
#include "initializearray.h"
#include "Main.h"
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
double initArray();
double prArray(double arrayone[50]);
double * dArray;
int main() {
dArray[50] = initArray();
system("PAUSE");
prArray(dArray);
system("PAUSE");
return 0;
}
#include "printArray.h"
#include "initializearray.h"
#include "Main.h"
#include <iostream>
#include <string>
using namespace std;
double prArray(double arraytwo[50])
{
for (int x = 0; x < 50; x++) {
cout << arraytwo[x];
if (x = 9 || 19 || 29 || 39 || 49) {
cout << endl;
}
}
return 0;
}
#include "printArray.h"
#include "initializearray.h"
#include "Main.h"
#include <iostream>
#include <string>
int x = 0;
double arrayone[50];
double initArray()
{
for (x = 0; x < 25; x++) {
arrayone[x] = (x*x);
}
for (x = 25; x <= 50; x++) {
arrayone[x] = (x * 3);
}
return arrayone[50];
}
Now my problem is that the assignment goes on to say
Write a Makefile to compile the program above that minimizes recompiling items upon changes. (e.g., if one function file gets updated, only the necessary file(s) are recompiled.) Include a clean target that removes compiled objects if invoked.
I have a basic makefile:
CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=Main.cpp initializeArray.cpp printArray.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=Main
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
Now, what I need help with is turning this into a makefile that satisfies the assignment conditions - preferably with step-by-step instructions so that I can learn from this.
Modified your Makefile to:
Automatically generate header dependencies.
Re-build and re-link when Makefile changes.
CXX := g++
LD := ${CXX}
CXXFLAGS := -Wall -Wextra -std=gnu++14 -pthread
LDFLAGS := -pthread
exes :=
# Specify EXEs here begin.
Main.SOURCES := Main.cpp initializeArray.cpp printArray.cpp
exes += Main
# Specify EXEs here end.
all: $(exes)
.SECONDEXPANSION:
get_objects = $(patsubst %.cpp,%.o,${${1}.SOURCES})
get_deps = $(patsubst %.cpp,%.d,${${1}.SOURCES})
# Links executables.
${exes} : % : $$(call get_objects,$$*) Makefile
${LD} -o $# $(filter-out Makefile,$^) ${LDFLAGS}
# Compiles C++ and generates dependencies.
%.o : %.cpp Makefile
${CXX} -o $# -c ${CPPFLAGS} ${CXXFLAGS} -MP -MD $<
# Include the dependencies generated on a previous build.
-include $(foreach exe,${exes},$(call get_deps,${exe}))
.PHONY: all

The executable test file is not running the tests

I have created a project:
// func.h :
#ifndef FUNCS_H_
#define FUNCS_H_
int addInts(int i, int j);
#endif /* FUNCS_H_ */
// func.cpp
#include "func.h"
int addInts(int i, int j) {
return i + j;
}
// main.cpp
#include "func.h"
#include <iostream>
int main() {
std::cout << addInts(5, 7) << std::endl;
return 0;
}
//makefile
OBJS := \
main.o \
func.o
CXX := g++
CXX_FLAGS := -Wall -Werror -Wextra -std=c++11
all: main_prj
main_prj: $(OBJS)
$(CXX) $(OBJS) -lm -o main
-include $(OBJS:.o=.d)
%.o: %.cpp
$(CXX) -c $(CXX_FLAGS) $*.cpp -o $*.o
clean:
rm -f main $(OBJS)
And I created also a test (boost test) for that function:
// test/main_test.cpp
#define BOOST_TEST_MODULE main_test
#include <boost/test/included/unit_test.hpp>
//____________________________________________________________________________//
// FIXTURES ...
//____________________________________________________________________________//
// test/addInts/addInts_test.cpp
#include <boost/test/unit_test.hpp>
#include "../../func.h"
BOOST_AUTO_TEST_CASE(addInts_5_7) {
int addInts_5_7 = 5 + 7;
BOOST_CHECK_EQUAL(addInts_5_7, addInts(5, 7));
}
// test/makefile
OBJS_TEST := \
main_test.o \
addInts/addInts_test.o \
../func.o
CXX_TEST := g++
CXX_FLAGS_TEST := -Wall -Werror -Wextra -std=c++11
all_test: main_test_prj
main_test_prj: $(OBJS_TEST)
$(CXX_TEST) $(OBJS_TEST) -lm -o main_test
-include $(OBJS_TEST:.o=.d)
%.o: %.cpp
$(CXX_TEST) -c $(CXX_FLAGS_TEST) $*.cpp -o $*.o
clean_test:
rm -f main_test $(OBJS_TEST)
Now, the make commands work, so they clean all the created files, or create the o files and the executables. When I run the main file, the output is correct: 12 ; but when I run the main_test file, the output is a little strange:
Running 1 test case...
*** No errors detected
I would expect the output with running tests and OK/KO, or pass/not pass... I cannot figure what am I doing wrong. Can anyone help me, please?
You have one test.
The output says that one test was run, and that no errors were found.
This output appears to be as documented.
There is no problem here.
Though, sadly, the documentation on how to change this output is rather lacking…

missing template arguments before [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have problem in compelling my code. The error message indicates "missing template arguments" in Map.h. But I do believe there is not any error in Map.h, because it is from Minisat, which is a sophistic API. So I think it is my fault in code or in makefile. I have tried so many times, can you help me on this? Thank you so much!
The error message is:
Compiling: queryOrac/queryOrac.o
In file included from /home/parallels/Desktop/Incremental_Solver/core/SolverTypes.h:30:0,
from /home/parallels/Desktop/Incremental_Solver/core/Solver.h:28,
from /home/parallels/Desktop/Incremental_Solver/simp/SimpSolver.h:25,
from /home/parallels/Desktop/Incremental_Solver/queryOrac/queryOrac.cc:12:
/home/parallels/Desktop/Incremental_Solver/mtl/Map.h: In member function ‘uint32_t Minisat::Hash<K>::operator()(const K&) const’:
/home/parallels/Desktop/Incremental_Solver/mtl/Map.h:32:99: error: missing template arguments before ‘(’ token
template<class K> struct Hash { uint32_t operator()(const K& k) const { return hash(k); } };
^
/home/parallels/Desktop/Incremental_Solver/mtl/Map.h: In member function ‘uint32_t Minisat::DeepHash<K>::operator()(const K*) const’:
/home/parallels/Desktop/Incremental_Solver/mtl/Map.h:35:103: error: missing template arguments before ‘(’ token
template<class K> struct DeepHash { uint32_t operator()(const K* k) const { return hash(*k); } };
^
make: *** [/home/parallels/Desktop/Incremental_Solver/queryOrac/queryOrac.o] Error 1
The .cc file is (This file is a implementation of a .h file):
#include <map>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <iostream>
#include <regex>
#include "queryOrac/queryOrac.h"
#include "incre/tools.h"
#include "incre/dict.h"
#include "simp/SimpSolver.h"
#include "utils/System.h"
#include "utils/ParseUtils.h"
#include "utils/Options.h"
#include "core/Dimacs.h"
using namespace std;
using namespace Minisat;
using namespace Incre;
Oracle::Oracle(const char * ora, const char * PI, const char * PO)
{
cout << "a Oracle is created" << endl;
PI_path = PI;
PO_path = PO;
Orac_Path = ora;
}
void Oracle::process()
{
parse_PI();
assign_PI();
solve();
}
void Oracle::parse_PI() {
cout << "reading from " << PI_path << endl;
ifstream infile;
infile.open(PI_path, ios::in);
string first_line;
string second_line;
getline(infile, first_line);
getline(infile, second_line);
vector<string> name_temp;
vector<string> value_temp;
SplitString(first_line, name_temp, " ");
SplitString(second_line, value_temp, " ");
vector<string>::iterator value = value_temp.begin();
for(vector<string>::iterator name = name_temp.begin(); name != name_temp.end(); ++name)
{
PI_temp.insert(pair<int, string>(varIndexDict[*name], *value));
value++;
}
}
void Oracle::assign_PI(){
vector<int>::iterator position = pisIndex.begin();
for(map<int, string>::iterator index = PI_temp.begin(); index != PI_temp.end(); ++index)
{
if(index->second == "1") PI_assignment_cnf.push_back(tostring(*position) + " 0\n");
else if(index->second == "0") PI_assignment_cnf.push_back("-" + tostring(*position) + " 0\n");
position++;
}
PI_assignment_cnf.insert(PI_assignment_cnf.begin(), "c this is assign_PI\n");
cnFile += PI_assignment_cnf;
print_vector(cnFile, "cnFile");
}
void Oracle::solve(){
cout << " start solving" << endl;
}
my makefile is:
##
## Template makefile for Standard, Profile, Debug, Release, and Release-static versions
##
## eg: "make rs" for a statically linked release version.
## "make d" for a debug version (no optimizations).
## "make" for the standard version (optimized, but with debug information and assertions active)
PWD = $(shell pwd)
EXEC ?= $(notdir $(PWD))
CSRCS = $(wildcard $(PWD)/*.cc)
DSRCS = $(foreach dir, $(DEPDIR), $(filter-out $(MROOT)/$(dir)/Main.cc, $(wildcard $(MROOT)/$(dir)/*.cc)))
CHDRS = $(wildcard $(PWD)/*.h)
COBJS = $(CSRCS:.cc=.o) $(DSRCS:.cc=.o)
PCOBJS = $(addsuffix p, $(COBJS))
DCOBJS = $(addsuffix d, $(COBJS))
RCOBJS = $(addsuffix r, $(COBJS))
CXX ?= g++
CFLAGS ?= -Wall -Wno-parentheses -std=c++11
LFLAGS ?= -Wall
COPTIMIZE ?= -O3
CFLAGS += -I$(MROOT) -D __STDC_LIMIT_MACROS -D __STDC_FORMAT_MACROS
LFLAGS += -lz
.PHONY : s p d r rs clean
s: $(EXEC)
p: $(EXEC)_profile
d: $(EXEC)_debug
r: $(EXEC)_release
rs: $(EXEC)_static
libs: lib$(LIB)_standard.a
libp: lib$(LIB)_profile.a
libd: lib$(LIB)_debug.a
libr: lib$(LIB)_release.a
## Compile options
%.o: CFLAGS +=$(COPTIMIZE) -g -D DEBUG
%.op: CFLAGS +=$(COPTIMIZE) -pg -g -D NDEBUG
%.od: CFLAGS +=-O0 -g -D DEBUG
%.or: CFLAGS +=$(COPTIMIZE) -g -D NDEBUG
## Link options
$(EXEC): LFLAGS += -g
$(EXEC)_profile: LFLAGS += -g -pg
$(EXEC)_debug: LFLAGS += -g
#$(EXEC)_release: LFLAGS += ...
$(EXEC)_static: LFLAGS += --static
## Dependencies
$(EXEC): $(COBJS)
$(EXEC)_profile: $(PCOBJS)
$(EXEC)_debug: $(DCOBJS)
$(EXEC)_release: $(RCOBJS)
$(EXEC)_static: $(RCOBJS)
lib$(LIB)_standard.a: $(filter-out */Main.o, $(COBJS))
lib$(LIB)_profile.a: $(filter-out */Main.op, $(PCOBJS))
lib$(LIB)_debug.a: $(filter-out */Main.od, $(DCOBJS))
lib$(LIB)_release.a: $(filter-out */Main.or, $(RCOBJS))
## Build rule
%.o %.op %.od %.or: %.cc
#echo Compiling: $(subst $(MROOT)/,,$#)
#$(CXX) $(CFLAGS) -c -o $# $<
## Linking rules (standard/profile/debug/release)
$(EXEC) $(EXEC)_profile $(EXEC)_debug $(EXEC)_release $(EXEC)_static:
#echo Linking: "$# ( $(foreach f,$^,$(subst $(MROOT)/,,$f)) )"
#$(CXX) $^ $(LFLAGS) -o $#
## Library rules (standard/profile/debug/release)
lib$(LIB)_standard.a lib$(LIB)_profile.a lib$(LIB)_release.a lib$(LIB)_debug.a:
#echo Making library: "$# ( $(foreach f,$^,$(subst $(MROOT)/,,$f)) )"
#$(AR) -rcsv $# $^
## Library Soft Link rule:
libs libp libd libr:
#echo "Making Soft Link: $^ -> lib$(LIB).a"
#ln -sf $^ lib$(LIB).a
## Clean rule
clean:
#rm -f $(EXEC) $(EXEC)_profile $(EXEC)_debug $(EXEC)_release $(EXEC)_static \
$(COBJS) $(PCOBJS) $(DCOBJS) $(RCOBJS) *.core depend.mk
## Make dependencies
depend.mk: $(CSRCS) $(CHDRS)
#echo Making dependencies
#$(CXX) $(CFLAGS) -I$(MROOT) \
$(CSRCS) -MM | sed 's|\(.*\):|$(PWD)/\1 $(PWD)/\1r $(PWD)/\1d $(PWD)/\1p:|' > depend.mk
#for dir in $(DEPDIR); do \
if [ -r $(MROOT)/$${dir}/depend.mk ]; then \
echo Depends on: $${dir}; \
cat $(MROOT)/$${dir}/depend.mk >> depend.mk; \
fi; \
done
-include $(MROOT)/mtl/config.mk
-include depend.mk
Your problem is due to using namespace std;. Don't do that, ever.
Some people say it's fine as long as it's not in a header file, but they are wrong, and your error is a great example.
In this case, you're accidentally referring to std::hash, which is a class template, so the <> cannot be omitted, unlike for function templates.

How to add directive in make file in c++

Is this the correct way of defining GLES_VERSION ?? I m getting #error in my program
c++ code
#if GLES_VERSION == 2
#include <GLES2/gl2.h>
#elif GLES_VERSION == 3
#include <GLES3/gl3.h>
#else
#error "GLES_VERSION must be defined as either 2 or 3"
#endif
i m ending up here in #error
make file code
CXXFLAGS = -O2 -g -Wall -fmessage-length=0
OBJS = hello.o
LIBS = -lX11 -lXau -lEGL -lGLESv2 -lm
GLES_VERSION = -D2 #is this correct ?
TARGET = hello \
$(TARGET): $(OBJS)
$(CXX) -o $(TARGET) $(GLES_VERSION) $(OBJS) $(LIBS)
all: $(TARGET)
clean:
rm -f $(OBJS) $(TARGET)
It should be
GLES_VERSION = -DGLES_VERSION=2
it must be,
GLES_VERSION = -DGLES_VERSION=2