To: J3 J3/13-347 From: Reinhold Bader Subject: First event example for TS Annex Date: 2013 October 07 References: N1983 Discussion: ~~~~~~~~~~~ The first event example in N1983 [33:42]-[34:17] is presently only a program fragment that by itself would never execute the EVENT WAIT branch. This paper therefore suggests replacing it by a complete single producer program that also illustrates how to deal with failed images, and that the EVENT_QUERY intrinsic may also be used in a context that does not involve a subsequent EVENT WAIT on the same image. <<>> EDITs to N1983: ~~~~~~~~~~~~~~~ Replace example text by the following: "The following example illustrates the use of events via a program whose first image shares out work items to all other images. Only one work item at a time can be active on the worker images, and these deal with the result (e.g. via I/O) without directly feeding back data to the master image. Because the work items are not expected to be balanced, the master keeps cycling through all available images in order to find one that is waiting for work. Furthermore, the master performs bookkeeping of failed images, so the program might continue with degraded performance even if worker images fail progressively. PROGRAM USE, INTRINSIC :: iso_fortran_env USE :: mod_work ! provides TYPE(work), create_work_item, ! repeat_work_item, queue_is_empty, process_item TYPE(event_type) :: submit_confirm[*] LOGICAL, ALLOCATABLE :: available[:] TYPE(work) :: work_item[*] INTEGER :: count, i, status IF (this_image() == 1) THEN ALLOCATE(available(2:num_images(), source = .TRUE.) ! ! work distribution loop master : DO image : DO i = 2, num_images() if (.NOT. available(i)) CYCLE image CALL event_query(submit_confirm[i], count, status) IF (status == STAT_FAILED_IMAGE) THEN available(i) = .FALSE. CYCLE image ELSE IF (STATUS /= 0) THEN STOP END IF IF (count == 0) THEN work_item[i] = create_work_item() ! Two event posts follow that are matched by waits ! on the worker before and after processing the work_item. ! This assures that (except for the first iteration) ! zero count is reached after the worker has completed ! processing its item. ! This works because only one image posts to the event, ! and does so inside a conditional that guarantees ! zero count on the first post. EVENT POST (submit_confirm[i], status) EVENT POST (submit_confirm[i], status) IF (status == STAT_FAILED_IMAGE) THEN call repeat_work_item() ! previous item re-created ! in next iteration available(i) = .FALSE. CYCLE image ELSE IF (STATUS /= 0) THEN STOP END IF END IF END DO image IF (queue_is_empty()) EXIT master ! may have created empty work_item before, but this ! is dealt with by the workers END DO master ELSE ! ! work processing loop worker : DO EVENT WAIT (submit_confirm) call process_item(work_item, status) EVENT WAIT (submit_confirm) ! signals event count zero ! to master IF (status == WORK_ITEM_EMPTY) EXIT worker END DO worker END IF END PROGRAM" <<>>