Software Archive
Read-only legacy content
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
17060 Discussions

Using Cilk reducer inside Cilker shared function

Jun
Beginner
870 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
870 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
870 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