I have a buffer that pass the mouse position to the
kernel void compute(texture2d<float, access::write> output [[texture(0)]],
constant float2 &mouse [[buffer(1)]],//<-- mouse buffer
uint2 gid [[thread_position_in_grid]])
{
...
}
How can I make it as global constant so that I can access it in any function outside of kernel? For example:
float abc(float p){
float a = p * globalmouseposition.x;
return a;
}
Metal doesn't support mutable global variables. You should pass the necessary values as parameters to all of the functions that use them. There are other approaches (such as wrapping all of your functions in a struct or class and using member variables to simulate global variables), but I recommend just passing down the values you need from function to function.
Related
Consider the following Dart code:
class Vec2 {
num x, y;
Vec2(this.x, this.y);
Vec2 operator*(num rhs) => Vec2(x * rhs, y * rhs);
String toString() => "<$x, $y>";
}
void main() => print(Vec2(1, 2) * 3);
The output is as expected:
<3, 6>
However, this only works when the left-hand side of the expression is a Vec2 and the right-hand side is a num. In this case, I want the multiplication operator to be commutative, so I write the following extension:
extension Vec2Util on num {
Vec2 operator*(Vec2 rhs) => Vec2(rhs.x * this, rhs.y * this);
}
One might naturally expect the following code to produce identical output to the first snippet:
void main() {
num x = 3;
print("${x * Vec2(1, 2)}");
}
However, the compiler is instead reporting that The argument type 'Vec2' can't be assigned to the parameter type 'num'. It looks as though the compiler is resolving the multiplication to num operator*(num rhs) in this case and then complaining that my Vec2 can't be passed in as a num operand. Why does the compiler apparently disregard my extension? What is the correct way to create custom commutative operators like this?
You cannot do what you want.
Dart user-definable binary operators are all methods on the first operand. Doing e1 + e2 is kind-of like doing e1.+(e2) where + is the name of the method, except you can't normally call a method +.
In order to be able to do 3 * vector, you need the method to be on 3.
You can't add methods to other people's classes, not without fiddling with their source code, and int is a system class so even that is not possible.
You cannot use extension methods because extension methods do not apply when the receiver type already has an instance method with the same name.
And int defines all the operators.
(It's like, and definitely not coincidentally, that the user-definable operators were chosen from exactly what int needs. That's not new in Dart, the operators go back to C and Java.)
So, you can define an extension method on int, but you can't call it anyway, not without an override:
extension MyInt on int {
Vector operator *(Vector other) => other.scalerMultiplication(this);
}
... MyInt(3) * vector ...
That's more complication than just swapping the operands.
typedef (void (^blockType)());
I need cast blocks with different argument types into a same type blockType, and invoke it as the original type later. But there is a issue while casting block type.
The following code works well with any argument type, ...
((blockType)^(BOOL b) {
NSLog(#"BOOL: %d", b);
})(YES); // >> BOOL: 1
((blockType)^(int i) {
NSLog(#"int: %d", i);
})(1); // >> int: 1
((blockType)^(double f) {
NSLog(#"double: %f", f);
})(1.0 / 3); // >> double: 0.333333
((blockType)^(NSString *s) {
NSLog(#"NSString *: %#", #"string");
})(1.0 / 3); // >> NSString *: string
except float:
((blockType)^(float f) {
NSLog(#"float: %f", f);
})(1.0f); // >> float: 0.000000
((blockType)^(float f) {
NSLog(#"float: %f", f);
})(1.0f / 3); // >> float: 36893488147419103232.000000
but it is ok without casting:
(^(float f) {
NSLog(#"float without casting: %f", f);
})(1.0 / 3); // >> float without casting: 0.333333
how to explain and resolve it?
It appears to be a taint of the good old C language. Consider the following code (we can say it is kind of 'translation' of your Obj-C block with issues to C as far as blocks are related to function pointers (see here)):
void test()
{
void (*pEmpty)();
pEmpty = functionFloat;
pEmpty(1.0f / 3);
}
void functionFloat(float f)
{
printf("float: %f", f);
}
If you call test you will see the same result as when you invoke your 'sick' block. Compiler will provide just a warning about incompatible pointers and will let you run. But if you change
void (*pEmpty)();
to
void (*pEmpty)(void);
there will be a compile-time error. Same will happen if you add void explicitly to your void-blocks, e.g. (void (^)(void) instead of (void (^)().
The reason for such behavior explained in the C Standard:
The empty list in a function declarator that is not part of a
definition of that function specifies that no information about the number or types of the
parameters is supplied.§6.7.6.3-14 (p.134)
Thus, as it doesn't mean that there are no parameters but rather no info about them, cast passes fine.
The problem with unexpected output is the following:
A pointer to a function of one type may be converted to a pointer to a function of another
type and back again; the result shall compare equal to the original pointer. If a converted
pointer is used to call a function whose type is not compatible with the referenced type,
the behavior is undefined.§6.3.2.3-8 (p.56)
and
If the function is defined with a type that is not compatible with the type (of the
expression) pointed to by the expression that denotes the called function, the behavior is
undefined.§6.5.2.2-9 (p.82)
So, it seems that the solution here is just like #jtbandes said: don't mess block types and re-design this part of code to avoid such casts.
Explain: Calling the block as blockType- (void (^)()), the block is treated as (void (^)(double)).
Resolve: Must cast the block back to (void (^)(float)) when invoking.
Does Rascal support function pointers or something like this to do this like Java Interfaces?
Essentially I want to extract specific (changing) logic from a common logic block as separate functions. The to be used function is passed to the common block, which then call this function. In C we can do this with function pointers or with Interfaces in Java.
First I want to know how this general concept is called in the language design world.
I checked the Rascal Function Helppage, but this provide no clarification on this aspect.
So e.g. I have:
int getValue(str input) {
.... }
int getValue2(str input){
... }
Now I want to say:
WhatDatatype? func = getValue2; // how to do this?
Now I can pass this to an another function and then:
int val = invoke_function(func,"Hello"); // how to invoke?, and pass parameters and get ret value
Tx,
Jos
This page in the tutor has an example of using higher-order functions, which are the Rascal feature closest to function pointers:
http://tutor.rascal-mpl.org/Rascal/Rascal.html#/Rascal/Concepts/Functions/Functions.html
You can define anonymous (unnamed) functions, called closures in Java; assign them to variables; pass them as arguments to functions (higher-order functions); etc. Here is an example:
rascal>myfun = int(int x) { return x + 1; };
int (int): int (int);
rascal>myfun;
int (int): int (int);
rascal>myfun(3);
int: 4
rascal>int applyIntFun(int(int) f, int x) { return f(x); }
int (int (int), int): int applyIntFun(int (int), int);
rascal>applyIntFun(myfun,10);
int: 11
The first command defines an increment function, int(int x) { return x + 1; }, and assigns this to variable myfun. The rest of the code would work the same if instead this was
int myfun(int x) { return x + 1; }
The second command just shows the type, which is a function that takes and returns int. The third command calls the function with value 3, returning 4. The fourth command then shows a function which takes a function as a parameter. This function parameter, f, will then be called with argument x. The final command just shows an example of using it.
I know that const is compile-time constant in dart, but I don't understand mechanism behind const [F0, F1, F2] in the following code:
class Foo {
static const F0 = 'F0';
static const F1 = 'F1';
static const F2 = 'F2';
// const list of const values I guess...
static const CONST_LIST = const [F0, F1, F2]; // please explain this line
static final String FOO = CONST_LIST[0]; // ok
// compile error: 'const' varaibles must be constant value
// static const String BAR = CONST_LIST[1];
}
main() {
// is CONST_LIST const or not?
// below line it's ok for dartanalyzer but
// in runtime: Cannot change the content of an unmodifiable List
Foo.CONST_LIST[1] = 'new value';
}
I noticed that const is required by dart analyzer in const [F0, F1, F2]; but it does make list more like final (runtime immutable list) rather than compile time const.
UPDATE:
Another question is why CONST_LIST[1] is not "constant value". See commented declaration of Foo.BAR.
Günter has answered the second part of your question. Here is some more information about const.
Const means that the object's entire deep state can be determined entirely at compile time and that the object will be frozen and completely immutable.
More information in this article. Also see the following question.
Regarding the second part of your question, consider the following:
const int foo = 10 * 10;
The expression "10 * 10" can be evaluated at compile time, so it is a "constant expression". The types of things you can do in a constant expression need to be quite limited (otherwise you could run arbitrary Dart code in the compiler!). But some of these limitations are being relaxed as dart matures, as you can see in the bug which Günter linked to.
In contrast, consider the following:
final int bar = 10;
final int foo = bar * bar;
Since "bar * bar" is not a constant expression it is evaluated at runtime.
There is an open bug for this: see https://github.com/dart-lang/sdk/issues/3059
Type Aliases do not provide compile-time type checking
Type aliases are very handy for shortening long type names. Type alias' are just syntatic sugar and are compiled into the aliased type at run-time, meaning two different aliases representing the same type can be used interchangeably without error:
type foo = int
type bar = int
let x : foo = 5
let y : bar = x
type foo = int
type bar = int
val x : foo = 5
val y : bar = 5
I understand why you wouldn't want to treat them as regular types with compile-time type enforcement. Still, in some scenarios, it would be very handy.
Sometimes, I need to differentiate between ints which represent different things
For example, I am importing some functions from a COM library that has several different kinds of values, but they are all represented as ints in my code:
[<DllImport(#"C:\API\COMAPI.dll", EntryPoint="Foobar")>]
extern int Foobar ( int hPool, int hServer )
In C, hPool is of type APIP and hServer and the function return type are both APIV:
typedef unsigned long API_INDEX; // index
typedef API_INDEX * APIV; // value handle
typedef void * APIP; // pool handle
I would like to represent these different types, representing different things, with different types that provide some compile-time type enforcement. That way, I can't accidentally pass an APIP to a function expecting an APIV.
Measures get me half-way there, but require a LOT of extra fluff
So far, the only solution I've found is to use measurements:
type [<Measure>] APIP
type [<Measure>] APIV
Unfortunately, it seems that measures cannot be added directly to externs:
[<DllImport(#"C:\API\COMAPI.dll", EntryPoint="Foobar")>]
extern int<APIV> _Foobar ( int<APIP> hPool, int<APIV> hServer )
error FS0010: Unexpected type application in extern declaration. Expected identifier or other token.
So I am having to write a wrapper function, resulting in a LOT of extra code:
[<DllImport(#"C:\API\COMAPI.dll", EntryPoint="Foobar")>]
extern int private _Foobar ( int hPool, int hServer )
let Foobar ( hPool : int<APIP> ) ( hServer : int<APIV> ) : APIV =
_Foobar( int hPool, int hServer ) |> LanguagePrimitives.Int32WithMeasure
Multiplied by dozens and dozens of imported functions, this is getting really bloated and tiresome.
Is there a more intuitive way to handle this, or am I stuck deciding between compile-time type checking and reasonably readable code?