parameterized task to swap two values in SystemVerilog - swap

I want to write a generic-width swap, but I'm not sure what the syntax should be.
My first guess:
task automatic swap #( int W=1 ) ( ref logic [W-1:0] a, ref logic [W-1:0] b );
begin
automatic logic[W-1:0] temp=a; a=b; b=temp;
end endtask
But I get the following error (from Cadence irun):
ncvlog: *E,SVNOCS: Class specialization syntax not allowed in method name for out-of-block method declaration.
Also, what is the syntax to invoke such a task?

Tasks and functions cannot have their own parameters. You can achieve the same effect by declaring a static method in a parameterized class. The methods can be made more generic by making the parameter a data type instead of a bit width. Example:
class generic #(type T=logic);
// Note: you may want to replace 'ref' with 'inout'
static function void swap( ref T a, b );
{b,a} = {a,b};
endfunction
endclass
Then somewhere in your code, you can do this like:
generic#(logic[4:0])::swap( my_a, my_b);
generic#(int)::swap( my_int_a, my_int_b);
generic#(my_struct_st)::swap( my_struct_a, my_struct_b);
generic#(my_class)::swap( my_class_a, my_class_b);
generic#(virtural my_interface)::swap( my_if_a, my_if_b);

Related

Is it bad practice to provide your own setter or should I use setproperty?

Suppose if I had the following Employee struct:
mutable struct Employee
_id::Int64
_first_name::String
_last_name::String
function Employee(_id::Int64,_first_name::String,_last_name::String)
# validation left out.
new(_id,_first_name,_last_name)
end
end
If I wanted to implement my own setproperty!() I can do:
function setproperty!(value::Employee,name::Symbol,x)
if name == :_id
if !isa(x,Int64)
throw(ErrorException("ID type is invalid"))
end
setfield!(value,:_id,x)
end
if name == :_first_name
if is_white_space(x)
throw(ErrorException("First Name cannot be blank!"))
end
setfield!(value,:_first_name,x)
end
if name == :_last_name
if is_white_space(x)
throw(ErrorException("Last Name cannot be blank!"))
end
setfield!(value,:_last_name,x)
end
end
Have I implemented setproperty!() correctly?
The reason why I use setfield!() for _first_name and _last_name, is because if I do:
if name == :_first_name
setproperty!(value,:_first_name,x) # or value._first_name = x
end
it causes a StackOverflowError because it's recursively using setproperty!().
I don't really like the use of setproperty!(), because as the number of parameters grows, so would setproperty!().
It also brings to mind using Enum and if statements (only we've switched Enum with Symbol).
One workaround I like, is to document that the fields are meant to be private and use the provided setter to set the field:
function set_first_name(obj::Employee,first_name::AbstractString)
# Validate first_name before assigning it.
obj._first_name = first_name
end
The function is smaller and has a single purpose.
Of course this doesn't prevent someone from using setproperty!(), setfield!() or value._field_name = x, but if you're going to circumvent the provided setter then you'll have the handle the consequences for doing it.
Of course this doesn't prevent someone from using setproperty!(), setfield!() or value._field_name = x, but if you're going to circumvent the provided setter then you'll have the handle the consequences for doing it.
I would recommend you to do this, defining getter,setter functions, instead of overloading getproperty/setproperty!. on the wild, the main use i saw on overloading getproperty/setproperty! is when fields can be calculated from the data. for a getter/setter pattern, i recommend you to use the ! convention:
getter:
function first_name(value::Employee)
return value._first_name
end
setter:
function first_name!(value::Employee,text::String)
#validate here
value._first_name = text
return value._first_name
end
if your struct is mutable, it could be that some fields are uninitialized. you could add a getter with default, by adding a method:
function first_name(value::Employee,default::String)
value_stored = value._first_name
if is_initialized(value_stored) #define is_initialized function
return value_stored
else
return default
end
end
with a setter/getter with default, the only difference between first_name(val,text) and first_name!(val,text) would be the mutability of val, but the result is the same. useful if you are doing mutable vs immutable functions. as you said it, the getproperty/setproperty! is cumbersome in comparison. If you want to disallow accessing the fields, you could do:
Base.getproperty(val::Employee,key::Symbol) = throw(error("use the getter functions instead!")
Base.setproperty!(val::Employee,key::Symbol,x) = throw(error("use the setter functions instead!")
Disallowing the syntax sugar of val.key and val.key = x. (if someone really want raw access, there is still getfield/setfield!, but they were warned.)
Finally, i found this recomendation in the julia docs, that recommends getter/setter methods over direct field access
https://docs.julialang.org/en/v1/manual/style-guide/#Prefer-exported-methods-over-direct-field-access

Can a pure function change input arguments?

Is a function that changes the values of an input argument still a pure function?
My example (Kotlin):
data class Klicker(
var id: Long = 0,
var value: Int = 0
)
fun Klicker.increment() = this.value++
fun Klicker.decrement() = this.value--
fun Klicker.reset() {
this.value = 0
}
Wikipedia says a pure function has these two requirements:
The function always evaluates the same result value given the same argument value(s). The function result value cannot depend on any hidden information or state that may change while program execution proceeds or between different executions of the program, nor can it depend on any external input from I/O devices.
Evaluation of the result does not cause any semantically observable side effect or output, such as mutation of mutable objects or output to I/O devices.
From my understanding, all functions from my example comply with the first requirement.
My uncertainty starts with the second requirement. With the change of the input argument, I mutate an object (rule violation), but this object is not outside of the function scope, so maybe no rule violation?
Also, does a pure function always need to return a completely new value?
I presume, this function is considert 100% pure:
fun pureIncrement(klicker: Klicker): Klicker {
return klicker.copy(value = klicker.value++)
}
Be gentle, this is my first Stackoverflow question.
The increment and decrement functions fulfill neither of the requirements for a pure function. Their return value depends on the state of the Klicker class, which may change while program execution proceeds, so the first requirement is not fulfilled. The evaluation of the result mutates the mutable Klicker instance, so the second requirement is also not fulfilled. It doesn't matter in which scope the mutable data is; a pure function must not mutate any data at all.
The reset function violates only the second requirement.
The pureIncrement function can be made pure if you change it to:
fun pureIncrement(klicker: Klicker): Klicker {
return klicker.copy(value = klicker.value + 1)
}

Java 8 Functional Programming - Passing function along with its argument

I have a question on Java 8 Functional Programming. I am trying to achieve something using functional programming, and need some guidance on how to do it.
My requirement is to wrap every method execution inside timer function which times the method execution. Here's the example of timer function and 2 functions I need to time.
timerMethod(String timerName, Function func){
timer.start(timerName)
func.apply()
timer.stop()
}
functionA(String arg1, String arg2)
functionB(int arg1, intArg2, String ...arg3)
I am trying to pass functionA & functionB to timerMethod, but functionA & functionB expects different number & type of arguments for execution.
Any ideas how can I achieve it.
Thanks !!
you should separate it into two things by Separation of Concerns to make your code easy to use and maintaining. one is timing, another is invoking, for example:
// v--- invoking occurs in request-time
R1 result1 = timerMethod("functionA", () -> functionA("foo", "bar"));
R2 result2 = timerMethod("functionB", () -> functionB(1, 2, "foo", "bar"));
// the timerMethod only calculate the timing-cost
<T> T timerMethod(String timerName, Supplier<T> func) {
timer.start(timerName);
try {
return func.get();
} finally {
timer.stop();
}
}
IF you want to return a functional interface rather than the result of that method, you can done it as below:
Supplier<R1> timingFunctionA =timerMethod("A", ()-> functionA("foo", "bar"));
Supplier<R2> timingFunctionB =timerMethod("B", ()-> functionB(1, 2, "foo", "bar"));
<T> Supplier<T> timerMethod(String timerName, Supplier<T> func) {
// v--- calculate the timing-cost when the wrapper function is invoked
return () -> {
timer.start(timerName);
try {
return func.get();
} finally {
timer.stop();
}
};
}
Notes
IF the return type of all of your functions is void, you can replacing Supplier with Runnable and then make the timerMethod's return type to void & remove return keyword from timerMethod.
IF some of your functions will be throws a checked exception, you can replacing Supplier with Callable & invoke Callable#call instead.
Don't hold onto the arguments and then pass them at the last moment. Pass them immediately, but delay calling the function by wrapping it with another function:
Producer<?> f1 =
() -> functionA(arg1, arg2);
Producer<?> f2 =
() -> functionB(arg1, arg2, arg3);
Here, I'm wrapping each function call in a lambda (() ->...) that takes 0 arguments. Then, just call them later with no arguments:
f1()
f2()
This forms a closure over the arguments that you supplied in the lambda, which allows you to use the variables later, even though normally they would have been GC'd for going out of scope.
Note, I have a ? as the type of the Producer since I don't know what type your functions return. Change the ? to the return type of each function.
Introduction
The other answers show how to use a closure to capture the arguments of your function, no matter its number. This is a nice approach and it's very useful, if you know the arguments in advance, so that they can be captured.
Here I'd like to show two other approaches that don't require you to know the arguments in advance...
If you think it in an abstract way, there are no such things as functions with multiple arguments. Functions either receive one set of values (aka a tuple), or they receive one single argument and return another function that receives another single argument, which in turn returns another one-argument function that returns... etc, with the last function of the sequence returning an actual result (aka currying).
Methods in Java might have multiple arguments, though. So the challenge is to build functions that always receive one single argument (either by means of tuples or currying), but that actually invoke methods that receive multiple arguments.
Approach #1: Tuples
So the first approach is to use a Tuple helper class and have your function receive one tuple, either a Tuple2 or Tuple3:
So, the functionA of your example might receive one single Tuple2<String, String> as an argument:
Function<Tuple2<String, String>, SomeReturnType> functionA = tuple ->
functionA(tuple.getFirst(), tuple.getSecond());
And you could invoke it as follows:
SomeReturnType resultA = functionA.apply(Tuple2.of("a", "b"));
Now, in order to decorate the functionA with your timerMethod method, you'd need to do a few modifications:
static <T, R> Function<T, R> timerMethod(
String timerName,
Function<? super T, ? extends R> func){
return t -> {
timer.start(timerName);
R result = func.apply(t);
timer.stop();
return result;
};
}
Please note that you should use a try/finally block to make your code more robust, as shown in holi-java's answer.
Here's how you might use your timerMethod method for functionA:
Function<Tuple2<String, String>, SomeReturnType> timedFunctionA = timerMethod(
"timerA",
tuple -> functionA(tuple.getFirst(), tuple.getSecond());
And you can invoke timedFunctionA as any other function, passing it the arguments now, at invocation time:
SomeReturnType resultA = timedFunctionA.apply(Tuple2.of("a", "b"));
You can take a similar approach with the functionB of your example, except that you'd need to use a Tuple3<Integer, Integer, String[]> for the argument (taking care of the varargs arguments).
The downside of this approach is that you need to create many Tuple classes, i.e. Tuple2, Tuple3, Tuple4, etc, because Java lacks built-in support for tuples.
Approach #2: Currying
The other approach is to use a technique called currying, i.e. functions that accept one single argument and return another function that accepts another single argument, etc, with the last function of the sequence returning the actual result.
Here's how to create a currified function for your 2-argument method functionA:
Function<String, Function<String, SomeReturnType>> currifiedFunctionA =
arg1 -> arg2 -> functionA(arg1, arg2);
Invoke it as follows:
SomeReturnType result = currifiedFunctionA.apply("a").apply("b");
If you want to decorate currifiedFunctionA with the timerMethod method defined above, you can do as follows:
Function<String, Function<String, SomeReturnType>> timedCurrifiedFunctionA =
arg1 -> timerMethod("timerCurryA", arg2 -> functionA(arg1, arg2));
Then, invoke timedCurrifiedFunctionA exactly as you'd do with any currified function:
SomeReturnType result = timedCurrifiedFunctionA.apply("a").apply("b");
Please note that you only need to decorate the last function of the sequence, i.e. the one that makes the actual call to the method, which is what we want to measure.
For the method functionB of your example, you can take a similar approach, except that the type of the currified function would now be:
Function<Integer, Function<Integer, Function<String[], SomeResultType>>>
which is quite cumbersome, to say the least. So this is the downside of currified functions in Java: the syntax to express their type. On the other hand, currified functions are very handy to work with and allow you to apply several functional programming techniques without needing to write helper classes.

gcl_memcpy auto detection of pointer types

I have a trivial kernel running on OS X that returns a single int. The essential bits are:
cl_int d;
cl_int* dptr = &d;
void* dev_d = gcl_malloc(sizeof(cl_int),NULL,CL_MEM_WRITE_ONLY);
// ... stuff to setup dispatch queue
dispatch_sync(queue, ^{
// ... running the kernel stuff
gcl_memcpy((void*)&d, dev_d, sizeof(cl_int)); // this gives d==0
gcl_memcpy((void*)dptr, dev_d, sizeof(cl_int)); // this gives correct d
});
Question is, what is the difference between &d and dptr? I've always thought of them as essentially interchangeable, but gcl_memcpy seems to be making a distinction. Any ideas? I can obviously just use the dptr solution, but I'm still curious what's happening.
I don't think this has to do with the gcl_memcpy call specifically. I think it has to do with your GCD call.
When you call dispatch_sync, your block gets a copy of the variables you use in it. In fact, in similar situations, I get a warning from my compiler about using &d in the block, since it's probably a common mistake.
So in your main function you have a variable d at Address1 with value 0 and a variable dptr at Address2 with value Address1. In your dispatch block you have a variable d at Address3 with value 0 and a variable dptr at Address4 with value Address1. So when you write to &d within your dispatch block, you are putting the value in Address3 which you won't see outside of your dispatch block. When you write to dptr in your dispatch block, you are putting the value in Address1, which is what you expect.
Or to put it another way, your call to dispatch_queue is like calling a function defined like
void myfunction(cl_int d, cl_int* dptr).
If you're skeptical of my answer, I suggest you try this with a simple assignment instead of the gcl_malloc call.

Passing strings as task creation discriminants in Ada

I'm moving my first steps with Ada, and I'm finding that I struggle to understand how to do common, even banal, operations that in other languages would be immediate.
In this case, I defined the following task type (and access type so I can create new instances):
task type Passenger(
Name : String_Ref;
Workplace_Station : String_Ref;
Home_Station : String_Ref
);
type Passenger_Ref is access all Passenger;
As you can see, it's a simple task that has 3 discriminants that can be passed to it when creating an instance. String_Ref is defined as:
type String_Ref is access all String;
and I use it because apparently you cannot use "normal" types as task discriminants, only references or primitive types.
So I want to create an instance of such a task, but whatever I do, I get an error. I cannot pass the strings directly by simply doing:
Passenger1 := new Passenger(Name => "foo", Workplace_Station => "man", Home_Station => "bar");
Because those are strings and not references to strings, fair enough.
So I tried:
task body Some_Task_That_Tries_To_Use_Passenger is
Passenger1 : Passenger_Ref;
Name1 : aliased String := "Foo";
Home1 : aliased String := "Man";
Work1 : aliased String := "Bar";
begin
Passenger1 := new Passenger(Name => Name1'Access, Workplace_Station => Work1'Access, Home_Station => Home1'Access);
But this doesn't work either, as, from what I understand, the Home1/Name1/Work1 variables are local to task Some_Task_That_Tries_To_Use_Passenger and so cannot be used by Passenger's "constructor".
I don't understand how I have to do it to be honest. I've used several programming languages in the past, but I never had so much trouble passing a simple String to a constructor, I feel like a total idiot but I don't understand why such a common operation would be so complicated, I'm sure I'm approaching the problem incorrectly, please enlighten me and show me the proper way to do this, because I'm going crazy :D
Yes, I agree it is a serious problem with the language that discriminates of task and record types have to be discrete. Fortunately there is a simple solution for task types -- the data can be passed via an "entry" point.
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
procedure Main is
task type Task_Passenger is
entry Construct(Name, Workplace, Home : in String);
end Passenger;
task body Task_Passenger is
N, W, H : Unbounded_String;
begin
accept Construct(Name, Workplace, Home : in String) do
N := To_Unbounded_String(Name);
W := To_Unbounded_String(Workplace);
H := To_Unbounded_String(Home);
end Construct;
--...
end Passenger;
Passenger : Task_Passenger;
begin
Passenger.Construct("Any", "length", "strings!");
--...
end Main;
Ada doesn't really have constructors. In other languages, a constructor is, in essence, a method that takes parameters and has a body that does stuff with those parameters. Trying to get discriminants to serve as a constructor doesn't work well, since there's no subprogram body to do anything with the discriminants. Maybe it looks like it should, because the syntax involves a type followed by a list of discriminant values in parentheses and separated by commas. But that's a superficial similarity. The purpose of discriminants isn't to emulate constructors.
For a "normal" record type, the best substitute for a constructor is a function that returns an object of the type. (Think of this as similar to using a static "factory method" instead of a constructor in a language like Java.) The function can take String parameters or parameters of any other type.
For a task type, it's a little trickier, but you can write a function that returns an access to a task.
type Passenger_Acc is access all Passenger;
function Make_Passenger (Name : String;
Workplace_Station : String;
Home_Station : String) return Passenger_Acc;
To implement it, you'll need to define an entry in the Passenger task (see Roger Wilco's answer), and then you can use it in the body:
function Make_Passenger (Name : String;
Workplace_Station : String;
Home_Station : String) return Passenger_Acc is
Result : Passenger_Acc;
begin
Result := new Passenger;
Result.Construct (Name, Workplace_Station, Home_Station);
return Result;
end Make_Passenger;
(You have to do this by returning a task access. I don't think you can get the function to return a task itself, because you'd have to use an extended return to set up the task object and the task object isn't activated until after the function returns and thus can't accept an entry.)
You say
"I don't understand how I have to do it to be honest. I've used several programming languages in the past, but I never had so much trouble passing a simple String to a constructor, I feel like a total idiot but I don't understand why such a common operation would be so complicated, I'm sure I'm approaching the problem incorrectly, please enlighten me and show me the proper way to do this, because I'm going crazy :D"
Ada's access types are often a source of confusion. The main issue is that Ada doesn't have automatic garbage collection, and wants to ensure you can't suffer from the problem of returning pointers to local variables. The combination of these two results in a curious set of rules that force you to design your solution carefully.
If you are sure your code is good, then you can always used 'Unrestricted_Access on an aliased String. This puts all the responsibility on you to ensure the accessed variable won't disappear from underneath the task though.
It doesn't have to be all that complicated. You can use an anonymous access type and allocate the strings on demand, but please consider if you really want the strings to be discriminants.
Here is a complete, working example:
with Ada.Text_IO;
procedure String_Discriminants is
task type Demo (Name : not null access String);
task body Demo is
begin
Ada.Text_IO.Put_Line ("Demo task named """ & Name.all & """.");
exception
when others =>
Ada.Text_IO.Put_Line ("Demo task terminated by an exception.");
end Demo;
Run_Demo : Demo (new String'("example 1"));
Second_Demo : Demo (new String'("example 2"));
begin
null;
end String_Discriminants;
Another option is to declare the strings as aliased constants in a library level package, but then you are quite close to just having an enumerated discriminant, and should consider that option carefully before discarding it.
I think another solution would be the following:
task body Some_Task_That_Tries_To_Use_Passenger is
Name1 : aliased String := "Foo";
Home1 : aliased String := "Man";
Work1 : aliased String := "Bar";
Passenger1 : aliased Passenger(
Name => Name1'Access,
Workplace_Station => Work1'Access,
Home_Station => Home1'Access
);
begin
--...

Resources