text:
package org.apache.hadoop.fs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem.Statistics;

import static org.apache.hadoop.fs.FileSystemTestHelper.*;

import java.io.*;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * This class tests the local file system via the FileSystem abstraction.
 */
public class TestLocalFileSystem {
  private static String TEST_ROOT_DIR
    = System.getProperty("test.build.data","build/test/data/work-dir/localfs");

  private final File base = new File(TEST_ROOT_DIR);
  private Configuration conf;
  private LocalFileSystem fileSys;

  private void cleanupFile(FileSystem fs, Path name) throws IOException {
    assertTrue(fs.exists(name));
    fs.delete(name, true);
    assertTrue(!fs.exists(name));
  }

  @Before
  public void setup() throws IOException {
    conf = new Configuration();
    fileSys = FileSystem.getLocal(conf);
    fileSys.delete(new Path(TEST_ROOT_DIR), true);
  }

  @After
  public void after() throws IOException {
    base.setWritable(true);
    FileUtil.fullyDelete(base);
    assertTrue(!base.exists());
  }

  /**
   * Test the capability of setting the working directory.
   */
  @Test
  public void testWorkingDirectory() throws IOException {
    Path origDir = fileSys.getWorkingDirectory();
    Path subdir = new Path(TEST_ROOT_DIR, "new");
    try {
      // make sure it doesn't already exist
      assertTrue(!fileSys.exists(subdir));
      // make it and check for it
      assertTrue(fileSys.mkdirs(subdir));
      assertTrue(fileSys.isDirectory(subdir));

      fileSys.setWorkingDirectory(subdir);

      // create a directory and check for it
      Path dir1 = new Path("dir1");
      assertTrue(fileSys.mkdirs(dir1));
      assertTrue(fileSys.isDirectory(dir1));

      // delete the directory and make sure it went away
      fileSys.delete(dir1, true);
      assertTrue(!fileSys.exists(dir1));

      // create files and manipulate them.
      Path file1 = new Path("file1");
      Path file2 = new Path("sub/file2");
      String contents = writeFile(fileSys, file1, 1);
      fileSys.copyFromLocalFile(file1, file2);
      assertTrue(fileSys.exists(file1));
      assertTrue(fileSys.isFile(file1));
      cleanupFile(fileSys, file2);
      fileSys.copyToLocalFile(file1, file2);
      cleanupFile(fileSys, file2);

      // try a rename
      fileSys.rename(file1, file2);
      assertTrue(!fileSys.exists(file1));
      assertTrue(fileSys.exists(file2));
      fileSys.rename(file2, file1);

      // try reading a file
      InputStream stm = fileSys.open(file1);
      byte[] buffer = new byte[3];
      int bytesRead = stm.read(buffer, 0, 3);
      assertEquals(contents, new String(buffer, 0, bytesRead));
      stm.close();
    } finally {
      fileSys.setWorkingDirectory(origDir);
    }
  }

  /**
   * test Syncable interface on raw local file system
   * @throws IOException
   */
  @Test
  public void testSyncable() throws IOException {
    Configuration conf = new Configuration();
    FileSystem fs = FileSystem.getLocal(conf).getRawFileSystem();
    Path file = new Path(TEST_ROOT_DIR, "syncable");
    FSDataOutputStream out = fs.create(file);;
    final int bytesWritten = 1;
    byte[] expectedBuf = new byte[] {'0', '1', '2', '3'};
    try {
      out.write(expectedBuf, 0, 1);
      out.hflush();
      verifyFile(fs, file, bytesWritten, expectedBuf);
      out.write(expectedBuf, bytesWritten, expectedBuf.length-bytesWritten);
      out.hsync();
      verifyFile(fs, file, expectedBuf.length, expectedBuf);
    } finally {
      out.close();
    }
  }

  private void verifyFile(FileSystem fs, Path file, int bytesToVerify,
      byte[] expectedBytes) throws IOException {
    FSDataInputStream in = fs.open(file);
    try {
      byte[] readBuf = new byte[bytesToVerify];
      in.readFully(readBuf, 0, bytesToVerify);
      for (int i=0; i<bytesToVerify; i++) {
        assertEquals(expectedBytes[i], readBuf[i]);
      }
    } finally {
      in.close();
    }
  }

  @Test
  public void testCopy() throws IOException {
    Configuration conf = new Configuration();
    LocalFileSystem fs = FileSystem.getLocal(conf);
    Path src = new Path(TEST_ROOT_DIR, "dingo");
    Path dst = new Path(TEST_ROOT_DIR, "yak");
    writeFile(fs, src, 1);
    assertTrue(FileUtil.copy(fs, src, fs, dst, true, false, conf));
    assertTrue(!fs.exists(src) && fs.exists(dst));
    assertTrue(FileUtil.copy(fs, dst, fs, src, false, false, conf));
    assertTrue(fs.exists(src) && fs.exists(dst));
    assertTrue(FileUtil.copy(fs, src, fs, dst, true, true, conf));
    assertTrue(!fs.exists(src) && fs.exists(dst));
    fs.mkdirs(src);
    assertTrue(FileUtil.copy(fs, dst, fs, src, false, false, conf));
    Path tmp = new Path(src, dst.getName());
    assertTrue(fs.exists(tmp) && fs.exists(dst));
    assertTrue(FileUtil.copy(fs, dst, fs, src, false, true, conf));
    assertTrue(fs.delete(tmp, true));
    fs.mkdirs(tmp);
    try {
      FileUtil.copy(fs, dst, fs, src, true, true, conf);
      fail("Failed to detect existing dir");
    } catch (IOException e) {
      // Expected
    }
  }

  @Test
  public void testHomeDirectory() throws IOException {
    Configuration conf = new Configuration();
    FileSystem fileSys = FileSystem.getLocal(conf);
    Path home = new Path(System.getProperty("user.home"))
      .makeQualified(fileSys);
    Path fsHome = fileSys.getHomeDirectory();
    assertEquals(home, fsHome);
  }

  @Test
  public void testPathEscapes() throws IOException {
    Configuration conf = new Configuration();
    FileSystem fs = FileSystem.getLocal(conf);
    Path path = new Path(TEST_ROOT_DIR, "foo%bar");
    writeFile(fs, path, 1);
    FileStatus status = fs.getFileStatus(path);
    assertEquals(path.makeQualified(fs), status.getPath());
    cleanupFile(fs, path);
  }

  @Test
  public void testMkdirs() throws IOException {
    Configuration conf = new Configuration();
    LocalFileSystem fs = FileSystem.getLocal(conf);
    Path test_dir = new Path(TEST_ROOT_DIR, "test_dir");
    Path test_file = new Path(TEST_ROOT_DIR, "file1");
    assertTrue(fs.mkdirs(test_dir));

    writeFile(fs, test_file, 1);
    // creating dir over a file
    Path bad_dir = new Path(test_file, "another_dir");

    try {
      fs.mkdirs(bad_dir);
      fail("Failed to detect existing file in path");
    } catch (FileAlreadyExistsException e) {
      // Expected
    }

    try {
      fs.mkdirs(null);
      fail("Failed to detect null in mkdir arg");
    } catch (IllegalArgumentException e) {
      // Expected
    }
  }

  /** Test deleting a file, directory, and non-existent path */
  @Test
  public void testBasicDelete() throws IOException {
    Configuration conf = new Configuration();
    LocalFileSystem fs = FileSystem.getLocal(conf);
    Path dir1 = new Path(TEST_ROOT_DIR, "dir1");
    Path file1 = new Path(TEST_ROOT_DIR, "file1");
    Path file2 = new Path(TEST_ROOT_DIR+"/dir1", "file2");
    Path file3 = new Path(TEST_ROOT_DIR, "does-not-exist");
    assertTrue(fs.mkdirs(dir1));
    writeFile(fs, file1, 1);
    writeFile(fs, file2, 1);
    assertFalse("Returned true deleting non-existant path",
        fs.delete(file3));
    assertTrue("Did not delete file", fs.delete(file1));
    assertTrue("Did not delete non-empty dir", fs.delete(dir1));
  }

  @Test
  public void testStatistics() throws Exception {
    FileSystem.getLocal(new Configuration());
    int fileSchemeCount = 0;
    for (Statistics stats : FileSystem.getAllStatistics()) {
      if (stats.getScheme().equals("file")) {
        fileSchemeCount++;
      }
    }
    assertEquals(1, fileSchemeCount);
  }

  @Test
  public void testListStatusWithColons() throws IOException {
    Configuration conf = new Configuration();
    LocalFileSystem fs = FileSystem.getLocal(conf);
    File colonFile = new File(TEST_ROOT_DIR, "foo:bar");
    colonFile.mkdirs();
    FileStatus[] stats = fs.listStatus(new Path(TEST_ROOT_DIR));
    assertEquals("Unexpected number of stats", 1, stats.length);
    assertEquals("Bad path from stat", colonFile.getAbsolutePath(),
        stats[0].getPath().toUri().getPath());
  }

  @Test
  public void testReportChecksumFailure() throws IOException {
    base.mkdirs();
    assertTrue(base.exists() && base.isDirectory());

    final File dir1 = new File(base, "dir1");
    final File dir2 = new File(dir1, "dir2");
    dir2.mkdirs();
    assertTrue(dir2.exists() && dir2.canWrite());

    final String dataFileName = "corruptedData";
    final Path dataPath = new Path(new File(dir2, dataFileName).toURI());
    final Path checksumPath = fileSys.getChecksumFile(dataPath);
    final FSDataOutputStream fsdos = fileSys.create(dataPath);
    try {
      fsdos.writeUTF("foo");
    } finally {
      fsdos.close();
    }
    assertTrue(fileSys.pathToFile(dataPath).exists());
    final long dataFileLength = fileSys.getFileStatus(dataPath).getLen();
    assertTrue(dataFileLength > 0);

    // check the the checksum file is created and not empty:
    assertTrue(fileSys.pathToFile(checksumPath).exists());
    final long checksumFileLength = fileSys.getFileStatus(checksumPath).getLen();
    assertTrue(checksumFileLength > 0);

    // this is a hack to force the #reportChecksumFailure() method to stop
    // climbing up at the 'base' directory and use 'dir1/bad_files' as the
    // corrupted files storage:
    base.setWritable(false);

    FSDataInputStream dataFsdis = fileSys.open(dataPath);
    FSDataInputStream checksumFsdis = fileSys.open(checksumPath);

    boolean retryIsNecessary = fileSys.reportChecksumFailure(dataPath, dataFsdis, 0, checksumFsdis, 0);
    assertTrue(!retryIsNecessary);

    // the data file should be moved:
    assertTrue(!fileSys.pathToFile(dataPath).exists());
    // the checksum file should be moved:
    assertTrue(!fileSys.pathToFile(checksumPath).exists());

    // check that the files exist in the new location where they were moved:
    File[] dir1files = dir1.listFiles(new FileFilter() {
      @Override
      public boolean accept(File pathname) {
        return pathname != null && !pathname.getName().equals("dir2");
      }
    });
    assertTrue(dir1files != null);
    assertTrue(dir1files.length == 1);
    File badFilesDir = dir1files[0];

    File[] badFiles = badFilesDir.listFiles();
    assertTrue(badFiles != null);
    assertTrue(badFiles.length == 2);
    boolean dataFileFound = false;
    boolean checksumFileFound = false;
    for (File badFile: badFiles) {
      if (badFile.getName().startsWith(dataFileName)) {
        assertTrue(dataFileLength == badFile.length());
        dataFileFound = true;
      } else if (badFile.getName().contains(dataFileName + ".crc")) {
        assertTrue(checksumFileLength == badFile.length());
        checksumFileFound = true;
      }
    }
    assertTrue(dataFileFound);
    assertTrue(checksumFileFound);
  }

}


text:
package ca.pfv.spmf.datastructures.binarytree;

/**
 * This is a class for testing the binary tree from code and it is intended for developers only.
 *
 * @author Philippe Fournier-Viger
 */
class MainBinaryTree {

	/**
	 * @param args
	 */
	@SuppressWarnings("unchecked")
	public static void main(String[] args) {
		BinaryTree tree = new BinaryTree(true);
		tree.add(1);
		tree.add(2);
		tree.add(5);
		tree.add(6);
		tree.add(7);
		tree.add(9);
		tree.add(3);
		tree.add(4);
		System.out.println("all elements : " + tree.toString() + "   Size of tree: " + tree.size());
		System.out.println("... will try to add 5 another time ...");
		tree.add(5);
		System.out.println("all elements : " + tree.toString() + "   Size of tree: " + tree.size());
		tree.add(500);
		tree.add(501);
		tree.add(100);
		tree.add(101);
		System.out.println("all elements : " + tree.toString() + "   Size of tree: " + tree.size());
		System.out.println("minimum: " + tree.minimum());
		System.out.println("maximum: " + tree.maximum());
		System.out.println("... will remove 7 ");
		tree.remove(7);
		System.out.println("all elements : " + tree.toString() + "   Size of tree: " + tree.size());
		System.out.println("... will remove 2 ");
		tree.remove(2);
		System.out.println("all elements : " + tree.toString() + "   Size of tree: " + tree.size());
		System.out.println("... will remove 5 ");
		tree.remove(5);
		System.out.println("all elements : " + tree.toString() + "   Size of tree: " + tree.size());
		System.out.println("... will remove 5 ");
		tree.remove(5);
		System.out.println("all elements : " + tree.toString() + "   Size of tree: " + tree.size());
		System.out.println("... will add 2 ");
		tree.add(2);
		System.out.println("all elements : " + tree.toString() + "   Size of tree: " + tree.size());
		System.out.println("... will remove 999 ");
		tree.remove(999);

		System.out.println("all elements : " + tree.toString() + "   Size of tree: " + tree.size());
		System.out.println(" lower than 5  = " + tree.lower(5));
		System.out.println(" lower than 1 = " + tree.lower(1));
		System.out.println(" lower than 10 = " + tree.lower(10));
		System.out.println(" lower than 8 = " + tree.lower(8));
		System.out.println(" lower than 200 = " + tree.lower(200));

		System.out.println("all elements : " + tree.toString() + "   Size of tree: " + tree.size());
		System.out.println(" higher than 5  = " + tree.higher(5));
		System.out.println(" higher than 1 = " + tree.higher(1));
		System.out.println(" higher than 10 = " + tree.higher(10));
		System.out.println(" higher than 8 = " + tree.higher(8));
		System.out.println(" higher than 200 = " + tree.higher(200));

		int [] array = {50, 60, 57, 58, 61, 62,  56, 51, 53, 54, 52,  55, 59};
		for(Integer in : array){
			tree.add(in);
		}

//		System.out.println("all elements : " + tree.toString() + "   Size of tree: " + tree.size());
//		tree.removeLowerThan(6);  //  4 ,  102, 500
//		System.out.println("all elements : " + tree.toString() + "   Size of tree: " + tree.size());

//		System.out.println("all elements : " + tree.toString() + "   Size of tree: " + tree.size());
//		System.out.println("... will pop maximum ...");
//		System.out.println(" maximum " + tree.popMaximum());
//		System.out.println("all elements : " + tree.toString() + "   Size of tree: " + tree.size());
//		System.out.println("... will pop maximum ...");
//		System.out.println(" maximum " + tree.popMaximum());
//		System.out.println("all elements : " + tree.toString() + "   Size of tree: " + tree.size());
//		System.out.println("... will pop minimum ...");
//		System.out.println(" minimum " + tree.popMinimum());
//		System.out.println("all elements : " + tree.toString() + "   Size of tree: " + tree.size());
	}

}

redpajama_set_name: RedPajamaGithub


text:
/*!
 * \file
 * \brief Synchronization internally synchronized objects tests
 *//*--------------------------------------------------------------------*/

#include "vktSynchronizationInternallySynchronizedObjectsTests.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktSynchronizationUtil.hpp"
#include "vktCustomInstancesDevices.hpp"

#include "vkRef.hpp"
#include "tcuDefs.hpp"
#include "vkTypeUtil.hpp"
#include "vkBarrierUtil.hpp"
#include "vkPlatform.hpp"
#include "vkBuilderUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkDeviceUtil.hpp"
#include "vkSafetyCriticalUtil.hpp"

#include "tcuResultCollector.hpp"
#include "tcuCommandLine.hpp"

#include "deThread.hpp"
#include "deMutex.hpp"
#include "deSharedPtr.hpp"
#include "deSpinBarrier.hpp"

#include <limits>
#include <iterator>

namespace vkt
{
namespace synchronization
{
namespace
{
using namespace vk;

using std::vector;
using std::string;
using std::map;
using std::exception;
using std::ostringstream;

using tcu::TestStatus;
using tcu::TestContext;
using tcu::ResultCollector;
using tcu::TestException;

using de::UniquePtr;
using de::MovePtr;
using de::SharedPtr;
using de::Mutex;
using de::Thread;
using de::clamp;

template<typename T>
inline SharedPtr<Move<T> > makeVkSharedPtr(Move<T> move)
{
	return SharedPtr<Move<T> >(new Move<T>(move));
}

#ifndef CTS_USES_VULKANSC
enum
{
	EXECUTION_PER_THREAD	= 100,
	BUFFER_ELEMENT_COUNT	= 16,
	BUFFER_SIZE				= BUFFER_ELEMENT_COUNT*4
};
#else
enum
{
	EXECUTION_PER_THREAD	= 10,
	BUFFER_ELEMENT_COUNT	= 16,
	BUFFER_SIZE				= BUFFER_ELEMENT_COUNT*4
};
#endif // CTS_USES_VULKANSC

class MultiQueues
{
	typedef struct QueueType
	{
		vector<VkQueue>							queues;
		vector<bool>							available;
		vector<SharedPtr<Move<VkCommandPool>>>	commandPools;
	} Queues;

public:
	inline void		addQueueFamilyIndex		(const deUint32& queueFamilyIndex, const deUint32& count)
	{
		Queues temp;
		vector<bool>::iterator it;
		it = temp.available.begin();
		temp.available.insert(it, count, false);

		temp.queues.resize(count);

		m_queues[queueFamilyIndex] = temp;
	}

	deUint32 getQueueFamilyIndex (const int index) const
	{
		map<deUint32,Queues>::const_iterator it = begin(m_queues);
		std::advance(it, index);
		return it->first;
	}

	inline size_t	countQueueFamilyIndex	(void)
	{
		return m_queues.size();
	}

	Queues &		getQueues				(int index)
	{
		map<deUint32,Queues>::iterator it = m_queues.begin();
		advance (it, index);
		return it->second;
	}

	bool			getFreeQueue			(const DeviceInterface& vk, const VkDevice device, deUint32& returnQueueFamilyIndex, VkQueue& returnQueues, Move<VkCommandBuffer>& commandBuffer, int& returnQueueIndex)
	{
		for (int queueFamilyIndexNdx = 0 ; queueFamilyIndexNdx < static_cast<int>(m_queues.size()); ++queueFamilyIndexNdx)
		{
			Queues& queue = m_queues[getQueueFamilyIndex(queueFamilyIndexNdx)];
			for (int queueNdx = 0; queueNdx < static_cast<int>(queue.queues.size()); ++queueNdx)
			{
				m_mutex.lock();
				if (queue.available[queueNdx])
				{
					queue.available[queueNdx]	= false;
					returnQueueFamilyIndex		= getQueueFamilyIndex(queueFamilyIndexNdx);
					returnQueues				= queue.queues[queueNdx];
					commandBuffer				= makeCommandBuffer(vk, device, queue.commandPools[queueNdx]->get());
					returnQueueIndex			= queueNdx;
					m_mutex.unlock();
					return true;
				}
				m_mutex.unlock();
			}
		}
		return false;
	}

	void			releaseQueue			(const deUint32& queueFamilyIndex, const int& queueIndex, Move<VkCommandBuffer>& commandBuffer)
	{
		m_mutex.lock();
		commandBuffer = Move<VkCommandBuffer>();
		m_queues[queueFamilyIndex].available[queueIndex] = true;
		m_mutex.unlock();
	}

	inline void		setDevice				(Move<VkDevice> device, const Context& context)
	{
		m_logicalDevice = device;
#ifndef CTS_USES_VULKANSC
		m_deviceDriver = de::MovePtr<DeviceDriver>		(new DeviceDriver(context.getPlatformInterface(), context.getInstance(), *m_logicalDevice));
#else
		m_deviceDriver = de::MovePtr<DeviceDriverSC, DeinitDeviceDeleter>(new DeviceDriverSC(context.getPlatformInterface(), context.getInstance(), *m_logicalDevice, context.getTestContext().getCommandLine(), context.getResourceInterface(), context.getDeviceVulkanSC10Properties(), context.getDeviceProperties()), vk::DeinitDeviceDeleter(context.getResourceInterface().get(), *m_logicalDevice));
#endif // CTS_USES_VULKANSC
	}

	inline VkDevice	getDevice				(void)
	{
		return *m_logicalDevice;
	}

	inline DeviceInterface&	getDeviceInterface(void)
	{
		return *m_deviceDriver;
	}

	MovePtr<Allocator>				m_allocator;
protected:
	Move<VkDevice>					m_logicalDevice;
#ifndef CTS_USES_VULKANSC
	de::MovePtr<vk::DeviceDriver>	m_deviceDriver;
#else
	de::MovePtr<DeviceDriverSC, DeinitDeviceDeleter>	m_deviceDriver;
#endif // CTS_USES_VULKANSC
	map<deUint32,Queues>			m_queues;
	Mutex							m_mutex;
};

MovePtr<Allocator> createAllocator (const Context& context, const VkDevice& device)
{
	const DeviceInterface&					deviceInterface			= context.getDeviceInterface();
	const InstanceInterface&				instance				= context.getInstanceInterface();
	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
	const VkPhysicalDeviceMemoryProperties	deviceMemoryProperties	= getPhysicalDeviceMemoryProperties(instance, physicalDevice);

	// Create memory allocator for device
	return MovePtr<Allocator> (new SimpleAllocator(deviceInterface, device, deviceMemoryProperties));
}

bool checkQueueFlags (const VkQueueFlags& availableFlag, const VkQueueFlags& neededFlag)
{
	if (VK_QUEUE_TRANSFER_BIT == neededFlag)
	{
		if ( (availableFlag & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT ||
			 (availableFlag & VK_QUEUE_COMPUTE_BIT)  == VK_QUEUE_COMPUTE_BIT  ||
			 (availableFlag & VK_QUEUE_TRANSFER_BIT) == VK_QUEUE_TRANSFER_BIT
		   )
			return true;
	}
	else if ((availableFlag & neededFlag) == neededFlag)
	{
		return true;
	}
	return false;
}

MovePtr<MultiQueues> createQueues (Context& context, const VkQueueFlags& queueFlag, const VkInstance& instance, const InstanceInterface& vki)
{
	const VkPhysicalDevice					physicalDevice			= chooseDevice(vki, instance, context.getTestContext().getCommandLine());
	MovePtr<MultiQueues>					moveQueues				(new MultiQueues());
	MultiQueues&							queues					= *moveQueues;
	VkDeviceCreateInfo						deviceInfo;
	VkPhysicalDeviceFeatures				deviceFeatures;
	vector<VkQueueFamilyProperties>			queueFamilyProperties;
	vector<float>							queuePriorities;
	vector<VkDeviceQueueCreateInfo>			queueInfos;

	queueFamilyProperties = getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);

	for (deUint32 queuePropertiesNdx = 0; queuePropertiesNdx < queueFamilyProperties.size(); ++queuePropertiesNdx)
	{
		if (checkQueueFlags(queueFamilyProperties[queuePropertiesNdx].queueFlags, queueFlag))
		{
			queues.addQueueFamilyIndex(queuePropertiesNdx, queueFamilyProperties[queuePropertiesNdx].queueCount);
		}
	}

	if (queues.countQueueFamilyIndex() == 0)
	{
		TCU_THROW(NotSupportedError, "Queue not found");
	}

	{
		vector<float>::iterator it				= queuePriorities.begin();
		unsigned int			maxQueueCount	= 0;
		for (int queueFamilyIndexNdx = 0; queueFamilyIndexNdx < static_cast<int>(queues.countQueueFamilyIndex()); ++queueFamilyIndexNdx)
		{
			if (queues.getQueues(queueFamilyIndexNdx).queues.size() > maxQueueCount)
				maxQueueCount = static_cast<unsigned int>(queues.getQueues(queueFamilyIndexNdx).queues.size());
		}
		queuePriorities.insert(it, maxQueueCount, 1.0);
	}

	for (int queueFamilyIndexNdx = 0; queueFamilyIndexNdx < static_cast<int>(queues.countQueueFamilyIndex()); ++queueFamilyIndexNdx)
	{
		VkDeviceQueueCreateInfo	queueInfo;
		const deUint32			queueCount	= static_cast<deUint32>(queues.getQueues(queueFamilyIndexNdx).queues.size());

		deMemset(&queueInfo, 0, sizeof(queueInfo));

		queueInfo.sType				= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
		queueInfo.pNext				= DE_NULL;
		queueInfo.flags				= (VkDeviceQueueCreateFlags)0u;
		queueInfo.queueFamilyIndex	= queues.getQueueFamilyIndex(queueFamilyIndexNdx);
		queueInfo.queueCount		= queueCount;
		queueInfo.pQueuePriorities	= &queuePriorities[0];

		queueInfos.push_back(queueInfo);
	}

	deMemset(&deviceInfo, 0, sizeof(deviceInfo));
	vki.getPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);

	void* pNext												= DE_NULL;
#ifdef CTS_USES_VULKANSC
	VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
	memReservationInfo.pNext								= pNext;
	pNext													= &memReservationInfo;

	VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
	sc10Features.pNext										= pNext;
	pNext													= &sc10Features;

	VkPipelineCacheCreateInfo			pcCI;
	std::vector<VkPipelinePoolSize>		poolSizes;
	if (context.getTestContext().getCommandLine().isSubProcess())
	{
		if (context.getResourceInterface()->getCacheDataSize() > 0)
		{
			pcCI =
			{
				VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,		// VkStructureType				sType;
				DE_NULL,											// const void*					pNext;
				VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
					VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT,	// VkPipelineCacheCreateFlags	flags;
				context.getResourceInterface()->getCacheDataSize(),	// deUintptr					initialDataSize;
				context.getResourceInterface()->getCacheData()		// const void*					pInitialData;
			};
			memReservationInfo.pipelineCacheCreateInfoCount		= 1;
			memReservationInfo.pPipelineCacheCreateInfos		= &pcCI;
		}

		poolSizes							= context.getResourceInterface()->getPipelinePoolSizes();
		if (!poolSizes.empty())
		{
			memReservationInfo.pipelinePoolSizeCount		= deUint32(poolSizes.size());
			memReservationInfo.pPipelinePoolSizes			= poolSizes.data();
		}
	}
#endif // CTS_USES_VULKANSC

	deviceInfo.sType					= VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
	deviceInfo.pNext					= pNext;
	deviceInfo.enabledExtensionCount	= 0u;
	deviceInfo.ppEnabledExtensionNames	= DE_NULL;
	deviceInfo.enabledLayerCount		= 0u;
	deviceInfo.ppEnabledLayerNames		= DE_NULL;
	deviceInfo.pEnabledFeatures			= &deviceFeatures;
	deviceInfo.queueCreateInfoCount		= static_cast<deUint32>(queues.countQueueFamilyIndex());
	deviceInfo.pQueueCreateInfos		= &queueInfos[0];

	queues.setDevice(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), instance, vki, physicalDevice, &deviceInfo), context);
	vk::DeviceInterface& vk = queues.getDeviceInterface();

	for (deUint32 queueFamilyIndex = 0; queueFamilyIndex < queues.countQueueFamilyIndex(); ++queueFamilyIndex)
	{
		for (deUint32 queueReqNdx = 0; queueReqNdx < queues.getQueues(queueFamilyIndex).queues.size(); ++queueReqNdx)
		{
			vk.getDeviceQueue(queues.getDevice(), queues.getQueueFamilyIndex(queueFamilyIndex), queueReqNdx, &queues.getQueues(queueFamilyIndex).queues[queueReqNdx]);
			queues.getQueues(queueFamilyIndex).available[queueReqNdx]=true;
			queues.getQueues(queueFamilyIndex).commandPools.push_back(makeVkSharedPtr(createCommandPool(vk, queues.getDevice(), VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queues.getQueueFamilyIndex(queueFamilyIndex))));
		}
	}

	queues.m_allocator = createAllocator(context, queues.getDevice());
	return moveQueues;
}

TestStatus executeComputePipeline (const Context& context, const VkPipeline& pipeline, const VkPipelineLayout& pipelineLayout,
									const VkDescriptorSetLayout& descriptorSetLayout, MultiQueues& queues, const deUint32& shadersExecutions)
{
	DE_UNREF(context);
	const DeviceInterface&			vk					= queues.getDeviceInterface();
	const VkDevice					device				= queues.getDevice();
	deUint32						queueFamilyIndex;
	VkQueue							queue;
	int								queueIndex;
	Move<VkCommandBuffer>			cmdBuffer;
	while(!queues.getFreeQueue(vk, device, queueFamilyIndex, queue, cmdBuffer, queueIndex)){}

	{
		const Unique<VkDescriptorPool>	descriptorPool		(DescriptorPoolBuilder()
																.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
																.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
		Buffer							resultBuffer		(vk, device, *queues.m_allocator, makeBufferCreateInfo(BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
		const VkBufferMemoryBarrier		bufferBarrier		= makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *resultBuffer, 0ull, BUFFER_SIZE);

		{
			const Allocation& alloc = resultBuffer.getAllocation();
			deMemset(alloc.getHostPtr(), 0, BUFFER_SIZE);
			flushAlloc(vk, device, alloc);
		}

		// Start recording commands
		beginCommandBuffer(vk, *cmdBuffer);

		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);

		// Create descriptor set
		const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, descriptorSetLayout));

		const VkDescriptorBufferInfo resultDescriptorInfo = makeDescriptorBufferInfo(*resultBuffer, 0ull, BUFFER_SIZE);

		DescriptorSetUpdateBuilder()
			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultDescriptorInfo)
			.update(vk, device);

		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);

		// Dispatch indirect compute command
		vk.cmdDispatch(*cmdBuffer, shadersExecutions, 1u, 1u);

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
								 0, (const VkMemoryBarrier*)DE_NULL,
								 1, &bufferBarrier,
								 0, (const VkImageMemoryBarrier*)DE_NULL);

		// End recording commands
		endCommandBuffer(vk, *cmdBuffer);

		// Wait for command buffer execution finish
		submitCommandsAndWait(vk, device, queue, *cmdBuffer);
		queues.releaseQueue(queueFamilyIndex, queueIndex, cmdBuffer);

		{
			const Allocation& resultAlloc = resultBuffer.getAllocation();
			invalidateAlloc(vk, device, resultAlloc);

			const deInt32*	ptr = reinterpret_cast<deInt32*>(resultAlloc.getHostPtr());
			for (deInt32 ndx = 0; ndx < BUFFER_ELEMENT_COUNT; ++ndx)
			{
				if (ptr[ndx] != ndx)
				{
					return TestStatus::fail("The data don't match");
				}
			}
		}
		return TestStatus::pass("Passed");
	}
}

TestStatus executeGraphicPipeline (const Context& context, const VkPipeline& pipeline, const VkPipelineLayout& pipelineLayout,
									const VkDescriptorSetLayout& descriptorSetLayout, MultiQueues& queues, const VkRenderPass& renderPass, const deUint32 shadersExecutions)
{
	DE_UNREF(context);
	const DeviceInterface&			vk					= queues.getDeviceInterface();
	const VkDevice					device				= queues.getDevice();
	deUint32						queueFamilyIndex;
	VkQueue							queue;
	int								queueIndex;
	Move<VkCommandBuffer>			cmdBuffer;
	while (!queues.getFreeQueue(vk, device, queueFamilyIndex, queue, cmdBuffer, queueIndex)) {}

	{
		const Unique<VkDescriptorPool>	descriptorPool				(DescriptorPoolBuilder()
																		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
																		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
		Move<VkDescriptorSet>			descriptorSet				= makeDescriptorSet(vk, device, *descriptorPool, descriptorSetLayout);
		Buffer							resultBuffer				(vk, device, *queues.m_allocator, makeBufferCreateInfo(BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
		const VkBufferMemoryBarrier		bufferBarrier				= makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *resultBuffer, 0ull, BUFFER_SIZE);
		const VkFormat					colorFormat					= VK_FORMAT_R8G8B8A8_UNORM;
		const VkExtent3D				colorImageExtent			= makeExtent3D(1u, 1u, 1u);
		const VkImageSubresourceRange	colorImageSubresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
		de::MovePtr<Image>				colorAttachmentImage		= de::MovePtr<Image>(new Image(vk, device, *queues.m_allocator,
																		makeImageCreateInfo(VK_IMAGE_TYPE_2D, colorImageExtent, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL),
																		MemoryRequirement::Any));
		Move<VkImageView>				colorAttachmentView			= makeImageView(vk, device, **colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorImageSubresourceRange);
		Move<VkFramebuffer>				framebuffer					= makeFramebuffer(vk, device, renderPass, *colorAttachmentView, colorImageExtent.width, colorImageExtent.height);
		const VkDescriptorBufferInfo	outputBufferDescriptorInfo	= makeDescriptorBufferInfo(*resultBuffer, 0ull, BUFFER_SIZE);

		DescriptorSetUpdateBuilder()
			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputBufferDescriptorInfo)
			.update		(vk, device);

		{
			const Allocation& alloc = resultBuffer.getAllocation();
			deMemset(alloc.getHostPtr(), 0, BUFFER_SIZE);
			flushAlloc(vk, device, alloc);
		}

		// Start recording commands
		beginCommandBuffer(vk, *cmdBuffer);
		// Change color attachment image layout
		{
			const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
				(VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
				VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
				**colorAttachmentImage, colorImageSubresourceRange);

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0,
				0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
		}

		{
			const VkRect2D	renderArea	= makeRect2D(1u, 1u);
			const tcu::Vec4	clearColor	= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
			beginRenderPass(vk, *cmdBuffer, renderPass, *framebuffer, renderArea, clearColor);
		}

		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);

		vk.cmdDraw(*cmdBuffer, shadersExecutions, 1u, 0u, 0u);
		endRenderPass(vk, *cmdBuffer);

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
						0, (const VkMemoryBarrier*)DE_NULL,
						1, &bufferBarrier,
						0, (const VkImageMemoryBarrier*)DE_NULL);

		// End recording commands
		endCommandBuffer(vk, *cmdBuffer);

		// Wait for command buffer execution finish
		submitCommandsAndWait(vk, device, queue, *cmdBuffer);
		queues.releaseQueue(queueFamilyIndex, queueIndex, cmdBuffer);

		{
			const Allocation& resultAlloc = resultBuffer.getAllocation();
			invalidateAlloc(vk, device, resultAlloc);

			const deInt32*	ptr = reinterpret_cast<deInt32*>(resultAlloc.getHostPtr());
			for (deInt32 ndx = 0; ndx < BUFFER_ELEMENT_COUNT; ++ndx)
			{
				if (ptr[ndx] != ndx)
				{
					return TestStatus::fail("The data don't match");
				}
			}
		}
		return TestStatus::pass("Passed");
	}
}

class ThreadGroupThread : private Thread
{
public:
							ThreadGroupThread	(const Context& context, VkPipelineCache pipelineCache, const VkPipelineLayout& pipelineLayout,
												const VkDescriptorSetLayout& descriptorSetLayout, MultiQueues& queues, const vector<deUint32>& shadersExecutions)
								: m_context				(context)
								, m_pipelineCache		(pipelineCache)
								, m_pipelineLayout		(pipelineLayout)
								, m_descriptorSetLayout	(descriptorSetLayout)
								, m_queues				(queues)
								, m_shadersExecutions	(shadersExecutions)
								, m_barrier				(DE_NULL)
	{
	}

	virtual					~ThreadGroupThread	(void)
	{
	}

	ResultCollector&		getResultCollector	(void)
	{
		return m_resultCollector;
	}

	void					start				(de::SpinBarrier* groupBarrier);
	using Thread::join;

protected:
	virtual TestStatus		runThread		() = 0;
	const Context&							m_context;
	VkPipelineCache							m_pipelineCache;
	const VkPipelineLayout&					m_pipelineLayout;
	const VkDescriptorSetLayout&			m_descriptorSetLayout;
	MultiQueues&							m_queues;
	const vector<deUint32>&					m_shadersExecutions;

	void					barrier				(void);

private:
							ThreadGroupThread	(const ThreadGroupThread&);
	ThreadGroupThread&		operator=			(const ThreadGroupThread&);

	void					run					(void)
	{
		try
		{
			TestStatus result = runThread();
			m_resultCollector.addResult(result.getCode(), result.getDescription());
		}
		catch (const TestException& e)
		{
			m_resultCollector.addResult(e.getTestResult(), e.getMessage());
		}
		catch (const exception& e)
		{
			m_resultCollector.addResult(QP_TEST_RESULT_FAIL, e.what());
		}
		catch (...)
		{
			m_resultCollector.addResult(QP_TEST_RESULT_FAIL, "Exception");
		}

		m_barrier->removeThread(de::SpinBarrier::WAIT_MODE_AUTO);
	}

	ResultCollector							m_resultCollector;
	de::SpinBarrier*						m_barrier;
};

void ThreadGroupThread::start (de::SpinBarrier* groupBarrier)
{
	m_barrier = groupBarrier;
	de::Thread::start();
}

inline void ThreadGroupThread::barrier (void)
{
	m_barrier->sync(de::SpinBarrier::WAIT_MODE_AUTO);
}

class ThreadGroup
{
	typedef vector<SharedPtr<ThreadGroupThread> >	ThreadVector;
public:
							ThreadGroup			(void)
								: m_barrier(1)
	{
	}
							~ThreadGroup		(void)
	{
	}

	void					add					(MovePtr<ThreadGroupThread> thread)
	{
		m_threads.push_back(SharedPtr<ThreadGroupThread>(thread.release()));
	}

	TestStatus				run					(void)
	{
		ResultCollector	resultCollector;

		m_barrier.reset((int)m_threads.size());

		for (ThreadVector::iterator threadIter = m_threads.begin(); threadIter != m_threads.end(); ++threadIter)
			(*threadIter)->start(&m_barrier);

		for (ThreadVector::iterator threadIter = m_threads.begin(); threadIter != m_threads.end(); ++threadIter)
		{
			ResultCollector&	threadResult	= (*threadIter)->getResultCollector();
			(*threadIter)->join();
			resultCollector.addResult(threadResult.getResult(), threadResult.getMessage());
		}

		return TestStatus(resultCollector.getResult(), resultCollector.getMessage());
	}

private:
	ThreadVector							m_threads;
	de::SpinBarrier							m_barrier;
};

class CreateComputeThread : public ThreadGroupThread
{
public:
			CreateComputeThread	(const Context& context, VkPipelineCache pipelineCache, vector<VkComputePipelineCreateInfo>& pipelineInfo,
								const VkPipelineLayout& pipelineLayout, const VkDescriptorSetLayout& descriptorSetLayout,
								MultiQueues& queues, const vector<deUint32>& shadersExecutions)
				: ThreadGroupThread		(context, pipelineCache, pipelineLayout, descriptorSetLayout, queues, shadersExecutions)
				, m_pipelineInfo		(pipelineInfo)
	{
	}

	TestStatus	runThread		(void)
	{
		ResultCollector		resultCollector;
		for (int executionNdx = 0; executionNdx < EXECUTION_PER_THREAD; ++executionNdx)
		{
			const int shaderNdx					= executionNdx % (int)m_pipelineInfo.size();
			const DeviceInterface&	vk			= m_context.getDeviceInterface();
			const VkDevice			device		= m_queues.getDevice();
			Move<VkPipeline>		pipeline	= createComputePipeline(vk,device,m_pipelineCache, &m_pipelineInfo[shaderNdx]);

			TestStatus result = executeComputePipeline(m_context, *pipeline, m_pipelineLayout, m_descriptorSetLayout, m_queues, m_shadersExecutions[shaderNdx]);

#ifdef CTS_USES_VULKANSC
			// While collecting pipelines, synchronize between all threads for each pipeline that gets
			// created, so we will reserve the maximum amount of pipeline pool space that could need.
			if (!m_context.getTestContext().getCommandLine().isSubProcess()) {
				barrier();
			}
#endif

			resultCollector.addResult(result.getCode(), result.getDescription());
		}
		return TestStatus(resultCollector.getResult(), resultCollector.getMessage());
	}
private:
	vector<VkComputePipelineCreateInfo>&	m_pipelineInfo;
};

class CreateGraphicThread : public ThreadGroupThread
{
public:
			CreateGraphicThread	(const Context& context, VkPipelineCache pipelineCache, vector<VkGraphicsPipelineCreateInfo>& pipelineInfo,
								const VkPipelineLayout& pipelineLayout, const VkDescriptorSetLayout& descriptorSetLayout,
								MultiQueues& queues, const VkRenderPass& renderPass, const vector<deUint32>& shadersExecutions)
				: ThreadGroupThread		(context, pipelineCache, pipelineLayout, descriptorSetLayout, queues, shadersExecutions)
				, m_pipelineInfo		(pipelineInfo)
				, m_renderPass			(renderPass)
	{}

	TestStatus	runThread		(void)
	{
		ResultCollector		resultCollector;
		for (int executionNdx = 0; executionNdx < EXECUTION_PER_THREAD; ++executionNdx)
		{
			const int shaderNdx					= executionNdx % (int)m_pipelineInfo.size();
			const DeviceInterface&	vk			= m_context.getDeviceInterface();
			const VkDevice			device		= m_queues.getDevice();
			Move<VkPipeline>		pipeline	= createGraphicsPipeline(vk,device, m_pipelineCache, &m_pipelineInfo[shaderNdx]);

			TestStatus result = executeGraphicPipeline(m_context, *pipeline, m_pipelineLayout, m_descriptorSetLayout, m_queues, m_renderPass, m_shadersExecutions[shaderNdx]);

#ifdef CTS_USES_VULKANSC
			// While collecting pipelines, synchronize between all threads for each pipeline that gets
			// created, so we will reserve the maximum amount of pipeline pool space that could need.
			if (!m_context.getTestContext().getCommandLine().isSubProcess()) {
				barrier();
			}
#endif

			resultCollector.addResult(result.getCode(), result.getDescription());
		}
		return TestStatus(resultCollector.getResult(), resultCollector.getMessage());
	}

private:
	vector<VkGraphicsPipelineCreateInfo>&	m_pipelineInfo;
	const VkRenderPass&						m_renderPass;
};

class PipelineCacheComputeTestInstance  : public TestInstance
{
	typedef vector<SharedPtr<Unique<VkShaderModule> > > ShaderModuleVector;
public:
				PipelineCacheComputeTestInstance	(Context& context, const vector<deUint32>& shadersExecutions)
					: TestInstance			(context)
					, m_shadersExecutions	(shadersExecutions)

	{
	}

	TestStatus	iterate								(void)
	{
#ifdef CTS_USES_VULKANSC
		MultithreadedDestroyGuard				mdGuard				(m_context.getResourceInterface());
#endif // CTS_USES_VULKANSC
		const CustomInstance					instance			(createCustomInstanceFromContext(m_context));
		const InstanceDriver&					instanceDriver		(instance.getDriver());

		MovePtr<MultiQueues>					queues				= createQueues(m_context, VK_QUEUE_COMPUTE_BIT, instance, instanceDriver);
		const DeviceInterface&					vk					= queues->getDeviceInterface();
		const VkDevice							device				= queues->getDevice();
		ShaderModuleVector						shaderCompModules	= addShaderModules(device);
		Buffer									resultBuffer		(vk, device, *queues->m_allocator, makeBufferCreateInfo(BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
		const Move<VkDescriptorSetLayout>		descriptorSetLayout	(DescriptorSetLayoutBuilder()
																		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
																		.build(vk, device));
		const Move<VkPipelineLayout>			pipelineLayout		(makePipelineLayout(vk, device, *descriptorSetLayout));
		vector<VkPipelineShaderStageCreateInfo>	shaderStageInfos	= addShaderStageInfo(shaderCompModules);
		vector<VkComputePipelineCreateInfo>		pipelineInfo		= addPipelineInfo(*pipelineLayout, shaderStageInfos);
		const VkPipelineCacheCreateInfo			pipelineCacheInfo	=
																	{
																		VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,	// VkStructureType             sType;
																		DE_NULL,										// const void*                 pNext;
#ifndef CTS_USES_VULKANSC
																		0u,												// VkPipelineCacheCreateFlags  flags;
																		0u,												// deUintptr                   initialDataSize;
																		DE_NULL,										// const void*                 pInitialData;
#else
																		VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
																			VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT,	// VkPipelineCacheCreateFlags	flags;
																		m_context.getResourceInterface()->getCacheDataSize(),		// deUintptr					initialDataSize;
																		m_context.getResourceInterface()->getCacheData()			// const void*					pInitialData;
#endif // CTS_USES_VULKANSC
																	};
		Move<VkPipelineCache>					pipelineCache		= createPipelineCache(vk, device, &pipelineCacheInfo);
		Move<VkPipeline>						pipeline			= createComputePipeline(vk, device, *pipelineCache, &pipelineInfo[0]);
#ifndef CTS_USES_VULKANSC
		const deUint32							numThreads			= clamp(deGetNumAvailableLogicalCores(), 4u, 32u);
#else
		const deUint32							numThreads			= 2u;
#endif // CTS_USES_VULKANSC
		ThreadGroup								threads;

		executeComputePipeline(m_context, *pipeline, *pipelineLayout, *descriptorSetLayout, *queues, m_shadersExecutions[0]);

		for (deUint32 ndx = 0; ndx < numThreads; ++ndx)
			threads.add(MovePtr<ThreadGroupThread>(new CreateComputeThread(
				m_context, *pipelineCache, pipelineInfo, *pipelineLayout, *descriptorSetLayout, *queues, m_shadersExecutions)));

		{
			TestStatus thread_result = threads.run();
			if(thread_result.getCode())
			{
				return thread_result;
			}
		}
		return TestStatus::pass("Passed");
	}

private:
	ShaderModuleVector							addShaderModules					(const VkDevice& device)
	{
		const DeviceInterface&	vk	= m_context.getDeviceInterface();
		ShaderModuleVector		shaderCompModules;
		shaderCompModules.resize(m_shadersExecutions.size());
		for (int shaderNdx = 0; shaderNdx <  static_cast<int>(m_shadersExecutions.size()); ++shaderNdx)
		{
			ostringstream shaderName;
			shaderName<<"compute_"<<shaderNdx;
			shaderCompModules[shaderNdx] = SharedPtr<Unique<VkShaderModule> > (new Unique<VkShaderModule>(createShaderModule(vk, device, m_context.getBinaryCollection().get(shaderName.str()), (VkShaderModuleCreateFlags)0)));
		}
		return shaderCompModules;
	}

	vector<VkPipelineShaderStageCreateInfo>		addShaderStageInfo					(const ShaderModuleVector& shaderCompModules)
	{
		VkPipelineShaderStageCreateInfo			shaderStageInfo;
		vector<VkPipelineShaderStageCreateInfo>	shaderStageInfos;
		shaderStageInfo.sType				=	VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
		shaderStageInfo.pNext				=	DE_NULL;
		shaderStageInfo.flags				=	(VkPipelineShaderStageCreateFlags)0;
		shaderStageInfo.stage				=	VK_SHADER_STAGE_COMPUTE_BIT;
		shaderStageInfo.pName				=	"main";
		shaderStageInfo.pSpecializationInfo	=	DE_NULL;

		for (int shaderNdx = 0; shaderNdx <  static_cast<int>(m_shadersExecutions.size()); ++shaderNdx)
		{
			shaderStageInfo.module = *(*shaderCompModules[shaderNdx]);
			shaderStageInfos.push_back(shaderStageInfo);
		}
		return shaderStageInfos;
	}

	vector<VkComputePipelineCreateInfo>		addPipelineInfo						(VkPipelineLayout pipelineLayout, const vector<VkPipelineShaderStageCreateInfo>& shaderStageInfos)
	{
		vector<VkComputePipelineCreateInfo> pipelineInfos;
		VkComputePipelineCreateInfo	computePipelineInfo;
									computePipelineInfo.sType				= VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
									computePipelineInfo.pNext				= DE_NULL;
									computePipelineInfo.flags				= (VkPipelineCreateFlags)0;
									computePipelineInfo.layout				= pipelineLayout;
									computePipelineInfo.basePipelineHandle	= DE_NULL;
									computePipelineInfo.basePipelineIndex	= 0;

		for (int shaderNdx = 0; shaderNdx < static_cast<int>(m_shadersExecutions.size()); ++shaderNdx)
		{
			computePipelineInfo.stage = shaderStageInfos[shaderNdx];
			pipelineInfos.push_back(computePipelineInfo);
		}
		return pipelineInfos;
	}

	const vector<deUint32>	m_shadersExecutions;
};

class PipelineCacheGraphicTestInstance  : public TestInstance
{
	typedef vector<SharedPtr<Unique<VkShaderModule> > > ShaderModuleVector;
public:
											PipelineCacheGraphicTestInstance	(Context& context, const vector<deUint32>& shadersExecutions)
								: TestInstance			(context)
								, m_shadersExecutions	(shadersExecutions)

	{
	}

	TestStatus								iterate								(void)
	{
#ifdef CTS_USES_VULKANSC
		MultithreadedDestroyGuard				mdGuard					(m_context.getResourceInterface());
#endif // CTS_USES_VULKANSC
		const CustomInstance					instance				(createCustomInstanceFromContext(m_context));
		const InstanceDriver&					instanceDriver			(instance.getDriver());
		const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, m_context.getTestContext().getCommandLine());
		requireFeatures(instanceDriver, physicalDevice, FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);

		MovePtr<MultiQueues>					queues					= createQueues(m_context, VK_QUEUE_GRAPHICS_BIT, instance, instanceDriver);
		const DeviceInterface&					vk						= m_context.getDeviceInterface();
		const VkDevice							device					= queues->getDevice();
		VkFormat								colorFormat				= VK_FORMAT_R8G8B8A8_UNORM;
		Move<VkRenderPass>						renderPass				= makeRenderPass(vk, device, colorFormat);
		const Move<VkDescriptorSetLayout>		descriptorSetLayout		(DescriptorSetLayoutBuilder()
																			.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_VERTEX_BIT)
																			.build(vk, device));
		ShaderModuleVector						shaderGraphicModules	= addShaderModules(device);
		const Move<VkPipelineLayout>			pipelineLayout			(makePipelineLayout(vk, device, *descriptorSetLayout));
		vector<VkPipelineShaderStageCreateInfo>	shaderStageInfos		= addShaderStageInfo(shaderGraphicModules);
		vector<VkGraphicsPipelineCreateInfo>	pipelineInfo			= addPipelineInfo(*pipelineLayout, shaderStageInfos, *renderPass);
		const VkPipelineCacheCreateInfo			pipelineCacheInfo		=
																		{
																			VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,	// VkStructureType             sType;
																			DE_NULL,										// const void*                 pNext;
#ifndef CTS_USES_VULKANSC
																			0u,												// VkPipelineCacheCreateFlags  flags;
																			0u,												// deUintptr                   initialDataSize;
																			DE_NULL											// const void*                 pInitialData;
#else
																			VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
																				VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT,	// VkPipelineCacheCreateFlags	flags;
																			m_context.getResourceInterface()->getCacheDataSize(),		// deUintptr					initialDataSize;
																			m_context.getResourceInterface()->getCacheData()			// const void*					pInitialData;
#endif // CTS_USES_VULKANSC
																		};
		Move<VkPipelineCache>					pipelineCache			= createPipelineCache(vk, device, &pipelineCacheInfo);
		Move<VkPipeline>						pipeline				= createGraphicsPipeline(vk, device, *pipelineCache, &pipelineInfo[0]);
#ifndef CTS_USES_VULKANSC
		const deUint32							numThreads				= clamp(deGetNumAvailableLogicalCores(), 4u, 32u);
#else
		const deUint32							numThreads				= 2u;
#endif // CTS_USES_VULKANSC
		ThreadGroup								threads;

		executeGraphicPipeline(m_context, *pipeline, *pipelineLayout, *descriptorSetLayout, *queues, *renderPass, m_shadersExecutions[0]);

		for (deUint32 ndx = 0; ndx < numThreads; ++ndx)
			threads.add(MovePtr<ThreadGroupThread>(new CreateGraphicThread(
				m_context, *pipelineCache, pipelineInfo, *pipelineLayout, *descriptorSetLayout, *queues, *renderPass, m_shadersExecutions)));

		{
			TestStatus thread_result = threads.run();
			if(thread_result.getCode())
			{
				return thread_result;
			}
		}
		return TestStatus::pass("Passed");
	}

private:
	ShaderModuleVector						addShaderModules					(const VkDevice& device)
	{
		const DeviceInterface&	vk					= m_context.getDeviceInterface();
		ShaderModuleVector		shaderModules;
		shaderModules.resize(m_shadersExecutions.size() + 1);
		for (int shaderNdx = 0; shaderNdx <  static_cast<int>(m_shadersExecutions.size()); ++shaderNdx)
		{
			ostringstream shaderName;
			shaderName<<"vert_"<<shaderNdx;
			shaderModules[shaderNdx] = SharedPtr<Unique<VkShaderModule> > (new Unique<VkShaderModule>(createShaderModule(vk, device, m_context.getBinaryCollection().get(shaderName.str()), (VkShaderModuleCreateFlags)0)));
		}
		shaderModules[m_shadersExecutions.size()] = SharedPtr<Unique<VkShaderModule> > (new Unique<VkShaderModule>(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), (VkShaderModuleCreateFlags)0)));
		return shaderModules;
	}

	vector<VkPipelineShaderStageCreateInfo>	addShaderStageInfo					(const ShaderModuleVector& shaderCompModules)
	{
		VkPipelineShaderStageCreateInfo			shaderStageInfo;
		vector<VkPipelineShaderStageCreateInfo>	shaderStageInfos;
		shaderStageInfo.sType				=	VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
		shaderStageInfo.pNext				=	DE_NULL;
		shaderStageInfo.flags				=	(VkPipelineShaderStageCreateFlags)0;
		shaderStageInfo.pName				=	"main";
		shaderStageInfo.pSpecializationInfo	=	DE_NULL;

		for (int shaderNdx = 0; shaderNdx <  static_cast<int>(m_shadersExecutions.size()); ++shaderNdx)
		{
			shaderStageInfo.stage	=	VK_SHADER_STAGE_VERTEX_BIT;
			shaderStageInfo.module	= *(*shaderCompModules[shaderNdx]);
			shaderStageInfos.push_back(shaderStageInfo);

			shaderStageInfo.stage	=	VK_SHADER_STAGE_FRAGMENT_BIT;
			shaderStageInfo.module	= *(*shaderCompModules[m_shadersExecutions.size()]);
			shaderStageInfos.push_back(shaderStageInfo);
		}
		return shaderStageInfos;
	}

	vector<VkGraphicsPipelineCreateInfo>	addPipelineInfo						(VkPipelineLayout pipelineLayout, const vector<VkPipelineShaderStageCreateInfo>& shaderStageInfos, const VkRenderPass& renderPass)
	{
		VkExtent3D								colorImageExtent	= makeExtent3D(1u, 1u, 1u);
		vector<VkGraphicsPipelineCreateInfo>	pipelineInfo;

		m_vertexInputStateParams.sType								= VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
		m_vertexInputStateParams.pNext								= DE_NULL;
		m_vertexInputStateParams.flags								= 0u;
		m_vertexInputStateParams.vertexBindingDescriptionCount		= 0u;
		m_vertexInputStateParams.pVertexBindingDescriptions			= DE_NULL;
		m_vertexInputStateParams.vertexAttributeDescriptionCount	= 0u;
		m_vertexInputStateParams.pVertexAttributeDescriptions		= DE_NULL;

		m_inputAssemblyStateParams.sType					= VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
		m_inputAssemblyStateParams.pNext					= DE_NULL;
		m_inputAssemblyStateParams.flags					= 0u;
		m_inputAssemblyStateParams.topology					= VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
		m_inputAssemblyStateParams.primitiveRestartEnable	= VK_FALSE;

		m_viewport.x			= 0.0f;
		m_viewport.y			= 0.0f;
		m_viewport.width		= (float)colorImageExtent.width;
		m_viewport.height		= (float)colorImageExtent.height;
		m_viewport.minDepth		= 0.0f;
		m_viewport.maxDepth		= 1.0f;

		//TODO
		m_scissor.offset.x		= 0;
		m_scissor.offset.y		= 0;
		m_scissor.extent.width	= colorImageExtent.width;
		m_scissor.extent.height	= colorImageExtent.height;

		m_viewportStateParams.sType			= VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
		m_viewportStateParams.pNext			= DE_NULL;
		m_viewportStateParams.flags			= 0u;
		m_viewportStateParams.viewportCount	= 1u;
		m_viewportStateParams.pViewports	= &m_viewport;
		m_viewportStateParams.scissorCount	= 1u;
		m_viewportStateParams.pScissors		= &m_scissor;

		m_rasterStateParams.sType					= VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
		m_rasterStateParams.pNext					= DE_NULL;
		m_rasterStateParams.flags					= 0u;
		m_rasterStateParams.depthClampEnable		= VK_FALSE;
		m_rasterStateParams.rasterizerDiscardEnable	= VK_FALSE;
		m_rasterStateParams.polygonMode				= VK_POLYGON_MODE_FILL;
		m_rasterStateParams.cullMode				= VK_CULL_MODE_NONE;
		m_rasterStateParams.frontFace				= VK_FRONT_FACE_COUNTER_CLOCKWISE;
		m_rasterStateParams.depthBiasEnable			= VK_FALSE;
		m_rasterStateParams.depthBiasConstantFactor	= 0.0f;
		m_rasterStateParams.depthBiasClamp			= 0.0f;
		m_rasterStateParams.depthBiasSlopeFactor	= 0.0f;
		m_rasterStateParams.lineWidth				= 1.0f;

		m_colorBlendAttachmentState.blendEnable			= VK_FALSE;
		m_colorBlendAttachmentState.srcColorBlendFactor	= VK_BLEND_FACTOR_ONE;
		m_colorBlendAttachmentState.dstColorBlendFactor	= VK_BLEND_FACTOR_ZERO;
		m_colorBlendAttachmentState.colorBlendOp		= VK_BLEND_OP_ADD;
		m_colorBlendAttachmentState.srcAlphaBlendFactor	= VK_BLEND_FACTOR_ONE;
		m_colorBlendAttachmentState.dstAlphaBlendFactor	= VK_BLEND_FACTOR_ZERO;
		m_colorBlendAttachmentState.alphaBlendOp		= VK_BLEND_OP_ADD;
		m_colorBlendAttachmentState.colorWriteMask		= VK_COLOR_COMPONENT_R_BIT |
														  VK_COLOR_COMPONENT_G_BIT |
														  VK_COLOR_COMPONENT_B_BIT |
														  VK_COLOR_COMPONENT_A_BIT;

		m_colorBlendStateParams.sType				= VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
		m_colorBlendStateParams.pNext				= DE_NULL;
		m_colorBlendStateParams.flags				= 0u;
		m_colorBlendStateParams.logicOpEnable		= VK_FALSE;
		m_colorBlendStateParams.logicOp				= VK_LOGIC_OP_COPY;
		m_colorBlendStateParams.attachmentCount		= 1u;
		m_colorBlendStateParams.pAttachments		= &m_colorBlendAttachmentState;
		m_colorBlendStateParams.blendConstants[0]	= 0.0f;
		m_colorBlendStateParams.blendConstants[1]	= 0.0f;
		m_colorBlendStateParams.blendConstants[2]	= 0.0f;
		m_colorBlendStateParams.blendConstants[3]	= 0.0f;

		m_multisampleStateParams.sType					= VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
		m_multisampleStateParams.pNext					= DE_NULL;
		m_multisampleStateParams.flags					= 0u;
		m_multisampleStateParams.rasterizationSamples	= VK_SAMPLE_COUNT_1_BIT;
		m_multisampleStateParams.sampleShadingEnable	= VK_FALSE;
		m_multisampleStateParams.minSampleShading		= 0.0f;
		m_multisampleStateParams.pSampleMask			= DE_NULL;
		m_multisampleStateParams.alphaToCoverageEnable	= VK_FALSE;
		m_multisampleStateParams.alphaToOneEnable		= VK_FALSE;

		m_depthStencilStateParams.sType					= VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
		m_depthStencilStateParams.pNext					= DE_NULL;
		m_depthStencilStateParams.flags					= 0u;
		m_depthStencilStateParams.depthTestEnable		= VK_TRUE;
		m_depthStencilStateParams.depthWriteEnable		= VK_TRUE;
		m_depthStencilStateParams.depthCompareOp		= VK_COMPARE_OP_LESS_OR_EQUAL;
		m_depthStencilStateParams.depthBoundsTestEnable	= VK_FALSE;
		m_depthStencilStateParams.stencilTestEnable		= VK_FALSE;
		m_depthStencilStateParams.front.failOp			= VK_STENCIL_OP_KEEP;
		m_depthStencilStateParams.front.passOp			= VK_STENCIL_OP_KEEP;
		m_depthStencilStateParams.front.depthFailOp		= VK_STENCIL_OP_KEEP;
		m_depthStencilStateParams.front.compareOp		= VK_COMPARE_OP_NEVER;
		m_depthStencilStateParams.front.compareMask		= 0u;
		m_depthStencilStateParams.front.writeMask		= 0u;
		m_depthStencilStateParams.front.reference		= 0u;
		m_depthStencilStateParams.back.failOp			= VK_STENCIL_OP_KEEP;
		m_depthStencilStateParams.back.passOp			= VK_STENCIL_OP_KEEP;
		m_depthStencilStateParams.back.depthFailOp		= VK_STENCIL_OP_KEEP;
		m_depthStencilStateParams.back.compareOp		= VK_COMPARE_OP_NEVER;
		m_depthStencilStateParams.back.compareMask		= 0u;
		m_depthStencilStateParams.back.writeMask		= 0u;
		m_depthStencilStateParams.back.reference		= 0u;
		m_depthStencilStateParams.minDepthBounds		= 0.0f;
		m_depthStencilStateParams.maxDepthBounds		= 1.0f;

		VkGraphicsPipelineCreateInfo	graphicsPipelineParams	=
																{
																	VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
																	DE_NULL,											// const void*										pNext;
																	0u,													// VkPipelineCreateFlags							flags;
																	2u,													// deUint32											stageCount;
																	DE_NULL,											// const VkPipelineShaderStageCreateInfo*			pStages;
																	&m_vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
																	&m_inputAssemblyStateParams,						// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
																	DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
																	&m_viewportStateParams,								// const VkPipelineViewportStateCreateInfo*			pViewportState;
																	&m_rasterStateParams,								// const VkPipelineRasterizationStateCreateInfo*	pRasterState;
																	&m_multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
																	&m_depthStencilStateParams,							// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
																	&m_colorBlendStateParams,							// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
																	(const VkPipelineDynamicStateCreateInfo*)DE_NULL,	// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
																	pipelineLayout,										// VkPipelineLayout									layout;
																	renderPass,											// VkRenderPass										renderPass;
																	0u,													// deUint32											subpass;
																	DE_NULL,											// VkPipeline										basePipelineHandle;
																	0,													// deInt32											basePipelineIndex;
																};
		for (int shaderNdx = 0; shaderNdx < static_cast<int>(m_shadersExecutions.size()) * 2; shaderNdx+=2)
		{
			graphicsPipelineParams.pStages = &shaderStageInfos[shaderNdx];
			pipelineInfo.push_back(graphicsPipelineParams);
		}
		return pipelineInfo;
	}

	const vector<deUint32>					m_shadersExecutions;
	VkPipelineVertexInputStateCreateInfo	m_vertexInputStateParams;
	VkPipelineInputAssemblyStateCreateInfo	m_inputAssemblyStateParams;
	VkViewport								m_viewport;
	VkRect2D								m_scissor;
	VkPipelineViewportStateCreateInfo		m_viewportStateParams;
	VkPipelineRasterizationStateCreateInfo	m_rasterStateParams;
	VkPipelineColorBlendAttachmentState		m_colorBlendAttachmentState;
	VkPipelineColorBlendStateCreateInfo		m_colorBlendStateParams;
	VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
	VkPipelineDepthStencilStateCreateInfo	m_depthStencilStateParams;
};

class PipelineCacheComputeTest : public TestCase
{
public:
							PipelineCacheComputeTest	(TestContext&		testCtx,
														const string&		name,
														const string&		description)
								:TestCase	(testCtx, name, description)
	{
	}

	void					initPrograms				(SourceCollections&	programCollection) const
	{
		ostringstream buffer;
		buffer	<< "layout(set = 0, binding = 0, std430) buffer Output\n"
				<< "{\n"
				<< "	int result[];\n"
				<< "} sb_out;\n";
		{
			ostringstream src;
			src	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
				<< "\n"
				<< "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
				<< "\n"
				<< buffer.str()
				<< "void main (void)\n"
				<< "{\n"
				<< "	highp uint ndx = gl_GlobalInvocationID.x;\n"
				<< "	sb_out.result[ndx] = int(ndx);\n"
				<< "}\n";
			programCollection.glslSources.add("compute_0") << glu::ComputeSource(src.str());
		}
		{
			ostringstream src;
			src	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
				<< "\n"
				<< "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
				<< "\n"
				<< buffer.str()
				<< "void main (void)\n"
				<< "{\n"
				<< "	for (highp uint ndx = 0u; ndx < "<<BUFFER_ELEMENT_COUNT<<"u; ndx++)\n"
				<< "	{\n"
				<< "		sb_out.result[ndx] = int(ndx);\n"
				<< "	}\n"
				<< "}\n";
			programCollection.glslSources.add("compute_1") << glu::ComputeSource(src.str());
		}
		{
			ostringstream src;
			src	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
				<< "\n"
				<< "layout(local_size_x = "<<BUFFER_ELEMENT_COUNT<<", local_size_y = 1, local_size_z = 1) in;\n"
				<< "\n"
				<< buffer.str()
				<< "void main (void)\n"
				<< "{\n"
				<< "	highp uint ndx = gl_LocalInvocationID.x;\n"
				<< "	sb_out.result[ndx] = int(ndx);\n"
				<< "}\n";
			programCollection.glslSources.add("compute_2") << glu::ComputeSource(src.str());
		}
	}

	TestInstance*			createInstance				(Context& context) const
	{
		vector<deUint32>	shadersExecutions;
		shadersExecutions.push_back(16u);	//compute_0
		shadersExecutions.push_back(1u);	//compute_1
		shadersExecutions.push_back(1u);	//compute_2
		return new PipelineCacheComputeTestInstance(context, shadersExecutions);
	}
};

class PipelineCacheGraphicTest : public TestCase
{
public:
							PipelineCacheGraphicTest	(TestContext&		testCtx,
														const string&		name,
														const string&		description)
								:TestCase	(testCtx, name, description)
	{

	}

	void					initPrograms				(SourceCollections&	programCollection) const
	{
		ostringstream buffer;
		buffer	<< "layout(set = 0, binding = 0, std430) buffer Output\n"
				<< "{\n"
				<< "	int result[];\n"
				<< "} sb_out;\n";

		// Vertex
		{
			std::ostringstream src;
			src	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
				<< "\n"
				<< buffer.str()
				<< "\n"
				<< "void main (void)\n"
				<< "{\n"
				<< "   sb_out.result[gl_VertexIndex] = int(gl_VertexIndex);\n"
				<< "   gl_PointSize = 1.0f;\n"
				<< "}\n";
			programCollection.glslSources.add("vert_0") << glu::VertexSource(src.str());
		}
		// Vertex
		{
			std::ostringstream src;
			src	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
				<< "\n"
				<< buffer.str()
				<< "\n"
				<< "void main (void)\n"
				<< "{\n"
				<< "	for (highp uint ndx = 0u; ndx < "<<BUFFER_ELEMENT_COUNT<<"u; ndx++)\n"
				<< "	{\n"
				<< "		sb_out.result[ndx] = int(ndx);\n"
				<< "	}\n"
				<< "	gl_PointSize = 1.0f;\n"
				<< "}\n";
			programCollection.glslSources.add("vert_1") << glu::VertexSource(src.str());
		}
		// Vertex
		{
			std::ostringstream src;
			src	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
				<< "\n"
				<< buffer.str()
				<< "\n"
				<< "void main (void)\n"
				<< "{\n"
				<< "	for (int ndx = "<<BUFFER_ELEMENT_COUNT-1<<"; ndx >= 0; ndx--)\n"
				<< "	{\n"
				<< "		sb_out.result[uint(ndx)] = ndx;\n"
				<< "	}\n"
				<< "	gl_PointSize = 1.0f;\n"
				<< "}\n";
			programCollection.glslSources.add("vert_2") << glu::VertexSource(src.str());
		}
		// Fragment
		{
			std::ostringstream src;
			src	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
				<< "\n"
				<< "layout(location = 0) out vec4 o_color;\n"
				<< "\n"
				<< "void main (void)\n"
				<< "{\n"
				<< "    o_color = vec4(1.0);\n"
				<< "}\n";
			programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
		}
	}

	TestInstance*			createInstance				(Context& context) const
	{
		vector<deUint32>	shadersExecutions;
		shadersExecutions.push_back(16u);	//vert_0
		shadersExecutions.push_back(1u);	//vert_1
		shadersExecutions.push_back(1u);	//vert_2
		return new PipelineCacheGraphicTestInstance(context, shadersExecutions);
	}
};

} // anonymous

tcu::TestCaseGroup* createInternallySynchronizedObjects (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> tests(new tcu::TestCaseGroup(testCtx, "internally_synchronized_objects", "Internally synchronized objects"));
	tests->addChild(new PipelineCacheComputeTest(testCtx, "pipeline_cache_compute", "Internally synchronized object VkPipelineCache for compute pipeline is tested"));
	tests->addChild(new PipelineCacheGraphicTest(testCtx, "pipeline_cache_graphics", "Internally synchronized object VkPipelineCache for graphics pipeline is tested"));
	return tests.release();
}

} // synchronization
} // vkt


text:
KISSY.Editor.add("htmlparser-comment", function() {
    var KE = KISSY.Editor,KEN = KE.NODE;

    /**
     * @constructor
     * @param value
     */
    function MComment(value) {
        /**
         * The comment text.
         * @type String
         * @example
         */
        this.value = value;

        /** @private */
        this._ =
        {
            isBlockLike : false
        };
    }

    KE.HtmlParser.Comment = MComment;
    KE.HtmlParser["Comment"] = MComment;
    MComment.prototype = {
        constructor:MComment,
        /**
         * The node type. This is a constant value set to  NODE_COMMENT.
         * @type Number
         * @example
         */
        type : KEN.NODE_COMMENT,

        /**
         * Writes the HTML representation of this comment to a CKEDITOR.htmlWriter.
         * @param  writer The writer to which write the HTML.
         * @example
         */
        writeHtml : function(writer, filter) {
            var comment = this.value;

            if (filter) {
                if (!( comment = filter.onComment(comment, this) ))
                    return;

                if (typeof comment != 'string') {
                    comment.parent = this.parent;
                    comment.writeHtml(writer, filter);
                    return;
                }
            }

            writer.comment(comment);
        }
    };
});


text:
package eu.com.cwsfe.cms.domains;

/**
 * Created by Radoslaw Osinski.
 */
public enum BlogKeywordStatus {

    NEW("N"), DELETED("D");

    private final String code;

    BlogKeywordStatus(String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }

    public static BlogKeywordStatus fromCode(String text) {
        if (text != null) {
            for (BlogKeywordStatus enumValue : BlogKeywordStatus.values()) {
                if (enumValue.code.equals(text)) {
                    return enumValue;
                }
            }
        }
        return null;
    }

}


text:
```
sudo pip install shutit
git clone --recursive <this repo>
cd <this repo folder>
./run.sh
```


text:
package com.pinterest.terrapin.client;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.pinterest.terrapin.thrift.generated.Options;
import com.pinterest.terrapin.thrift.generated.TerrapinGetErrorCode;
import com.pinterest.terrapin.thrift.generated.TerrapinGetException;
import com.pinterest.terrapin.zookeeper.FileSetInfo;
import com.pinterest.terrapin.zookeeper.ViewInfo;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.helix.model.ExternalView;
import org.junit.Before;
import org.junit.Test;

import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
 * Test for FileSetViewManager.
 */
public class FileSetViewManagerTest {
  private static final String FILE_SET = "file_set";

  private FileSetViewManager manager;

  @Before
  public void setUp() {
    manager = new FileSetViewManager("test");
  }

  private void triggerFileSetInfoWatch(String fileSet, FileSetInfo fsInfo) throws Exception {
    manager.zkBackedFileSetInfoMap.put(fileSet, manager.fileSetInfoFunction.apply(fsInfo.toJson()));
  }

  private void triggerViewInfoWatch(ViewInfo viewInfo) throws Exception {
    manager.zkBackedViewInfoMap.put(viewInfo.getResource(),
        manager.viewInfoFunction.apply(viewInfo.toCompressedJson()));
  }

  @Test
  public void testWithBackup() throws Exception {
    boolean exception = false;
    try {
      manager.getFileSetViewInfo(FILE_SET);
    } catch (TerrapinGetException e) {
      assertEquals(TerrapinGetErrorCode.FILE_SET_NOT_FOUND, e.getErrorCode());
      exception = true;
    }
    assertTrue(exception);
    // Now, a fileset watch is triggered but the external view is not triggered.
    FileSetInfo fsInfo1 = new FileSetInfo(
        "file_set", "/terrapin/data/file_set/1", 1, (List)Lists.newArrayList(), new Options());
    triggerFileSetInfoWatch(FILE_SET, fsInfo1);
    exception = false;
    try {
      manager.getFileSetViewInfo(FILE_SET);
    } catch (TerrapinGetException e) {
      assertEquals(TerrapinGetErrorCode.INVALID_FILE_SET_VIEW, e.getErrorCode());
      exception = true;
    }
    assertTrue(exception);

    // Now the watch for the first view is triggered.
    ExternalView externalView1 = new ExternalView("$terrapin$data$file_set$1");
    externalView1.setStateMap("0", ImmutableMap.of("host1", "ONLINE"));
    ViewInfo viewInfo1 = new ViewInfo(externalView1);
    triggerViewInfoWatch(viewInfo1);

    Pair<FileSetInfo, ViewInfo> pair = manager.getFileSetViewInfo(FILE_SET);
    assertEquals(fsInfo1, pair.getLeft());
    assertEquals(viewInfo1, pair.getRight());

    // The fileset info alone gets updated but the other watch is not yet triggered.
    FileSetInfo fsInfo2 = new FileSetInfo(
        FILE_SET, "/terrapin/data/file_set/2", 1, (List)Lists.newArrayList(), new Options());
    triggerFileSetInfoWatch(FILE_SET, fsInfo2);
    pair = manager.getFileSetViewInfo(FILE_SET);
    // We should see the view from the backup only.
    assertEquals(fsInfo1, pair.getLeft());
    assertEquals(viewInfo1, pair.getRight());

    // Finally, a watch is triggered for the resource corresponding to the second fileset.
    ExternalView externalView2 = new ExternalView("$terrapin$data$file_set$2");
    externalView2.setStateMap("0", ImmutableMap.of("host2", "ONLINE"));
    ViewInfo viewInfo2 = new ViewInfo(externalView2);
    triggerViewInfoWatch(viewInfo2);

    pair = manager.getFileSetViewInfo(FILE_SET);
    assertEquals(fsInfo2, pair.getLeft());
    assertEquals(viewInfo2, pair.getRight());

    // Watches execute in the correct order. Firs the view is propagated.
    ExternalView externalView3 = new ExternalView("$terrapin$data$file_set$3");
    externalView3.setStateMap("0", ImmutableMap.of("host3", "ONLINE"));
    ViewInfo viewInfo3 = new ViewInfo(externalView3);
    triggerViewInfoWatch(viewInfo3);

    // We should still continue to serve previous view.
    pair = manager.getFileSetViewInfo(FILE_SET);
    assertEquals(fsInfo2, pair.getLeft());
    assertEquals(viewInfo2, pair.getRight());

    // Finally, the fileset version update watch is propagated.
    FileSetInfo fsInfo3 = new FileSetInfo(
        FILE_SET, "/terrapin/data/file_set/3", 1, (List)Lists.newArrayList(), new Options());
    triggerFileSetInfoWatch(FILE_SET, fsInfo3);

    pair = manager.getFileSetViewInfo(FILE_SET);
    assertEquals(fsInfo3, pair.getLeft());
    assertEquals(viewInfo3, pair.getRight());
  }
}


text:
#ifndef TB_CONTAINER_H
#define TB_CONTAINER_H

/* //////////////////////////////////////////////////////////////////////////////////////
 * includes
 */
#include "prefix.h"
#include "element.h"
#include "iterator.h"
#include "array_iterator.h"
#include "heap.h"
#include "stack.h"
#include "vector.h"
#include "hash_set.h"
#include "hash_map.h"
#include "queue.h"
#include "circle_queue.h"
#include "priority_queue.h"
#include "list.h"
#include "list_entry.h"
#include "single_list.h"
#include "single_list_entry.h"
#include "bloom_filter.h"

#endif


text:
__author__ = 'nick.york'
__license__ = 'https://www.apache.org/licenses/LICENSE-2.0'
__copyright__ = 'Copyright (c) 2015 Virtual Instruments Corporation. All rights reserved.'
__date__ = '2015-02-22'
__version__ = '1.0'

# requires python requests module by Kenneth Reitz
# http://docs.python-requests.org/en/latest/
# git clone git://github.com/kennethreitz/requests.git
# pip3 install requests
import requests
import json
import sys, os, optparse

jsonheaders = {'content-type': 'application/json'}
requests.packages.urllib3.disable_warnings()
s = requests.session()

def ParseCmdLineParameters():
    opts = optparse.OptionParser(description='Upload a JSON Entity Import File to VirtualWisdom.')
    opts.add_option("-v", "--virtualwisdom", action="store", type="string", dest="host")
    opts.add_option("-u", "--username", action="store", type="string", dest="username")
    opts.add_option("-p", "--password", action="store", type="string", dest="password")
    opts.add_option("-z", "--password-file", action="store", type="string", dest="passwordfile")
    opts.add_option("-f", "--file", action="store", type="string", dest="filename")
    opts.add_option("-i", "--stdin", action="store_true", dest="stdin", default=False)
    opts.add_option("-F", "--force", action="store_true", dest="force", default=False)
    opt, argv = opts.parse_args()

    if opt.host == None or opt.username == None or (opt.password == None and opt.passwordfile == None) or (opt.filename == None and not opt.stdin):
        PrintHelpAndExit("You must specify the VirtualWisdom host, username, password or password file and file to import or stdin.")
        exit()

    if opt.passwordfile != None:
        if not os.path.exists(opt.passwordfile):
            PrintHelpAndExit("Specified password file does not exist.")

    if opt.filename != None:
        if not os.path.exists(opt.filename):
            PrintHelpAndExit("Specified entity file does not exist.")

    return opt

def PrintHelpAndExit(errormessage=""):
    if (errormessage != ""):
        print("\n\n" + errormessage)
    print("\n\nUsage:\n\tEntityImport -v <VW Appliance IP> -u <Username> -p <Password> -f <Entity Import File>\n\n\tEntityImport -v <VW Appliance IP> -u <Username> -z <PasswordFile> -f <Entity Import File>\n\n\t\techo 'admin' > pwfile\n\t\tchmod 600 pwfile\n\t\tpython3 EntityImport.py -v 10.20.30.40 -u Administrator -z pwfile -f import.json\n\n")
    exit()

# the server will do a much more thorough job of validating
# this is just making sure that the user has really specified a json file
# and that it has a version, before we start logging into VW
def ValidateJSON(fh=None,str=None):
    try:
        if fh is not None:
            inputobject = json.load(fh)
        else:
            inputobject = json.loads(str)
    except ValueError as e:
        PrintHelpAndExit("Provided JSON could not be parsed.\n\n" + e)
    if ("version" not in inputobject or inputobject["version"] not in (1, 2)):
        PrintHelpAndExit("Provided JSON does not conform to VW4 Entity Import standard.  Version number mismatch.")
    if ("entities" not in inputobject or len(inputobject["entities"]) == 0):
        PrintHelpAndExit("Provided JSON contains no entities.")
    return inputobject

# logs into VirtualWisdom using the provided credentials
# on the global session
def VirtualWisdomLogin(ipaddr, login, password):
    loginpayload = { 'username' : login, 'password' : password, 'targetRoute' : None}
    try:
        r = s.post('https://{0}/api/sec/login'.format(ipaddr), verify=False, data=loginpayload)
        if 'Login failed' in r.text:
            PrintHelpAndExit("Unable to log into VirtualWisdom with the provided credentials")
        else:
            r = s.get('https://{0}/api/sec/session'.format(ipaddr), verify=False)
            if r.json()['status'] == "OK":
                return
            else:
                PrintHelpAndExit("Logged into VirtualWisdom, but session check was unsuccessful")
    except requests.exceptions.SSLError:
        import ssl
        print('PROTOCOL_TLSv1_2 in ssl.__dict__: {0}'.format('PROTOCOL_TLSv1_2' in ssl.__dict__))
        PrintHelpAndExit("Exception caught connecting to VW. OpenSSL version does not support TLSv1.2: {0}".format(ssl.OPENSSL_VERSION))
    except requests.exceptions.ConnectionError:
        PrintHelpAndExit("Exception caught connecting to VW. Please check your IP address")

# uploads entity import file, checks validation and commits changes if validation successful
def UploadEntityImport(ipaddr, payload, force=False):
    #try:
    # undocumented and unsupported apis, subject to change in every release
    r = s.post('https://%s/api/config/entity/import/start' % (ipaddr), verify=False, data=json.dumps(payload), headers=jsonheaders)
    if r.status_code == 200 and r.json()['status'] == "OK":
        transactionid = r.json()['result']['transactionId']
        commitpayload = {"transactionId":transactionid,"async":"true"}
        # undocumented and unsupported apis, subject to change in every release
        r = s.put('https://{0}/api/config/entity/import/commit'.format(ipaddr), verify=False, data=json.dumps(commitpayload), headers=jsonheaders)
        return True
    else:
        # loop through the errors and print them all out
        for entity in r.json()['result']['entities']:
            try:
                print("\nMessage: " + entity['marker']['message'])
                print("Entity: {0} [{1}]".format(entity['name'], entity['type']))
                print("Location: Line: {0} Column: {1}".format(entity['marker']['location']['line'], entity['marker']['location']['column']))
            except:
                pass

        if not force:
            print("\n\nValidation failure.  To attempt to import anyway run again with --force\n")
            exit()
        else:
            transactionid = r.json()['result']['transactionId']
            commitpayload = {"transactionId":transactionid,"async":"true"}
            # undocumented and unsupported apis, subject to change in every release
            r = s.put('https://{0}/api/config/entity/import/commit'.format(ipaddr), verify=False, data=json.dumps(commitpayload), headers=jsonheaders)
            if r.status_code == 200 and r.json()['status'] == "OK":
                return True
            else:
                print(r.status_code)
                print(r.json()['status'])
                print("Force failed.")
                exit()
    #except:
    #    PrintHelpAndExit("Exception caught during Entity Import.")

def main():
    options = ParseCmdLineParameters()

    # if the user specified an entity file, use it otherwise read from standard input
    if options.filename != None:
        payload = ValidateJSON(fh=open(options.filename, 'r'))
    else:
        stdinstring = ''.join(sys.stdin.readlines())
        payload = ValidateJSON(str=stdinstring)

    # if the user specified a password use it, otherwise read from the provided password file
    if options.password != None:
        VirtualWisdomLogin(options.host, options.username, options.password)
    else:
        VirtualWisdomLogin(options.host, options.username, open(options.passwordfile,'r').readline().strip())

    UploadEntityImport(options.host, payload, force=options.force)
    print("Successfully Imported!")

if __name__ == '__main__':
    main()


text:
#include "entity_viewer.hpp"
#include <higanbana/core/entity/query.hpp>
#include <higanbana/core/datastructures/deque.hpp>
#include <higanbana/core/datastructures/vector.hpp>
#include "components.hpp"
#include <imgui.h>
#include <optional>

using namespace higanbana;

namespace app
{
void EntityView::render(higanbana::Database<2048>& ecs)
{
  //ImGui::ShowDemoWindow(&m_show);
  /*
  */
  if (ImGui::Begin("EntityViewer", &m_show, ImGuiWindowFlags_AlwaysAutoResize)) {
    auto& childsTable = ecs.get<components::Childs>();
    auto& names = ecs.get<components::Name>();
    auto& meshes = ecs.get<components::Mesh>();
    auto& matrices = ecs.get<components::Matrix>();

    auto& activeScenes = ecs.get<components::SceneInstance>();
    higanbana::Id oldActiveScene = 0;
    bool wasActive = false;

    higanbana::Id activeGameObject;

    query(pack(activeScenes), [&](higanbana::Id id, components::SceneInstance target){
      oldActiveScene = target.target;
      activeGameObject = id;
      wasActive = true;
    });

    if (!wasActive)
    {
      auto id = ecs.createEntity();
      activeScenes.insert(id, components::SceneInstance{oldActiveScene});
      ecs.get<components::Position>().insert(id, components::Position{float3(0,0,0)});
      activeGameObject = id;
    }

    // choose active gltf scene... take first one for now.
    auto nameInstance = names.tryGet(oldActiveScene);
    std::string currentSceneStr = "null";
    if (nameInstance)
    {
      currentSceneStr = nameInstance.value().str;
    }
    bool activeSceneSet = false;
    higanbana::Id newActiveScene = oldActiveScene;
    if (ImGui::BeginCombo("Active GLTF scene", currentSceneStr.c_str()))
    {
      query(pack(names), pack(ecs.getTag<components::GltfNode>()), [&](higanbana::Id id, components::Name& name)
      {
        bool selected = id == newActiveScene;
        if (ImGui::Selectable(name.str.c_str(), selected))
        {
          newActiveScene = id;
        }
        if (selected)
        {
          ImGui::SetItemDefaultFocus();
        }
      });
      ImGui::EndCombo();
    }

    activeScenes.insert(activeGameObject, components::SceneInstance{newActiveScene});

    // viewer part functionality
    ImGui::NewLine();
    auto hasMesh = [&](higanbana::Id id){
    if (auto meshId = meshes.tryGet(id))
    {
      std::string meshn = "mesh " + std::to_string(meshId.value().target);
      ImGui::Text(meshn.c_str());
    }
    };

    auto hasMatrix = [&](higanbana::Id id){
    if (auto matrix = matrices.tryGet(id))
    {
      std::string matn = "matrics " + std::to_string(id);
      if (ImGui::TreeNode(matn.c_str()))
      {
        float4x4 val = matrix.value().mat;
        matn.clear();
        for (int i = 0; i < 16;++i)
        {
          matn += " " + std::to_string(val(i));
          if ((i+1) % 4 == 0)
          {
            matn += "\n";
            //ImGui::Text(matn.c_str());
            //ImGui::NewLine();
            //matn.clear();
          }
        }
        ImGui::Text(matn.c_str());
        ImGui::TreePop();
      }
    }
    };

    auto allChecks = [&](higanbana::Id id)
    {
    hasMesh(id);
    hasMatrix(id);
    };

    auto forSingleId = [&](higanbana::Id id) -> std::optional<components::Childs>
    {
    std::string nodeName = "node ";
    if (auto name = names.tryGet(id))
    {
      nodeName += name.value().str;
    }
    nodeName += "##";
    nodeName += std::to_string(id);
    if (ImGui::TreeNode(nodeName.c_str())) {
      allChecks(id);
      if (auto opt = childsTable.tryGet(id))
      {
        return opt; // early out to form a tree, defer TreePop to later date.
      }
      ImGui::TreePop();
    }
    return {};
    };

    query(pack(names, childsTable), pack(ecs.getTag<components::GltfNode>()), [&](higanbana::Id id, components::Name& name, components::Childs& childs)
    {
    higanbana::deque<higanbana::vector<higanbana::Id>> stack;
    auto clds = forSingleId(id);
    if (clds)
    {
      // memoize tree traversal
      stack.push_back(clds.value().childs);
      while (!stack.empty())
      {
        if (stack.back().empty())
        {
          stack.pop_back();
          ImGui::TreePop(); // to match ImGui TreeNode counts.
          continue;
        }
        auto& workingSet = stack.back();
        auto val = workingSet.back();
        workingSet.pop_back();
        if (auto new_chlds = forSingleId(val))
        {
          stack.push_back(new_chlds.value().childs);
        }
      }
    }
    });
  }

  ImGui::End();
}
};


text:
""" Encoding/decoding `wc_lang` models to/from SBML and
reading/writing SBML-encoded models to/from XML files, one per submodel.

This enables WC-Lang-encoded models to be "round-tripped" with this sequence of operations:

1. Model is transformed to remove metadata that can't be exported to SBML
2. Model is split into multiple models, each with one submodel
3. Each model with one submodel is exported to SBML
4. Each model with one submodel is imported from SBML
5. Models with individual submodels are merged into a single model

WC-Lang models are exported to SBML with the following class mapping:

=============================  =====================
WC-Lang                        SBML
=============================  =====================
Model                          Model
Taxon                          Model.annotation
Environment                    Model.annotation
Submodel                       Model
Compartment                    Compartment
SpeciesType                    Species.annotation
Species                        Species
DistributionInitConcentration  Species.initialAmount
Observable                     AssignmentRule
ObservableExpression           AssignmentRule.math
Function                       AssignmentRule
FunctionExpression             AssignmentRule.math
Reaction                       Reaction
SpeciesCoefficient             SpeciesReference
RateLaw                        KineticLaw
RateLawExpression              KineticLaw.math
Parameter                      Parameter
DfbaObjective                  Objective
DfbaObjectiveExpression        FluxObjective
DfbaObjReaction                Reaction
DfbaObjSpecies                 SpeciesReference
StopCondition                  --
StopConditionExpression        --
Observation                       --
Conclusion                 --
Reference                      --
Author                         Model.annotation
Change                         --
Identifier              SBase.annotation
pint.Unit                      UnitDefinition
obj_model.Model.comments       SBase.notes
=============================  =====================

In addition, WC-Lang attributes which have no equivalent SBML attribute are mapped to
``SBase.annotation``.

Note, that because WC-Lang and SBML have different semantics, some of aspects of
WC-Lang cannot be mapped to SBML and vice-versa.

:Author: Jonathan Karr <karr@mssm.edu>
:Author: Arthur Goldberg <Arthur.Goldberg@mssm.edu>
:Date: 2019-03-21
:Copyright: 2017-2019, Karr Lab
:License: MIT
"""

from obj_model.utils import group_objects_by_model
from wc_lang.transform.prep_for_sbml import PrepForSbmlTransform
from wc_lang.sbml.util import LibSbmlInterface
from wc_onto import onto
from wc_utils.util.ontology import are_terms_equivalent
from wc_utils.util.units import unit_registry
import abc
import glob
import libsbml
import obj_model
import os
import warnings
import wc_lang.core

class SbmlWriter(object):
    """ Write `wc_lang` models to collections of SBML-encoded XML files, one for each submodel """

    def run(self, model, dirname):
        """ Write the submodels of a `wc_lang` model to separate SBML-encoded XML files.

        Args:
            model (:obj:`wc_lang.core.Model`): `wc_lang` model
            dirname (:obj:`str`): path to directory to save SBML-encoded XML files for each submodel

        Raises:
            :obj:`ValueError`: if the model could not be written to a SBML-encoded file
        """
        # validate model
        model = PrepForSbmlTransform().run(model.copy())
        error = wc_lang.core.Validator().run(model)
        if error:
            warnings.warn('Model is invalid: ' + str(error), wc_lang.core.WcLangWarning)

        # split submodels into separate models
        core, submodels = model.submodels.gen_models()
        all_models = [core] + submodels
        all_models_ids = ['core'] + [m.submodels[0].id for m in submodels]

        # create a directory to save SBML-encoded XML documents for model
        if not os.path.isdir(dirname):
            os.makedirs(dirname)

        # encode models in SBML and save to XML file
        for model, model_id in zip(all_models, all_models_ids):
            # encode models in SBML
            sbml_doc = SbmlExporter.run(model)

            # save SBML-encoded model to XML file
            path = os.path.join(dirname, model_id + '.xml')
            if not LibSbmlInterface.call_libsbml(libsbml.writeSBMLToFile, sbml_doc, path, returns_int=True):
                raise ValueError("Submodel '{}' could not be written to SBML at '{}'.".format(
                    model_id, path))

class SbmlReader(object):
    """ Read `wc_lang` models from SBML-encoded XML files, one for each submodel """

    def run(self, dirname):
        """ Read `wc_lang` models from SBML-encoded XML files, one for each submodel

        Args:
            dirname (:obj:`str`): path to directory that contains SBML-encoded submodels of a model

        Returns:
            model (:obj:`wc_lang.core.Model`): `wc_lang` model
        """
        merged_model = None
        sbml_reader = LibSbmlInterface.call_libsbml(libsbml.SBMLReader)

        paths = glob.glob(os.path.join(dirname, '*.xml'))
        core_path = os.path.join(dirname, 'core.xml')
        if core_path in paths:
            paths.remove(core_path)
            paths.insert(0, core_path)

        for path in paths:
            # read model from XML file
            sbml_doc = LibSbmlInterface.call_libsbml(sbml_reader.readSBMLFromFile, path)
            LibSbmlInterface.raise_if_error(sbml_doc, 'Model could not be read from {}'.format(path))

            # convert SBML-encoded model to wc_lang
            model = SbmlImporter.run(sbml_doc)

            import obj_model.core
            error = obj_model.core.Validator().run(model, get_related=True)
            assert error is None, str(error)

            # merge models
            if merged_model is None:
                merged_model = model
            else:
                merged_model.merge(model)

        # return merged model
        return merged_model

class SbmlExporter(object):
    """ Encode a `wc_lang` model with at most 1 submodel into SBML """

    @classmethod
    def run(cls, model):
        """ Encode a `wc_lang` model with at most 1 submodel into SBML

        * Validate model
        * Create SBML document
        * Create SBML model
        * Encode model objects in SBML and add to SBML model in dependent order

        Args:
            model (:obj:`wc_lang.core.Model`): `wc_lang` model with at most 1 submodel

        Returns:
            :obj:`libsbml.SBMLDocument`: SBML document with SBML-encoded model

        Raises:
            :obj:`ValueError`: if the model cannot be exported to SBML because it contains multiple submodels
        """
        # verify model has at most 1 submodel
        if len(model.submodels) > 1:
            raise ValueError('Only 1 submodel can be encoded to SBML at a time')

        # validate model
        error = wc_lang.core.Validator().run(model)
        if error:
            warnings.warn('Model is invalid: ' + str(error), wc_lang.core.WcLangWarning)

        # determine SBML packages needed to export model
        packages = {}
        for submodel in model.submodels:
            if submodel.framework == onto['WC:dynamic_flux_balance_analysis']:
                packages['fbc'] = 2

        # create an SBML document
        sbml_doc = LibSbmlInterface.create_doc(packages=packages)

        # create a SBML model
        sbml_model = LibSbmlInterface.init_model(model, sbml_doc, packages=packages)

        # add objects to SBML model
        related_objs = model.get_related()
        sbml_objs = []
        for obj in related_objs:
            sbml_obj = obj.export_to_sbml(sbml_model)
            sbml_objs.append(sbml_obj)

        # add object relationships to SBML
        for obj, sbml_obj in zip(related_objs, sbml_objs):
            obj.export_relations_to_sbml(sbml_model, sbml_obj)

        # verify document is compatible with SBML, valid SBML, and consistent
        LibSbmlInterface.verify_doc(sbml_doc)

        # return SBML document
        return sbml_doc

class SbmlImporter(object):
    """ Import a `wc_lang` model from an SBML-encoded model """

    @classmethod
    def run(cls, sbml_doc):
        """ Import a `wc_lang` model from an SBML-encoded model

        Args:
            sbml_doc (:obj:`libsbml.SBMLDocument`): SBML document with SBML-encoded model

        Returns:
            :obj:`wc_lang.core.Model`: `wc_lang` model
        """
        LibSbmlInterface.verify_doc(sbml_doc)
        sbml_model = LibSbmlInterface.call_libsbml(sbml_doc.getModel)

        # initialize model and submodel
        model = wc_lang.core.Model(created=None, updated=None)

        if LibSbmlInterface.call_libsbml(sbml_model.getNumReactions, returns_int=True):
            submodel = model.submodels.create()
            submodel.import_from_sbml(sbml_model)
        else:
            model.import_from_sbml(sbml_model)

        types = [
            ((wc_lang.core.Compartment, 'compartments'), (sbml_model, 'getNumCompartments', 'getCompartment')),
            ((wc_lang.core.Species, 'species'), (sbml_model, 'getNumSpecies', 'getSpecies')),
            ((wc_lang.core.Parameter, 'parameters'), (sbml_model, 'getNumParameters', 'getParameter')),
            ((wc_lang.core.Observable, 'observables'), (sbml_model, 'getNumRules', 'getRule')),
            ((wc_lang.core.Function, 'functions'), (sbml_model, 'getNumRules', 'getRule')),
            ((wc_lang.core.Reaction, 'reactions'), (sbml_model, 'getNumReactions', 'getReaction')),
        ]

        if LibSbmlInterface.call_libsbml(sbml_doc.isSetPackageRequired, 'fbc'):
            sbml_plugin = LibSbmlInterface.call_libsbml(sbml_model.getPlugin, 'fbc')
            types.append(((wc_lang.core.DfbaObjReaction, 'dfba_obj_reactions'), (sbml_model, 'getNumReactions', 'getReaction')))
            types.append(((wc_lang.core.DfbaObjective, 'dfba_objs'), (sbml_plugin, 'getNumObjectives', 'getObjective')))

        # create model objects
        idx_to_wc_lang_obj = {}
        id_to_wc_lang_obj = {}
        for (wc_lang_type, wc_lang_type_container), (sbml_root, sbml_type_counter, sbml_type_getter) in types:
            n_sbml_objs = LibSbmlInterface.call_libsbml(getattr(sbml_root, sbml_type_counter), returns_int=True)
            idx_to_wc_lang_obj[wc_lang_type] = {}
            id_to_wc_lang_obj[wc_lang_type] = {}
            for i_sbml_obj in range(n_sbml_objs):
                sbml_obj = LibSbmlInterface.call_libsbml(getattr(sbml_root, sbml_type_getter), i_sbml_obj)
                if not LibSbmlInterface.call_libsbml(sbml_obj.getIdAttribute).startswith(wc_lang_type.__name__ + '__'):
                    continue
                wc_lang_obj = getattr(model, wc_lang_type_container).create()
                wc_lang_obj.import_from_sbml(sbml_obj)
                idx_to_wc_lang_obj[wc_lang_type][i_sbml_obj] = wc_lang_obj
                id_to_wc_lang_obj[wc_lang_type][wc_lang_obj.id] = wc_lang_obj

        # link model objects
        if LibSbmlInterface.call_libsbml(sbml_model.getNumReactions, returns_int=True):
            submodel.import_relations_from_sbml(sbml_model, id_to_wc_lang_obj)
        else:
            model.import_relations_from_sbml(sbml_model, id_to_wc_lang_obj)
        for (wc_lang_type, wc_lang_type_container), (sbml_root, sbml_type_counter, sbml_type_getter) in types:
            for i_sbml_obj, wc_lang_obj in idx_to_wc_lang_obj[wc_lang_type].items():
                sbml_obj = getattr(sbml_root, sbml_type_getter)(i_sbml_obj)
                wc_lang_obj.import_relations_from_sbml(sbml_obj, id_to_wc_lang_obj)

        # return model
        return model


text:
namespace chrono {
namespace vehicle {

/// @addtogroup vehicle_tracked_test_rig
/// @{

/// Driver inputs for a track test rig based on road profile.
/// A driver model based on a user-specified road profile.  Post displacements are computed based on current road height
/// at each post location and a given translation speed of the road profile. The road profile input data is assumed to
/// contain (x,z) pairs, with x locations in increasing order.
class CH_VEHICLE_API ChRoadDriverTTR : public ChDriverTTR {
  public:
    /// Construct using data from the specified file.
    ChRoadDriverTTR(const std::string& filename,  ///< name of data file
                    double speed                  ///< translation speed
    );

    ~ChRoadDriverTTR();

    /// Return true when driver stopped producing inputs (end of data).
    virtual bool Ended() const override;

  private:
    /// Initialize the driver system.
    virtual void Initialize(size_t num_posts, const std::vector<double>& locations) override;

    /// Update the driver system at the specified time.
    virtual void Synchronize(double time) override;

    /// Get string message.
    virtual std::string GetInfoMessage() const override { return "Road driver inputs"; }

    std::string m_filename;       ///< input file name
    double m_speed;               ///< vehicle speed over road profile
    ChCubicSpline* m_curve_road;  ///< spline for road profile
    double m_min;                 ///< first value of road x
    double m_max;                 ///< last value fo road x
    bool m_ended;                 ///< flag indicating end of input data
};

/// @} vehicle_tracked_test_rig

}  // end namespace vehicle
}  // end namespace chrono

#endif