Problem on spe_context_run

Discussion in 'CellPerformance@B3D' started by jhhsia, Oct 8, 2007.

  1. jhhsia

    Newcomer

    Joined:
    Sep 11, 2007
    Messages:
    2
    Likes Received:
    0
    Location:
    LA
    Hi All,

    For some reason the address argument that I want to pass to SPU does not get through. I am following the simple DMA sample from SDK 2.0 and I am passing my stuff like:

    spe_context_run(speid, &entry, 0, &cb, NULL, &stop_info)

    Where cb is aligned to 128 byte. and my SPU entry looks like:

    int main( unsigned long long spuid, unsigned long long argp, unsigned long long envp)

    If I print argp out, it always shows 0. And I will get bus error trying to do DMA. :cry: However, if I hard code the address in SPU I get correct result no problem. Please help!

    Thanks
     
  2. OzzyBC42

    Newcomer

    Joined:
    Jul 8, 2007
    Messages:
    25
    Likes Received:
    0
    Hard to say. Can you post the rest of the code?
     
  3. jhhsia

    Newcomer

    Joined:
    Sep 11, 2007
    Messages:
    2
    Likes Received:
    0
    Location:
    LA
    PPU:

    control_block cb __attribute__ ((aligned (128)));
    int data[64] __attribute__ ((aligned (128)));

    int main(){

    unsigned int flag = 0;
    unsigned int runflag = 0;
    unsigned int entry = SPE_DEFAULT_ENTRY;
    void* envp = 0;
    spe_stop_info_t stop_info;

    printf("Address being sent in control block: %p\n", data);
    data[0] = 1; data[1] = 2; data[2] = 3;
    cb.addr.p = data;
    printf("Address being sent in control block: %p\n", cb.addr.p);
    printf("Address being sent in control block: %p\n", (void*)&cb);

    spe_program_handle_t* program = spe_image_open("spu_hello");
    spe_context_ptr_t spe = spe_context_create(flag, NULL);

    spe_program_load(spe, program);
    /* run the SPE context */
    if (spe_context_run(spe, &entry, 0, &cb, NULL, &stop_info) < 0) {
    fprintf (stderr, "FAILED: spe_context_run(errno=%d )\n", errno);
    exit (1);
    }
    spe_image_close(program);
    spe_context_destroy(spe);
    return (0);
    }

    SPU:
    /* Here's the local copy of the control block, to be filled by the DMA */
    control_block cb __attribute__ ((aligned (128)));

    /* Here's the local copy of the data array, to be filled by the DMA */
    int data[DATA_BUFFER_ENTRIES] __attribute__ ((aligned (128)));

    int main( unsigned long long spuid, unsigned long long argp, unsigned long long envp)
    {
    printf("speid = 0x%llx\n", spuid);
    printf("Address received through control block = 0x%llx\n", spuid);
    argp = 0x10011780;
    mfc_get(&cb, argp, sizeof(cb), 31, 0, 0);


    mfc_write_tag_mask(1<<31);

    /* Now, issue the read and wait to guarantee DMA completion before we continue. */
    mfc_read_tag_status_all();

    printf("Address received through control block = 0x%llx\n", cb.addr.ull);
    /* DMA the data from system memory to our local store buffer. */
    mfc_get(data, cb.addr.ull, DATA_BUFFER_SIZE, 31, 0, 0);

    printf("data 0 %d \n",data[0]);
    printf("data 1 %d \n",data[1]);
    printf("data 2 %d \n",data[2]);
    return (0);
    }

    Thanks.
     
  4. OzzyBC42

    Newcomer

    Joined:
    Jul 8, 2007
    Messages:
    25
    Likes Received:
    0
    Works fine for me (after commenting that "argp= 0x...", in the spu code of course) and using the 64-Bit Compiler.

    You don't seem to check for thar last mfc_get line to finish, though, even that worked fine on my end.

    You can try to read out the spe_stop_info_t struct, that should give you a clue.

    But have to enable it first with

    spe_context_ptr_t spe = spe_context_create(SPE_EVENTS_ENABLE, NULL);

    You can check the returned Status(int) with

    spe_stop_info_read(spe, &stop_info)
     
  5. Vitaly Vidmirov

    Newcomer

    Joined:
    Jul 9, 2007
    Messages:
    108
    Likes Received:
    10
    Location:
    Russia
    jhhsia

    from SDK 2.0
    This is known SDK 2.0 bug.

    argp stored as LOW | HIGH
    should be HIGH | LOW

    So, you'll need to swap argp or just do
    argp >>= 32;
     
  6. Sousuke

    Newcomer

    Joined:
    Jan 16, 2006
    Messages:
    17
    Likes Received:
    1
    I had the same problem but didn't find out what it was so I used a workaround with mbox.
    So thats how to fix it ;) thanks Vitaly.
     
  7. Filippo

    Newcomer

    Joined:
    Nov 9, 2007
    Messages:
    1
    Likes Received:
    0
    Hi, Im experiencing a similiar problem to the above. I have just started on a project but cant the DMA transfer to work. Ill post the essential part of my code below:

    PPU:

    extern spe_program_handle_t rrt_spu;
    typedef struct ppu_pthread_data {
    spe_context_ptr_t spe_ctx;
    pthread_t pthread;
    unsigned int entry;
    void *argp;
    } ppu_pthread_data_t;

    void intersect()
    {
    ppu_pthread_data_t ppuThreadData;
    context ctx __attribute__ ((aligned (16)));

    ctx._nU = 1;
    ctx._nV = 2;
    ctx._nD = 3;

    if ((ppuThreadData.spe_ctx = spe_context_create (0, NULL)) == NULL)
    {
    perror ("Failed creating context");
    exit (1);
    }

    if (spe_program_load (ppuThreadData.spe_ctx, &rrt_spu))
    {
    perror ("Failed loading program");
    exit (1);
    }

    ppuThreadData.entry = SPE_DEFAULT_ENTRY;
    ppuThreadData.argp = &ctx;

    if (pthread_create (&ppuThreadData.pthread, NULL, &ppu_pthread_function, &ppuThreadData))
    {
    perror ("Failed creating thread");
    exit (1);
    }
    }

    if (pthread_join (ppuThreadData.pthread, NULL))
    {
    perror("Failed pthread_join");
    exit (1);
    }
    }


    SPE:

    // LS structures
    volatile context ctx;

    int main(unsigned long long spe_id, unsigned long long parm)
    {
    unsigned int tag_id = mfc_tag_reserve();

    spu_writech(MFC_WrTagMask, -1);

    printf("spe p.2\n");

    printf("speid = 0x%llx : ", spe_id);
    printf("parm 0x%llx : ", parm);
    printf("size cb %d : ", sizeof(context));
    printf("tag id 0x%llx\n", tag_id);

    spu_mfcdma32((void *)(&ctx), parm, sizeof(context), tag_id, MFC_GET_CMD);

    printf("spe p.3\n");
    (void)spu_mfcstat(MFC_TAG_UPDATE_ALL);

    printf("spe p.4\n");

    float nU = ctx._nU;
    float nV = ctx._nV;
    float nD = ctx._nD;
    float uiProj = ctx._uiProj;

    printf("spe p.5\n");

    printf("%f %f %f %f \n", nU, nV, nD, uiProj);


    (void)spu_mfcstat(MFC_TAG_UPDATE_ALL);

    printf("spe p.6\n");
    return 0;
    }


    In this case 'parm' is equal to zero and as I understood it should be the adress of the context? I also tried using a mailbox and send the value ppuThreadData.argp through the mailbox and then use this for the DMA call, Bot h cases give a a buss error.

    How can I do it correctly? If i were to use mailbox, which value should I send?

    Im using a PS3 with fedora 7 installed and the early release of the cell sdk 3.0

    $>>uname -a
    Linux ps3 2.6.23-rc3 #1 SMP Fri Aug 17 11:39:09 JST 2007 ppc64 ppc64 ppc64 GNU/Linux

    If anyone could help me out I would be grateful

    //Filip
     
Loading...

Share This Page

  • About Us

    Beyond3D has been around for over a decade and prides itself on being the best place on the web for in-depth, technically-driven discussion and analysis of 3D graphics hardware. If you love pixels and transistors, you've come to the right place!

    Beyond3D is proudly published by GPU Tools Ltd.
Loading...