Second order functions in GLSL? - struct

I'm looking for a way to use a function as an argument to another function in GLSL. In regular C, it can be simulated by passing a function pointer as a function argument. It also seems that other languages (like HLSL) now provide ways to deal with high-level constructs like higher-order functions, or can simulate them with clever use of HLSL structures. unfortunately I'm stuck with GLSL for now, and I can't find any way to simulate higher-order functions. Is it really impossible in current (4.2) GLSL ? Or am I missing some clever trick ?
common example of what I'm trying to achieve :
int f(someType f2, int i) {
return f2(i);
}

I'm looking for a way to use a function as an argument to another function in GLSL.
Short answer: you can't.
The closest thing to this kind of functionality you'll get in GLSL is shader subroutines. And that only allows the external OpenGL API to select which subroutine to use, not the shader itself.
So just do the switch/case statement and get it over with.

There are no higher-order functions in GLSL, but it's possible to simulate them:
#define second_order 1
#define second_order1 2
#define another_function 3
//there are no function pointers in GLSL, so I use integers instead
int call(int f2,int param1){
//instead of a function, an integer is passed as a parameter
switch(f2){
case second_order:
return param1*2;
case second_order1:
return param1*3;
}
}
int call(int f2,int param1,int param2){
//this function can be overloaded to accept more parameters
switch(f2){
case another_function:
return param1 + param2;
}
}
int f(int f2, int i) {
return call(f2,i);
}
Alternatively, this can be done using structs:
struct function{
int x;
};
function Sin(){
return function(1);
}
function Cos(){
return function(2);
}
float call(function func,float x){
if(func == Sin()){
return sin(x);
}
else if(func == Cos()){
return cos(x);
}
}
vec4 map(function func,vec4 a1){
//this function can be overloaded for different array sizes
vec4 a2;
for(int i = 0; i < 4; i++){
a2[i] = call(func,a1[i]);
}
return a2;
}
It's also possible to simulate generic second-order functions using macros:
#define map(function,input1,output1) \
for(int i = 0; i < input1.length(); i++){ \
output1[i] = function(input1[i]); \
}
This macro can be used with any type of array:
float[] arr1 = float[](1.,3.,4.);
float[arr1.length()] output1;
map(sin,arr1,output1)

Related

CUDD BDDs: building a boolean as disjunction of conjunctions but get runtime error: segmentation fault

Does anyone with experience using CUDD (not be confused with CUDA) for manipulating BDDs know why possibly I keep getting the dreaded "segmentation error (dumped core)". I suspect it could be related to referencing de-referencing which I confess I don't fully understand. Any hints pointers appreciated. I (commented out some things I have been trying):
#include <stdio.h>
#include <stdlib.h>
#include "cudd.h"
int main(int argc, char* argv[])
{
/*char filename[30];*/
DdManager * gbm; /* Global BDD manager. */
gbm = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); /* Initialize a new BDD manager with defaults. */
int const n = 3;
int i, j;
DdNode *var, *tmp, *tmp2, *BDD, *BDD_t;
BDD_t = Cudd_ReadLogicZero(gbm);
/*Cudd_Ref(BDD_t);*/
/* Outter loop: disjunction of the n terms*/
for (j = 0; j <= n - 1; j++) {
BDD = Cudd_ReadOne(gbm); /*Returns the logic one constant of the manager*/
/* Cudd_Ref(BDD);*/
/* Inner loop: assemble each of the n conjunctions */
for (i = j * (n - 1); i >= (j - 1) * (n - 1); i--) {
var = Cudd_bddIthVar(gbm, i); /*Create a new BDD variable*/
tmp = Cudd_bddAnd(gbm, var, BDD); /*Perform AND boolean operation*/
BDD = tmp;
}
tmp2 = Cudd_bddOr(gbm, BDD, BDD_t); /*Perform OR boolean operation*/
/*Cudd_RecursiveDeref(gbm, tmp);*/
BDD_t = tmp2;
}
Cudd_PrintSummary(gbm, BDD_t, 4, 0);
/* Cudd_bddPrintCover(mgr, BDD_t, BDD);*/
/* BDD = Cudd_BddToAdd(gbm, BDD_t);*/
/* printf(gbm,BDD_t, 2, 4);*/
Cudd_Quit(gbm);
return 0;
}
While you are correc that Cudd_Ref'find and Cudd_RecursiveDeref'ing is not correct in your code (yet), the current and first problem is actually a different one.
You never check the return values of the CUDD function. Some of them return NULL (0) on error, and your code does not detect such cases. In fact, the call to "Cudd_bddIthVar" returns NULL (0) at least once, and then the subsequent call to the BDD AND function makes the CUDD library access the memory at memory address 0+4, causing the segmentation fault.
There are multiple ways to fix this:
The best way is to always check for NULL return values and then notify the user of the program of the problem. Since this is your main() function, this could be printing an error message and the returning 1
At the very bare minimum, you can add assert(...) statements, so that at least in debug mode, the problem will become obvious. This is not recommended in general, as when compiling not in debug mode, such problems may go unnoticed.
In C++, there is also the possibility to work with exception - but you don't seem to be using C++.
Now why does "Cudd_bddIthVar(gbm, i)" return NULL? Because in the second iteration, variable "i" of the loop has value -1.
Now as far as Ref'fing and Deref'fing is concerned:
You need to call Cudd_Ref(...) to every BDD variable that you want to use until after calling the next Cudd function. Exceptions are constants are variables.
You need to call Cudd_RecursiveDeref(...) on every BDD node that you initially Ref'd that is no longer needed.
This is because every BDD node has a counter telling you how often it is currently in use. Once the counter hits 0, the BDD node may be recycled. Ref'fing while the node is in use makes sure that it does not happen while the node is in use.
You program could be fixed as follows:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "cudd.h"
int main(int argc, char* argv[])
{
/*char filename[30];*/
DdManager * gbm; /* Global BDD manager. */
gbm = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); /* Initialize a new BDD manager with defaults. */
assert(gbm!=0);
int const n = 3;
int i, j;
DdNode *var, *tmp, *tmp2, *BDD, *BDD_t;
BDD_t = Cudd_ReadLogicZero(gbm);
assert(BDD_t!=0);
Cudd_Ref(BDD_t);
/* Outter loop: disjunction of the n terms*/
for (j = 0; j <= n - 1; j++) {
BDD = Cudd_ReadOne(gbm); /*Returns the logic one constant of the manager*/
assert(BDD!=0);
Cudd_Ref(BDD);
/* Inner loop: assemble each of the n conjunctions */
for (i = j * (n - 1); i >= (j) * (n - 1); i--) {
var = Cudd_bddIthVar(gbm, i); /*Create a new BDD variable*/
assert(var!=0);
tmp = Cudd_bddAnd(gbm, var, BDD); /*Perform AND boolean operation*/
assert(tmp!=0);
Cudd_Ref(tmp);
Cudd_RecursiveDeref(gbm,BDD);
BDD = tmp;
}
tmp2 = Cudd_bddOr(gbm, BDD, BDD_t); /*Perform OR boolean operation*/
assert(tmp2!=0);
Cudd_Ref(tmp2);
Cudd_RecursiveDeref(gbm, BDD_t);
Cudd_RecursiveDeref(gbm, BDD);
BDD_t = tmp2;
}
Cudd_PrintSummary(gbm, BDD_t, 4, 0);
/* Cudd_bddPrintCover(mgr, BDD_t, BDD);*/
/* BDD = Cudd_BddToAdd(gbm, BDD_t);*/
/* printf(gbm,BDD_t, 2, 4);*/
Cudd_RecursiveDeref(gbm,BDD_t);
assert(Cudd_CheckZeroRef(gbm)==0);
Cudd_Quit(gbm);
return 0;
}
For brevity, I used assert(...) statements to check the conditions. Don't use this in production code - this is only to keep the code shorter during learning. Also look up in the CUDD documentation which calls can actually return NULL. Those that cannot do not need such a check. But most calls can return 0.
Note that:
The return value of Cudd_bddIthVar is not Cudd_Ref's - it doesn't need to.
The return value of Cudd_ReadLogicZero(gbm) is Cudd_Ref'd - this is because the variable is overwritten with nodes that have to be Ref'd later, and hence the code needs to have a call to RecursiveDeref(...) in that case. To make Ref's and Deref's symmetric, the node is needlessly Ref'd (which is allowed).
The last assert statement checks if there are any nodes still in use -- if that is the case before calling Cudd_Quit, this tells you that your code doesn't Deref correctly, which should be fixed. If you comment out any RecursiveDeref line and run the code, the assert statement should halt execution then.
I've rewritten your for-loop condition to ensure that no negative variable numbers occur. But your code may not do what it is supposed to now.
Thanks, #DCTLib. I've found that the C++ interface is much more convenient for formulating Boolean expressions. The only problem is how to go back and forth between the C and C++ interfaces, since ultimately I still need C for printing out the minterms (called cutsets in the world I inhabit, Reliability Eng. Let me pose the question in separate entry. It seems you know CUDD quite well. You should be maintaining that repo! It's a great product but sparsely documented or interacted with.

How do you code the perfect fuzzing function for some other function?

Here is a snippet of code:
struct somedata {
char mychar;
int myint;
unsigned short myushort;
string mystring;
};
void some_func(somedata *data) {
/* does something with data */
}
How do you write a perfect fuzzing function to test the correct functionality, security, and robustness of this code?
By perfect I mean complete tests that cover all cases (if possible). Say: out of range values, different data types, etc..
You do not have source code for some_func.
One thing that you might find interesting is using genetic fuzzers like american fuzzy lop instead of writing the fuzz tests on your own. You would have to modify your program to operate on standard input and output (or on a file that is mentioned in the command line) and compile it with a special GCC/LLVM wrapper, but for exchange you would get a way to perform fuzzing with a tool that can learn your input/output format. It learns which bits induce new code paths when modified and gives them some extra attention. Also, have a look at LLVM's LibFuzzer, which uses a similar idea.
It seems that I got fuzzing wrong.
Fuzz testing is a simple technique that can have a profound effect on
your code quality. In fuzzing we inject random bad data into an
application to see what breaks
Because Fuzzing != Testing, we do not build perfect test-cases or test all possible cases, instead we just generate random bad data and insert it into the application.
A Typical fuzzing function for the mentioned code would be:
void fuzzTesting ()
{
//create somedata
somedata data;
//generate a random vector
srand(time(NULL)); //seed = current_time
//bufferOverflow
int i= 200000
while(i>=0)
{
r = rand()
data.mychar = r;
data.myint = r;
data.myushort = r;
some_func(&data);
--i;
}
//Format String
int i= 200000
while(i>=0)
{
r = rand()
data.mychar = '%s' + r;
data.myint = '%s' + r;
data.myushort = '%s' + r;
some_func(&data);
--i;
}
//Integer overflow
int i= 200000
while(i>=0)
{
r = rand()
data.mychar = r + 0xffffffff;
data.myint = r + 0xffffffff;
data.myushort = r + 0xffffffff;
some_func(&data);
--i;
}
}
for more fuzz testing vectors and details see this wikipage

using malloc in dgels function of lapacke

i am trying to use dgels function of lapacke:
when i use it with malloc fucntion. it doesnot give correct value.
can anybody tell me please what is the mistake when i use malloc and create a matrix?
thankyou
/* Calling DGELS using row-major order */
#include <stdio.h>
#include <lapacke.h>
#include <conio.h>
#include <malloc.h>
int main ()
{
double a[3][2] = {{1,0},{1,1},{1,2}};
double **outputArray;
int designs=3;
int i,j,d,i_mal;
lapack_int info,m,n,lda,ldb,nrhs;
double outputArray[3][1] = {{6},{0},{0}};*/
outputArray = (double**) malloc(3* sizeof(double*));
for(i_mal=0;i_mal<3;i_mal++)
{
outputArray[i_mal] = (double*) malloc(1* sizeof(double));
}
for (i=0;i<designs;i++)
{
printf("put first value");
scanf("%lf",&outputArray[i][0]);
}
m = 3;
n = 2;
nrhs = 1;
lda = 2;
ldb = 1;
info = LAPACKE_dgels(LAPACK_ROW_MAJOR,'N',m,n,nrhs,*a,lda,*outputArray,ldb);
for(i=0;i<m;i++)
{
for(j=0;j<nrhs;j++)
{
printf("%lf ",outputArray[i][j]);
}
printf("\n");
}
getch();
return (info);
}
The problem may come from outputArray not being contiguous in memory. You may use something like this instead :
outputArray = (double**) malloc(3* sizeof(double*));
outputArray[0]=(double*) malloc(3* sizeof(double));
for (i=0;i<designs;i++){
outputArray[i]=&outputArray[0][i];
}
Don't forget to free the memory !
free(outputArray[0]);
free(outputArray);
Edit : Contiguous means that you have to allocate the memory for all values at once. See http://www.fftw.org/doc/Dynamic-Arrays-in-C_002dThe-Wrong-Way.html#Dynamic-Arrays-in-C_002dThe-Wrong-Way : some packages, like fftw or lapack require this feature for optimization. As you were calling malloc three times, you created three parts and things went wrong.
If you have a single right hand side, there is no need for a 2D array (double**). outputArray[i] is a double*, that is, the start of the i-th row ( row major). The right line may be outputArray[i]=&outputArray[0][i*nrhs]; if you have many RHS.
By doing this in your code, you are building a 3 rows, one column, that is one RHS. The solution, is of size n=2. It should be outputArray[0][0] , outputArray[1][0]. I hope i am not too wrong, check this on simple cases !
Bye,

allocating enough memory using typedef struct object whose size varies in another typedef struct

I have defined two typedef structs, and the second has the first as an object:
typedef struct
{
int numFeatures;
float* levelNums;
} Symbol;
typedef struct
{
int numSymbols;
Symbol* symbols;
} Data_Set;
I then defined numFeatures and numSymbols and allocate memory for both symbols and levelNums, then fill levelNums inside a for loop with value of the inner loop index just to verify it is working as expected.
Data_Set lung_cancer;
lung_cancer.numSymbols = 5;
lung_cancer.symbols = (Symbol*)malloc( lung_cancer.numSymbols * sizeof( Symbol ) );
lung_cancer.symbols->numFeatures = 3;
lung_cancer.symbols->levelNums = (float*)malloc( lung_cancer.symbols->numFeatures * sizeof( float ) );
for(int symbol = 0; symbol < lung_cancer.numSymbols; symbol++ )
for( int feature = 0; feature < lung_cancer.symbols->numFeatures; feature++ )
*(lung_cancer.symbols->levelNums + symbol * lung_cancer.symbols->numFeatures + feature ) = feature;
for(int symbol = 0; symbol < lung_cancer.numSymbols; symbol++ )
for( int feature = 0; feature < lung_cancer.symbols->numFeatures; feature++ )
cout << *(lung_cancer.symbols->levelNums + symbol * lung_cancer.symbols->numFeatures + feature ) << endl;
return 0;
When levelNums are int I get what I expect( i.e. 0,1,2,0,1,2,...) but when they are float, only the first 3 are correct and the remaining are very small or very large values, not 0,1,2 like expected. I then have two questions:
When allocating memory for symbols, how does it know how big a Symbol is since I have not yet defined how large levelNums will be yet.
How do I get float values into levelNums correctly.
The reason I am doing it like this is this is a data structure that will be sent to a GPU for GPGPU programming in CUDA and arrays are not recognized. I can only send in a continuous block of memory explicitly and the typedef structs are only there for conveying/defining the memory struture of the data.
A couple thing jump out at meet. For one thing, you only allocated a buffer for levelNums of the first symbol. Similarly, your inner loops always loop over the numFeatures of the first symbol.
You're doing a whole lot of dereferencing of arrays, which is fine in general, but the assignment in particular (inside the first set of loops) looks very strange. It's entirely possible I just don't understand what you're trying to do there, but I think it'd be a lot less confusing if you used some square bracket array accessors.

Having trouble passing array to function

I am getting all kinds of errors when passing my array to this function. The function is suppose to have the user enter a name and a score and store them in 2 seperate arrays, one for the names, one for the scores. I believe I have to use pointers but have no idea on how to use them. I don't want the answer, just a push in the right direction. Here is the code:
#include <iostream>
int InputData(int &, char, int);
using namespace std;
int main()
{
char playerName[100][20];
int score[100];
int numPlayers = 0;
InputData(numPlayers, playerName, score);
return 0;
}
int InputData(int &numPlayers, char playerName[][20], int score[])
{
while (numPlayers <= 100)
{
cout << "Enter Player Name (Q to quit): ";
cin.getline(playerName, 100, ā€˜\nā€™);
if ((playerName[numPlayers] = 'Q') || (playerName[numPlayers] = 'q'))
return 0;
cout << "Enter score for " << playerName[numPlayers] <<": ";
cin >> score[numPlayers];
numPlayers++;
}
}
Ok, I made some more changes and the errors are less, must be getting close, Lol!
This looks like a school assignment and I applaud you for not asking for the answer. There are several ways to do it, but you are already fairly close in the approach that you are using. When you pass an array reference, you do not want to include the length of the array. For example, the parameter int score[100] should be int score[]. The exception, especially in your scenario, is with multidimensional arrays. In this case, you want to use char playerName[][20]. Your function declaration also needs to change to match. Don't forget InputData returns an int. Your declarations and function call are correct; you just need to adjust your function signature.
Keeping the errors aside -
InputData(numPlayers, playerName, score, size);
// ^^^^ size is no where declared
// resulting Undeclared indentifier error
Prototype mentions of taking 3 arguments but calling the function passing 4 parameters.
Hint regarding errors:
An 1D array decays to a pointer pointing to first element in the array while passing to a function.
A 2D array decays to a pointer pointing to the 1D array ( i.e., T[][size] ) while passing to a function.
Return type of main() should be int.
It seems with the given hints you corrected most of the errors. But you forgot to change the prototype. So, change -
int InputData(int &, char, int);
to
int InputData(int &, char[][20], int[]);
Why aren't you using std::string array for player names ? Use it and remove rest of the errors. Good luck.

Resources