I have a simple question. Is it possible to write structures of arrays like this with Alea.Gpu?
public struct SVDFactorsStructGpu
{
public deviceptr<float> ItemsBiases;
public deviceptr<float> UsersBiases;
public deviceptr<float> ItemsFeatures;
public deviceptr<float> UsersFeatures;
}
[...]
SVDFactorsStructGpu factors = new SVDFactorsStructGpu();
factors.ItemsBiases = gpuItemsBiases.Ptr;
factors.UsersBiases = gpuUsersBiases.Ptr;
factors.ItemsFeatures = gpuItemsFeatures.Ptr;
factors.UsersFeatures = gpuUsersFeatures.Ptr;
[...]
And pass them somehow like this to a kernel:
public void TrainEpochKernel(SVDParamsStructGpu svdParams,
deviceptr<float> ratings,
deviceptr<int> ratingsItemsIds,
deviceptr<int> userProfilesIds,
deviceptr<int> ratingsStartIdxs,
deviceptr<int> ratingsCounts,
deviceptr<float> userProfilesSSE,
SVDFactorsStructGpu factors)
{
int startUserProfileIdx = blockIdx.x * (blockDim.x * svdParams.StridePerThread) + threadIdx.x * svdParams.StridePerThread;
[...]
pred = svdParams.GlobalMean;
pred += factors.ItemsBiases[i];
pred += factors.UsersBiases[u];
[...]
This works without a structure but yields an illegal address when encapsulated.
Thanks in advance
[edit #1] It seems that the Ptr copy is in cause here, as if I try to pass them from the structure directly in the kernel signature the error is the same.
[edit #2] Maybe it is a very obvious question, I tried to pass the DeviceMemory<> directly but was unable to set values. I am going to keep the "one parameter for one array version" as it is not critical and got a very efficient algorithm overall. Was just curious to know more about Alea.Gpu C#.
Cf, comment above. Everything worked fine with the arrays. :)
Related
I'm building a publish-subscribe class (called SystermInterface), which is responsible to receive updates from its instances, and publish them to subscribers.
Adding a subscriber callback function is trivial and has no issues, but removing it yields an error, because std::function<()> is not comparable in C++.
std::vector<std::function<void()> subs;
void subscribe(std::function<void()> f)
{
subs.push_back(f);
}
void unsubscribe(std::function<void()> f)
{
std::remove(subs.begin(), subs.end(), f); // Error
}
I've came down to five solutions to this error:
Registering the function using a weak_ptr, where the subscriber must keep the returned shared_ptr alive.
Solution example at this link.
Instead of registering at a vector, map the callback function by a custom key, unique per callback function.
Solution example at this link
Using vector of function pointers. Example
Make the callback function comparable by utilizing the address.
Use an interface class (parent class) to call a virtual function.
In my design, all intended classes inherits a parent class called
ServiceCore, So instead of registering a callback function, just
register ServiceCore reference in the vector.
Given that the SystemInterface class has a field attribute per instance (ID) (Which is managed by ServiceCore, and supplied to SystemInterface by constructing a ServiceCore child instance).
To my perspective, the first solution is neat and would work, but it requires handling at subscribers, which is something I don't really prefer.
The second solution would make my implementation more complex, where my implementation looks as:
using namespace std;
enum INFO_SUB_IMPORTANCE : uint8_t
{
INFO_SUB_PRIMARY, // Only gets the important updates.
INFO_SUB_COMPLEMENTARY, // Gets more.
INFO_SUB_ALL // Gets all updates
};
using CBF = function<void(string,string)>;
using INFO_SUBTREE = map<INFO_SUB_IMPORTANCE, vector<CBF>>;
using REQINF_SUBS = map<string, INFO_SUBTREE>; // It's keyed by an iterator, explaining it goes out of the question scope.
using INFSRC_SUBS = map<string, INFO_SUBTREE>;
using WILD_SUBS = INFO_SUBTREE;
REQINF_SUBS infoSubrs;
INFSRC_SUBS sourceSubrs;
WILD_SUBS wildSubrs;
void subscribeInfo(string info, INFO_SUB_IMPORTANCE imp, CBF f) {
infoSubrs[info][imp].push_back(f);
}
void subscribeSource(string source, INFO_SUB_IMPORTANCE imp, CBF f) {
sourceSubrs[source][imp].push_back(f);
}
void subscribeWild(INFO_SUB_IMPORTANCE imp, CBF f) {
wildSubrs[imp].push_back(f);
}
The second solution would require INFO_SUBTREE to be an extended map, but can be keyed by an ID:
using KEY_T = uint32_t; // or string...
using INFO_SUBTREE = map<INFO_SUB_IMPORTANCE, map<KEY_T,CBF>>;
For the third solution, I'm not aware of the limitations given by using function pointers, and the consequences of the fourth solution.
The Fifth solution would eliminate the purpose of dealing with CBFs, but it'll be more complex at subscriber-side, where a subscriber is required to override the virtual function and so receives all updates at one place, in which further requires filteration of the message id and so direct the payload to the intended routines using multiple if/else blocks, which will increase by increasing subscriptions.
What I'm looking for is an advice for the best available option.
Regarding your proposed solutions:
That would work. It can be made easy for the caller: have subscribe() create the shared_ptr and corresponding weak_ptr objects, and let it return the shared_ptr.
Then the caller must not lose the key. In a way this is similar to the above.
This of course is less generic, and then you can no longer have (the equivalent of) captures.
You can't: there is no way to get the address of the function stored inside a std::function. You can do &f inside subscribe() but that will only give you the address of the local variable f, which will go out of scope as soon as you return.
That works, and is in a way similar to 1 and 2, although now the "key" is provided by the caller.
Options 1, 2 and 5 are similar in that there is some other data stored in subs that refers to the actual std::function: either a std::shared_ptr, a key or a pointer to a base class. I'll present option 6 here, which is kind of similar in spirit but avoids storing any extra data:
Store a std::function<void()> directly, and return the index in the vector where it was stored. When removing an item, don't std::remove() it, but just set it to std::nullptr. Next time subscribe() is called, it checks if there is an empty element in the vector and reuses it:
std::vector<std::function<void()> subs;
std::size_t subscribe(std::function<void()> f) {
if (auto it = std::find(subs.begin(), subs.end(), std::nullptr); it != subs.end()) {
*it = f;
return std::distance(subs.begin(), it);
} else {
subs.push_back(f);
return subs.size() - 1;
}
}
void unsubscribe(std::size_t index) {
subs[index] = std::nullptr;
}
The code that actually calls the functions stored in subs must now of course first check against std::nullptrs. The above works because std::nullptr is treated as the "empty" function, and there is an operator==() overload that can check a std::function against std::nullptr, thus making std::find() work.
One drawback of option 6 as shown above is that a std::size_t is a rather generic type. To make it safer, you might wrap it in a class SubscriptionHandle or something like that.
As for the best solution: option 1 is quite heavy-weight. Options 2 and 5 are very reasonable, but 6 is, I think, the most efficient.
I'm pretty much trying to make a AddInputEvent but, after a month, can't find a way to turn a local "function from FunctionCallbackInfo"(i'll just call this argf) in to a Persistent Function so that garbage collection doesn't erase the pointers.
Most stakeoverflow threads and example code I can find just say to Cast argf with a Local Function; then to throw that in to a Persistent New. This results in a error: cannot convert 'v8::Local<v8::Function>' to 'v8::Function*'
here is the code, not completely sure why I can't convert it
class inputevnt_feld{
public:
char* call_on;
v8::Persistent<v8::Function> func;
};
int entvcount = -1;
vector<inputevnt_feld> event_calls; //this is pretty much a array of events that we can call later
// in js looks like this "AddInputEvent("string", function);"
void AddInputEvent( const v8::FunctionCallbackInfo<v8::Value>& args ) {
v8::HandleScope handle_scope(args.GetIsolate());
//gotta make sure that we ain't letting in some trojan horse that has nothing in it
if (args[1]->IsFunction() && args[0]->IsString()) {
inputevnt_feld newt;
//converts js string to char array
v8::String::Utf8Value str(args.GetIsolate(), args[0]);
const char* cstr = ToCString(str);
newt.call_on = (char*)cstr;
//here is where the problem is with function casting
v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(args[1]);
newt.func = v8::Persistent<v8::Function>::New(args.GetIsolate(), callback);
//push the new stuff in to even array
event_calls.push_back(newt);
//getting vector array size is too much for my smol brain
//so I'ma just do this myself
entvcount++;
//cout << event_calls[entvcount].call_on << endl; //debug
}
}
Most stakeoverflow threads and example code I can find just say to Cast argf with a Local Function; then to throw that in to a Persistent New
Yes, that's correct. If you know how to read it, the C++ type system is your friend for figuring out the details.
If you look at the definition of v8::PersistentBase<T>::New, you'll see that it takes a T* (for its template type T). If you look at the v8::Local<T> class, you'll see that a way to get a T* from it is to use its operator*. That leads to:
v8::Local<v8::Function> callback = ...Cast(args[1]);
... = v8::Persistent<v8::Function>::New(..., *callback);
Alternatively, you can use the Persistent constructor directly, and pass it the Local without dereferencing it first:
v8::Local<v8::Function> callback = ...Cast(args[1]);
... = v8::Persistent<v8::Function>(..., callback);
Both options are entirely equivalent. Personally I'd prefer the latter as it takes slightly fewer characters to spell out, but that's really the only difference.
(Your current code as posted does something else: it ignores the result of the cast and passes the original args[1] directly to Persistent::New -- that's not going to work.)
Can I have pointers to user defined functions as the template type for atomic variables ? Something like this
class A
{
int d;
public:
void foo() { cout<<"Hellow wolrd!"; }
};
int main()
{
atomic<A*> ptrA;
//now how to call A::foo() from ptrA ?
}
You have two ways to call the method:
Method 1:
(*ptrA).foo();
Method 2
A* a = ptrA.load();
a->foo();
I don't know anything about your multi-threaded scenario to advise how best to avoid any pitfalls as you've not provided much information but the second way obviously allows you to guard against certain outcomes. Note also that the load method on std::atomic can accept a number of different memory ordering constraints.
I've been using JoSQL for quite a few months now and today I came across a problem I am not sure how to solve. I probably could solve it by binding variables/placeholders, but I'd like to include the fields in the query.
SELECT * FROM ...MyObject WHERE getType != com.mypackage.myclass.TYPE_A
This is the query that I have. TYPE_A is a public static final int attribute in "myclass" class. Accessing methods (such as getType) is easy, because getType is expected to be a method from MyObject - just that I do not write round brackets after it (this is how JoSQL works as far as I know).
Does anyone happen to have an idea how to access a public static final field?
JoSQL uses gentlyweb-utils; it seems to be some sort of Accessor/Getter/Setter framework. I'd love to access that attribute without having to bind variables, but I haven't been able to do so.
Thanks for your help in advance! I really appreciate it.
I think I have figured something out. First: it seems not possible to access the static variables for whatever reason. I've used the following approach to solve my issue:
create a method, which picks up a given JoSQL-statement
mark the constants, which you want to replace, by say "{?FULL_PACKAGE_AND$CONSTANT}"
use reflections to determine the column as well as the column (and value) from the field
iteratively replace the statement until no "{?"-values are available
Example:
JoSQL-statement looks like this:
(isWeapon = TRUE AND getItem.getType2 = {?com.l2jserver.gameserver.model.items.L2Item$TYPE2_WEAPON})
Method using the query-object:
final Query query = DataLayer.createJoSqlQuery(joSql);
Method (pre)processing the JoSQL-statement:
final Query query = new Query();
int variableColumn = 0;
while (joSql.indexOf("{?") > -1) {
variableColumn++;
final int startIndex = joSql.indexOf("{?");
final int endIndex = joSql.indexOf("}", startIndex);
final String value = joSql.substring(startIndex + 2, endIndex);
try {
final Object variableValue = Class.forName(value.split("\\$")[0]).getField(value.split("\\$")[1]).get(null);
query.setVariable(variableColumn, variableValue);
joSql = joSql.replace("{?" + value + "}", "?");
}
catch (...) {
e.printStackTrace();
}
}
query.parse(joSql);
return query;
The JoSQL-statement preprocessing method bascially iterates through a given JoSQL-statement and sees whether it contains the string "{?". If it does, it does some copy and paste (note the dollar-symbol right in front of the constant name).
Finally it creates the objects and sets them using something similar to prepared statements "setObject"-method. In the end it just replaces the values within the JoSQL-statement with question marks ("?") and sets a corresponding object in the newly created Query-object, which is later used to retrieve information.
I have a good idea on how this structure works and how to update it, however when it comes to work with Lazy Propagation I don't know what to do, as many many many problems requires this to pass in competitions I want to know how to make it work.
I am trying this problem on spoj: http://www.spoj.com/problems/CDC12_H/
If somebody can explain me how the lazy propagation can be adapted to this situation I will take that and work on the idea, I really don't want to post my code because the idea for me is to make this work by myself but with a little help.
I hope someone comes with the solution to my problem.
This is my snippet of segment tree implementation with lazy propagation.
Hope this will help you.
#define int long long
#define MAX 100005*3
int stree[MAX],lazy[MAX];
void update(int cur,int cur_lft,int cur_rgt,int st,int en,int val)
{
if(cur_lft>en || cur_rgt<st) return ;
if(cur_lft>=st && cur_rgt<=en)
{
stree[cur]+=val*(cur_rgt-cur_lft+1);
lazy[cur]+=val;
return;
}
int l=cur<<1,r=(cur<<1)+1,mid=(cur_lft+cur_rgt)>>1;
update(l,cur_lft,mid,st,en,val);
update(r,mid+1,cur_rgt,st,en,val);
stree[cur]=stree[l]+stree[r]+lazy[cur]*(cur_rgt-cur_lft+1);
}
int query(int cur,int cur_lft,int cur_rgt,int st,int en,int lzy)
{
if(cur_lft>en || cur_rgt<st) return 0;
if(cur_lft>=st && cur_rgt<=en) return stree[cur]+lzy*(cur_rgt-cur_lft+1);
int l=cur<<1,r=(cur<<1)+1,mid=(cur_lft+cur_rgt)>>1;
int left_tree=query(l,cur_lft,mid,st,en,lzy+lazy[cur]);
int right_tree=query(r,mid+1,cur_rgt,st,en,lzy+lazy[cur]);
return left_tree+right_tree;
}
Edit
To update and query into segment tree we can call following functions:
query(1,0,n-1,lower_range,upper_range,0));
update(1,0,n-1,lower_range,upper_range,v);