I browsed through the internet, and I've only saw people doing forward declarations on class using the typedef keyword. But, I was wondering how'd I do that with functions/tasks?
I wanted to put the main function above the definitions of other functions/tasks to ease the reader when one is previewing it. In C++, forward declaration for a function looks something like this:
//forward declaration of sub2
int sub2(int A, int B);
int main(){
cout << "Difference: " << sub2(25, 10);
return 0;
}
int sub2(int A, int B) //Defining sub2 here{
return A - B;
}
For SystemVerilog, will it be something like this?
function somefunction();
virtual task body();
somefunction();
endtask: body
function somefunction();
// do something here.
endfunction: somefunction
Should I use typedef for forward declarations with functions/tasks?
Functions and tasks do not need to be declared before use as long as they have a set of trailing parenthesis () which may also include required arguments. They use search rules similar to hierarchical references. See section 23.8.1 Task and function name resolution in the IEEE 1800-2017 SystemVerilog LRM
Function declaration order doesn't matter, like in C. You can call somefunction in body before declaring it.
You don't need to do any kind of declarations.
Related
In HLSL, is there a way to make defines act like swap-able methods? My use case is creating a method that does fractal brownian noise with a sampling function(x, y). Ideally I would be able to have a parameter that is a method, and just call that parameter, but I can't seem to do that in HLSL in Unity. It wouldn't make sense to copy+paste the entire fractal brown method and change just the one sampler line, especially if I'm using multiple layers of different noise functions for a final output. But I can't seem to find out how to do it.
Here is what I've tried:
#define NOISE_SAMPLE Random(x, y)
float FBM()
{
...
float somevalue = NOISE_SAMPLE;
....
}
And in a compute buffer, I have something like this:
void CSMain(uint3 id : SV_DispatchThreadID)
{
...
#undef NOISE_SAMPLE
#define NOISE_SAMPLE Perlin(x, y)
float result = FBM();
...
}
However this doesn't seem to work. If I use NOISE_SAMPLE in the CSMain function, it uses the Perlin version. However, calling FBM() still uses the random version. This doesn't seem to make sense as I've read elsewhere that all functions are inline, so I thought the FBM function would 'inline' itself below the redefinition with the Perlin version. Why is this the case and what are some options for my use case?
This doesn't work, as a #define is a preprocessor instruction, and the preprocessor does its work before any other part of the HLSL compiler. So, even though your function is eventually inlined, this inlining only happens long after the preprocessor has run. In fact, the preprocessor is basically doing a purely string-based find-and-replace (just slightly smarter) before the actual compiler even sees your code. It isn't even aware of the concept of a function.
Out of my head, I can think of two options for your use case:
You could pass an integer as a parameter to your FBM() method, which identifies your noise function, and then have a switch (or an if-else-chain) inside your FBM() method, which selects the proper noise function based on this integer. Since the integer is passed as a compile-time constant, I'd expect that the compiler optimizes that branching away (and even if it doesn't, the cost of such a branch is fairly low, since all threads are always taking the same path through the code):
float FBM(uint noise)
{
...
float somevalue = 0.0f;
if(noise == 0)
somevalue = Random(x, y);
else
somevalue = Perlin(x, y);
...
}
void CSMain(uint3 id : SV_DispatchThreadID)
{
...
float result = FMB(1);
...
}
You could write your whole FBM() method as a preprocessor macro instead of a function (you can end a line in a #define with \ to have the macro spanning multiple lines). This is a bit more cumbersome, but your #undef and #define would work, as the inlining is then actually done by the preprocesor as well.
#define NOISE_SAMPLE Random(x, y)
#define FBM { \
... \
float somevalue = NOISE_SAMPLE; \
... \
result = ...; \
}
void CSMain(uint3 id : SV_DispatchThreadID)
{
float result = 0.0f;
...
#undef NOISE_SAMPLE
#define NOISE_SAMPLE Perlin(x, y)
FBM;
...
}
(Note that, with this approach, the compiler errors/warnings will never reference a line inside the FBM macro, but only ever the line(s) where the FBM macro is being called, so debugging these errors/warnings is slightly harder)
I have this piece of code which output is 4. I assumed the answer be 3 because of the pre-increment. Can anyone explain this??
#include<iostream>
#include<cstdio>
#define MAX(A,B) ((A>B)? A : B)
using namespace std;
int main()
{
int i=1,j=2,k;
k= MAX(++i,++j);
cout<<k;
return 0;
}
#define does not work like a function, think of it more like a find and replace so doing the macro expansion manually you get
int main()
{
int i=1,j=2,k;
k= ((++i > ++j) ? ++i : ++j);
cout<<k;
return 0;
}
This means you increment i and j once when you compare then, and increment the larger of the two another time before assigning it to k. I generally avoid including pre and post increment instructions inside of over logic since it is harder to reason about. You are better just incrementing i and j on their own lines before using them in MAX
Macros are not functions, they just perform text substitution pre-compile time. Your line of code becomes
k=((++i>++j)? ++i : ++j);
which clearly increments j twice.
It's called the conditional operator (or ternary operator) which is used in macro substitution
#define MAX(a,b) ((a) > (b) ? (a) : (b))
Means:
if ((a) > (b)){
return a;
} else {
return b;
}
So if you would do:
int test = MAX(5,10);
test would be 10
What's the difference in the outcome between call by reference and copy/restore?
Background: I'm currently studying distributed systems. Concerning the passing of reference parameters for remote procedure calls, the book states that: "the call by reference has been replaced by copy/restore. Although this is not always identical, it is good enough". I understand how call by reference and copy/restore work in principle, but I fail to see where a difference in the result may be?
Examples taken from here.
Main code:
#include <stdio.h>
int a;
int main() {
a = 3;
f( 4, &a );
printf("%d\n", a);
return 0;
}
Call by Value:
f(int x, int &y){
// x will be 3 as passed argument
x += a;
// now a is added to x so x will be 6
// but now nothing is done with x anymore
a += 2*y;
// a is still 3 so the result is 11
}
Value is passed in and has no effect on the value of the variable passed in.
Call by Reference:
f(int x, int &y){
// x will be 3 as passed argument
x += a;
// now a is added to x so x will be 6
// but because & is used x is the same as a
// meaning if you change x it will change a
a += 2*y;
// a is now 6 so the result is 14
}
Reference is passed in. Effectively the variable in the function is the same as the one outside.
Call with Copy/Restore:
int a;
void unsafe(int x) {
x= 2; //a is still 1
a= 0; //a is now 0
}//function ends so the value of x is now stored in a -> value of a is now 2
int main() {
a= 1;
unsafe(a); //when this ends the value of a will be 2
printf("%d\n", a); //prints 2
}
Value is passed in and has no effect on the value of the variable passed in UNTIL the end of the function, at which point the FINAL value of the function variable is stored in the passed in variable.
The basic difference between call by reference and copy/restore then is that changes made to the function variable will not show up in the passed in variable until after the end of the function while call by reference changes will be seen immediately.
Call by Copy/Restore is a special case of call-by-reference where the provided reference is unique to the caller. The final result on the referenced values will not be saved until the end of the function.
This type of calling is useful when a method in RPC called by reference. The actual data is sent to the server side and the final result will send to the client. This will reduce the traffic, since the server will not update the reference each time.
Call By Reference:
In call-by-reference, we pass a pointer to the called function. Any changes that happens to the data pointed by that pointer will be reflected immediately.
Suppose if there are numerous changes to be made to that data, while it wouldn’t incur much cost locally, it’ll be expensive in terms of network cost as for each change data will have to be copied back to the client.
C Code:
void addTwo(int *arr, int n){
for(int i=0;i<n;i++){
arr[i]+=2; //change is happening in the original data as well
}
}
int main(){
int arr[100]={1,2,3,...}; // assuming it to be initialised
addTwo(arr,100);
}
Call By Copy/Restore:
In call-by-copy/restore, the idea is that when the function is called with the reference to the data, only the final result of the changes made to the data is copied back to the original data(when the function is about to return) without making any changes to the original data during the function call, requiring only one transfer back to the client.
In the C code below, the data pointed by arr is copied in the function and stored back to arr after all the changes to the local data are finalised.
C Code:
void addTwo(int *arr, int n){
// copy data locally
larr = (int*)malloc(n*sizeof(int));
for(int i=0;i<n;i++){
larr[i]=arr[i];
}
for(int i=0;i<n;i++){
// change is happening to the local variable larr
larr[i]+=2;
}
//copy all the changes made to the local variable back to the original data
for(int i=0;i<n;i++){
arr[i]=larr[i];
}
}
int main(){
int arr[100]={1,2,3,...}; // assuming it to be initialised
addTwo(arr,100);
}
Note: Code shown above doesn’t represent actual RPC implementation, just an illustration of the concepts. In real RPC, complete data is passed in the message instead of pointers(addresses).
I have two cuda files say A and B.
I need to call a function from A to B like..
__device__ int add(int a, int b) //this is a function in A
{
return a+b;
}
__device__ void fun1(int a, int b) //this is a function in B
{
int c = A.add(a,b);
}
How can I do this??
Can I use static keyword? Please give me an example..
The short answer is that you can't. CUDA only supports internal linkage, thus everything needed to compile a kernel must be defined within the same translation unit.
What you might be able to do is put the functions into a header file like this:
// Both functions in func.cuh
#pragma once
__device__ inline int add(int a, int b)
{
return a+b;
}
__device__ inline void fun1(int a, int b)
{
int c = add(a,b);
}
and include that header file into each .cu file you need to use the functions. The CUDA built chain seems to honour the inline keyword and that sort of declaration won't generate duplicate symbols on any of the CUDA platforms I use (which doesn't include Windows). I am not sure whether it is intended to work or not, so cavaet emptor.
I think meanwhile there is a possibilty to solve it:
CUDA external class linkage and unresolved extern function in ptxas file
You can enable "Generate Relocateable Device Code" in VS Project Properies->CUDA C/C++->Common or use compiler parameter -rdc=true.
I'm using the STL function count_if to count all the positive values
in a vector of doubles. For example my code is something like:
vector<double> Array(1,1.0)
Array.push_back(-1.0);
Array.push_back(1.0);
cout << count_if(Array.begin(), Array.end(), isPositive);
where the function isPositive is defined as
bool isPositive(double x)
{
return (x>0);
}
The following code would return 2. Is there a way of doing the above
without writting my own function isPositive? Is there a built-in
function I could use?
Thanks!
std::count_if(v.begin(), v.end(), std::bind1st(std::less<double>(), 0)) is what you want.
If you're already using namespace std, the clearer version reads
count_if(v.begin(), v.end(), bind1st(less<double>(), 0));
All this stuff belongs to the <functional> header, alongside other standard predicates.
If you are compiling with MSVC++ 2010 or GCC 4.5+ you can use real lambda functions:
std::count_if(Array.begin(), Array.end(), [](double d) { return d > 0; });
I don't think there is a build-in function.
However, you could use boost lambda http://www.boost.org/doc/libs/1_43_0/doc/html/lambda.html
to write it :
cout << count_if(Array.begin(), Array.end(), _1 > 0);
cout<<std::count_if (Array.begin(),Array.end(),std::bind2nd (std::greater<double>(),0)) ;
greater_equal<type>() -> if >= 0