cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
NellyWu
Visitor
Visitor
261 Views
Registered: ‎06-03-2021

Question regarding Multi-Process Support

Hi @ViratAgarwal 

Below is my code snippet, let me describe the issue in detail.

[Issue description]:

I create two kernels (i.e ‘testkernel’ and ‘testkernel_1’) , each kernel has 15 compute units, if I run below scenario 1, everything looks fine. However, if I run below scenario 2, sometimes we can see incorrect data result returned by kernel calculation.

<Scenario 1>:

[Publisher]:

  1. [Publisher 1]: Create a shell to run “HelloWorldExampleTCP” application, it will create multiple publisher threads and call KernelTestFunc() while sending data

 

[Subscriber]:

  1. [Subscriber 1]: Create another shell to run “HelloWorldExampleTCP” application, it will create multiple publisher threads and call KernelTestFunc() while receiving data

 

<Scenario 2>:

[Publisher]:

  1. [Publisher 1]: Create a shell to run “HelloWorldExampleTCP” application, it will create multiple publisher threads and call KernelTestFunc() while sending data
  2. [Publisher 2]: Create another shell to run “HelloWorldExampleTCP” application, it will create multiple publisher threads and call KernelTestFunc() while sending data

 

[Subscriber]:

  1. [Subscriber 1]: Create another shell to run “HelloWorldExampleTCP” application, it will create multiple publisher threads and call KernelTestFunc() while receiving data
  2. [Subscriber 2]: Create another shell to run “HelloWorldExampleTCP” application, it will create multiple publisher threads and call KernelTestFunc() while receiving data

 

#define num_cu 15
cl::Kernel krnl[num_cu];
cl::CommandQueue q;

//testkernel: for publisher
//testkernel_1: for subscriber
const char* krnl_names[] = {"testkernel", "testkernel_1"};

int Init_OpenCL(char* xclbinFilename, int role){
    cl_int err;
    //Setting XCL_MULTIPROCESS_MODE
    std::cout << "Set the env variable for Multi Process Support (MPS)"
              << std::endl;
    char mps_env[] = "XCL_MULTIPROCESS_MODE=1";
    if (putenv(mps_env) != 0) {
        std::cout << "putenv failed" << std::endl;
    } else
        std::cout << "Env variable: XCL_MULTIPROCESS_MODE: " << getenv("XCL_MULTIPROCESS_MODE") << std::endl;
    ...
    OCL_CHECK(err, q = cl::CommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &err));
    char k_name[100];
    for (uint32_t i = 0; i < num_cu; i++)
    {
       memset(k_name, 0, sizeof(k_name));
       if(role == 0)
       {
         sprintf(k_name,"%s:{testkernel_%d}", krnl_names[role], i+1);
       }
       else
       {
         sprintf(k_name,"%s:{testkernel_1_%d}", krnl_names[role], i+1);
       }
       printf("k_name:%s\n",k_name);
       krnl[i] = cl::Kernel(program, k_name, &err);
    }
    ...
}

void KernelTestFunc(...)
{
    ...
    cl::Buffer buffer_data(context, CL_MEM_READ_ONLY, sizeof(unsigned char) * size);
    cl::Buffer buffer_result(context, CL_MEM_WRITE_ONLY, sizeof(unsigned int));

    octet *ptr_data= (octet *) q.enqueueMapBuffer (buffer_data , CL_TRUE , CL_MAP_WRITE , 0, sizeof(unsigned char) * size);
    uint32_t *ptr_result = (uint32_t *) q.enqueueMapBuffer (buffer_result , CL_TRUE , CL_MAP_READ , 0, sizeof(unsigned int));
	
    //set the kernel Arguments
    int narg=0;
    kernel.setArg(narg++,buffer_data);
    kernel.setArg(narg++,buffer_result);
    kernel.setArg(narg++,size);

    cl::Event migrate_event, enqueue_event, data_read_event;
    q.enqueueMigrateMemObjects({buffer_data},0/* 0 means from host*/,nullptr, &migrate_event);

    //Launch the Kernel
    std::vector<cl::Event> kernelWriteWait;
    kernelWriteWait.push_back(migrate_event);
    q.enqueueTask(kernel, &kernelWriteWait, &enqueue_event);

    // The result of the previous kernel execution will need to be retrieved in
    // order to view the results. This call will transfer the data from FPGA to
    // source_results vector
    std::vector<cl::Event> kernelComputeWait;
    kernelComputeWait.push_back(enqueue_event);
    q.enqueueMigrateMemObjects({buffer_result},CL_MIGRATE_MEM_OBJECT_HOST, &kernelComputeWait, &data_read_event);
    data_read_event.wait();

    q.flush();
    q.finish();
	...
}

 

 clipboard-202105211754-assjn.png

0 Kudos
2 Replies
ViratAgarwal
Xilinx Employee
Xilinx Employee
256 Views
Registered: ‎06-24-2020

Hi @NellyWu ,

 

Can you please mention how did you set the "XCL_MULTIPROCESS_MODE" variable. You may refer the following snippet for your reference -

https://github.com/Xilinx/Vitis_Accel_Examples/blob/master/sys_opt/multiple_process/src/host.cpp#L147

 

0 Kudos
NellyWu
Visitor
Visitor
190 Views
Registered: ‎06-03-2021

Hi @ViratAgarwal 

Below is my code snippet, thanks.

int Init_OpenCL(char* xclbinFilename, int role){
    cl_int err;
    //Setting XCL_MULTIPROCESS_MODE
    std::cout << "Set the env variable for Multi Process Support (MPS)"
              << std::endl;
    char mps_env[] = "XCL_MULTIPROCESS_MODE=1";
    if (putenv(mps_env) != 0) {
        std::cout << "putenv failed" << std::endl;
    } else
        std::cout << "Env variable: XCL_MULTIPROCESS_MODE: " << getenv("XCL_MULTIPROCESS_MODE") << std::endl;
...
}

 

0 Kudos