<commit_before>/**
 * nets-nodegroups - Research node group structure of networks
 *
 * To research and explore node group structure of various networks, we introduced the *group type parameter Tau* and implemented a *node group extraction framework*. The framework is capable of identifying groups, such as communities, modules, core/periphery, hubs&spokes, or similar structures. Detailed description of the algorithm can be found in:
 *
 * - L. Šubelj, N. Blagus, and M. Bajec, "Group extraction for real-world networks: The case of communities, modules, and hubs and spokes," in Proc. of NetSci '13, 2013, p. 152.
 * - L. Šubelj, S. Žitnik, N. Blagus, and M. Bajec, “Node mixing and group structure of complex software networks,” Adv. Complex Syst., vol. 17, 2014.
 *
 * The adopted network node group extraction framework extracts groups from a simple undirected graph sequentially. An optimization method (currently random-restart hill climbing) is used to maximize the group criterion *W(S,T)* and extract group *S* with the corresponding linking pattern *T*. After extraction edges between *S* and *T* are removed and the whole process repeated on the largest weakly-connected component until the group criterion *W* is larger than expected on a Erdös-Rényi random graph.
 *
 * @author  gw0 [http://gw.tnode.com/] <gw.2014@tnode.com>
 * @version (see group_h_VERSION)
 */

#include "Snap.h"
#include "group.h"

/**
 * Output ST-group assignments (*.groups)
 *
 * @param OutFNm Output file name
 * @param OutMode Output fopen mode (eg. "wt")
 * @param argc Number of program parameters
 * @param argv Program parameters
 * @param InFNm Input file name
 * @param GroupV List of ST-group extraction results
 */
void OutputGroups(const TStr& OutFNm, const TStr& OutMode, const int argc, /*const*/ char* argv[], const TStr& InFNm, const TIntStrH& NIdLabelH, /*const*/ TGroupSTV& GroupV) {
  FILE* F = fopen(OutFNm.CStr(), OutMode.CStr());
  fprintf(F, "# nets-nodegroups. Build: %.2f, %s, %s. Time: %s\n", group_h_VERSION, __TIME__, __DATE__, TExeTm::GetCurTm());
  fprintf(F, "#");
  for (int i = 0; i < argc; ++i) {
    fprintf(F, " %s", argv[i]);
  }
  fprintf(F, "\n");
  fprintf(F, "# Input: %s  Nodes: %d  Edges: %d\n", InFNm.CStr(), GroupV[0].N, GroupV[0].M);
  fprintf(F, "# Group results: %d\n", GroupV.Len());
  for (int j = 0; j < GroupV.Len(); ++j) {
    TGroupST& G = GroupV[j];
    fprintf(F, "#   %-3d %s\n", j, G.GetStr().CStr());
  }
  fprintf(F, "# NId\tGroupS\tGroupT\tNLabel\n");
  for (int j = 0; j < GroupV.Len(); ++j) {
    // in S and T
    for (int i = 0; i < GroupV[j].SubSNIdV.Len(); ++i) {
      int NId = GroupV[j].SubSNIdV[i].Val;
      TStr NIdLabel = TStr("-");
      if (NIdLabelH.IsKey(NId))
        NIdLabel = NIdLabelH.GetDat(NId);

      if (GroupV[j].SubTNIdV.IsInBin(NId)) {
        fprintf(F, "%d\t%d\t%d\t%s\n", NId, j, j, NIdLabel.CStr());
      }
    }
    // in S, but not T
    for (int i = 0; i < GroupV[j].SubSNIdV.Len(); ++i) {
      int NId = GroupV[j].SubSNIdV[i].Val;
      TStr NIdLabel = TStr("-");
      if (NIdLabelH.IsKey(NId))
        NIdLabel = NIdLabelH.GetDat(NId);

      if (!GroupV[j].SubTNIdV.IsInBin(NId)) {
        fprintf(F, "%d\t%d\t-1\t%s\n", NId, j, NIdLabel.CStr());
      }
    }
    // in T, but not S
    for (int i = 0; i < GroupV[j].SubTNIdV.Len(); ++i) {
      int NId = GroupV[j].SubTNIdV[i].Val;
      TStr NIdLabel = TStr("-");
      if (NIdLabelH.IsKey(NId))
        NIdLabel = NIdLabelH.GetDat(NId);

      if (!GroupV[j].SubSNIdV.IsInBin(NId)) {
        fprintf(F, "%d\t-1\t%d\t%s\n", NId, j, NIdLabel.CStr());
      }
    }
  }
  fclose(F);
}

/**
 * Output ST-group extraction results summary (*.groupssum)
 *
 * @param OutSumFNm Output file name
 * @param OutMode Output fopen mode (eg. "wt")
 * @param argc Number of program parameters
 * @param argv Program parameters
 * @param InFNm Input file name
 * @param GroupV List of ST-group extraction results
 */
void OutputGroupsSum(const TStr& OutSumFNm, const TStr& OutMode, const int argc, /*const*/ char* argv[], const TStr& InFNm, const TIntStrH& NIdLabelH, /*const*/ TGroupSTV& GroupV) {
  FILE* F = fopen(OutSumFNm.CStr(), OutMode.CStr());
  fprintf(F, "# nets-nodegroups. Build: %.2f, %s, %s. Time: %s\n", group_h_VERSION, __TIME__, __DATE__, TExeTm::GetCurTm());
  fprintf(F, "#");
  for (int i = 0; i < argc; ++i) {
    fprintf(F, " %s", argv[i]);
  }
  fprintf(F, "\n");
  fprintf(F, "# Input: %s  Nodes: %d  Edges: %d\n", InFNm.CStr(), GroupV[0].N, GroupV[0].M);
  fprintf(F, "# Group results: %d\n", GroupV.Len());
  fprintf(F, "N\tM\tN_S\tM_S\tN_T\tM_T\tN_ST\tM_ST\tL_ST\tL_STc\tW\tTau\tMod_S\tMod_T\tType\n");
  for (int j = 0; j < GroupV.Len(); ++j) {
    TGroupST& G = GroupV[j];
    fprintf(F, "%s\n", G.GetStr(21).CStr());
  }
  fclose(F);
}

/**
 * Console application entry point
 */
int main(int argc, char* argv[]) {
  // Header
  Env = TEnv(argc, argv, TNotify::StdNotify);
  Env.PrepArgs(TStr::Fmt("nets-nodegroups. Build: %.2f, %s, %s. Time: %s", group_h_VERSION, __TIME__, __DATE__, TExeTm::GetCurTm()), 1);
  TExeTm ExeTm;
  Try

  // Parameters
  const TStr PrefixFNm = Env.GetIfArgPrefixStr("-o:", "graph", "Input and output file name prefix (can be overriden)");
  const TStr InFNm = Env.GetIfArgPrefixStr("-i:", PrefixFNm + ".edgelist", "Input file with graph edges (undirected edge per line)");
  const TStr LabelFNm = Env.GetIfArgPrefixStr("-l:", PrefixFNm + ".labels", "Optional input file with node labels (node ID, node label)");
  const TStr OutFNm = Env.GetIfArgPrefixStr("-og:", PrefixFNm + ".groups", "Output file with ST-group assignments");
  const TStr OutSumFNm = Env.GetIfArgPrefixStr("-os:", PrefixFNm + ".groupssum", "Output file with only ST-group extraction summary");
  const TInt OptRestarts = Env.GetIfArgPrefixInt("-n:", DEF_OptRestarts, "Number of restarts of the optimization algorithm");
  const TInt OptMxSteps = Env.GetIfArgPrefixInt("-sm:", DEF_OptMxSteps, "Maximal number of steps in each optimization run");
  const TInt OptStopSteps = Env.GetIfArgPrefixInt("-sw:", DEF_OptStopSteps, "Stop optimization if no W improvement in steps");
  const TInt OptInitSample = Env.GetIfArgPrefixInt("-ss:", DEF_OptInitSample, "Initial random-sample size of S ant T (0=random)");
  const TInt FinishCnt = Env.GetIfArgPrefixInt("-fn:", DEF_FinishCnt, "Finish after extracting so many groups");
  const TFlt FinishRndW = Env.GetIfArgPrefixFlt("-fw:", DEF_FinishRndW, "Finish if W smaller than top percentile on random graphs");
  const TInt RndGraphs = Env.GetIfArgPrefixInt("-rg:", DEF_RndGraphs, "Number of different Erdos-Renyi random graphs");
  const TInt RndRestarts = Env.GetIfArgPrefixInt("-rn:", DEF_RndRestarts, "Number of restarts on each Erdos-Renyi random graph");
  const TFlt RndRecompW = Env.GetIfArgPrefixFlt("-rf:", DEF_RndRecompW, "Force W recomputation on random graphs when relative difference smaller");

  // Input
  PUNGraph Graph = TSnap::LoadEdgeList<PUNGraph>(InFNm, false);
  TIntStrH NIdLabelH;
  if (TFile::Exists(LabelFNm)) {  // optional labels
    TSsParser Ss(LabelFNm, ssfTabSep);
    while (Ss.Next()) {
      if (Ss.GetFlds() > 0) {
        NIdLabelH.AddDat(Ss.GetInt(0), Ss.GetFld(1));
      }
    }
  }

  // Run ST-group extraction framework
  TGroupSTV GroupV;
  GroupExtractFramework(GroupV, Graph, OptRestarts, OptMxSteps, OptStopSteps, OptInitSample, FinishCnt, FinishRndW, RndGraphs, RndRestarts, RndRecompW);

  // Output ST-group assignments (*.groups)
  if(OutFNm.Len() > 0) {
    OutputGroups(OutFNm, "wt", argc, argv, InFNm, NIdLabelH, GroupV);
  }

  // Output ST-group extraction results summary (*.groupssum)
  if(OutSumFNm.Len() > 0) {
    OutputGroupsSum(OutSumFNm, "wt", argc, argv, InFNm, NIdLabelH, GroupV);
  }

  // Footer
  Catch
  printf("\nrun time: %s (%s)\n", ExeTm.GetTmStr(), TSecTm::GetCurTm().GetTmStr().CStr());
  return 0;
}
<commit_msg>Fix segfault if no group is extracted.<commit_after>/**
 * nets-nodegroups - Research node group structure of networks
 *
 * To research and explore node group structure of various networks, we introduced the *group type parameter Tau* and implemented a *node group extraction framework*. The framework is capable of identifying groups, such as communities, modules, core/periphery, hubs&spokes, or similar structures. Detailed description of the algorithm can be found in:
 *
 * - L. Šubelj, N. Blagus, and M. Bajec, "Group extraction for real-world networks: The case of communities, modules, and hubs and spokes," in Proc. of NetSci '13, 2013, p. 152.
 * - L. Šubelj, S. Žitnik, N. Blagus, and M. Bajec, “Node mixing and group structure of complex software networks,” Adv. Complex Syst., vol. 17, 2014.
 *
 * The adopted network node group extraction framework extracts groups from a simple undirected graph sequentially. An optimization method (currently random-restart hill climbing) is used to maximize the group criterion *W(S,T)* and extract group *S* with the corresponding linking pattern *T*. After extraction edges between *S* and *T* are removed and the whole process repeated on the largest weakly-connected component until the group criterion *W* is larger than expected on a Erdös-Rényi random graph.
 *
 * @author  gw0 [http://gw.tnode.com/] <gw.2014@tnode.com>
 * @version (see group_h_VERSION)
 */

#include "Snap.h"
#include "group.h"

/**
 * Output ST-group assignments (*.groups)
 *
 * @param OutFNm Output file name
 * @param OutMode Output fopen mode (eg. "wt")
 * @param argc Number of program parameters
 * @param argv Program parameters
 * @param InFNm Input file name
 * @param GroupV List of ST-group extraction results
 */
void OutputGroups(const TStr& OutFNm, const TStr& OutMode, const int argc, /*const*/ char* argv[], const TStr& InFNm, const int GraphN, const int GraphM, const TIntStrH& NIdLabelH, /*const*/ TGroupSTV& GroupV) {
  FILE* F = fopen(OutFNm.CStr(), OutMode.CStr());
  fprintf(F, "# nets-nodegroups. Build: %.2f, %s, %s. Time: %s\n", group_h_VERSION, __TIME__, __DATE__, TExeTm::GetCurTm());
  fprintf(F, "#");
  for (int i = 0; i < argc; ++i) {
    fprintf(F, " %s", argv[i]);
  }
  fprintf(F, "\n");
  fprintf(F, "# Input: %s  Nodes: %d  Edges: %d\n", InFNm.CStr(), GraphN, GraphM);
  fprintf(F, "# Group results: %d\n", GroupV.Len());
  for (int j = 0; j < GroupV.Len(); ++j) {
    TGroupST& G = GroupV[j];
    fprintf(F, "#   %-3d %s\n", j, G.GetStr().CStr());
  }
  fprintf(F, "# NId\tGroupS\tGroupT\tNLabel\n");
  for (int j = 0; j < GroupV.Len(); ++j) {
    // in S and T
    for (int i = 0; i < GroupV[j].SubSNIdV.Len(); ++i) {
      int NId = GroupV[j].SubSNIdV[i].Val;
      TStr NIdLabel = TStr("-");
      if (NIdLabelH.IsKey(NId))
        NIdLabel = NIdLabelH.GetDat(NId);

      if (GroupV[j].SubTNIdV.IsInBin(NId)) {
        fprintf(F, "%d\t%d\t%d\t%s\n", NId, j, j, NIdLabel.CStr());
      }
    }
    // in S, but not T
    for (int i = 0; i < GroupV[j].SubSNIdV.Len(); ++i) {
      int NId = GroupV[j].SubSNIdV[i].Val;
      TStr NIdLabel = TStr("-");
      if (NIdLabelH.IsKey(NId))
        NIdLabel = NIdLabelH.GetDat(NId);

      if (!GroupV[j].SubTNIdV.IsInBin(NId)) {
        fprintf(F, "%d\t%d\t-1\t%s\n", NId, j, NIdLabel.CStr());
      }
    }
    // in T, but not S
    for (int i = 0; i < GroupV[j].SubTNIdV.Len(); ++i) {
      int NId = GroupV[j].SubTNIdV[i].Val;
      TStr NIdLabel = TStr("-");
      if (NIdLabelH.IsKey(NId))
        NIdLabel = NIdLabelH.GetDat(NId);

      if (!GroupV[j].SubSNIdV.IsInBin(NId)) {
        fprintf(F, "%d\t-1\t%d\t%s\n", NId, j, NIdLabel.CStr());
      }
    }
  }
  fclose(F);
}

/**
 * Output ST-group extraction results summary (*.groupssum)
 *
 * @param OutSumFNm Output file name
 * @param OutMode Output fopen mode (eg. "wt")
 * @param argc Number of program parameters
 * @param argv Program parameters
 * @param InFNm Input file name
 * @param GroupV List of ST-group extraction results
 */
void OutputGroupsSum(const TStr& OutSumFNm, const TStr& OutMode, const int argc, /*const*/ char* argv[], const TStr& InFNm, const int GraphN, const int GraphM, const TIntStrH& NIdLabelH, /*const*/ TGroupSTV& GroupV) {
  FILE* F = fopen(OutSumFNm.CStr(), OutMode.CStr());
  fprintf(F, "# nets-nodegroups. Build: %.2f, %s, %s. Time: %s\n", group_h_VERSION, __TIME__, __DATE__, TExeTm::GetCurTm());
  fprintf(F, "#");
  for (int i = 0; i < argc; ++i) {
    fprintf(F, " %s", argv[i]);
  }
  fprintf(F, "\n");
  fprintf(F, "# Input: %s  Nodes: %d  Edges: %d\n", InFNm.CStr(), GraphN, GraphM);
  fprintf(F, "# Group results: %d\n", GroupV.Len());
  fprintf(F, "N\tM\tN_S\tM_S\tN_T\tM_T\tN_ST\tM_ST\tL_ST\tL_STc\tW\tTau\tMod_S\tMod_T\tType\n");
  for (int j = 0; j < GroupV.Len(); ++j) {
    TGroupST& G = GroupV[j];
    fprintf(F, "%s\n", G.GetStr(21).CStr());
  }
  fclose(F);
}

/**
 * Console application entry point
 */
int main(int argc, char* argv[]) {
  // Header
  Env = TEnv(argc, argv, TNotify::StdNotify);
  Env.PrepArgs(TStr::Fmt("nets-nodegroups. Build: %.2f, %s, %s. Time: %s", group_h_VERSION, __TIME__, __DATE__, TExeTm::GetCurTm()), 1);
  TExeTm ExeTm;
  Try

  // Parameters
  const TStr PrefixFNm = Env.GetIfArgPrefixStr("-o:", "graph", "Prefix for all file names (simplified usage)");
  const TStr InFNm = Env.GetIfArgPrefixStr("-i:", PrefixFNm + ".edgelist", "Input file with graph edges (undirected edge per line)");
  const TStr LabelFNm = Env.GetIfArgPrefixStr("-l:", PrefixFNm + ".labels", "Input file (optional) with node labels (node ID, node label)");
  const TStr OutFNm = Env.GetIfArgPrefixStr("-og:", PrefixFNm + ".groups", "Output file with ST-group assignments");
  const TStr OutSumFNm = Env.GetIfArgPrefixStr("-os:", PrefixFNm + ".groupssum", "Output file with only ST-group extraction summary");
  const TInt OptRestarts = Env.GetIfArgPrefixInt("-n:", DEF_OptRestarts, "Number of restarts of the optimization algorithm");
  const TInt OptMxSteps = Env.GetIfArgPrefixInt("-sm:", DEF_OptMxSteps, "Maximal number of steps in each optimization run");
  const TInt OptStopSteps = Env.GetIfArgPrefixInt("-sw:", DEF_OptStopSteps, "Stop optimization if no W improvement in steps");
  const TInt OptInitSample = Env.GetIfArgPrefixInt("-ss:", DEF_OptInitSample, "Initial random-sample size of S ant T (0=random)");
  const TInt FinishCnt = Env.GetIfArgPrefixInt("-fn:", DEF_FinishCnt, "Finish after extracting so many groups");
  const TFlt FinishRndW = Env.GetIfArgPrefixFlt("-fw:", DEF_FinishRndW, "Finish if W smaller than top percentile on random graphs");
  const TInt RndGraphs = Env.GetIfArgPrefixInt("-rg:", DEF_RndGraphs, "Random graphs (Erdos-Renyi) to construct for estimating W");
  const TInt RndRestarts = Env.GetIfArgPrefixInt("-rn:", DEF_RndRestarts, "Random graph restarts of the optimization algorithm");
  const TFlt RndRecompW = Env.GetIfArgPrefixFlt("-rf:", DEF_RndRecompW, "Random graph reestimation of W if relative difference smaller");

  // Input
  PUNGraph Graph = TSnap::LoadEdgeList<PUNGraph>(InFNm, false);
  TIntStrH NIdLabelH;
  if (TFile::Exists(LabelFNm)) {  // optional labels
    TSsParser Ss(LabelFNm, ssfTabSep);
    while (Ss.Next()) {
      if (Ss.GetFlds() > 0) {
        NIdLabelH.AddDat(Ss.GetInt(0), Ss.GetFld(1));
      }
    }
  }

  // Run ST-group extraction framework
  TGroupSTV GroupV;
  GroupExtractFramework(GroupV, Graph, OptRestarts, OptMxSteps, OptStopSteps, OptInitSample, FinishCnt, FinishRndW, RndGraphs, RndRestarts, RndRecompW);

  // Output ST-group assignments (*.groups)
  if(OutFNm.Len() > 0) {
    OutputGroups(OutFNm, "wt", argc, argv, InFNm, Graph->GetNodes(), Graph->GetEdges(), NIdLabelH, GroupV);
  }

  // Output ST-group extraction results summary (*.groupssum)
  if(OutSumFNm.Len() > 0) {
    OutputGroupsSum(OutSumFNm, "wt", argc, argv, InFNm, Graph->GetNodes(), Graph->GetEdges(), NIdLabelH, GroupV);
  }

  // Footer
  Catch
  printf("\nrun time: %s (%s)\n", ExeTm.GetTmStr(), TSecTm::GetCurTm().GetTmStr().CStr());
  return 0;
}
<|endoftext|>


<commit_before>/*******************************************************************************
 *
 * MIT License
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 *******************************************************************************/
#include <../driver/tensor_driver.hpp>
#include <miopen/rnn.hpp>
#include <miopen/env.hpp>
#include <miopen/util.hpp>
#include <miopen/float_equal.hpp>
#include <vector>
#include <numeric>

#include <miopengemm/gemm.hpp>

namespace miopen {

MIOPEN_DECLARE_ENV_VAR(MIOPEN_DEBUG_CONV_DIRECT)

struct AutoEnableProfiling
{
    AutoEnableProfiling(Handle& x) : h(x)
    {
        prev_state = h.IsProfilingEnabled();
        h.EnableProfiling();
    }

    ~AutoEnableProfiling()
    {
        h.EnableProfiling(prev_state);
        h.ResetKernelTime();
    }

    private:
    Handle& h;
    bool prev_state;
};

void RNNDescriptor::RNNForwardTraining(Handle& handle,
	const int seqLen,
//	const TensorDescriptor& xDesc,
	ConstData_t x,
//	const TensorDescriptor& hxDesc,
	ConstData_t hx,
//	const TensorDescriptor& cxDesc,
	ConstData_t cx,
//	const TensorDescriptor& wDesc,
	ConstData_t w,
//	const TensorDescriptor& yDesc,
	Data_t y,
//	const TensorDescriptor& hyDesc,
	Data_t hy,
//	const TensorDescriptor& cyDesc,
	Data_t cy,
	Data_t workSpace,
	size_t workSpaceSize,
	Data_t reserveSpace,
	size_t reserveSpaceSize,
	const std::vector<int> &in_n,
	const int in_h,
	const int hy_d,
	const int hy_n,
	const int hy_h,
	const int out_h) const
{/*
	if (x == nullptr || w == nullptr || y == nullptr)
	{
		MIOPEN_THROW(miopenStatusBadParm);
	}
	if (xDesc.GetSize() != yDesc.GetSize() || xDesc.GetSize() != wDesc.GetSize())
	{
		MIOPEN_THROW(miopenStatusBadParm);
	}
	if (xDesc.GetType() != yDesc.GetType() || xDesc.GetType() != wDesc.GetType())
	{
		MIOPEN_THROW(miopenStatusBadParm);
	}
*/
//	int in_n, in_c, in_h, in_w;
	//		std::tie(in_n, in_c, in_h, in_w) = tie4(xDesc.GetLengths());

//	int out_h, out_w;
	//		std::tie(std::ignore, std::ignore, out_h, out_w) = tie4(yDesc.GetLengths());
/*
	if (workSpace == nullptr ||
		workSpaceSize < ForwardGetWorkSpaceSize(handle, wDesc, xDesc, yDesc) || reserveSpaceSize < ForwardGetReserveSpaceSize(handle, wDesc, xDesc, yDesc))
	{
		MIOPEN_THROW("Workspace is required");
	}
	*/

//	miopenRNNMode_t mode;
//	int seqLength;
//	int layer;
//	int bidir;
//	int bias;

	int batch_n = std::accumulate(in_n.begin(), in_n.end(), 0);

	bool bidirection = (bidir != 0);
	bool biased = (bias != 0);
	int numlayer = layer;
	int bacc, baccbi;
	int bi = bidirection ? 2 : 1;

	int wei_len = (bi * (in_h + hy_h + out_h) + (numlayer - 1) * bi * (bi + 1) * hy_h) * hy_h;
	if (biased)
	{
		wei_len += (bi * 2 + (numlayer - 1) * bi * (bi + 1)) * hy_h + bi * out_h;
	}

	int wei_shift_bias =
		((in_h + hy_h + out_h) * bi + (bi * hy_h + hy_h) * bi * (numlayer - 1)) * hy_h;
	int in_stride = in_h;
	int hy_stride = hy_h * bi;
	int h_stride = hy_h * bi;
	int out_stride = out_h;
	int wei_stride = hy_h * bi;

	if (mode == miopenRNNRELU || mode == miopenRNNTANH)
	{
#if MIOPEN_USE_MIOPENGEMM

		printf("rnn gpu \n");
		cl_command_queue Q = (cl_command_queue)handle.GetStream();

		for (int li = 0; li < numlayer; li++)
		{
			int hid_shift = li * batch_n * hy_h * bi;
			int hx_shift = li * bi * in_n[0] * hy_h;

			// from input
			if (li == 0)
			{
				MIOpenGEMM::gemm0<float>(false,
					false,
					false,
					batch_n,
					hy_h * bi,
					in_h,
					1,
					x,
					0,
					in_stride,
					w,
					0,
					wei_stride,
					1,
					reserveSpace,
					hid_shift,
					hy_stride,
					&Q,
					0,
					nullptr,
					nullptr);
			}
			else
			{
				int wei_shift = bi * (in_h + hy_h) * hy_h + (li - 1) * bi * (bi * hy_h + hy_h) * hy_h;
				int prelayer_shift = (li - 1) * batch_n * hy_h * bi;

				MIOpenGEMM::gemm0<float>(false,
					false,
					false,
					batch_n,
					hy_h * bi,
					hy_h * bi,
					1,
					workSpace,
					prelayer_shift,
					hy_stride,
					w,
					wei_shift,
					wei_stride,
					1,
					reserveSpace,
					hid_shift,
					hy_stride,
					&Q,
					0,
					nullptr,
					nullptr);
			}

			// from hidden state
			bacc = 0;
			baccbi = batch_n;
			for (int ti = 0; ti < seqLen; ti++)
			{
				baccbi -= in_n[seqLen - 1 - ti];

				int wei_shift =
					li == 0 ? (in_h * hy_h * bi)
					: (bi * (in_h + hy_h) * hy_h + (li - 1) * bi * (bi * hy_h + hy_h) * hy_h +
						bi * hy_h * hy_stride);

				if (ti == 0)
				{
					MIOpenGEMM::gemm0<float>(false,
						false,
						false,
						in_n[ti],
						hy_h,
						hy_h,
						1,
						hx,
						hx_shift,
						h_stride,
						w,
						wei_shift,
						wei_stride,
						1,
						reserveSpace,
						hid_shift + bacc * hy_stride,
						hy_stride,
						&Q,
						0,
						nullptr,
						nullptr);

					if (bidirection)
					{
						MIOpenGEMM::gemm0<float>(false,
							false,
							false,
							in_n[seqLen - 1 - ti],
							hy_h,
							hy_h,
							1,
							hx,
							hx_shift + hy_h,
							h_stride,
							w,
							wei_shift + hy_h,
							wei_stride,
							1,
							reserveSpace,
							hid_shift + baccbi * hy_stride + hy_h,
							hy_stride,
							&Q,
							0,
							nullptr,
							nullptr);
					}
				}
				else
				{
					MIOpenGEMM::gemm0<float>(false,
						false,
						false,
						in_n[ti],
						hy_h,
						hy_h,
						1,
						hy,
						hx_shift,
						h_stride,
						w,
						wei_shift,
						wei_stride,
						1,
						reserveSpace,
						hid_shift + bacc * hy_stride,
						hy_stride,
						&Q,
						0,
						nullptr,
						nullptr);

					if (bidirection)
					{
						MIOpenGEMM::gemm0<float>(false,
							false,
							false,
							in_n[seqLen - 1 - ti],
							hy_h,
							hy_h,
							1,
							hy,
							hx_shift + hy_h,
							h_stride,
							w,
							wei_shift + hy_h,
							wei_stride,
							1,
							reserveSpace,
							hid_shift + baccbi * hy_stride + hy_h,
							hy_stride,
							&Q,
							0,
							nullptr,
							nullptr);
					}
				}

				int rsv_sz = batch_n * hy_d * hy_h;
				std::vector<int> rsv_size(3, 1);
				rsv_size.push_back(rsv_sz);

				miopenTensorDescriptor_t rsvTensor;
				miopenCreateTensorDescriptor(&rsvTensor);
				SetTensor4d(rsvTensor, rsv_size);

				miopenActivationDescriptor_t activDesc;
				miopenCreateActivationDescriptor(&activDesc);

				miopenActivationMode_t amode;
				amode = (mode == miopenRNNRELU) ? miopenActivationRELU : miopenActivationLOGISTIC;
				miopenSetActivationDescriptor(activDesc, amode, 1, 0, 1);

				miopenActivationForward(GetHandle(),
					activDesc,
					1,
					rsvTensor,
					reserveSpace,
					0,
					rsvTensor,
					workSpace);

				bacc += in_n[ti];
			}

		}

		int prelayer_shift = (numlayer - 1) * batch_n * hy_h * bi;
		int wei_shift = bi * (in_h + hy_h) * hy_h + (numlayer - 1) * bi * (bi * hy_h + hy_h) * hy_h;

		MIOpenGEMM::gemm0<float>(false,
			false,
			true,
			batch_n,
			out_h,
			hy_h * bi,
			1,
			workSpace,
			prelayer_shift,
			hy_stride,
			w,
			wei_shift,
			wei_stride,
			1,
			y,
			0,
			out_stride,
			&Q,
			0,
			nullptr,
			nullptr);

		clFinish(Q);
#else
		MIOPEN_THROW("GEMM is not supported");
#endif
	}
	else if (mode == miopenLSTM)
	{
		printf("lstm gpu \n");
	}
	else if (mode == miopenGRU)
	{
		printf("gru gpu \n");
	}

};

void RNNDescriptor::RNNBackwardData(Handle& handle,
	const int seqLen,
	const TensorDescriptor& yDesc,
	ConstData_t y,
	const TensorDescriptor& dyDesc,
	ConstData_t dy,
	const TensorDescriptor& dhyDesc,
	ConstData_t dhy,
	const TensorDescriptor& dcyDesc,
	ConstData_t dcy,
	const TensorDescriptor& wDesc,
	ConstData_t w,
	const TensorDescriptor& hxDesc,
	ConstData_t hx,
	const TensorDescriptor& cxDesc,
	ConstData_t cx,
	const TensorDescriptor& dxDesc,
	Data_t dx,
	const TensorDescriptor& dhxDesc,
	Data_t dhx,
	const TensorDescriptor& dcxDesc,
	Data_t dcx,
	Data_t workSpace,
	size_t workSpaceSize,
	ConstData_t reserveSpace,
	size_t reserveSpaceSize) const
{
	/*
	if (dx == nullptr || w == nullptr || dy == nullptr)
	{
		MIOPEN_THROW(miopenStatusBadParm);
	}
	if (dyDesc.GetSize() != dxDesc.GetSize() || dyDesc.GetSize() != wDesc.GetSize())
	{
		MIOPEN_THROW(miopenStatusBadParm);
	}
	if (dyDesc.GetType() != dxDesc.GetType() || dyDesc.GetType() != wDesc.GetType())
	{
		MIOPEN_THROW(miopenStatusBadParm);
	}

	*/

        int in_n, in_c, in_h, in_w;
	//		std::tie(in_n, in_c, in_h, in_w) = tie4(xDesc.GetLengths());

	int wei_n, wei_h, wei_w;
	//		std::tie(wei_n, std::ignore, wei_h, wei_w) = tie4(wDesc.GetLengths());

	int out_h, out_w;
	//		std::tie(std::ignore, std::ignore, out_h, out_w) = tie4(yDesc.GetLengths());
};

void RNNDescriptor::RNNBackwardWeights(Handle& handle,
	const int seqLen,
	const TensorDescriptor& xDesc,
	ConstData_t x,
	const TensorDescriptor& hxDesc,
	ConstData_t hx,
	const TensorDescriptor& dyDesc,
	ConstData_t dy,
	ConstData_t workSpace,
	size_t workSpaceSize,
	const TensorDescriptor& dwDesc,
	Data_t dw,
	ConstData_t reserveSpace,
	size_t reserveSpaceSize) const
{

        int in_n, in_c, in_h, in_w;
	//		std::tie(in_n, in_c, in_h, in_w) = tie4(xDesc.GetLengths());

	int wei_n, wei_h, wei_w;
	//		std::tie(wei_n, std::ignore, wei_h, wei_w) = tie4(wDesc.GetLengths());

	int out_h, out_w;
	//		std::tie(std::ignore, std::ignore, out_h, out_w) = tie4(yDesc.GetLengths());
};

} // namespace miopen
<commit_msg>activ......<commit_after>/*******************************************************************************
 *
 * MIT License
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 *******************************************************************************/
#include <../driver/tensor_driver.hpp>
#include <../driver/driver.hpp>
#include <miopen/rnn.hpp>
#include <miopen/env.hpp>
#include <miopen/util.hpp>
#include <miopen/float_equal.hpp>
#include <vector>
#include <numeric>

#include <miopengemm/gemm.hpp>

namespace miopen {

MIOPEN_DECLARE_ENV_VAR(MIOPEN_DEBUG_CONV_DIRECT)

struct AutoEnableProfiling
{
    AutoEnableProfiling(Handle& x) : h(x)
    {
        prev_state = h.IsProfilingEnabled();
        h.EnableProfiling();
    }

    ~AutoEnableProfiling()
    {
        h.EnableProfiling(prev_state);
        h.ResetKernelTime();
    }

    private:
    Handle& h;
    bool prev_state;
};

void RNNDescriptor::RNNForwardTraining(Handle& handle,
	const int seqLen,
//	const TensorDescriptor& xDesc,
	ConstData_t x,
//	const TensorDescriptor& hxDesc,
	ConstData_t hx,
//	const TensorDescriptor& cxDesc,
	ConstData_t cx,
//	const TensorDescriptor& wDesc,
	ConstData_t w,
//	const TensorDescriptor& yDesc,
	Data_t y,
//	const TensorDescriptor& hyDesc,
	Data_t hy,
//	const TensorDescriptor& cyDesc,
	Data_t cy,
	Data_t workSpace,
	size_t workSpaceSize,
	Data_t reserveSpace,
	size_t reserveSpaceSize,
	const std::vector<int> &in_n,
	const int in_h,
	const int hy_d,
	const int hy_n,
	const int hy_h,
	const int out_h) const
{/*
	if (x == nullptr || w == nullptr || y == nullptr)
	{
		MIOPEN_THROW(miopenStatusBadParm);
	}
	if (xDesc.GetSize() != yDesc.GetSize() || xDesc.GetSize() != wDesc.GetSize())
	{
		MIOPEN_THROW(miopenStatusBadParm);
	}
	if (xDesc.GetType() != yDesc.GetType() || xDesc.GetType() != wDesc.GetType())
	{
		MIOPEN_THROW(miopenStatusBadParm);
	}
*/
//	int in_n, in_c, in_h, in_w;
	//		std::tie(in_n, in_c, in_h, in_w) = tie4(xDesc.GetLengths());

//	int out_h, out_w;
	//		std::tie(std::ignore, std::ignore, out_h, out_w) = tie4(yDesc.GetLengths());
/*
	if (workSpace == nullptr ||
		workSpaceSize < ForwardGetWorkSpaceSize(handle, wDesc, xDesc, yDesc) || reserveSpaceSize < ForwardGetReserveSpaceSize(handle, wDesc, xDesc, yDesc))
	{
		MIOPEN_THROW("Workspace is required");
	}
	*/

//	miopenRNNMode_t mode;
//	int seqLength;
//	int layer;
//	int bidir;
//	int bias;

	int batch_n = std::accumulate(in_n.begin(), in_n.end(), 0);

	bool bidirection = (bidir != 0);
	bool biased = (bias != 0);
	int numlayer = layer;
	int bacc, baccbi;
	int bi = bidirection ? 2 : 1;

	int wei_len = (bi * (in_h + hy_h + out_h) + (numlayer - 1) * bi * (bi + 1) * hy_h) * hy_h;
	if (biased)
	{
		wei_len += (bi * 2 + (numlayer - 1) * bi * (bi + 1)) * hy_h + bi * out_h;
	}

	int wei_shift_bias =
		((in_h + hy_h + out_h) * bi + (bi * hy_h + hy_h) * bi * (numlayer - 1)) * hy_h;
	int in_stride = in_h;
	int hy_stride = hy_h * bi;
	int h_stride = hy_h * bi;
	int out_stride = out_h;
	int wei_stride = hy_h * bi;

	if (mode == miopenRNNRELU || mode == miopenRNNTANH)
	{
#if MIOPEN_USE_MIOPENGEMM

		printf("rnn gpu \n");
		cl_command_queue Q = (cl_command_queue)handle.GetStream();

		for (int li = 0; li < numlayer; li++)
		{
			int hid_shift = li * batch_n * hy_h * bi;
			int hx_shift = li * bi * in_n[0] * hy_h;

			// from input
			if (li == 0)
			{
				MIOpenGEMM::gemm0<float>(false,
					false,
					false,
					batch_n,
					hy_h * bi,
					in_h,
					1,
					x,
					0,
					in_stride,
					w,
					0,
					wei_stride,
					1,
					reserveSpace,
					hid_shift,
					hy_stride,
					&Q,
					0,
					nullptr,
					nullptr);
			}
			else
			{
				int wei_shift = bi * (in_h + hy_h) * hy_h + (li - 1) * bi * (bi * hy_h + hy_h) * hy_h;
				int prelayer_shift = (li - 1) * batch_n * hy_h * bi;

				MIOpenGEMM::gemm0<float>(false,
					false,
					false,
					batch_n,
					hy_h * bi,
					hy_h * bi,
					1,
					workSpace,
					prelayer_shift,
					hy_stride,
					w,
					wei_shift,
					wei_stride,
					1,
					reserveSpace,
					hid_shift,
					hy_stride,
					&Q,
					0,
					nullptr,
					nullptr);
			}

			// from hidden state
			bacc = 0;
			baccbi = batch_n;
			for (int ti = 0; ti < seqLen; ti++)
			{
				baccbi -= in_n[seqLen - 1 - ti];

				int wei_shift =
					li == 0 ? (in_h * hy_h * bi)
					: (bi * (in_h + hy_h) * hy_h + (li - 1) * bi * (bi * hy_h + hy_h) * hy_h +
						bi * hy_h * hy_stride);

				if (ti == 0)
				{
					MIOpenGEMM::gemm0<float>(false,
						false,
						false,
						in_n[ti],
						hy_h,
						hy_h,
						1,
						hx,
						hx_shift,
						h_stride,
						w,
						wei_shift,
						wei_stride,
						1,
						reserveSpace,
						hid_shift + bacc * hy_stride,
						hy_stride,
						&Q,
						0,
						nullptr,
						nullptr);

					if (bidirection)
					{
						MIOpenGEMM::gemm0<float>(false,
							false,
							false,
							in_n[seqLen - 1 - ti],
							hy_h,
							hy_h,
							1,
							hx,
							hx_shift + hy_h,
							h_stride,
							w,
							wei_shift + hy_h,
							wei_stride,
							1,
							reserveSpace,
							hid_shift + baccbi * hy_stride + hy_h,
							hy_stride,
							&Q,
							0,
							nullptr,
							nullptr);
					}
				}
				else
				{
					MIOpenGEMM::gemm0<float>(false,
						false,
						false,
						in_n[ti],
						hy_h,
						hy_h,
						1,
						hy,
						hx_shift,
						h_stride,
						w,
						wei_shift,
						wei_stride,
						1,
						reserveSpace,
						hid_shift + bacc * hy_stride,
						hy_stride,
						&Q,
						0,
						nullptr,
						nullptr);

					if (bidirection)
					{
						MIOpenGEMM::gemm0<float>(false,
							false,
							false,
							in_n[seqLen - 1 - ti],
							hy_h,
							hy_h,
							1,
							hy,
							hx_shift + hy_h,
							h_stride,
							w,
							wei_shift + hy_h,
							wei_stride,
							1,
							reserveSpace,
							hid_shift + baccbi * hy_stride + hy_h,
							hy_stride,
							&Q,
							0,
							nullptr,
							nullptr);
					}
				}

				int rsv_sz = batch_n * hy_d * hy_h;
				std::vector<int> rsv_size(3, 1);
				rsv_size.push_back(rsv_sz);

				miopenTensorDescriptor_t rsvTensor;
				miopenCreateTensorDescriptor(&rsvTensor);
				SetTensor4d(rsvTensor, rsv_size);

				miopenActivationDescriptor_t activDesc;
				miopenCreateActivationDescriptor(&activDesc);

				miopenActivationMode_t amode;
				amode = (mode == miopenRNNRELU) ? miopenActivationRELU : miopenActivationLOGISTIC;
				miopenSetActivationDescriptor(activDesc, amode, 1, 0, 1);

				miopenActivationForward(GetHandle(),
					activDesc,
					1,
					rsvTensor,
					reserveSpace,
					0,
					rsvTensor,
					workSpace);

				bacc += in_n[ti];
			}

		}

		int prelayer_shift = (numlayer - 1) * batch_n * hy_h * bi;
		int wei_shift = bi * (in_h + hy_h) * hy_h + (numlayer - 1) * bi * (bi * hy_h + hy_h) * hy_h;

		MIOpenGEMM::gemm0<float>(false,
			false,
			true,
			batch_n,
			out_h,
			hy_h * bi,
			1,
			workSpace,
			prelayer_shift,
			hy_stride,
			w,
			wei_shift,
			wei_stride,
			1,
			y,
			0,
			out_stride,
			&Q,
			0,
			nullptr,
			nullptr);

		clFinish(Q);
#else
		MIOPEN_THROW("GEMM is not supported");
#endif
	}
	else if (mode == miopenLSTM)
	{
		printf("lstm gpu \n");
	}
	else if (mode == miopenGRU)
	{
		printf("gru gpu \n");
	}

};

void RNNDescriptor::RNNBackwardData(Handle& handle,
	const int seqLen,
	const TensorDescriptor& yDesc,
	ConstData_t y,
	const TensorDescriptor& dyDesc,
	ConstData_t dy,
	const TensorDescriptor& dhyDesc,
	ConstData_t dhy,
	const TensorDescriptor& dcyDesc,
	ConstData_t dcy,
	const TensorDescriptor& wDesc,
	ConstData_t w,
	const TensorDescriptor& hxDesc,
	ConstData_t hx,
	const TensorDescriptor& cxDesc,
	ConstData_t cx,
	const TensorDescriptor& dxDesc,
	Data_t dx,
	const TensorDescriptor& dhxDesc,
	Data_t dhx,
	const TensorDescriptor& dcxDesc,
	Data_t dcx,
	Data_t workSpace,
	size_t workSpaceSize,
	ConstData_t reserveSpace,
	size_t reserveSpaceSize) const
{
	/*
	if (dx == nullptr || w == nullptr || dy == nullptr)
	{
		MIOPEN_THROW(miopenStatusBadParm);
	}
	if (dyDesc.GetSize() != dxDesc.GetSize() || dyDesc.GetSize() != wDesc.GetSize())
	{
		MIOPEN_THROW(miopenStatusBadParm);
	}
	if (dyDesc.GetType() != dxDesc.GetType() || dyDesc.GetType() != wDesc.GetType())
	{
		MIOPEN_THROW(miopenStatusBadParm);
	}

	*/

        int in_n, in_c, in_h, in_w;
	//		std::tie(in_n, in_c, in_h, in_w) = tie4(xDesc.GetLengths());

	int wei_n, wei_h, wei_w;
	//		std::tie(wei_n, std::ignore, wei_h, wei_w) = tie4(wDesc.GetLengths());

	int out_h, out_w;
	//		std::tie(std::ignore, std::ignore, out_h, out_w) = tie4(yDesc.GetLengths());
};

void RNNDescriptor::RNNBackwardWeights(Handle& handle,
	const int seqLen,
	const TensorDescriptor& xDesc,
	ConstData_t x,
	const TensorDescriptor& hxDesc,
	ConstData_t hx,
	const TensorDescriptor& dyDesc,
	ConstData_t dy,
	ConstData_t workSpace,
	size_t workSpaceSize,
	const TensorDescriptor& dwDesc,
	Data_t dw,
	ConstData_t reserveSpace,
	size_t reserveSpaceSize) const
{

        int in_n, in_c, in_h, in_w;
	//		std::tie(in_n, in_c, in_h, in_w) = tie4(xDesc.GetLengths());

	int wei_n, wei_h, wei_w;
	//		std::tie(wei_n, std::ignore, wei_h, wei_w) = tie4(wDesc.GetLengths());

	int out_h, out_w;
	//		std::tie(std::ignore, std::ignore, out_h, out_w) = tie4(yDesc.GetLengths());
};

} // namespace miopen
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#include <osg/TexGen>
#include <osg/Notify>

using namespace osg;

TexGen::TexGen()
{
    _mode = OBJECT_LINEAR;
    _plane_s.set(1.0f, 0.0f, 0.0f, 0.0f);
    _plane_t.set(0.0f, 1.0f, 0.0f, 0.0f);
    _plane_r.set(0.0f, 0.0f, 1.0f, 0.0f);
    _plane_q.set(0.0f, 0.0f, 0.0f, 1.0f);
}

TexGen::~TexGen()
{
}

void TexGen::setPlane(Coord which, const Plane& plane)
{
    switch( which )
    {
        case S : _plane_s = plane; break;
        case T : _plane_t = plane; break;
        case R : _plane_r = plane; break;
        case Q : _plane_q = plane; break;
        default : notify(WARN)<<"Error: invalid 'which' passed TexGen::setPlane("<<(unsigned int)which<<","<<plane<<")"<<std::endl; break;
    }
}

const Plane& TexGen::getPlane(Coord which) const
{
    switch( which )
    {
        case S : return _plane_s;
        case T : return _plane_t;
        case R : return _plane_r;
        case Q : return _plane_q;
        default : notify(WARN)<<"Error: invalid 'which' passed TexGen::getPlane(which)"<<std::endl; return _plane_r;
    }
}

Plane& TexGen::getPlane(Coord which)
{
    switch( which )
    {
        case S : return _plane_s;
        case T : return _plane_t;
        case R : return _plane_r;
        case Q : return _plane_q;
        default : notify(WARN)<<"Error: invalid 'which' passed TexGen::getPlane(which)"<<std::endl; return _plane_r;
    }
}

void TexGen::apply(State&) const
{

    if (_mode == OBJECT_LINEAR)
    {
        glTexGenfv(GL_S, GL_OBJECT_PLANE, _plane_s.ptr());
        glTexGenfv(GL_T, GL_OBJECT_PLANE, _plane_t.ptr());
        glTexGenfv(GL_R, GL_OBJECT_PLANE, _plane_r.ptr());
        glTexGenfv(GL_Q, GL_OBJECT_PLANE, _plane_q.ptr());

        glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );

        // note, R & Q will be disabled so R&Q settings won't
        // have an effect, see above comment in enable(). RO.

    }
    else if (_mode == EYE_LINEAR)
    {
        glTexGenfv(GL_S, GL_EYE_PLANE, _plane_s.ptr());
        glTexGenfv(GL_T, GL_EYE_PLANE, _plane_t.ptr());
        glTexGenfv(GL_R, GL_EYE_PLANE, _plane_r.ptr());
        glTexGenfv(GL_Q, GL_EYE_PLANE, _plane_q.ptr());

        glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );

        // note, R & Q will be disabled so R&Q settings won't
        // have an effect, see above comment in enable(). RO.

    }
    else if (_mode == NORMAL_MAP)
    {
        glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
//      glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );
    }
    else if (_mode == REFLECTION_MAP)
    {
        glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
//      glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );
    }
    else                         // SPHERE_MAP
    {
        // We ignore the planes if we are not in OBJECT_ or EYE_LINEAR mode.

        // Also don't set the mode of GL_R & GL_Q as these will generate
        // GL_INVALID_ENUM (See OpenGL Refrence Guide, glTexGEn.)

        glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
    }

}
<commit_msg>Added setPlanesFromMatrix method<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#include <osg/TexGen>
#include <osg/Notify>

using namespace osg;

TexGen::TexGen()
{
    _mode = OBJECT_LINEAR;
    _plane_s.set(1.0f, 0.0f, 0.0f, 0.0f);
    _plane_t.set(0.0f, 1.0f, 0.0f, 0.0f);
    _plane_r.set(0.0f, 0.0f, 1.0f, 0.0f);
    _plane_q.set(0.0f, 0.0f, 0.0f, 1.0f);
}

TexGen::~TexGen()
{
}

void TexGen::setPlane(Coord which, const Plane& plane)
{
    switch( which )
    {
        case S : _plane_s = plane; break;
        case T : _plane_t = plane; break;
        case R : _plane_r = plane; break;
        case Q : _plane_q = plane; break;
        default : notify(WARN)<<"Error: invalid 'which' passed TexGen::setPlane("<<(unsigned int)which<<","<<plane<<")"<<std::endl; break;
    }
}

const Plane& TexGen::getPlane(Coord which) const
{
    switch( which )
    {
        case S : return _plane_s;
        case T : return _plane_t;
        case R : return _plane_r;
        case Q : return _plane_q;
        default : notify(WARN)<<"Error: invalid 'which' passed TexGen::getPlane(which)"<<std::endl; return _plane_r;
    }
}

Plane& TexGen::getPlane(Coord which)
{
    switch( which )
    {
        case S : return _plane_s;
        case T : return _plane_t;
        case R : return _plane_r;
        case Q : return _plane_q;
        default : notify(WARN)<<"Error: invalid 'which' passed TexGen::getPlane(which)"<<std::endl; return _plane_r;
    }
}

void TexGen::setPlanesFromMatrix(const Matrixd& matrix)
{
    _plane_s.set(matrix(0,0),matrix(1,0),matrix(2,0),matrix(3,0));
    _plane_t.set(matrix(0,1),matrix(1,1),matrix(2,1),matrix(3,1));
    _plane_r.set(matrix(0,2),matrix(1,2),matrix(2,2),matrix(3,2));
    _plane_q.set(matrix(0,3),matrix(1,3),matrix(2,3),matrix(3,3));
}

void TexGen::apply(State&) const
{

    if (_mode == OBJECT_LINEAR)
    {
        glTexGenfv(GL_S, GL_OBJECT_PLANE, _plane_s.ptr());
        glTexGenfv(GL_T, GL_OBJECT_PLANE, _plane_t.ptr());
        glTexGenfv(GL_R, GL_OBJECT_PLANE, _plane_r.ptr());
        glTexGenfv(GL_Q, GL_OBJECT_PLANE, _plane_q.ptr());

        glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );

        // note, R & Q will be disabled so R&Q settings won't
        // have an effect, see above comment in enable(). RO.

    }
    else if (_mode == EYE_LINEAR)
    {
        glTexGenfv(GL_S, GL_EYE_PLANE, _plane_s.ptr());
        glTexGenfv(GL_T, GL_EYE_PLANE, _plane_t.ptr());
        glTexGenfv(GL_R, GL_EYE_PLANE, _plane_r.ptr());
        glTexGenfv(GL_Q, GL_EYE_PLANE, _plane_q.ptr());

        glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );

        // note, R & Q will be disabled so R&Q settings won't
        // have an effect, see above comment in enable(). RO.

    }
    else if (_mode == NORMAL_MAP)
    {
        glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
//      glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );
    }
    else if (_mode == REFLECTION_MAP)
    {
        glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
//      glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );
    }
    else                         // SPHERE_MAP
    {
        // We ignore the planes if we are not in OBJECT_ or EYE_LINEAR mode.

        // Also don't set the mode of GL_R & GL_Q as these will generate
        // GL_INVALID_ENUM (See OpenGL Refrence Guide, glTexGEn.)

        glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
        glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
    }

}
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdlib>

#include "population.h"

int **POPULATION::initializePopulation(int individuals, int genes, bool FILL_ZERO)
{
  int **population;

  if (!FILL_ZERO)
  {
    population = (int **) malloc(individuals * sizeof(int *));
    for (int i = 0; i < individuals; i++)
      population[i] = (int *) malloc(genes * sizeof(int));
  }
  else
  {
    population = (int **) calloc(individuals, sizeof(int *));
    for (int i = 0; i < individuals; i++)
      population[i] = (int *) calloc(genes, sizeof(int));
  }

  return population;
}

int **POPULATION::createRandomPopulation(int **population, int individuals, int genes)
{
  // Fill the 2d array with random genes
  for (int pop = 0; pop < individuals; pop++)
  {
    for (int gene = 0; gene < genes; gene++)
    {
      population[pop][gene] = rand() % 2;
    }
  }
  return 0;
}
<commit_msg>Update return datatype function 'createRandomPopulation'.<commit_after>#include <iostream>
#include <cstdlib>

#include "population.h"

int **POPULATION::initializePopulation(int individuals, int genes, bool FILL_ZERO)
{
  int **population;

  if (!FILL_ZERO)
  {
    population = (int **) malloc(individuals * sizeof(int *));
    for (int i = 0; i < individuals; i++)
      population[i] = (int *) malloc(genes * sizeof(int));
  }
  else
  {
    population = (int **) calloc(individuals, sizeof(int *));
    for (int i = 0; i < individuals; i++)
      population[i] = (int *) calloc(genes, sizeof(int));
  }

  return population;
}

int POPULATION::createRandomPopulation(int **population, int individuals, int genes)
{
  // Fill the 2d array with random genes
  for (int pop = 0; pop < individuals; pop++)
  {
    for (int gene = 0; gene < genes; gene++)
    {
      population[pop][gene] = rand() % 2;
    }
  }
  return 1;
}
<|endoftext|>


<commit_before>/*
 * W.J. van der Laan 2011
 */
#include "bitcoingui.h"
#include "clientmodel.h"
#include "walletmodel.h"
#include "optionsmodel.h"

#include "headers.h"
#include "init.h"

#include <QApplication>
#include <QMessageBox>
#include <QThread>
#include <QTextCodec>
#include <QLocale>
#include <QTranslator>
#include <QSplashScreen>

// Need a global reference for the notifications to find the GUI
BitcoinGUI *guiref;
QSplashScreen *splashref;

int MyMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y)
{
    // Message from main thread
    if(guiref)
    {
        guiref->error(QString::fromStdString(caption),
                      QString::fromStdString(message));
    }
    else
    {
        QMessageBox::critical(0, QString::fromStdString(caption),
            QString::fromStdString(message),
            QMessageBox::Ok, QMessageBox::Ok);
    }
    return 4;
}

int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y)
{
    // Message from network thread
    if(guiref)
    {
        QMetaObject::invokeMethod(guiref, "error", Qt::QueuedConnection,
                                   Q_ARG(QString, QString::fromStdString(caption)),
                                   Q_ARG(QString, QString::fromStdString(message)));
    }
    else
    {
        printf("%s: %s\n", caption.c_str(), message.c_str());
        fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
    }
    return 4;
}

bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindow* parent)
{
    if(!guiref)
        return false;
    if(nFeeRequired < MIN_TX_FEE || nFeeRequired <= nTransactionFee || fDaemon)
        return true;
    bool payFee = false;

    // Call slot on GUI thread.
    // If called from another thread, use a blocking QueuedConnection.
    Qt::ConnectionType connectionType = Qt::DirectConnection;
    if(QThread::currentThread() != QCoreApplication::instance()->thread())
    {
        connectionType = Qt::BlockingQueuedConnection;
    }

    QMetaObject::invokeMethod(guiref, "askFee", connectionType,
                               Q_ARG(qint64, nFeeRequired),
                               Q_ARG(bool*, &payFee));

    return payFee;
}

void CalledSetStatusBar(const std::string& strText, int nField)
{
    // Only used for built-in mining, which is disabled, simple ignore
}

void UIThreadCall(boost::function0<void> fn)
{
    // Only used for built-in mining, which is disabled, simple ignore
}

void MainFrameRepaint()
{
}

void InitMessage(const std::string &message)
{
    if(splashref)
    {
        splashref->showMessage(QString::fromStdString(message), Qt::AlignBottom|Qt::AlignHCenter, QColor(255,255,200));
        QApplication::instance()->processEvents();
    }
}

/*
   Translate string to current locale using Qt.
 */
std::string _(const char* psz)
{
    return QCoreApplication::translate("bitcoin-core", psz).toStdString();
}

int main(int argc, char *argv[])
{
    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
    QTextCodec::setCodecForCStrings(QTextCodec::codecForTr());

    Q_INIT_RESOURCE(bitcoin);
    QApplication app(argc, argv);

    // Load language file for system locale
    QString locale = QLocale::system().name();
    QTranslator translator;
    translator.load(":/translations/"+locale);
    app.installTranslator(&translator);

    QSplashScreen splash(QPixmap(":/images/splash"), 0);
    splash.show();
    splash.setAutoFillBackground(true);
    splashref = &splash;

    app.processEvents();

    app.setQuitOnLastWindowClosed(false);

    try
    {
        if(AppInit2(argc, argv))
        {
            {
                // Put this in a block, so that BitcoinGUI is cleaned up properly before
                // calling Shutdown().
                BitcoinGUI window;
                splash.finish(&window);
                OptionsModel optionsModel(pwalletMain);
                ClientModel clientModel(&optionsModel);
                WalletModel walletModel(pwalletMain, &optionsModel);

                guiref = &window;
                window.setClientModel(&clientModel);
                window.setWalletModel(&walletModel);

                window.show();

                app.exec();

                guiref = 0;
            }
            Shutdown(NULL);
        }
        else
        {
            return 1;
        }
    } catch (std::exception& e) {
        PrintException(&e, "Runaway exception");
    } catch (...) {
        PrintException(NULL, "Runaway exception");
    }
    return 0;
}
<commit_msg>only install translator when not empty<commit_after>/*
 * W.J. van der Laan 2011
 */
#include "bitcoingui.h"
#include "clientmodel.h"
#include "walletmodel.h"
#include "optionsmodel.h"

#include "headers.h"
#include "init.h"

#include <QApplication>
#include <QMessageBox>
#include <QThread>
#include <QTextCodec>
#include <QLocale>
#include <QTranslator>
#include <QSplashScreen>

// Need a global reference for the notifications to find the GUI
BitcoinGUI *guiref;
QSplashScreen *splashref;

int MyMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y)
{
    // Message from main thread
    if(guiref)
    {
        guiref->error(QString::fromStdString(caption),
                      QString::fromStdString(message));
    }
    else
    {
        QMessageBox::critical(0, QString::fromStdString(caption),
            QString::fromStdString(message),
            QMessageBox::Ok, QMessageBox::Ok);
    }
    return 4;
}

int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y)
{
    // Message from network thread
    if(guiref)
    {
        QMetaObject::invokeMethod(guiref, "error", Qt::QueuedConnection,
                                   Q_ARG(QString, QString::fromStdString(caption)),
                                   Q_ARG(QString, QString::fromStdString(message)));
    }
    else
    {
        printf("%s: %s\n", caption.c_str(), message.c_str());
        fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
    }
    return 4;
}

bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindow* parent)
{
    if(!guiref)
        return false;
    if(nFeeRequired < MIN_TX_FEE || nFeeRequired <= nTransactionFee || fDaemon)
        return true;
    bool payFee = false;

    // Call slot on GUI thread.
    // If called from another thread, use a blocking QueuedConnection.
    Qt::ConnectionType connectionType = Qt::DirectConnection;
    if(QThread::currentThread() != QCoreApplication::instance()->thread())
    {
        connectionType = Qt::BlockingQueuedConnection;
    }

    QMetaObject::invokeMethod(guiref, "askFee", connectionType,
                               Q_ARG(qint64, nFeeRequired),
                               Q_ARG(bool*, &payFee));

    return payFee;
}

void CalledSetStatusBar(const std::string& strText, int nField)
{
    // Only used for built-in mining, which is disabled, simple ignore
}

void UIThreadCall(boost::function0<void> fn)
{
    // Only used for built-in mining, which is disabled, simple ignore
}

void MainFrameRepaint()
{
}

void InitMessage(const std::string &message)
{
    if(splashref)
    {
        splashref->showMessage(QString::fromStdString(message), Qt::AlignBottom|Qt::AlignHCenter, QColor(255,255,200));
        QApplication::instance()->processEvents();
    }
}

/*
   Translate string to current locale using Qt.
 */
std::string _(const char* psz)
{
    return QCoreApplication::translate("bitcoin-core", psz).toStdString();
}

int main(int argc, char *argv[])
{
    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
    QTextCodec::setCodecForCStrings(QTextCodec::codecForTr());

    Q_INIT_RESOURCE(bitcoin);
    QApplication app(argc, argv);

    // Load language file for system locale
    QString locale = QLocale::system().name();
    QTranslator translator;
    translator.load(":/translations/"+locale);
    if (!translator.isEmpty())
        app.installTranslator(&translator);

    QSplashScreen splash(QPixmap(":/images/splash"), 0);
    splash.show();
    splash.setAutoFillBackground(true);
    splashref = &splash;

    app.processEvents();

    app.setQuitOnLastWindowClosed(false);

    try
    {
        if(AppInit2(argc, argv))
        {
            {
                // Put this in a block, so that BitcoinGUI is cleaned up properly before
                // calling Shutdown().
                BitcoinGUI window;
                splash.finish(&window);
                OptionsModel optionsModel(pwalletMain);
                ClientModel clientModel(&optionsModel);
                WalletModel walletModel(pwalletMain, &optionsModel);

                guiref = &window;
                window.setClientModel(&clientModel);
                window.setWalletModel(&walletModel);

                window.show();

                app.exec();

                guiref = 0;
            }
            Shutdown(NULL);
        }
        else
        {
            return 1;
        }
    } catch (std::exception& e) {
        PrintException(&e, "Runaway exception");
    } catch (...) {
        PrintException(NULL, "Runaway exception");
    }
    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2021 ScyllaDB
 */

/*
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

#pragma once

#include "mutation_fragment_v2.hh"
#include "range_tombstone_list.hh"

template<typename T>
concept RangeTombstoneChangeConsumer = std::invocable<T, range_tombstone_change>;

/// Generates range_tombstone_change fragments for a stream of range_tombstone fragments.
///
/// The input range_tombstones passed to consume() may be overlapping, but must be weakly ordered by position().
/// It's ok to pass consecutive range_tombstone objects with the same position.
///
/// Generated range_tombstone_change fragments will have strictly monotonic positions.
///
/// Example usage:
///
///   consume(range_tombstone(1, +inf, t));
///   flush(2, consumer);
///   consume(range_tombstone(2, +inf, t));
///   flush(3, consumer);
///   consume(range_tombstone(4, +inf, t));
///   consume(range_tombstone(4, 7, t));
///   flush(5, consumer);
///   flush(6, consumer);
///
class range_tombstone_change_generator {
    range_tombstone_list _range_tombstones;
    // All range_tombstone_change fragments with positions < than this have been emitted.
    position_in_partition _lower_bound = position_in_partition::before_all_clustered_rows();
    const schema& _schema;
public:
    range_tombstone_change_generator(const schema& s)
        : _range_tombstones(s)
        , _schema(s)
    { }

    // Discards deletion information for positions < lower_bound.
    // After this, the lowest position of emitted range_tombstone_change will be before_key(lower_bound).
    void trim(const position_in_partition& lower_bound) {
        position_in_partition::less_compare less(_schema);

        if (lower_bound.is_clustering_row()) {
            _lower_bound = position_in_partition::before_key(lower_bound.key());
        } else {
            _lower_bound = lower_bound;
        }

        while (!_range_tombstones.empty() && !less(lower_bound, _range_tombstones.begin()->end_position())) {
            _range_tombstones.pop(_range_tombstones.begin());
        }

        if (!_range_tombstones.empty() && less(_range_tombstones.begin()->position(), _lower_bound)) {
            // _range_tombstones.begin()->end_position() < lower_bound is guaranteed by previous loop.
            _range_tombstones.begin()->tombstone().set_start(_lower_bound);
        }
    }

    // Emits range_tombstone_change fragments with positions smaller than upper_bound
    // for accumulated range tombstones.
    // After this, only range_tombstones with positions >= upper_bound may be added,
    // which guarantees that they won't affect the output of this flush.
    // FIXME: respect preemption
    template<RangeTombstoneChangeConsumer C>
    void flush(position_in_partition_view upper_bound, C consumer) {
        if (_range_tombstones.empty()) {
            return;
        }

        position_in_partition::tri_compare cmp(_schema);
        std::optional<range_tombstone> prev;

        while (!_range_tombstones.empty() && (cmp(_range_tombstones.begin()->end_position(), upper_bound) < 0)) {
            auto rt = _range_tombstones.pop(_range_tombstones.begin());

            if (prev && (cmp(prev->end_position(), rt.position()) < 0)) { // [1]
                // previous range tombstone not adjacent, emit gap.
                consumer(range_tombstone_change(prev->end_position(), tombstone()));
            }

            // Check if start of rt was already emitted, emit if not.
            if (cmp(rt.position(), _lower_bound) >= 0) {
                consumer(range_tombstone_change(rt.position(), rt.tomb));
            }

            // Delay emitting end bound in case it's adjacent with the next tombstone. See [1] and [2]
            prev = std::move(rt);
        }

        // If previous range tombstone not adjacent with current, emit gap.
        // It cannot get adjacent later because prev->end_position() < upper_bound,
        // so nothing == prev->end_position() can be added after this invocation.
        if (prev && (_range_tombstones.empty()
                     || (cmp(prev->end_position(), _range_tombstones.begin()->position()) < 0))) {
            consumer(range_tombstone_change(prev->end_position(), tombstone())); // [2]
        }

        // Emit the fragment for start bound of a range_tombstone which is overlapping with upper_bound,
        // unless no such fragment or already emitted.
        if (!_range_tombstones.empty()
            && (cmp(_range_tombstones.begin()->position(), upper_bound) < 0)
            && (cmp(_range_tombstones.begin()->position(), _lower_bound) >= 0)) {
            consumer(range_tombstone_change(
                    _range_tombstones.begin()->position(), _range_tombstones.begin()->tombstone().tomb));
        }

        _lower_bound = upper_bound;
    }

    void consume(range_tombstone rt) {
        _range_tombstones.apply(_schema, std::move(rt));
    }

    void reset() {
        _range_tombstones.clear();
        _lower_bound = position_in_partition::before_all_clustered_rows();
    }

    bool discardable() const {
        return _range_tombstones.empty();
    }
};
<commit_msg>range_tombstone_change_generator: flush: emit end_position when upper limit is after all clustered rows<commit_after>/*
 * Copyright (C) 2021 ScyllaDB
 */

/*
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

#pragma once

#include "mutation_fragment_v2.hh"
#include "range_tombstone_list.hh"

template<typename T>
concept RangeTombstoneChangeConsumer = std::invocable<T, range_tombstone_change>;

/// Generates range_tombstone_change fragments for a stream of range_tombstone fragments.
///
/// The input range_tombstones passed to consume() may be overlapping, but must be weakly ordered by position().
/// It's ok to pass consecutive range_tombstone objects with the same position.
///
/// Generated range_tombstone_change fragments will have strictly monotonic positions.
///
/// Example usage:
///
///   consume(range_tombstone(1, +inf, t));
///   flush(2, consumer);
///   consume(range_tombstone(2, +inf, t));
///   flush(3, consumer);
///   consume(range_tombstone(4, +inf, t));
///   consume(range_tombstone(4, 7, t));
///   flush(5, consumer);
///   flush(6, consumer);
///
class range_tombstone_change_generator {
    range_tombstone_list _range_tombstones;
    // All range_tombstone_change fragments with positions < than this have been emitted.
    position_in_partition _lower_bound = position_in_partition::before_all_clustered_rows();
    const schema& _schema;
public:
    range_tombstone_change_generator(const schema& s)
        : _range_tombstones(s)
        , _schema(s)
    { }

    // Discards deletion information for positions < lower_bound.
    // After this, the lowest position of emitted range_tombstone_change will be before_key(lower_bound).
    void trim(const position_in_partition& lower_bound) {
        position_in_partition::less_compare less(_schema);

        if (lower_bound.is_clustering_row()) {
            _lower_bound = position_in_partition::before_key(lower_bound.key());
        } else {
            _lower_bound = lower_bound;
        }

        while (!_range_tombstones.empty() && !less(lower_bound, _range_tombstones.begin()->end_position())) {
            _range_tombstones.pop(_range_tombstones.begin());
        }

        if (!_range_tombstones.empty() && less(_range_tombstones.begin()->position(), _lower_bound)) {
            // _range_tombstones.begin()->end_position() < lower_bound is guaranteed by previous loop.
            _range_tombstones.begin()->tombstone().set_start(_lower_bound);
        }
    }

    // Emits range_tombstone_change fragments with positions smaller than upper_bound
    // for accumulated range tombstones.
    // After this, only range_tombstones with positions >= upper_bound may be added,
    // which guarantees that they won't affect the output of this flush.
    //
    // If upper_bound == position_in_partition::after_all_clustered_rows(),
    // emits all remaining range_tombstone_changes.
    // No range_tombstones may be added after this.
    //
    // FIXME: respect preemption
    template<RangeTombstoneChangeConsumer C>
    void flush(const position_in_partition_view upper_bound, C consumer) {
        if (_range_tombstones.empty()) {
            return;
        }

        position_in_partition::tri_compare cmp(_schema);
        std::optional<range_tombstone> prev;
        bool flush_all = cmp(upper_bound, position_in_partition::after_all_clustered_rows()) == 0;

        while (!_range_tombstones.empty() && (flush_all || (cmp(_range_tombstones.begin()->end_position(), upper_bound) < 0))) {
            auto rt = _range_tombstones.pop(_range_tombstones.begin());

            if (prev && (cmp(prev->end_position(), rt.position()) < 0)) { // [1]
                // previous range tombstone not adjacent, emit gap.
                consumer(range_tombstone_change(prev->end_position(), tombstone()));
            }

            // Check if start of rt was already emitted, emit if not.
            if (cmp(rt.position(), _lower_bound) >= 0) {
                consumer(range_tombstone_change(rt.position(), rt.tomb));
            }

            // Delay emitting end bound in case it's adjacent with the next tombstone. See [1] and [2]
            prev = std::move(rt);
        }

        // If previous range tombstone not adjacent with current, emit gap.
        // It cannot get adjacent later because prev->end_position() < upper_bound,
        // so nothing == prev->end_position() can be added after this invocation.
        if (prev && (_range_tombstones.empty()
                     || (cmp(prev->end_position(), _range_tombstones.begin()->position()) < 0))) {
            consumer(range_tombstone_change(prev->end_position(), tombstone())); // [2]
        }

        // Emit the fragment for start bound of a range_tombstone which is overlapping with upper_bound,
        // unless no such fragment or already emitted.
        if (!_range_tombstones.empty()
            && (cmp(_range_tombstones.begin()->position(), upper_bound) < 0)
            && (cmp(_range_tombstones.begin()->position(), _lower_bound) >= 0)) {
            consumer(range_tombstone_change(
                    _range_tombstones.begin()->position(), _range_tombstones.begin()->tombstone().tomb));
        }

        _lower_bound = upper_bound;
    }

    void consume(range_tombstone rt) {
        _range_tombstones.apply(_schema, std::move(rt));
    }

    void reset() {
        _range_tombstones.clear();
        _lower_bound = position_in_partition::before_all_clustered_rows();
    }

    bool discardable() const {
        return _range_tombstones.empty();
    }
};
<|endoftext|>


<commit_before>// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/web_dialog_helper.h"

#include <string>
#include <vector>

#include "atom/browser/atom_browser_context.h"
#include "atom/browser/native_window.h"
#include "atom/browser/ui/file_dialog.h"
#include "base/bind.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/file_chooser_file_info.h"
#include "content/public/common/file_chooser_params.h"
#include "net/base/mime_util.h"
#include "ui/shell_dialogs/selected_file_info.h"

namespace {

class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
                         public content::WebContentsObserver {
 public:
  FileSelectHelper(content::RenderFrameHost* render_frame_host,
                   const content::FileChooserParams::Mode& mode)
      : render_frame_host_(render_frame_host), mode_(mode) {
    auto web_contents = content::WebContents::FromRenderFrameHost(
        render_frame_host);
    content::WebContentsObserver::Observe(web_contents);
    // Add ref that will be released when the dialog is completed
    AddRef();
  }

  void ShowOpenDialog(const file_dialog::DialogSettings& settings) {
    auto callback = base::Bind(&FileSelectHelper::OnOpenDialogDone, this);
    file_dialog::ShowOpenDialog(settings, callback);
  }

  void ShowSaveDialog(const file_dialog::DialogSettings& settings) {
    auto callback = base::Bind(&FileSelectHelper::OnSaveDialogDone, this);
    file_dialog::ShowSaveDialog(settings, callback);
  }

 private:
  friend class base::RefCounted<FileSelectHelper>;

  ~FileSelectHelper() {}

  void OnOpenDialogDone(bool result, const std::vector<base::FilePath>& paths) {
    std::vector<content::FileChooserFileInfo> file_info;
    if (result) {
      for (auto& path : paths) {
        content::FileChooserFileInfo info;
        info.file_path = path;
        info.display_name = path.BaseName().value();
        file_info.push_back(info);
      }

      if (!paths.empty()) {
        auto browser_context = static_cast<atom::AtomBrowserContext*>(
            render_frame_host_->GetProcess()->GetBrowserContext());
        browser_context->prefs()->SetFilePath(prefs::kSelectFileLastDirectory,
                                              paths[0].DirName());
      }
    }
    OnFilesSelected(file_info);
  }

  void OnSaveDialogDone(bool result, const base::FilePath& path) {
    std::vector<content::FileChooserFileInfo> file_info;
    if (result) {
      content::FileChooserFileInfo info;
      info.file_path = path;
      info.display_name = path.BaseName().value();
      file_info.push_back(info);
    }
    OnFilesSelected(file_info);
  }

  void OnFilesSelected(
      const std::vector<content::FileChooserFileInfo>& file_info) {
    if (render_frame_host_)
      render_frame_host_->FilesSelectedInChooser(file_info, mode_);
    Release();
  }

  // content::WebContentsObserver:
  void RenderFrameHostChanged(content::RenderFrameHost* old_host,
                              content::RenderFrameHost* new_host) override {
    if (old_host == render_frame_host_)
      render_frame_host_ = nullptr;
  }

  // content::WebContentsObserver:
  void RenderFrameDeleted(content::RenderFrameHost* deleted_host) override {
    if (deleted_host == render_frame_host_)
      render_frame_host_ = nullptr;
  }

  // content::WebContentsObserver:
  void WebContentsDestroyed() override {
    render_frame_host_ = nullptr;
  }

  content::RenderFrameHost* render_frame_host_;
  content::FileChooserParams::Mode mode_;
};

file_dialog::Filters GetFileTypesFromAcceptType(
    const std::vector<base::string16>& accept_types) {
  file_dialog::Filters filters;
  if (accept_types.empty())
    return filters;

  std::vector<base::FilePath::StringType> extensions;

  for (const auto& accept_type : accept_types) {
    std::string ascii_type = base::UTF16ToASCII(accept_type);
    if (ascii_type[0] == '.') {
      // If the type starts with a period it is assumed to be a file extension,
      // like `.txt`, // so we just have to add it to the list.
      base::FilePath::StringType extension(
          ascii_type.begin(), ascii_type.end());
      // Skip the first character.
      extensions.push_back(extension.substr(1));
    } else {
      // For MIME Type, `audio/*, vidio/*, image/*
      net::GetExtensionsForMimeType(ascii_type, &extensions);
    }
  }

  // If no valid exntesion is added, return empty filters.
  if (extensions.empty())
    return filters;

  filters.push_back(file_dialog::Filter());
  for (const auto& extension : extensions) {
#if defined(OS_WIN)
    filters[0].second.push_back(base::UTF16ToASCII(extension));
#else
    filters[0].second.push_back(extension);
#endif
  }
  return filters;
}

}  // namespace

namespace atom {

WebDialogHelper::WebDialogHelper(NativeWindow* window)
    : window_(window),
      weak_factory_(this) {
}

WebDialogHelper::~WebDialogHelper() {
}

void WebDialogHelper::RunFileChooser(
    content::RenderFrameHost* render_frame_host,
    const content::FileChooserParams& params) {
  std::vector<content::FileChooserFileInfo> result;

  file_dialog::DialogSettings settings;
  settings.filters = GetFileTypesFromAcceptType(params.accept_types);
  settings.parent_window = window_;
  settings.title = base::UTF16ToUTF8(params.title);

  scoped_refptr<FileSelectHelper> file_select_helper(
      new FileSelectHelper(render_frame_host, params.mode));
  if (params.mode == content::FileChooserParams::Save) {
    settings.default_path = params.default_file_name;
    file_select_helper->ShowSaveDialog(settings);
  } else {
    int flags = file_dialog::FILE_DIALOG_CREATE_DIRECTORY;
    switch (params.mode) {
      case content::FileChooserParams::OpenMultiple:
        flags |= file_dialog::FILE_DIALOG_MULTI_SELECTIONS;
      case content::FileChooserParams::Open:
        flags |= file_dialog::FILE_DIALOG_OPEN_FILE;
        break;
      case content::FileChooserParams::UploadFolder:
        flags |= file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
        break;
      default:
        NOTREACHED();
    }

    AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
        window_->web_contents()->GetBrowserContext());
    settings.default_path = browser_context->prefs()->GetFilePath(
        prefs::kSelectFileLastDirectory).Append(params.default_file_name);
    settings.properties = flags;
    file_select_helper->ShowOpenDialog(settings);
  }
}

void WebDialogHelper::EnumerateDirectory(content::WebContents* web_contents,
                                         int request_id,
                                         const base::FilePath& dir) {
  int types = base::FileEnumerator::FILES |
              base::FileEnumerator::DIRECTORIES |
              base::FileEnumerator::INCLUDE_DOT_DOT;
  base::FileEnumerator file_enum(dir, false, types);

  base::FilePath path;
  std::vector<base::FilePath> paths;
  while (!(path = file_enum.Next()).empty())
    paths.push_back(path);

  web_contents->GetRenderViewHost()->DirectoryEnumerationFinished(
      request_id, paths);
}

}  // namespace atom
<commit_msg>Check render frame host before getting context<commit_after>// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/web_dialog_helper.h"

#include <string>
#include <vector>

#include "atom/browser/atom_browser_context.h"
#include "atom/browser/native_window.h"
#include "atom/browser/ui/file_dialog.h"
#include "base/bind.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/file_chooser_file_info.h"
#include "content/public/common/file_chooser_params.h"
#include "net/base/mime_util.h"
#include "ui/shell_dialogs/selected_file_info.h"

namespace {

class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
                         public content::WebContentsObserver {
 public:
  FileSelectHelper(content::RenderFrameHost* render_frame_host,
                   const content::FileChooserParams::Mode& mode)
      : render_frame_host_(render_frame_host), mode_(mode) {
    auto web_contents = content::WebContents::FromRenderFrameHost(
        render_frame_host);
    content::WebContentsObserver::Observe(web_contents);
    // Add ref that will be released when the dialog is completed
    AddRef();
  }

  void ShowOpenDialog(const file_dialog::DialogSettings& settings) {
    auto callback = base::Bind(&FileSelectHelper::OnOpenDialogDone, this);
    file_dialog::ShowOpenDialog(settings, callback);
  }

  void ShowSaveDialog(const file_dialog::DialogSettings& settings) {
    auto callback = base::Bind(&FileSelectHelper::OnSaveDialogDone, this);
    file_dialog::ShowSaveDialog(settings, callback);
  }

 private:
  friend class base::RefCounted<FileSelectHelper>;

  ~FileSelectHelper() {}

  void OnOpenDialogDone(bool result, const std::vector<base::FilePath>& paths) {
    std::vector<content::FileChooserFileInfo> file_info;
    if (result) {
      for (auto& path : paths) {
        content::FileChooserFileInfo info;
        info.file_path = path;
        info.display_name = path.BaseName().value();
        file_info.push_back(info);
      }

      if (render_frame_host_ && !paths.empty()) {
        auto browser_context = static_cast<atom::AtomBrowserContext*>(
            render_frame_host_->GetProcess()->GetBrowserContext());
        browser_context->prefs()->SetFilePath(prefs::kSelectFileLastDirectory,
                                              paths[0].DirName());
      }
    }
    OnFilesSelected(file_info);
  }

  void OnSaveDialogDone(bool result, const base::FilePath& path) {
    std::vector<content::FileChooserFileInfo> file_info;
    if (result) {
      content::FileChooserFileInfo info;
      info.file_path = path;
      info.display_name = path.BaseName().value();
      file_info.push_back(info);
    }
    OnFilesSelected(file_info);
  }

  void OnFilesSelected(
      const std::vector<content::FileChooserFileInfo>& file_info) {
    if (render_frame_host_)
      render_frame_host_->FilesSelectedInChooser(file_info, mode_);
    Release();
  }

  // content::WebContentsObserver:
  void RenderFrameHostChanged(content::RenderFrameHost* old_host,
                              content::RenderFrameHost* new_host) override {
    if (old_host == render_frame_host_)
      render_frame_host_ = nullptr;
  }

  // content::WebContentsObserver:
  void RenderFrameDeleted(content::RenderFrameHost* deleted_host) override {
    if (deleted_host == render_frame_host_)
      render_frame_host_ = nullptr;
  }

  // content::WebContentsObserver:
  void WebContentsDestroyed() override {
    render_frame_host_ = nullptr;
  }

  content::RenderFrameHost* render_frame_host_;
  content::FileChooserParams::Mode mode_;
};

file_dialog::Filters GetFileTypesFromAcceptType(
    const std::vector<base::string16>& accept_types) {
  file_dialog::Filters filters;
  if (accept_types.empty())
    return filters;

  std::vector<base::FilePath::StringType> extensions;

  for (const auto& accept_type : accept_types) {
    std::string ascii_type = base::UTF16ToASCII(accept_type);
    if (ascii_type[0] == '.') {
      // If the type starts with a period it is assumed to be a file extension,
      // like `.txt`, // so we just have to add it to the list.
      base::FilePath::StringType extension(
          ascii_type.begin(), ascii_type.end());
      // Skip the first character.
      extensions.push_back(extension.substr(1));
    } else {
      // For MIME Type, `audio/*, vidio/*, image/*
      net::GetExtensionsForMimeType(ascii_type, &extensions);
    }
  }

  // If no valid exntesion is added, return empty filters.
  if (extensions.empty())
    return filters;

  filters.push_back(file_dialog::Filter());
  for (const auto& extension : extensions) {
#if defined(OS_WIN)
    filters[0].second.push_back(base::UTF16ToASCII(extension));
#else
    filters[0].second.push_back(extension);
#endif
  }
  return filters;
}

}  // namespace

namespace atom {

WebDialogHelper::WebDialogHelper(NativeWindow* window)
    : window_(window),
      weak_factory_(this) {
}

WebDialogHelper::~WebDialogHelper() {
}

void WebDialogHelper::RunFileChooser(
    content::RenderFrameHost* render_frame_host,
    const content::FileChooserParams& params) {
  std::vector<content::FileChooserFileInfo> result;

  file_dialog::DialogSettings settings;
  settings.filters = GetFileTypesFromAcceptType(params.accept_types);
  settings.parent_window = window_;
  settings.title = base::UTF16ToUTF8(params.title);

  scoped_refptr<FileSelectHelper> file_select_helper(
      new FileSelectHelper(render_frame_host, params.mode));
  if (params.mode == content::FileChooserParams::Save) {
    settings.default_path = params.default_file_name;
    file_select_helper->ShowSaveDialog(settings);
  } else {
    int flags = file_dialog::FILE_DIALOG_CREATE_DIRECTORY;
    switch (params.mode) {
      case content::FileChooserParams::OpenMultiple:
        flags |= file_dialog::FILE_DIALOG_MULTI_SELECTIONS;
      case content::FileChooserParams::Open:
        flags |= file_dialog::FILE_DIALOG_OPEN_FILE;
        break;
      case content::FileChooserParams::UploadFolder:
        flags |= file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
        break;
      default:
        NOTREACHED();
    }

    AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
        window_->web_contents()->GetBrowserContext());
    settings.default_path = browser_context->prefs()->GetFilePath(
        prefs::kSelectFileLastDirectory).Append(params.default_file_name);
    settings.properties = flags;
    file_select_helper->ShowOpenDialog(settings);
  }
}

void WebDialogHelper::EnumerateDirectory(content::WebContents* web_contents,
                                         int request_id,
                                         const base::FilePath& dir) {
  int types = base::FileEnumerator::FILES |
              base::FileEnumerator::DIRECTORIES |
              base::FileEnumerator::INCLUDE_DOT_DOT;
  base::FileEnumerator file_enum(dir, false, types);

  base::FilePath path;
  std::vector<base::FilePath> paths;
  while (!(path = file_enum.Next()).empty())
    paths.push_back(path);

  web_contents->GetRenderViewHost()->DirectoryEnumerationFinished(
      request_id, paths);
}

}  // namespace atom
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/gtk/cairo_cached_surface.h"

#include "base/basictypes.h"
#include "base/logging.h"

CairoCachedSurface::CairoCachedSurface() : pixbuf_(NULL), surface_(NULL) {
}

CairoCachedSurface::~CairoCachedSurface() {
  if (surface_)
    cairo_surface_destroy(surface_);

  if (pixbuf_)
    g_object_unref(pixbuf_);
}

int CairoCachedSurface::Width() const {
  return pixbuf_ ? gdk_pixbuf_get_width(pixbuf_) : -1;
}

int CairoCachedSurface::Height() const {
  return pixbuf_ ? gdk_pixbuf_get_height(pixbuf_) : -1;
}

void CairoCachedSurface::UsePixbuf(GdkPixbuf* pixbuf) {
  if (surface_) {
    cairo_surface_destroy(surface_);
    surface_ = NULL;
  }

  if (pixbuf)
    g_object_ref(pixbuf);

  if (pixbuf_)
    g_object_unref(pixbuf_);

  pixbuf_ = pixbuf;
}

void CairoCachedSurface::SetSource(cairo_t* cr, int x, int y) {
  DCHECK(pixbuf_);
  DCHECK(cr);

  if (!surface_) {
    // First time here since last UsePixbuf call. Generate the surface.
    cairo_surface_t* target = cairo_get_target(cr);
    surface_ = cairo_surface_create_similar(
        target,
        CAIRO_CONTENT_COLOR_ALPHA,
        gdk_pixbuf_get_width(pixbuf_),
        gdk_pixbuf_get_height(pixbuf_));

    DCHECK(surface_);
    DCHECK(cairo_surface_get_type(surface_) == CAIRO_SURFACE_TYPE_XLIB ||
           cairo_surface_get_type(surface_) == CAIRO_SURFACE_TYPE_XCB);

    cairo_t* copy_cr = cairo_create(surface_);
    gdk_cairo_set_source_pixbuf(copy_cr, pixbuf_, 0, 0);
    cairo_paint(copy_cr);
    cairo_destroy(copy_cr);
  }

  cairo_set_source_surface(cr, surface_, x, y);
}
<commit_msg>Make Chromium Linux work over VNC again.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/gtk/cairo_cached_surface.h"

#include "base/basictypes.h"
#include "base/logging.h"

CairoCachedSurface::CairoCachedSurface() : pixbuf_(NULL), surface_(NULL) {
}

CairoCachedSurface::~CairoCachedSurface() {
  if (surface_)
    cairo_surface_destroy(surface_);

  if (pixbuf_)
    g_object_unref(pixbuf_);
}

int CairoCachedSurface::Width() const {
  return pixbuf_ ? gdk_pixbuf_get_width(pixbuf_) : -1;
}

int CairoCachedSurface::Height() const {
  return pixbuf_ ? gdk_pixbuf_get_height(pixbuf_) : -1;
}

void CairoCachedSurface::UsePixbuf(GdkPixbuf* pixbuf) {
  if (surface_) {
    cairo_surface_destroy(surface_);
    surface_ = NULL;
  }

  if (pixbuf)
    g_object_ref(pixbuf);

  if (pixbuf_)
    g_object_unref(pixbuf_);

  pixbuf_ = pixbuf;
}

void CairoCachedSurface::SetSource(cairo_t* cr, int x, int y) {
  DCHECK(pixbuf_);
  DCHECK(cr);

  if (!surface_) {
    // First time here since last UsePixbuf call. Generate the surface.
    cairo_surface_t* target = cairo_get_target(cr);
    surface_ = cairo_surface_create_similar(
        target,
        CAIRO_CONTENT_COLOR_ALPHA,
        gdk_pixbuf_get_width(pixbuf_),
        gdk_pixbuf_get_height(pixbuf_));

    DCHECK(surface_);
#if !defined(NDEBUG)
    int surface_type = cairo_surface_get_type(surface_);
    DCHECK(surface_type == CAIRO_SURFACE_TYPE_XLIB ||
           surface_type == CAIRO_SURFACE_TYPE_XCB ||
           surface_type == CAIRO_SURFACE_TYPE_IMAGE);
#endif

    cairo_t* copy_cr = cairo_create(surface_);
    gdk_cairo_set_source_pixbuf(copy_cr, pixbuf_, 0, 0);
    cairo_paint(copy_cr);
    cairo_destroy(copy_cr);
  }

  cairo_set_source_surface(cr, surface_, x, y);
}
<|endoftext|>