How to manually compile shared dpi lib? - c

I try to import some C-function that generates an array in SystemVerilog.
Here is code:
#include "svdpi.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void getPacket(int packetSize, svOpenArrayHandle fpSig, svOpenArrayHandle err)
{
int* cfpSig = (int*) calloc(packetSize, sizeof(int));
double* cerr = (double*)calloc(packetSize, sizeof(double));
for(int i = 0; i < packetSize; ++i)
{
cfpSig[i] = i;
cerr[i] = 1.1*i;
printf("%d %f\n",cfpSig[i],cerr[i]);
}
printf("----------");
memcpy((int*) svGetArrayPtr(fpSig),cfpSig,packetSize);
memcpy((int*) svGetArrayPtr(err),cerr,packetSize);
free(cfpSig);
free(cerr);
}
import "DPI-C" function void getPacket(input int packetSize,
output int fpSig[], output real err[]);
module top();
initial begin
parameter int packetSize = 4;
int fpSig[packetSize];
real err[packetSize];
getPacket(packetSize,fpSig,err);
for(int i = 0; i < packetSize; ++i) begin
$display("fpSig: %d\nerr : %f",fpSig[i],err[i]);
end
end
endmodule
But when I compile the c-code manually, an error is generated at the linking stage: undefined reference to 'svGetArrayPtr'.
I have not previously worked with svOpenArrayHandle and it was enough to connect the header file "svdpi.h". I tried to look for some svdpi.dll lib in the questa install folder, but didn't find it.
If I compile c-file by vlog it's working fine, but I want to compile it manually because I plan to include matlab libs and compiling via vlog will become uncomfortable.

In Questasim simulator, the library containing the svGetArrayPtr symbol is mtipli.dll

Related

Can't create ppm File from an executable (C)

I am trying to create a ppm file from inside a C program, but somehow it doesn't work.
It works fine when I am inside the IDE and run the program there. The program is executed and the file created inside the file's folder.
But once I build it and open the executable with a double click, the program runs in the terminal but does not create the file.
I am working on a mac and this is the relevant code, thanks in advance you all!
// from generalSettings.h
#define WIDTH 1100
#define HEIGHT 966
#define MYFILENAME "testimage.ppm"
int pictureArray[HEIGHT][WIDTH];
//from the main.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "generalSettings.h"
int main()
{
triangle firstParentTriangle;
// these two functions "draw" sierpinsky triangles in the pictureArray
drawFirstParentTriangle(&firstParentTriangle);
drawChildTriangles(firstParentTriangle, numberOfRecursions);
create_ppm();
return 0;
}
void create_ppm()
{
unsigned char color_black[] = "000 000 000\n";
unsigned char color_white[] = "255 255 255\n";
FILE *p_file = fopen(MYFILENAME, "w");
if (NULL != p_file)
{
fprintf(p_file, "P3\n %d %d\n 255\n", WIDTH, HEIGHT);
for (int i = 0; i < HEIGHT; i++)
for (int j = 0; j < WIDTH; j++)
if (1 == pictureArray[i][j])
fprintf(p_file, color_black);
else
fprintf(p_file, color_white);
fclose(p_file);
}
}
Here, I have replaced the foreground and background variables with local ones.
Generally, the program inserts 1 to the pictureArray[][] on certain elements and leaves others with a 0.
For my problem, this should be the relevant code for a reproducable example.
EDIT: Problem solver. File was created in the user folder due to missing path.

Call GNU Octave functions in C?

I want to use matrix algebra and optimization. I have tested different C and C++ libraries for matrix algebra but the problem with those is they cannot handle garbage data as good as GNU Octave does. Garbage data in C and C++ goes low to like e-8 but in GNU Octave it will be pushed down way to low as e-17. That's very useful if you planning to use garbage data from e.g measurement in calculations. They don't effect nothing of your results.
But GNU Octave have a C++ API, which I don't really understand how to use. But I want to use C and call GNU Octave functions from C.
Is that possible that I can create a struct that contains a 2D array and dimensions, and send it to GNU Octave and I will return a struct again that have the result and the dimension e.g solution.
There is a c mex interface. However the octave interpreter must be embedded and initialized before any mex function can be called. As of Octave 4.4 octave_main as suggested by the linked answer has been deprecated and some other changes also are needed for it to be useful for mex programs. So I have prepared a c++ source file calloctave.cc containing the functions mexCallOctave and free_arg_list and its header calloctave.h.
calloctave.cc
// calloctave.cc
#include "interpreter.h"
#include "mxarray.h"
#include "parse.h"
extern "C"
int
mexCallOctave (int nargout, mxArray *argout[], int nargin,
mxArray *argin[], const char *fname)
{
static octave::interpreter embedded_interpreter;
if (!embedded_interpreter.initialized())
embedded_interpreter.execute ();
octave_value_list args;
args.resize (nargin);
for (int i = 0; i < nargin; i++)
args(i) = mxArray::as_octave_value (argin[i]);
bool execution_error = false;
octave_value_list retval;
retval = octave::feval (fname, args, nargout);
int num_to_copy = retval.length ();
if (nargout < retval.length ())
num_to_copy = nargout;
for (int i = 0; i < num_to_copy; i++)
{
argout[i] = new mxArray (retval(i));
}
while (num_to_copy < nargout)
argout[num_to_copy++] = nullptr;
return execution_error ? 1 : 0;
}
extern "C"
void
free_arg_list (int nargs, mxArray* arglist[])
{
for(int i = 0; i < nargs; i++)
delete arglist[i];
}
calloctave.h
// calloctave.h
#pragma once
#include "mex.h"
#if defined (__cplusplus)
extern "C" {
#endif
int
mexCallOctave (int nargout, mxArray *argout[], int nargin,
mxArray *argin[], const char *fname);
void
free_arg_list (int nargs, mxArray* arglist[]);
#if defined (__cplusplus)
}
#endif
Here is a basic introduction into mex files. You can compile an example hello world program adding the option --verbose as mkoctfile --mex --verbose hello.c to get the list of compiler options that you need to use them for compilation of your actual programs. Note that because calloctave.cc is a c++ source it should be compiled using a c++ compiler such as g++.
In the following example a m function "myfunction" is called. It gets one input and produces one output. mexCallOctave is used for calling the octave function and it has the same signature as mexCallMATLAB.
myfunction.m
% myfunction.m
function out= myfunction( a )
out = sum(a);
endfunction
main.c
//main.c
#include <stdio.h>
#include "calloctave.h"
int main()
{
double input_data[] = {0,1,2,3,4,5,6,7,8,9,10};
const int nargin = 1;
const int nargout = 1;
mxArray* rhs[nargin];
mxArray* lhs[nargout];
// allocate mex array
rhs[0] = mxCreateDoubleMatrix( 10, 1, mxREAL);
double* rhs_ptr = mxGetPr( rhs[0] );
// copy data from input buffer to mex array
for (int i = 0 ; i < 10; i++)
rhs_ptr[i] = input_data[i];
// call octave function
mexCallOctave(nargout, lhs, nargin, rhs, "myfunction");
double* lhs_ptr = mxGetPr( lhs[0] );
double output_data = *lhs_ptr;
// show the result
printf ("result = %f", output_data);
// free memory
mxDestroyArray(rhs[0]);
free_arg_list(nargout, lhs);
}

CTypes "[WinError 126] The specified module could not be found"

I have a (64-bit) DLL written in C to call from CTypes in Windows. It's compiled and linked with GCC in Cygwin, but when I call it from CTypes I get "[WinError 126] The specified module could not be found."
The path to the DLL is correct (I even checked it with "if os.path.exists(path_to_dll)"). Research says that this error is most commonly found when the dll depends on other dlls, so I compiled it with the -M flag in GCC and it reports no dependencies.
I have called DLLs written in assembler using the same ctypes strings, but this C dll does not load even though there are no dependencies.
Here is the C code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "WL_02.h"
double* main(double* X, int64_t len_X)
{
double *collect;
int64_t while_counter = 0;
int64_t collect_counter = 0;
int64_t new_len = 0;
int64_t this = 0;
int64_t start = 0;
int64_t stop = 0;
int64_t x = 0;
/* Initial memory allocation */
collect = (double *) malloc(len_X);
while (while_counter < len_X)
{
this = X[while_counter];
if (this < 10)
{
start = 0;
stop = this;
}
else
{
start = this - 10;
stop = this;
}
for (x = start; x < stop; x++)
{
if ((x % 2) != 0)
{
x *= x;
collect[collect_counter] = x;
collect_counter ++;
if (collect_counter >= len_X)
{
/* Reallocating memory */
new_len = len_X * 2;
collect = (double *) realloc(collect, new_len);
len_X = new_len;
}
}
}
while_counter += 1;
}
return (0);
}
Here is the .h file (WL_02.h):
#ifndef WL_02_H
#define WL_02_H
#define EXPORT_DLL __declspec(dllexport)
EXPORT_DLL double* main (double* X, int64_t len_X);
#endif
Here are the GCC compile and link strings:
gcc -c WL_02.c -o WL_02.obj
gcc -shared -o WL_02.dll WL_02.obj
Here is the CTypes code:
hDLL = ctypes.WinDLL("C:/cygwin64/our_files/WL_02/WL_02.dll")
CallName = hDLL.main
CallName.argtypes = [ctypes.POINTER(ctypes.c_double),ctypes.c_int64]
CallName.restype = ctypes.POINTER(ctypes.c_int64)
ret_ptr = CallName(CA_X,length_array_out)
The error occurs on the first line (hDLL = ...) where I load the DLL.
The only external dependency I can think of is msvcrt.dll which contains malloc and realloc, but I believe all I need to do is include stdlib.h, which I did.
Thanks in advance for any help.

Error in cudaMemcpyToSymbol using CUDA 5

The Problem
I have prepared one sample CUDA code using the constant memory. I can run this in cuda 4.2 successfully but I get "invalid device symbol" when I compile using the CUDA 5.
I have attached the sample code here.
The Code
#include <iostream>
#include <stdio.h>
#include <cuda_runtime.h>
#include <cuda.h>
struct CParameter
{
int A;
float B;
float C;
float D;
};
__constant__ CParameter * CONSTANT_PARAMETER;
#define PARAMETER "CONSTANT_PARAMETER"
bool ERROR_CHECK(cudaError_t Status)
{
if(Status != cudaSuccess)
{
printf(cudaGetErrorString(Status));
return false;
}
return true;
}
// Kernel that executes on the CUDA device
__global__ void square_array(float *a, int N)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx<N)
{
a[idx] = CONSTANT_PARAMETER->A * a[idx];
}
}
////Main Function/////
int main(void)
{
/////Variable Definition
const int N = 10;
size_t size = N * sizeof(float);
cudaError_t Status = cudaSuccess;
CParameter * m_dParameter;
CParameter * m_hParameter;
float * m_D;
float * m_H;
//Memory Allocation Host
m_hParameter = new CParameter;
m_H = new float[N];
//Memory Allocation Device
cudaMalloc((void **) &m_D, size);
cudaMalloc((void**)&m_dParameter,sizeof(CParameter));
////Data Initialization
for (int i=0; i<N; i++)
m_H[i] = (float)i;
m_hParameter->A = 5;
m_hParameter->B = 3;
m_hParameter->C = 98;
m_hParameter->D = 100;
//Memory Copy from Host To Device
Status = cudaMemcpy(m_D, m_H, size, cudaMemcpyHostToDevice);
ERROR_CHECK(Status);
Status = cudaMemcpy(m_dParameter,m_hParameter,sizeof(CParameter),cudaMemcpyHostToDevice);
ERROR_CHECK(Status);
Status = cudaMemcpyToSymbol(PARAMETER, &m_dParameter, sizeof(m_dParameter));
ERROR_CHECK(Status);
// Do calculation on device:
int block_size = 4;
int n_blocks = N/block_size + (N%block_size == 0 ? 0:1);
square_array <<<n_blocks, block_size>>>(m_D,N);
// Retrieve result from device and store it in host array
cudaMemcpy(m_H, m_D, sizeof(float)*N, cudaMemcpyDeviceToHost);
// Print results
for (int i=0; i<N; i++)
printf("%d %f\n", i, m_H[i]);
// Cleanup
free(m_H);
free(m_hParameter);
cudaFree(m_dParameter);
cudaFree(m_D);
return 0;
}
I have tried WINDOWS: CUDA 5.0 Production Release and the Graphics card is GTX 590.
Any help will be appreciated.
In an effort to avoid being "Stringly Typed", the use of character strings to refer to device symbols was deprecated in CUDA runtime API functions in CUDA 4.1, and removed in CUDA 5.0.
The CUDA 5 release notes read:
** The use of a character string to indicate a device symbol, which was possible
with certain API functions, is no longer supported. Instead, the symbol should be
used directly.
If you change your code to the following, it should work.
Status = cudaMemcpyToSymbol(CONSTANT_PARAMETER, &m_dParameter, sizeof(m_dParameter));
ERROR_CHECK(Status);
From the CUDA 5.0 Release Notes:
** The use of a character string to indicate a device symbol, which was possible with certain API functions, is no longer supported. Instead, the symbol should be used directly. "
These API functions still exist, but they accept the target symbol argument only as a bare identifier now, not as either a bare identifier or a string literal naming an ident. E.g.
__ device__ __ constant__ type ident;
main() { cudaMemcpyToSymbol("ident", ...); } // no longer valid, returns cudaErrorInvalidSymbol
main() { cudaMemcpyToSymbol(ident, ...); } // valid
So get rid of this:
#define PARAMETER "CONSTANT_PARAMETER"
And change this:
Status = cudaMemcpyToSymbol(PARAMETER, &m_dParameter, sizeof(m_dParameter));
To this:
Status = cudaMemcpyToSymbol(CONSTANT_PARAMETER, &m_dParameter, sizeof(m_dParameter));
And I think it will work.

How to include socket.h in my c file in Ubuntu

This is my a.c code :
#include <stdio.h>
#include <socket.h>
int main(void)
{
int count[4] = {[2] = 3 }, i;
for (i = 0; i < 4; i++)
printf("count[%d]=%d\n", i, count[i]);
return 0;
}
When I compile it, it shows:
a.c:2: fatal error: socket.h: No such file or directory
compilation terminated.
So how do I include it / where can download it?
It should be:
#include <sys/socket.h>
Paths are given relatively to the /usr/include path. So e.g. the socket.h file is under /usr/include/sys/socket.h. You can search for it if you don't know:
find /usr/include/ -name SEARCHED_HEADER.h

Resources