I need to compare pHashes (phash.org) with a hamming distance function.
I tried the one from pg_similarity, but it doesn't seem to work right. (identical pHashes don't have a hamming distance of 0).
So I figured I'd just use a c-extension to use the ph_hamming_distance function that's part of the pHash library.
What I've got:
phash.c
#include <postgres.h>
#include <pHash.h>
#include <fmgr.h>
#include <utils/bytea.h>
#include <utils/datum.h>
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(phash_hamming);
Datum phash_hamming(PG_FUNCTION_ARGS) {
bytea *bytea1 = PG_GETARG_BYTEA_P(0);
bytea *bytea2 = PG_GETARG_BYTEA_P(1);
//FIXME - length of bytea1 & bytea2 must be 4 bytes (64bits)
ulong64 long1 = *((ulong64*) bytea1);
ulong64 long2 = *((ulong64*) bytea2);
int32 ret = ph_hamming_distance(long1, long2);
PG_RETURN_INT32(ret);
}
Makefile
CXXFLAGS=-I/usr/include/postgresql/server
LDFLAGS=-Bstatic -lpHash
all: phash.o
phash.o:
$(CXX) $(CXXFLAGS) -fpic -c phash.c
$(CXX) $(LDFLAGS) -shared -o phash.so phash.o
install:
cp phash.so `pg_config --pkglibdir`
clean:
rm -f phash.o phash.so
SQL
CREATE FUNCTION phash_hamming (bytea1 bytea, bytea2 bytea) RETURNS int AS '$libdir/phash' LANGUAGE C;
Error that I'm getting:
ERROR: could not load library "/usr/lib/postgresql/phash.so": /usr/lib/postgresql/phash.so: undefined symbol: _Z16pg_detoast_datumP7varlena
I must not be linking right to postgresql somehow?
It's an old question, but...
There is no need to add extra wrapper file and compile it using gcc.
You need extern "C" both PostgreSQL headers and PostgreSQL macros.
extern "C" {
#include <postgres.h>
#include <fmgr.h>
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC
#endif
}
I'm still convinced there might be a better way but this is what I did that worked.
(I will add range-checking, instead of just assuming all bytea's are 4-bytes... eventually, leaving a potential segfault in production would be bad, so it's a good thing this is just a toy project)
phash.c - pure C file, compiled with gcc
#include <postgres.h>
#include <fmgr.h>
#include <utils/bytea.h>
#include <utils/datum.h>
//typedef unsigned __int64 ulong64;
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 ulong64;
#else
typedef unsigned long long ulong64;
#endif
extern int32 c_ph_hamming_distance (ulong64 b1, ulong64 b2);
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(phash_hamming);
Datum phash_hamming(PG_FUNCTION_ARGS) {
bytea *bytea1 = PG_GETARG_BYTEA_P(0);
bytea *bytea2 = PG_GETARG_BYTEA_P(1);
//FIXME - length of bytea1 & bytea2 must be 4 bytes (64bits)
ulong64 long1 = *((ulong64*) bytea1);
ulong64 long2 = *((ulong64*) bytea2);
int32 ret = c_ph_hamming_distance(long1, long2);
PG_RETURN_INT32(ret);
}
phash_wrapper.cpp - make convert a version of ph_hamming_distance with c-linking instead of cpp linking (compiled with g++)
#include <pHash.h>
extern "C" {
int c_ph_hamming_distance (ulong64 b1, ulong64 b2){
return ph_hamming_distance(b1, b2);
}
}
Makefile
CFLAGS=-I/usr/include/postgresql/server
LDFLAGS=-lpHash
all: phash.so
phash_wrapper.o: phash_wrapper.cpp
$(CXX) $(CXXFLAGS) -fpic -c phash_wrapper.cpp
phash.o: phash.c
$(CC) $(CFLAGS) -fpic -c phash.c
phash.so: phash.o phash_wrapper.o
$(CC) $(LDFLAGS) -shared -o phash.so phash.o phash_wrapper.o
install:
cp phash.so `pg_config --pkglibdir`
clean:
rm -f phash.o phash.so phash_wrapper.o
SQL - the same
CREATE FUNCTION phash_hamming (bytea1 bytea, bytea2 bytea) RETURNS int AS '$libdir/phash' LANGUAGE C;
Related
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!!
I'm experimenting with building a simple application from a couple of .cu source files and a very simple C++ main that calls a function from one of the .cu files. I'm making a shared library (.so file) from the compiled .cu files. I'm finding that everything builds without trouble, but when I try to run the application, I get a linker undefined symbol error, with the mangled name of the .cu function I'm calling from main(). If I build a static library instead, my application runs just fine. Here's the makefile I've set up:
.PHONY: clean
NVCCFLAGS = -std=c++11 --compiler-options '-fPIC'
CXXFLAGS = -std=c++11
HLIB = libhello.a
SHLIB = libhello.so
CUDA_OBJECTS = bridge.o add.o
all: driver
%.o :: %.cu
nvcc -o $# $(NVCCFLAGS) -c -I. $<
%.o :: %.cpp
c++ $(CXXFLAGS) -o $# -c -I. $<
$(HLIB): $(CUDA_OBJECTS)
ar rcs $# $^
$(SHLIB): $(CUDA_OBJECTS)
nvcc $(NVCCFLAGS) --shared -o $# $^
#driver : driver.o $(HLIB)
# c++ -std=c++11 -fPIC -o $# driver.o -L. -lhello -L/usr/local/cuda-10.1/targets/x86_64-linux/lib -lcudart
driver : driver.o $(SHLIB)
c++ -std=c++11 -fPIC -o $# driver.o -L. -lhello
clean:
-rm -f driver *.o *.so *.a
Here are the various source files that the makefile takes as fodder.
add.cu:
__global__ void add(int n, int* a, int* b, int* c) {
int index = threadIdx.x;
int stride = blockDim.x;
for (int ii = index; ii < n; ii += stride) {
c[ii] = a[ii] + b[ii];
}
}
add.h:
extern __global__ void add(int n, int* a, int* b, int* c);
bridge.cu:
#include <iostream>
#include "add.h"
void bridge() {
int N = 1 << 16;
int blockSize = 256;
int numBlocks = (N + blockSize - 1)/blockSize;
int* a;
int* b;
int* c;
cudaMallocManaged(&a, N*sizeof(int));
cudaMallocManaged(&b, N*sizeof(int));
cudaMallocManaged(&c, N*sizeof(int));
for (int ii = 0; ii < N; ii++) {
a[ii] = ii;
b[ii] = 2*ii;
}
add<<<numBlocks, blockSize>>>(N, a, b, c);
cudaDeviceSynchronize();
for (int ii = 0; ii < N; ii++) {
std::cout << a[ii] << " + " << b[ii] << " = " << c[ii] << std::endl;
}
cudaFree(a);
cudaFree(b);
cudaFree(c);
}
bridge.h:
extern void bridge();
driver.cpp:
#include "bridge.h"
int main() {
bridge();
return 0;
}
I'm very new to cuda, so I expect that's where I'm doing something wrong. I've played a bit with using extern "C" declarations, but that just seems to move the "undefined symbol" error from run time to build time.
I'm familiar with various ways that one can end up with an undefined symbol, and I've mentioned various experiments I've already performed (static linking, extern "C" declarations) that make me think that this problem isn't addressed by the proposed duplicate question.
My unresolved symbol is _Z6bridgev
It looks to me as though the linker should be able resolve the symbol. If I can nm on driver.o, I see:
0000000000000000 T main
U _Z6bridgev
And if I run nm on libhello.so, I see:
0000000000006e56 T _Z6bridgev
When Robert Crovella was able to get my example to work on his machine, while I wasn't able to get his example to work on mine, I started realizing that my problem had nothing to do with cuda or nvcc. It was the fact that with a shared library, the loader has to resolve symbols at runtime, and my shared library wasn't in a "well-known location". I built a simple test case just now, purely with c++ sources, and repeated my failure. Once I copied libhello.so to /usr/local/lib, I was able to run driver successfully. So, I'm OK with closing my original question, if that's the will of the people.
I need to compile a C++ library to use with contiki on the Zolertia Re-Mote. I am trying a simple program first:
hello-world.c
#include "contiki.h"
#include "misc.h"
/*---------------------------------------------------------------------------*/
PROCESS(hello_world_process, "Hello world process");
AUTOSTART_PROCESSES(&hello_world_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(hello_world_process, ev, data)
{
PROCESS_BEGIN();
say_hello();
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
misc.cpp
/* C++ implementation */
#ifdef CONTIKI_TARGET_ZOUL
void* __dso_handle;
void* __exidx_end;
void* __exidx_start;
#endif
#include <iostream>
using namespace std;
void cpp_say_hello(){
cout << "Hello world!" << endl;
}
/* C wrapper */
extern "C"{
#include "misc.h"
void say_hello(){
cpp_say_hello();
}
}
misc.h
#ifndef _MISC_H_
#define _MISC_H_
/**
* \brief Prints hello to stdout
*/
void say_hello();
#endif /* _MISC_H_ */
Makefile
ifeq ($(TARGET),)
TARGET = native
endif
CONTIKI_PROJECT = hello-world
all: $(CONTIKI_PROJECT)
PROJECT_LIBRARIES = obj_$(TARGET)/misc.o
include $(CONTIKI)/Makefile.include
obj_$(TARGET)/misc.o: misc.cpp
#mkdir -p obj_$(TARGET)
$(TRACE_CXX)
$(Q)$(CXX) $(CFLAGS) $(CXXFLAGS) -c $^ -o $#
This (with some modifications to the contiki Makefiles: here) made possible for me to use C++ code for the 'native' target. However when i try to compile for the Zolertia Re-Mote platform (TARGET=zoul) i obtain the following error:
/usr/lib/gcc/arm-none-eabi/8.2.0/../../../../arm-none-eabi/bin/ld: hello-world.elf section `.ARM.extab.text._Z13cpp_say_hellov' will not fit in region `FLASH_CCA'
/usr/lib/gcc/arm-none-eabi/8.2.0/../../../../arm-none-eabi/bin/ld: region `FLASH_CCA' overflowed by 788 bytes
collect2: error: ld returned 1 exit status
make: *** [/home/wellsaid/contiki/cpu/cc2538/Makefile.cc2538:103: hello-world.elf] Error 1
rm hello-world.co obj_zoul/startup-gcc.o
Any way to fix this?
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
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…