Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

How can I use parallel processing in ABAP?

Former Member
0 Likes
4,020

Hello everyone,

I am experiencing some difficulties in the implementation of a function to use under parallel processing.
Here's what I have:

  1. Function Group created;
  2. Function Module created;
    1. Attributes: Normal Function Module;
    2. Import: Variables that I want to process internally ("Associated Type": ANY; "Pass Value" selected);
    3. Export: Variables that I want to retrieve their values ("Pass Value" selected);
    4. Source Code: implementation of the function using the Import Variables and assigning them to Export Variables.
  3. Program in ABAP created as follows:

LOOP AT i_tab INTO aux_tab.

index = sy-tabix.

CONCATENATE 'Task' index INTO taskname.

CALL FUNCTION 'Z_FUNCTION'

     STARTING NEW TASK taskname

          DESTINATION IN GROUP DEFAULT

               PERFORMING receive_results ON END OF TASK

     EXPORTING

          var1 = var1

          var2 = var2, and so on...

ENDLOOP.

FORM receive_results

     USING

               taskname.

     RECEIVE RESULTS FROM FUNCTION 'Z_FUNCTION'

          IMPORTING

               var3 = var3, and so on...

ENDFORM.

If I don't use the "RECEIVE RESULTS FROM..." function, everything works (except for the fact that I don't receive the value of 'var3'). However, when I use such function, I receive this error: CALL_FUNCTION_REMOTE_ERROR (short text: "The function module 'Z_FUNCTION' cannot be used for 'remote' calls.").

Even if I don't use generic types for the import variables and check the "Remote-Enabled Module" option I still get errors, but this time they don't have anything to do directly to my code.


Thank you so much in advance!

1 ACCEPTED SOLUTION
Read only

RaymondGiuseppi
Active Contributor
0 Likes
2,975

Once you switched your FM to RFC enabled, add an exception like NODATA to the FM to raise an error if no data read and add some code like

* Call

CALL FUNCTION 'Z_FUNCTION'
   STARTING NEW TASK taskname
   DESTINATION IN GROUP DEFAULT
   PERFORMING receive_results ON END OF TASK
   EXPORTING
     var1                  = var1
     var2                  = var2 " , and so on...
   EXCEPTIONS
     communication_failure = 1
     system_failure        = 2
     resource_failure      = 3.

ADD 1 TO gv_active.
* Receive

RECEIVE RESULTS FROM FUNCTION 'Z_FUNCTION'
     IMPORTING
       var3 = var3 " and so on...
     EXCEPTIONS
       nodata    = 1.

SUBTRACT 1 FROM gv_active.

And manage the exceptions in the program (Like not submitting more call than available process, look at FM like SPBT_INITIALIZE and other FMs of group SPBT)

Regards,

Raymond


Hello everyone,

I am experiencing some difficulties in the implementation of a function to use under parallel processing.
Here's what I have:

  1. Function Group created;
  2. Function Module created;
    1. Attributes: Normal Function Module;
    2. Import: Variables that I want to process internally ("Associated Type": ANY; "Pass Value" selected);
    3. Export: Variables that I want to retrieve their values ("Pass Value" selected);
    4. Source Code: implementation of the function using the Import Variables and assigning them to Export Variables.
  3. Program in ABAP created as follows:

LOOP AT i_tab INTO aux_tab.

index = sy-tabix.

CONCATENATE 'Task' index INTO taskname.

CALL FUNCTION 'Z_FUNCTION'

     STARTING NEW TASK taskname

          DESTINATION IN GROUP DEFAULT

               PERFORMING receive_results ON END OF TASK

     EXPORTING

          var1 = var1

          var2 = var2, and so on...

ENDLOOP.

FORM receive_results

     USING

               taskname.

     RECEIVE RESULTS FROM FUNCTION 'Z_FUNCTION'

          IMPORTING

               var3 = var3, and so on...

ENDFORM.

If I don't use the "RECEIVE RESULTS FROM..." function, everything works (except for the fact that I don't receive the value of 'var3'). However, when I use such function, I receive this error: CALL_FUNCTION_REMOTE_ERROR (short text: "The function module 'Z_FUNCTION' cannot be used for 'remote' calls.").

Even if I don't use generic types for the import variables and check the "Remote-Enabled Module" option I still get errors, but this time they don't have anything to do directly to my code.


Thank you so much in advance!

12 REPLIES 12
Read only

Former Member
0 Likes
2,975

Remote-Enabled module has to be turned on to use the starting new task... What is the error you receive when this is enabled?

Read only

0 Likes
2,975

Hi, Lucas!

I just did what you told me and also solved some of the issues. Now it's working (kind of).
The results are still not being returned (after using RECEIVE RESULTS...IMPORT var3). Var3 is still empty.


Thanks!

Read only

0 Likes
2,975

I can't see any reason you wouldn't be getting back the results you expect... I guess at this point make sure the function module you're calling is working properly (run it on its own to see expected output) and make sure in the receive_results you're putting the results in to some global field that is accessible from the rest of your program.

Read only

0 Likes
2,975

You could put WRITE statements everywhere to track flow of logic.

Inside Z_FUNCTION , print var1 var2.

In subroutine receive_results, print var3.

Add var3 to global variable OR append var3 to global internal table.

Increment a counter every time Z_FUNCTION is called. (threads_started)

Increment a counter every time results are received. (threads_finished)

Add a statement right after ENDLOOP. ( WAIT UNTIL threads_finished >= threads_started. )

After WAIT statement, all threads should have completed and your global variable/table will have aggregated results.

Read only

former_member219762
Contributor
0 Likes
2,975

Hi Rafael,

                  The form execute only when program is roll out state. This is asynchronous call so we have to make calling program wait for receiving result that is make program roll out state. We can done it by statement WAIT UNTILL<LOGICAL STAMENT>

I think we cannot use generic type in rfc FM as parameters,we  should use dictionary type

For more details

http://help.sap.com/saphelp_nw70/helpdata/en/fa/096e92543b11d1898e0000e8322d00/content.htm

Regards,

Sreenivas.

Read only

former_member186413
Participant
2,975

Hi Rafael,

Add this line after your call function statement.

WAIT UNTIL NOT ( <f1> IS INITIAL AND <f2> IS INITIAL AND ..<fn> IS INITIAL).

Read only

RaymondGiuseppi
Active Contributor
0 Likes
2,976

Once you switched your FM to RFC enabled, add an exception like NODATA to the FM to raise an error if no data read and add some code like

* Call

CALL FUNCTION 'Z_FUNCTION'
   STARTING NEW TASK taskname
   DESTINATION IN GROUP DEFAULT
   PERFORMING receive_results ON END OF TASK
   EXPORTING
     var1                  = var1
     var2                  = var2 " , and so on...
   EXCEPTIONS
     communication_failure = 1
     system_failure        = 2
     resource_failure      = 3.

ADD 1 TO gv_active.
* Receive

RECEIVE RESULTS FROM FUNCTION 'Z_FUNCTION'
     IMPORTING
       var3 = var3 " and so on...
     EXCEPTIONS
       nodata    = 1.

SUBTRACT 1 FROM gv_active.

And manage the exceptions in the program (Like not submitting more call than available process, look at FM like SPBT_INITIALIZE and other FMs of group SPBT)

Regards,

Raymond


Read only

0 Likes
2,975

what's gv_active?

Read only

0 Likes
2,975

Counter gv_active is meant to keep track of number of active tasks (parallel threads).

Counter is incremented every time new task is started.

Counter is decremented every time results are received.

This variable can be used in WAIT UNTIL statement to check whether all tasks have completed.

Read only

0 Likes
2,975

Mmm, good idea. what's type of this variable(gv_active).  I can't find any in the system field list.

Read only

0 Likes
2,975

Define it as an integer in global area of the program, its purpose is to keep the number of already active call (called but not yet received, so number of interactive process used by those call, look at transaction RZ12 for group definition, and SM50 during execution to see your active call) 

So in your loop after each call wait until this number get lower or equal than the maximum number of process returned by SPBT_INITIALIZE. (WAIT UNTIL gv_active LE max_pbt_wps.)

For more information, read some documentation like Implementing Parallel Processing.

Regards,

Raymond

Read only

0 Likes
2,975

Integer type would work fine.

The SAP Help example uses two counters in WAIT UNTIL condition.

WAIT UNTIL RCV_JOBS >= SND_JOBS UP TO '1' SECONDS.

While using gv_active, statement would be something like this.

WAIT UNTIL gv_active = 0 UP TO '1' SECONDS.

So, gv_active is essentially the difference between rcv_jobs and snd_jobs.