Software Archive
Read-only legacy content
17061 Discussions

Using Cilk reducer inside Cilker shared function

Jun
Beginner
692 Views

Hi I am trying to offload some parallel work to MIC using _Cilk_Shared and _Cilk_offload. 

I declare a Cilk shared function:

_Cilk_shared void somefun(int count)

 

In main I call this function using 

_Cilk_offload somefun(12) ;

inside this function everything is expected to be offloaded to MIC;

I want to declare a Cilk reducer inside somefun, so I can then use cilk_for and append to a cilk reducer list, 

but I get error:

error: illegal to declare an object of a class not marked _Cilk_shared, in a _Cilk_shared context
      cilk::reducer_list_append<int> rw;

 

I know I can do this with offload pragma so I should be able to this with cilk shared as well right?

I can't find concrete example of using _Cilk_shared and _Cilk_offload. 

Thanks in advance

0 Kudos
2 Replies
Hansang_B_Intel
Employee
692 Views

Hi,

I don't know how your code uses the reducer object in the offloaded function, but there is a list of rules when using _Cilk_offload and _Cilk_shared as described in https://software.intel.com/en-us/node/522499. Important rules for your code are:

  • When applied to a C++ class, all member functions are shared and all objects of that class type are shared.

  • Functions called from _Cilk_offload _Cilk_for must be shared.

For this reason, your will have to declare all member functions as "shared":

#pragma offload_attribute(push, _Cilk_shared)
#include <list>
#include <cilk/reducer_list.h>
#pragma offload_attribute(pop)

However, I don't think Cilk reducers are fully supported with _Cilk_shared keyword. I was not able to find a way to directly share a reduce_list object (e.g., by declaring it as a global _Cilk_shared variable), but the following one-directional use works fine:

#define N 16
#pragma offload_attribute(push, _Cilk_shared)
#include <list>
#include <cilk/reducer_list.h>
int host_list;
#pragma offload_attribute(pop)

#include <iostream>

_Cilk_shared
void dowork()
{
    cilk::reducer_list_append<int> list;
    _Cilk_for (int i = 0; i < N; ++i) {
        list->push_back(i);
    }
    // copies target's reducer data to the shared plain container (host_list).
    std::list<int> &lout = list.get_reference();
    std::copy(lout.begin(), lout.end(), host_list);
}

int main()
{
    _Cilk_offload dowork();
    for (int i = 0; i < N; ++i) {
        std::cout << host_list << std::endl;
    }
    return 0;
}

This example may not be optimal in performance, but should give an answer how to collect the target's computation result at least.

0 Kudos
Jun
Beginner
692 Views

Thank you for you help!. I realized it yesterday that I need to push the library as _Cilk_shared. 

Another question followed by this, I found that if I am using pragma offload_attributes with either _Cilk_shared or target(mic),  I should not define some librarys(cilk or iostream) outside of this pragma.

I ran into this problem where If I define iostream outside the pragma I will get a run time error of can not load library blablabla

For example the simple code I attached , if I uncomment line 2(#define <iostream>) in RegionF.cxx, I will get a run time error can not load library

compile:  icpc RegionF.cxx

I am not sure this is intended or some bugs?

I think I should open another threads in MIC topic. 

0 Kudos
Reply