@SuppressWarnings("deprecation")
   protected void executeJava(ExecutionSettings _settings, Device device) {
      if (logger.isLoggable(Level.FINE)) {
         logger.fine("executeJava: range = " + _settings.range + ", device = " + device);
      }
      boolean legacySequentialMode = kernel.getExecutionMode().equals(Kernel.EXECUTION_MODE.SEQ);

      passId = PASS_ID_PREPARING_EXECUTION;
      _settings.profile.onEvent(device, ProfilingEvent.PREPARE_EXECUTE);

      try {
         if (device == JavaDevice.ALTERNATIVE_ALGORITHM) {
            if (kernel.hasFallbackAlgorithm()) {
               for (passId = 0; passId < _settings.passes; ++passId) {
                  kernel.executeFallbackAlgorithm(_settings.range, passId);
               }
            } else {
               boolean silently = true; // not having an alternative algorithm is the normal state, and does not need reporting
               fallBackToNextDevice(device, _settings, (Exception) null, silently);
            }
         } else {
            final int localSize0 = _settings.range.getLocalSize(0);
            final int localSize1 = _settings.range.getLocalSize(1);
            final int localSize2 = _settings.range.getLocalSize(2);
            final int globalSize1 = _settings.range.getGlobalSize(1);
            if (legacySequentialMode || device == JavaDevice.SEQUENTIAL) {
               /**
                * SEQ mode is useful for testing trivial logic, but kernels which use SEQ mode cannot be used if the
                * product of localSize(0..3) is >1.  So we can use multi-dim ranges but only if the local size is 1 in all dimensions.
                *
                * As a result of this barrier is only ever 1 work item wide and probably should be turned into a no-op.
                *
                * So we need to check if the range is valid here. If not we have no choice but to punt.
                */
               if ((localSize0 * localSize1 * localSize2) > 1) {
                  throw new IllegalStateException("Can't run range with group size >1 sequentially. Barriers would deadlock!");
               }

               final Kernel kernelClone = kernel.clone();
               final KernelState kernelState = kernelClone.getKernelState();

               kernelState.setRange(_settings.range);
               kernelState.setGroupId(0, 0);
               kernelState.setGroupId(1, 0);
               kernelState.setGroupId(2, 0);
               kernelState.setLocalId(0, 0);
               kernelState.setLocalId(1, 0);
               kernelState.setLocalId(2, 0);
               kernelState.setLocalBarrier(new FJSafeBarrier(1));

               for (passId = 0; passId < _settings.passes; passId++) {
                  if (getCancelState() == CANCEL_STATUS_TRUE) {
                     break;
                  }
                  kernelState.setPassId(passId);

                  if (_settings.range.getDims() == 1) {
                     for (int id = 0; id < _settings.range.getGlobalSize(0); id++) {
                        kernelState.setGlobalId(0, id);
                        kernelClone.run();
                     }
                  }
                  else if (_settings.range.getDims() == 2) {
                     for (int x = 0; x < _settings.range.getGlobalSize(0); x++) {
                        kernelState.setGlobalId(0, x);

                        for (int y = 0; y < globalSize1; y++) {
                           kernelState.setGlobalId(1, y);
                           kernelClone.run();
                        }
                     }
                  }
                  else if (_settings.range.getDims() == 3) {
                     for (int x = 0; x < _settings.range.getGlobalSize(0); x++) {
                        kernelState.setGlobalId(0, x);

                        for (int y = 0; y < globalSize1; y++) {
                           kernelState.setGlobalId(1, y);

                           for (int z = 0; z < _settings.range.getGlobalSize(2); z++) {
                              kernelState.setGlobalId(2, z);
                              kernelClone.run();
                           }

                           kernelClone.run();
                        }
                     }
                  }
               }
               passId = PASS_ID_COMPLETED_EXECUTION;
            }
            else {
               if (device != JavaDevice.THREAD_POOL && kernel.getExecutionMode() != Kernel.EXECUTION_MODE.JTP) {
                  throw new AssertionError("unexpected JavaDevice or EXECUTION_MODE");
               }
               final int threads = localSize0 * localSize1 * localSize2;
               final int numGroups0 = _settings.range.getNumGroups(0);
               final int numGroups1 = _settings.range.getNumGroups(1);
               final int globalGroups = numGroups0 * numGroups1 * _settings.range.getNumGroups(2);
               
               /**
                * This localBarrier is only ever used by the kernels.  If the kernel does not use the barrier the threads
                * can get out of sync, we promised nothing in JTP mode.
                *
                * As with OpenCL all threads within a group must wait at the barrier or none.  It is a user error (possible deadlock!)
                * if the barrier is in a conditional that is only executed by some of the threads within a group.
                *
                * Kernel developer must understand this.
                *
                * This barrier is threadCount wide.  We never hit the barrier from the dispatch thread.
                */
               final FJSafeBarrier localBarrier = new FJSafeBarrier(threads);

               final ThreadIdSetter threadIdSetter;

               if (_settings.range.getDims() == 1) {
                  threadIdSetter = new ThreadIdSetter() {
                     @Override
                     public void set(KernelState kernelState, int globalGroupId, int threadId) {
                        //                   (kernelState, globalGroupId, threadId) ->{
                        kernelState.setLocalId(0, (threadId % localSize0));
                        kernelState.setGlobalId(0, (threadId + (globalGroupId * threads)));
                        kernelState.setGroupId(0, globalGroupId);
                     }
                  };
               }
               else if (_settings.range.getDims() == 2) {

                  /**
                   * Consider a 12x4 grid of 4*2 local groups
                   * <pre>
                   *                                             threads = 4*2 = 8
                   *                                             localWidth=4
                   *                                             localHeight=2
                   *                                             globalWidth=12
                   *                                             globalHeight=4
                   *
                   *    00 01 02 03 | 04 05 06 07 | 08 09 10 11
                   *    12 13 14 15 | 16 17 18 19 | 20 21 22 23
                   *    ------------+-------------+------------
                   *    24 25 26 27 | 28 29 30 31 | 32 33 34 35
                   *    36 37 38 39 | 40 41 42 43 | 44 45 46 47
                   *
                   *    00 01 02 03 | 00 01 02 03 | 00 01 02 03  threadIds : [0..7]*6
                   *    04 05 06 07 | 04 05 06 07 | 04 05 06 07
                   *    ------------+-------------+------------
                   *    00 01 02 03 | 00 01 02 03 | 00 01 02 03
                   *    04 05 06 07 | 04 05 06 07 | 04 05 06 07
                   *
                   *    00 00 00 00 | 01 01 01 01 | 02 02 02 02  groupId[0] : 0..6
                   *    00 00 00 00 | 01 01 01 01 | 02 02 02 02
                   *    ------------+-------------+------------
                   *    00 00 00 00 | 01 01 01 01 | 02 02 02 02
                   *    00 00 00 00 | 01 01 01 01 | 02 02 02 02
                   *
                   *    00 00 00 00 | 00 00 00 00 | 00 00 00 00  groupId[1] : 0..6
                   *    00 00 00 00 | 00 00 00 00 | 00 00 00 00
                   *    ------------+-------------+------------
                   *    01 01 01 01 | 01 01 01 01 | 01 01 01 01
                   *    01 01 01 01 | 01 01 01 01 | 01 01 01 01
                   *
                   *    00 01 02 03 | 08 09 10 11 | 16 17 18 19  globalThreadIds == threadId + groupId * threads;
                   *    04 05 06 07 | 12 13 14 15 | 20 21 22 23
                   *    ------------+-------------+------------
                   *    24 25 26 27 | 32[33]34 35 | 40 41 42 43
                   *    28 29 30 31 | 36 37 38 39 | 44 45 46 47
                   *
                   *    00 01 02 03 | 00 01 02 03 | 00 01 02 03  localX = threadId % localWidth; (for globalThreadId 33 = threadId = 01 : 01%4 =1)
                   *    00 01 02 03 | 00 01 02 03 | 00 01 02 03
                   *    ------------+-------------+------------
                   *    00 01 02 03 | 00[01]02 03 | 00 01 02 03
                   *    00 01 02 03 | 00 01 02 03 | 00 01 02 03
                   *
                   *    00 00 00 00 | 00 00 00 00 | 00 00 00 00  localY = threadId /localWidth  (for globalThreadId 33 = threadId = 01 : 01/4 =0)
                   *    01 01 01 01 | 01 01 01 01 | 01 01 01 01
                   *    ------------+-------------+------------
                   *    00 00 00 00 | 00[00]00 00 | 00 00 00 00
                   *    01 01 01 01 | 01 01 01 01 | 01 01 01 01
                   *
                   *    00 01 02 03 | 04 05 06 07 | 08 09 10 11  globalX=
                   *    00 01 02 03 | 04 05 06 07 | 08 09 10 11     groupsPerLineWidth=globalWidth/localWidth (=12/4 =3)
                   *    ------------+-------------+------------     groupInset =groupId%groupsPerLineWidth (=4%3 = 1)
                   *    00 01 02 03 | 04[05]06 07 | 08 09 10 11
                   *    00 01 02 03 | 04 05 06 07 | 08 09 10 11     globalX = groupInset*localWidth+localX (= 1*4+1 = 5)
                   *
                   *    00 00 00 00 | 00 00 00 00 | 00 00 00 00  globalY
                   *    01 01 01 01 | 01 01 01 01 | 01 01 01 01
                   *    ------------+-------------+------------
                   *    02 02 02 02 | 02[02]02 02 | 02 02 02 02
                   *    03 03 03 03 | 03 03 03 03 | 03 03 03 03
                   *
                   * </pre>
                   * Assume we are trying to locate the id's for #33
                   *
                   */
                  threadIdSetter = new ThreadIdSetter() {
                     @Override
                     public void set(KernelState kernelState, int globalGroupId, int threadId) {
                        //                   (kernelState, globalGroupId, threadId) ->{
                    	final int localId0 = (threadId % localSize0);
                    	final int localId1 = (threadId / localSize0);
                        kernelState.setLocalId(0, localId0); // threadId % localWidth =  (for 33 = 1 % 4 = 1)
                        kernelState.setLocalId(1, localId1); // threadId / localWidth = (for 33 = 1 / 4 == 0)

                        //The displacement in the overall 2D computation grid in the X direction is
                        //the offset in X given by the current group being executed, plus the X displacement
                        //inside that work-group.
                        //Groups are like this:
                        //[Group 0] [Group 1] [Group 2]
                        //[Group 3] [Group 4] [Group 5]
                        final int globalThreadIdOffsetX = (globalGroupId % numGroups0) * localSize0; 
                        kernelState.setGlobalId(0, globalThreadIdOffsetX + localId0);

                        //Likewise X, but now for the Y direction. 
                        final int globalThreadIdOffsetY = (globalGroupId / numGroups0) * localSize1;
                        kernelState.setGlobalId(1, globalThreadIdOffsetY + localId1);
                        
                        kernelState.setGroupId(0, (globalGroupId % numGroups0));
                        kernelState.setGroupId(1, (globalGroupId / numGroups0));
                     }
                  };
               }
               else if (_settings.range.getDims() == 3) {
                  //Same as 2D actually turns out that localId[0] is identical for all three dims so could be hoisted out of conditional code
                  threadIdSetter = new ThreadIdSetter() {
                     @Override
                     public void set(KernelState kernelState, int globalGroupId, int threadId) {
                        //                   (kernelState, globalGroupId, threadId) ->{
                        kernelState.setLocalId(0, (threadId % localSize0));

                        kernelState.setLocalId(1, ((threadId / localSize0) % localSize1));

                        // the thread id's span WxHxD so threadId/(WxH) should yield the local depth
                        kernelState.setLocalId(2, (threadId / (localSize0 * localSize1)));

                        kernelState.setGlobalId(0, (((globalGroupId % numGroups0) * localSize0) + kernelState.getLocalIds()[0]));

                        kernelState.setGlobalId(1,
                        ((((globalGroupId / numGroups0) * localSize1) % globalSize1) + kernelState.getLocalIds()[1]));

                        kernelState.setGlobalId(2,
                        (((globalGroupId / (numGroups0 * numGroups1)) * localSize2) + kernelState.getLocalIds()[2]));

                        kernelState.setGroupId(0, (globalGroupId % numGroups0));
                        kernelState.setGroupId(1, ((globalGroupId / numGroups0) % numGroups1));
                        kernelState.setGroupId(2, (globalGroupId / (numGroups0 * numGroups1)));
                     }
                  };
               }
               else {
                  throw new IllegalArgumentException("Expected 1,2 or 3 dimensions, found " + _settings.range.getDims());
               }
               
               ForkJoinTask<?>[] tasks = new ForkJoinTask<?>[threads];
               for (passId = 0; passId < _settings.passes; passId++) {
                  if (getCancelState() == CANCEL_STATUS_TRUE) {
                     break;
                  }
                  
                  long deadThreadCount = handler.threadsDiedCounter.get();
                  /**
                   * Note that we emulate OpenCL by creating one thread per localId (across the group).
                   *
                   * So threadCount == range.getLocalSize(0)*range.getLocalSize(1)*range.getLocalSize(2);
                   *
                   * For a 1D range of 12 groups of 4 we create 4 threads. One per localId(0).
                   *
                   * We also clone the kernel 4 times. One per thread.
                   *
                   * We create local barrier which has a width of 4
                   *
                   *    Thread-0 handles localId(0) (global 0,4,8)
                   *    Thread-1 handles localId(1) (global 1,5,7)
                   *    Thread-2 handles localId(2) (global 2,6,10)
                   *    Thread-3 handles localId(3) (global 3,7,11)
                   *
                   * This allows all threads to synchronize using the local barrier.
                   *
                   * Initially the use of local buffers seems broken as the buffers appears to be per Kernel.
                   * Thankfully Kernel.clone() performs a shallow clone of all buffers (local and global)
                   * So each of the cloned kernels actually still reference the same underlying local/global buffers.
                   *
                   * If the kernel uses local buffers but does not use barriers then it is possible for different groups
                   * to see mutations from each other (unlike OpenCL), however if the kernel does not us barriers then it
                   * cannot assume any coherence in OpenCL mode either (the failure mode will be different but still wrong)
                   *
                   * So even JTP mode use of local buffers will need to use barriers. Not for the same reason as OpenCL but to keep groups in lockstep.
                   *
                   **/
                  for (int id = 0; id < threads; id++) {
                     final int threadId = id;

                     /**
                      *  We clone one kernel for each thread.
                      *
                      *  They will all share references to the same range, localBarrier and global/local buffers because the clone is shallow.
                      *  We need clones so that each thread can assign 'state' (localId/globalId/groupId) without worrying
                      *  about other threads.
                      */
                     final Kernel kernelClone = kernel.clone();
                     final KernelState kernelState = kernelClone.getKernelState();
                     kernelState.setRange(_settings.range);
                     kernelState.setPassId(passId);

                     if (threads == 1) {
                        kernelState.disableLocalBarrier();
                     }
                     else {
                        kernelState.setLocalBarrier(localBarrier);
                     }

                     ForkJoinTask<?> fjt = threadPool.submit(
                     //                     () -> {
                     new Runnable() {
                        public void run() {
                           try {
                              for (int globalGroupId = 0; globalGroupId < globalGroups; globalGroupId++) {
                                 threadIdSetter.set(kernelState, globalGroupId, threadId);
                                 kernelClone.run();
                              }
                           } catch (AparapiBrokenBarrierException e) {
                        	   //Intentionally empty to not obfuscate threads that failed executing the kernel with those that had
                        	   //the barrier broken by the first ones.
                           } catch (RuntimeException | Error e) {
                        	  localBarrier.breakBarrier(e);
                        	  throw new AparapiKernelFailedException(kernelState.describe(), e);
                           }
                        }
                     });
                     
                     tasks[id] = fjt;
                  }

                  for (ForkJoinTask<?> task : tasks) { // This dispatch thread waits for all worker threads here.
                	  task.join();
                  }
                  
                  long deathCount = handler.threadsDiedCounter.get() - deadThreadCount;
                  if (deathCount > 0) {
                	  logger.log(Level.SEVERE, "(" + deathCount + ") Pool threads died during execution of kernel: " + kernel.getClass().getName() + " at pass: " + passId);
                  }
               }
               passId = PASS_ID_COMPLETED_EXECUTION;
            } // execution mode == JTP
         }
      } finally {
         passId = PASS_ID_COMPLETED_EXECUTION;
      }
   }
@ SuppressWarnings ( "deprecation" ) protected void executeJava ( ExecutionSettings _settings , Device device ) { if ( logger . isLoggable ( Level . FINE ) ) { logger . fine ( "executeJava: range = " + _settings . range + ", device = " + device ) ; } boolean legacySequentialMode = kernel . getExecutionMode ( ) . equals ( Kernel . EXECUTION_MODE . SEQ ) ; passId = PASS_ID_PREPARING_EXECUTION ; _settings . profile . onEvent ( device , ProfilingEvent . PREPARE_EXECUTE ) ; try { if ( device == JavaDevice . ALTERNATIVE_ALGORITHM ) { if ( kernel . hasFallbackAlgorithm ( ) ) { for ( passId = 0 ; passId < _settings . passes ; ++ passId ) { kernel . executeFallbackAlgorithm ( _settings . range , passId ) ; } } else { boolean silently = true ; fallBackToNextDevice ( device , _settings , ( Exception ) null , silently ) ; } } else { final int localSize0 = _settings . range . getLocalSize ( 0 ) ; final int localSize1 = _settings . range . getLocalSize ( 1 ) ; final int localSize2 = _settings . range . getLocalSize ( 2 ) ; final int globalSize1 = _settings . range . getGlobalSize ( 1 ) ; if ( legacySequentialMode || device == JavaDevice . SEQUENTIAL ) { if ( ( localSize0 * localSize1 * localSize2 ) > 1 ) { throw new IllegalStateException ( "Can't run range with group size >1 sequentially. Barriers would deadlock!" ) ; } final Kernel kernelClone = kernel . clone ( ) ; final KernelState kernelState = kernelClone . getKernelState ( ) ; kernelState . setRange ( _settings . range ) ; kernelState . setGroupId ( 0 , 0 ) ; kernelState . setGroupId ( 1 , 0 ) ; kernelState . setGroupId ( 2 , 0 ) ; kernelState . setLocalId ( 0 , 0 ) ; kernelState . setLocalId ( 1 , 0 ) ; kernelState . setLocalId ( 2 , 0 ) ; kernelState . setLocalBarrier ( new FJSafeBarrier ( 1 ) ) ; for ( passId = 0 ; passId < _settings . passes ; passId ++ ) { if ( getCancelState ( ) == CANCEL_STATUS_TRUE ) { break ; } kernelState . setPassId ( passId ) ; if ( _settings . range . getDims ( ) == 1 ) { for ( int id = 0 ; id < _settings . range . getGlobalSize ( 0 ) ; id ++ ) { kernelState . setGlobalId ( 0 , id ) ; kernelClone . run ( ) ; } } else if ( _settings . range . getDims ( ) == 2 ) { for ( int x = 0 ; x < _settings . range . getGlobalSize ( 0 ) ; x ++ ) { kernelState . setGlobalId ( 0 , x ) ; for ( int y = 0 ; y < globalSize1 ; y ++ ) { kernelState . setGlobalId ( 1 , y ) ; kernelClone . run ( ) ; } } } else if ( _settings . range . getDims ( ) == 3 ) { for ( int x = 0 ; x < _settings . range . getGlobalSize ( 0 ) ; x ++ ) { kernelState . setGlobalId ( 0 , x ) ; for ( int y = 0 ; y < globalSize1 ; y ++ ) { kernelState . setGlobalId ( 1 , y ) ; for ( int z = 0 ; z < _settings . range . getGlobalSize ( 2 ) ; z ++ ) { kernelState . setGlobalId ( 2 , z ) ; kernelClone . run ( ) ; } kernelClone . run ( ) ; } } } } passId = PASS_ID_COMPLETED_EXECUTION ; } else { if ( device != JavaDevice . THREAD_POOL && kernel . getExecutionMode ( ) != Kernel . EXECUTION_MODE . JTP ) { throw new AssertionError ( "unexpected JavaDevice or EXECUTION_MODE" ) ; } final int threads = localSize0 * localSize1 * localSize2 ; final int numGroups0 = _settings . range . getNumGroups ( 0 ) ; final int numGroups1 = _settings . range . getNumGroups ( 1 ) ; final int globalGroups = numGroups0 * numGroups1 * _settings . range . getNumGroups ( 2 ) ; final FJSafeBarrier localBarrier = new FJSafeBarrier ( threads ) ; final ThreadIdSetter threadIdSetter ; if ( _settings . range . getDims ( ) == 1 ) { threadIdSetter = new ThreadIdSetter ( ) { @ Override public void set ( KernelState kernelState , int globalGroupId , int threadId ) { kernelState . setLocalId ( 0 , ( threadId % localSize0 ) ) ; kernelState . setGlobalId ( 0 , ( threadId + ( globalGroupId * threads ) ) ) ; kernelState . setGroupId ( 0 , globalGroupId ) ; } } ; } else if ( _settings . range . getDims ( ) == 2 ) { threadIdSetter = new ThreadIdSetter ( ) { @ Override public void set ( KernelState kernelState , int globalGroupId , int threadId ) { final int localId0 = ( threadId % localSize0 ) ; final int localId1 = ( threadId / localSize0 ) ; kernelState . setLocalId ( 0 , localId0 ) ; kernelState . setLocalId ( 1 , localId1 ) ; final int globalThreadIdOffsetX = ( globalGroupId % numGroups0 ) * localSize0 ; kernelState . setGlobalId ( 0 , globalThreadIdOffsetX + localId0 ) ; final int globalThreadIdOffsetY = ( globalGroupId / numGroups0 ) * localSize1 ; kernelState . setGlobalId ( 1 , globalThreadIdOffsetY + localId1 ) ; kernelState . setGroupId ( 0 , ( globalGroupId % numGroups0 ) ) ; kernelState . setGroupId ( 1 , ( globalGroupId / numGroups0 ) ) ; } } ; } else if ( _settings . range . getDims ( ) == 3 ) { threadIdSetter = new ThreadIdSetter ( ) { @ Override public void set ( KernelState kernelState , int globalGroupId , int threadId ) { kernelState . setLocalId ( 0 , ( threadId % localSize0 ) ) ; kernelState . setLocalId ( 1 , ( ( threadId / localSize0 ) % localSize1 ) ) ; kernelState . setLocalId ( 2 , ( threadId / ( localSize0 * localSize1 ) ) ) ; kernelState . setGlobalId ( 0 , ( ( ( globalGroupId % numGroups0 ) * localSize0 ) + kernelState . getLocalIds ( ) [ 0 ] ) ) ; kernelState . setGlobalId ( 1 , ( ( ( ( globalGroupId / numGroups0 ) * localSize1 ) % globalSize1 ) + kernelState . getLocalIds ( ) [ 1 ] ) ) ; kernelState . setGlobalId ( 2 , ( ( ( globalGroupId / ( numGroups0 * numGroups1 ) ) * localSize2 ) + kernelState . getLocalIds ( ) [ 2 ] ) ) ; kernelState . setGroupId ( 0 , ( globalGroupId % numGroups0 ) ) ; kernelState . setGroupId ( 1 , ( ( globalGroupId / numGroups0 ) % numGroups1 ) ) ; kernelState . setGroupId ( 2 , ( globalGroupId / ( numGroups0 * numGroups1 ) ) ) ; } } ; } else { throw new IllegalArgumentException ( "Expected 1,2 or 3 dimensions, found " + _settings . range . getDims ( ) ) ; } ForkJoinTask < ? > [ ] tasks = new ForkJoinTask < ? > [ threads ] ; for ( passId = 0 ; passId < _settings . passes ; passId ++ ) { if ( getCancelState ( ) == CANCEL_STATUS_TRUE ) { break ; } long deadThreadCount = handler . threadsDiedCounter . get ( ) ; for ( int id = 0 ; id < threads ; id ++ ) { final int threadId = id ; final Kernel kernelClone = kernel . clone ( ) ; final KernelState kernelState = kernelClone . getKernelState ( ) ; kernelState . setRange ( _settings . range ) ; kernelState . setPassId ( passId ) ; if ( threads == 1 ) { kernelState . disableLocalBarrier ( ) ; } else { kernelState . setLocalBarrier ( localBarrier ) ; } ForkJoinTask < ? > fjt = threadPool . submit ( new Runnable ( ) { public void run ( ) { try { for ( int globalGroupId = 0 ; globalGroupId < globalGroups ; globalGroupId ++ ) { threadIdSetter . set ( kernelState , globalGroupId , threadId ) ; kernelClone . run ( ) ; } } catch ( AparapiBrokenBarrierException e ) { } catch ( RuntimeException | Error e ) { localBarrier . breakBarrier ( e ) ; throw new AparapiKernelFailedException ( kernelState . describe ( ) , e ) ; } } } ) ; tasks [ id ] = fjt ; } for ( ForkJoinTask < ? > task : tasks ) { task . join ( ) ; } long deathCount = handler . threadsDiedCounter . get ( ) - deadThreadCount ; if ( deathCount > 0 ) { logger . log ( Level . SEVERE , "(" + deathCount + ") Pool threads died during execution of kernel: " + kernel . getClass ( ) . getName ( ) + " at pass: " + passId ) ; } } passId = PASS_ID_COMPLETED_EXECUTION ; } } } finally { passId = PASS_ID_COMPLETED_EXECUTION ; } }
Execute using a Java thread pool, or sequentially, or using an alternative algorithm, usually as a result of failing to compile or execute OpenCL