// Path: src/main/java/org/shaman/jmecl/OpenCLSettings.java
// public class OpenCLSettings {
// 	
// 	private final Context clContext;
// 	private final CommandQueue clCommandQueue;
// 	private final ProgramCache programCache;
// 	private final AssetManager assetManager;
// 
// 	public OpenCLSettings(Context clContext, CommandQueue clCommandQueue, 
// 			ProgramCache programCache, AssetManager assetManager) {
// 		this.clContext = clContext;
// 		this.clCommandQueue = clCommandQueue;
// 		this.programCache = programCache!=null ? programCache : new ProgramCache();
// 		this.assetManager = assetManager;
// 	}
// 
// 	public Context getClContext() {
// 		return clContext;
// 	}
// 
// 	public CommandQueue getClCommandQueue() {
// 		return clCommandQueue;
// 	}
// 
// 	public ProgramCache getProgramCache() {
// 		return programCache;
// 	}
// 
// 	public AssetManager getAssetManager() {
// 		return assetManager;
// 	}
// 
// 	@Override
// 	public int hashCode() {
// 		int hash = 3;
// 		hash = 43 * hash + Objects.hashCode(this.clContext);
// 		hash = 43 * hash + Objects.hashCode(this.clCommandQueue);
// 		return hash;
// 	}
// 
// 	@Override
// 	public boolean equals(Object obj) {
// 		if (obj == null) {
// 			return false;
// 		}
// 		if (getClass() != obj.getClass()) {
// 			return false;
// 		}
// 		final OpenCLSettings other = (OpenCLSettings) obj;
// 		if (!Objects.equals(this.clContext, other.clContext)) {
// 			return false;
// 		}
// 		if (!Objects.equals(this.clCommandQueue, other.clCommandQueue)) {
// 			return false;
// 		}
// 		return true;
// 	}
// 
// }


import com.jme3.asset.AssetManager;
import com.jme3.math.FastMath;
import com.jme3.opencl.*;;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.shaman.jmecl.OpenCLSettings;
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.shaman.jmecl.sorting;


/**
 * Bitonic sort.
 * This is a comparison-based, in-place, non-stable sorting algorithm.
 * For simplicity and speed, the length of the input array must be a power of two.
 * 
 * <p>
 * Peters, H. , Schulz-Hildebrandt, O., Luttenberger, N.,
"Fast in-place, comparison-based sorting with cuda: a
study with bitonic sort," Concurrency and computation,
vol. 2011 (23), no. 7, pp. 681-693.
* http://onlinelibrary.wiley.com/store/10.1002/cpe.1686/asset/1686 ftp.
pdf?v=1&t=ioo1otg2&s=ad0c0650d7248a8d9d943cd0327bbcd7db093c0d
 * @author shaman
 */
public class BitonicSort implements Sorter {
	private static final Logger LOG = Logger.getLogger(BitonicSort.class.getName());
	private static final String PROGRAM_FILE = "org/shaman/jmecl/sorting/BitonicSort.cl";

	private final Context clContext;
	private final Device clDevice;
	private final CommandQueue clQueue;
	private final Sorter.ComparisonSettings settings;
	
	private int sharedMemorySize;
	private int workGroupSize;
	private Program program;
	private Kernel bitonicTrivialKernel;
	private Kernel bitonicSharedKernel;
	
	private final boolean useSharedMemory;

	/**
	 * Creates a new instance of the bitonic sort algorithm.
	 * @param openCLSettings the OpenCL settings
	 * @param comparisonSettings the comparison settings
	 */
// Path: src/main/java/org/shaman/jmecl/OpenCLSettings.java
// public class OpenCLSettings {
// 	
// 	private final Context clContext;
// 	private final CommandQueue clCommandQueue;
// 	private final ProgramCache programCache;
// 	private final AssetManager assetManager;
// 
// 	public OpenCLSettings(Context clContext, CommandQueue clCommandQueue, 
// 			ProgramCache programCache, AssetManager assetManager) {
// 		this.clContext = clContext;
// 		this.clCommandQueue = clCommandQueue;
// 		this.programCache = programCache!=null ? programCache : new ProgramCache();
// 		this.assetManager = assetManager;
// 	}
// 
// 	public Context getClContext() {
// 		return clContext;
// 	}
// 
// 	public CommandQueue getClCommandQueue() {
// 		return clCommandQueue;
// 	}
// 
// 	public ProgramCache getProgramCache() {
// 		return programCache;
// 	}
// 
// 	public AssetManager getAssetManager() {
// 		return assetManager;
// 	}
// 
// 	@Override
// 	public int hashCode() {
// 		int hash = 3;
// 		hash = 43 * hash + Objects.hashCode(this.clContext);
// 		hash = 43 * hash + Objects.hashCode(this.clCommandQueue);
// 		return hash;
// 	}
// 
// 	@Override
// 	public boolean equals(Object obj) {
// 		if (obj == null) {
// 			return false;
// 		}
// 		if (getClass() != obj.getClass()) {
// 			return false;
// 		}
// 		final OpenCLSettings other = (OpenCLSettings) obj;
// 		if (!Objects.equals(this.clContext, other.clContext)) {
// 			return false;
// 		}
// 		if (!Objects.equals(this.clCommandQueue, other.clCommandQueue)) {
// 			return false;
// 		}
// 		return true;
// 	}
// 
// }


// Path: src/main/java/org/shaman/jmecl/sorting/BitonicSort.java
import com.jme3.asset.AssetManager;
import com.jme3.math.FastMath;
import com.jme3.opencl.*;;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.shaman.jmecl.OpenCLSettings;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.shaman.jmecl.sorting;


/**
 * Bitonic sort.
 * This is a comparison-based, in-place, non-stable sorting algorithm.
 * For simplicity and speed, the length of the input array must be a power of two.
 * 
 * <p>
 * Peters, H. , Schulz-Hildebrandt, O., Luttenberger, N.,
"Fast in-place, comparison-based sorting with cuda: a
study with bitonic sort," Concurrency and computation,
vol. 2011 (23), no. 7, pp. 681-693.
* http://onlinelibrary.wiley.com/store/10.1002/cpe.1686/asset/1686 ftp.
pdf?v=1&t=ioo1otg2&s=ad0c0650d7248a8d9d943cd0327bbcd7db093c0d
 * @author shaman
 */
public class BitonicSort implements Sorter {
	private static final Logger LOG = Logger.getLogger(BitonicSort.class.getName());
	private static final String PROGRAM_FILE = "org/shaman/jmecl/sorting/BitonicSort.cl";

	private final Context clContext;
	private final Device clDevice;
	private final CommandQueue clQueue;
	private final Sorter.ComparisonSettings settings;
	
	private int sharedMemorySize;
	private int workGroupSize;
	private Program program;
	private Kernel bitonicTrivialKernel;
	private Kernel bitonicSharedKernel;
	
	private final boolean useSharedMemory;

	/**
	 * Creates a new instance of the bitonic sort algorithm.
	 * @param openCLSettings the OpenCL settings
	 * @param comparisonSettings the comparison settings
	 */
	public BitonicSort(OpenCLSettings openCLSettings, Sorter.ComparisonSettings comparisonSettings) {