Why it isn't working? I have seen examples using this, but when I use it, it crashes. Why?(C) - c

Why can't I do g->n=n ? Can someone explain?
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX 100000
int N[]={100,200,300,400,500,600,700,800,900,1000};
double B[]={0.125, 0.250, 0.375, 0.5, 0.625, 0.750, 0.875};
typedef struct Graph
{
int n;
int M[MAX][MAX];
int val;
int adjacent[MAX-1];
}G;
struct Graph * RandomDirectedGraph(int n, double b)
{
struct Graph * g = (struct Graph*)malloc(sizeof(struct Graph));
g->n=n;
int u,i,v;
for(u=0;u<n;u++)
{
for(i=0;i<n;i++)
{
g->M[u][i]=0;
}
}
int m=b*n*n;
for(i=0;i<m;i++)
{
do
{
u=rand()%n;
v=rand()%n;
}
while(u==v || g->M[u][v]==1);
g->M[u][v]=1;
}
};
int main()
{
int i,j,n,b;
for(i=0;i<sizeof(N)/sizeof(*N);i++)
{
for(j=0;j<sizeof(B)/sizeof(*B);j++)
{
RandomDirectedGraph(N[i],B[j]);
}
}
return 0;
}
When I compile and run it, ERROR pops up and says that some memory can't be written. I don't know what I'm doing wrong here.

The issue is that everytime you are executing the method RandomDirectedGraph, your application tries to reserve about 40GB of RAM memory. I guess your computer doesn't have that much.
Furthermore you should release all memory by calling free on the pointers.
For such big matrices, you don't use classic C matrices. You need external librarys for sparse matrix calculations like https://www.alglib.net/matrixops/sparse.php

Related

a.at<uchar>(x,y) wont works in Vivado SDSoC

I want to get 2d array from a Mat in Vivado SDSoC but Im not able to do that because as described Xilinx(XAPP1167),
cv::Mat<>.at() method and cvGet2D() function have no corresponding equivalent
function in the synthesizable library
I appreciate any help. Thank you.
The project is about face recognition system. The system first will go viola-jone face detection and then feed the output to the CNN classification.
The output of viola-jones face detection is in unsigned char*.
I plant to convert it back to Mat and obtain 2d array for the input of CNN Classifier.
#include <cstdio>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <ctime>
#include <fcntl.h>
#include <fstream>
#include <iostream>
#include <sys/mman.h>
#include <malloc.h>
#include <unistd.h>
#include <sds_lib.h>
#include <opencv2/core/core.hpp>
#include <opencv2/contrib/contrib.hpp>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/core/core_c.h"
using namespace cv;
using namespace std;
void resize_2_gray(unsigned char *imageIn, unsigned char *imageOut)
{
int k=0;
int coord;
for (int i=0; i<240; i++) {
for(int j=0; j<320; j++){
//coord=(i*2*640+j*2)*3;
#pragma HLS PIPELINE II=1
coord=6*(i*640+j);
imageOut[k] = 0.2126*imageIn[coord] + 0.7152*imageIn[coord+1] + 0.0722*imageIn[coord+2] ;
k++;
}
}
}
int main(){
Mat ROI;
unsigned int cam_num =5;//camera USB port
unsigned char *image_ROI;
image_ROI = (unsigned char*)sds_alloc(sizeof(unsigned char)*56*46);
VideoCapture stream(cam_num);
stream.read(ROI);
cvtColor(ROI,ROI, CV_BGR2RGB);
resize_2_gray(ROI.data, image_ROI);
double face_2darray [56][46]={0};
int h1=3, w1=3,w2=46,h2=56;
int x_ratio = (int)((w1<<16)/w2)+1;
int y_ratio = (int)((h1<<16)/h2)+1;
int x2,y2;
//resize image before fed into classification
for (int a=0;a<h2;a++)
{
for (int b=0;b<w2;b++)
{
x2=((b*x_ratio)>>16);
y2=((a*y_ratio)>>16);
image_ROI[(a*w2)+b]=ROI.data[(y2*w1)+x2];
face_2darray[a][b]=(double)image_ROI[a+b];
face_2darray[a][b]= 2*(face_2darray[a][b]/255)-1;
}
}
Mat Image = Mat(56,46,0,image_ROI);
imshow("Output",Image);
sds_free(image_ROI);
}
I believe the synthesized version is using a streaming interface, so you can't use random access APIs, and instead must read pixels/elements one by one.

Why can't I create an opaque data type?

I'm trying to experiment with opaque data types to get an understanding of them. The main problem is that I keep getting an 'incomplete' error.
main.c
#include <stdio.h>
#include <stdlib.h>
#include "blepz.h"
int main()
{
setfnarp(GOO,5);
int loogaboo = getfnarp(GOO);
printf("%i", loogaboo);
return 0;
}
fnarpishnoop.c
#include "blepz.h"
struct noobza {
int fnarp;
};
void setfnarp(struct noobza x, int i){
x.fnarp = i;
};
int getfnarp(struct noobza x){
return x.fnarp;
};
blepz.h
struct noobza;
void setfnarp(struct noobza x, int i);
int getfnarp(struct noobza x);
struct noobza GOO;
I clearly don't understand something here and I was hoping someone could help me figure out how opaque data types are implemented if the whole point of them is that you have a hard time finding actual code for them.
Using a struct that you haven't declared the contents of gives an "incomplete type" error, as you have already mentioned.
Instead, use a pointer to the struct and a function that returns a pointer to the struct, like this:
struct noobza;
struct noobza *create_noobza(void);
void setfnarp(struct noobza *x, int i);
int getfnarp(struct noobza *x);
struct noobza *GOO;
...
#include <stdlib.h>
#include "blepz.h"
struct noobza {
int fnarp;
};
struct noobza *create_noobza(void)
{
return calloc(1, sizeof(struct noobza));
}
void setfnarp(struct noobza *x, int i){
x->fnarp = i;
};
int getfnarp(struct noobza *x){
return x->fnarp;
};
...
#include <stdio.h>
#include <stdlib.h>
#include "blepz.h"
int main()
{
GOO = create_noobza();
setfnarp(GOO,5);
int loogaboo = getfnarp(GOO);
printf("%i", loogaboo);
return 0;
}

Passing a Struct Containing a Vector to a CUDA Kernel

I have a large code that I need to pass a struct to a CUDA kernel that has a larger number of ints for parameters and a vector. I can't figure out how to pass the struct to the CUDA kernel. I've copied it to the device, but get the following error when trying to compile:
test_gpu.cpp:63:17: error: invalid operands to binary expression ('void (*)(Test)' and 'dim3')
computeTotal<<dimGrid, dimBlock>>(test_Device);
test_gpu.cpp:63:36: error: invalid operands to binary expression ('dim3' and 'Test *')
computeTotal<<dimGrid, dimBlock>>(test_Device);
Attached is a small almost working example of the code, any ideas?
#include <stdio.h>
#include <stdlib.h>
#include <cuda_runtime_api.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include <device_functions.h>
#include <device_launch_parameters.h>
#include <vector>
#include <string>
typedef struct Test{
int x;
int y;
int z;
std::vector<int> vector;
std::string string;
}Test;
Test test;
__device__ void addvector(Test test, int i){
test.x += test.vector[i];
test.y += test.vector[i+1];
test.z += test.vector[i+2];
}
__global__ void computeTotal(Test test){
for (int tID = threadIdx.x; tID < threadIdx.x; ++tID )
addvector(test, tID);
}
int main()
{
Test test_Host;
int vector_size = 512;
test_Host.x = test_Host.y = test_Host.z = 0;
for (int i=0; i < vector_size; ++i)
{
test_Host.vector.push_back(rand());
}
Test* test_Device;
int size = sizeof(test_Host);
cudaMalloc((void**)&test_Device, size);
cudaMemcpy(test_Device, &test_Host, size, cudaMemcpyHostToDevice);
dim3 dimBlock(16);
dim3 dimGrid(1);
computeTotal<<dimGrid, dimBlock>>(test_Device);
return 0;
}
Items from C++ standard libraries aren't generally/normally usable in CUDA device code. The documentation support for this is here.
For this particular case, it means you may have trouble with either std::vector or std::string. One possible workaround is to replace these with ordinary C-style arrays:
#define MAX_VEC_SIZE 512
#define MAX_STR_SIZE 512
typedef struct Test{
int x;
int y;
int z;
int vec[MAX_VEC_SIZE];
char str[MAX_STR_SIZE];
}Test;
This will of course necessitate changes elsewhere in your code.

Segmentation fault on char

I am getting a segmentation fault when I run prog.c. I have found that it is something with my *char. Here's the code.
prog.c
#include <stdio.h>
#include "worker.h"
#include "manager.h"
#include "employee.h"
int main(int argc, char **argv) {
int i;
Worker boss = (Worker) new_Manager("Carl Cracker", 80000, 1987, 12, 15);
return 0;
}
worker.h
#ifndef _WORKER_H_
#define _WORKER_H_
#define WORKER char *name; \
double salary; \
long hireDay; \
void (*raiseSalary)(Worker this, double byPercent);
typedef struct Worker_struct* Worker;
struct Worker_struct {
WORKER;
} Worker_struct;
void raiseSalary(Worker this, double byPercent);
#endif
worker.c
#include <stdio.h>
#include <stdlib.h>
#include "worker.h"
void raiseSalary(Worker this, double byPercent) {
Worker worker = (Worker) this;
printf("worker_c: raising salary\n");
double raise = worker->salary * byPercent / 100;
worker->salary = worker->salary + raise;
}
manager.h
#ifndef _MANAGER_H_
#define _MANAGER_H_
#include "worker.h"
typedef struct Manager_struct* Manager;
struct Manager_struct {
WORKER;
double bonus;
void (*setBonus)(Worker this, double b);
} Manager_struct;
Manager new_Manager(char *name, double salary, int year, int month, int day);
#endif
manager.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include "manager.h"
static void setBonus(Worker this, double b) {
Manager manager = (Manager) this;
manager->bonus = b;
}
Manager new_Manager (char *name, double salary, int year, int month, int day) {
Manager manager;
strcpy (manager->name, name);//----i think my problem is here----
manager->salary = salary;
manager->bonus = 0;
manager->setBonus = setBonus;
manager->raiseSalary = raiseSalary;
return manager;
}
I think that my problem is in the manager.c at strcpy. What am i doing wrong?
You've declared char *name in the WORKER macro, but memory hasn't been allocated to it.
Please, please don't define variables in macros like this; there's absolutely no benefit, and it complicates the code unnecessarily. Just define them directly in the Worker_struct.

GCC division truncates (rounding problem)

Using GCC on the Ubuntu Linux 10.04, I have unwanted rounding after a division.
I tried:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void FormatReading(int temp)
{
double reading = temp / 100;
printf("%f\n",reading); /* displays 226.000000, was expecting 226.60 */
}
int main(void)
{
FormatReading(22660);
return 0;
}
It was suggested to me to try:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void FormatReading(int temp)
{
long reading = temp ;
reading = reading / 100;
printf("%3.2ld\n",reading); /* displays 226 */
}
int main(void)
{
FormatReading(22660);
return 0;
}
I also tried:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void FormatReading(int temp)
{
long reading = temp ;
double reading2 = reading / 100;
printf("%3.2f\n",reading2); /* displays 226.00 */
}
int main(void)
{
FormatReading(22660);
return 0;
}
I also tried the round function using include math.h with compiler tag -lm in various ways, but did not find what I was looking for.
Any help greatly appreciated.
Best regards,
Bert
double reading = temp / 100.0;
^^
temp / 100 is an integer division - that you assign the result to a double doesn't change this.
You are using integer division which always gives integral results rather than fractions, and then the result is being assigned to a double. Divide by 100.0 instead of 100 to get the behavior you want.

Resources