<commit_before>/*
 * PVParams.hpp
 *
 *  Created on: Nov 27, 2008
 *      Author: rasmussn
 */

#ifndef PVPARAMS_HPP_
#define PVPARAMS_HPP_

#include "../include/pv_common.h"
#include "../columns/HyPerCol.hpp"
#include <string.h>

// TODO - make MAX_PARAMS dynamic
#define MAX_PARAMS 100  // maximum number of parameters in a group

#undef HAS_MAIN   // define if provides a main function

namespace PV {

class Parameter {
public:
   Parameter(const char * name, double value);
   virtual ~Parameter();

   const char * name()      { return paramName; }
   double value()           { hasBeenReadFlag = true; return paramDblValue; }
   const float * valuePtr() { hasBeenReadFlag = true; return &paramValue; }
   const double * valueDblPtr() { hasBeenReadFlag = true; return &paramDblValue; }
   bool hasBeenRead()       { return hasBeenReadFlag; }
   int outputParam(FILE * fp, int indentation);
   void clearHasBeenRead()    { hasBeenReadFlag = false; }
   void setValue(double v)  { paramValue = (float) v; }

private:
   char * paramName;
   float paramValue;
   double paramDblValue;
   bool   hasBeenReadFlag;
};

class ParameterArray {
public:
   ParameterArray(int initialSize);
   virtual ~ParameterArray();
   int getArraySize() {return arraySize;}
   const char * name() {return paramName;}
   int setName(const char * name);
   const float * getValues(int * sz) { hasBeenReadFlag = true; *sz = arraySize; return values;}
   const double * getValuesDbl(int * sz) { hasBeenReadFlag = true; *sz = arraySize; return valuesDbl;}
   int pushValue(double value);
   bool hasBeenRead() { return hasBeenReadFlag; }
   void clearHasBeenRead() { hasBeenReadFlag = false; }

private:
   bool paramNameSet;
   char * paramName;
   int arraySize; // The number of values that have been pushed
   int bufferSize; // The size of the buffer in memory
   double * valuesDbl;
   float * values;
   bool hasBeenReadFlag;
};

class ParameterString {
public:
   ParameterString(const char * name, const char * value);
   virtual ~ParameterString();

   const char * getName()      { return paramName; }
   const char * getValue()     { hasBeenReadFlag = true; return paramValue; }
   bool hasBeenRead()          { return hasBeenReadFlag; }
   int outputString(FILE * fp, int indentation);
   void clearHasBeenRead()     { hasBeenReadFlag = false; }
   void setValue(const char * s) { free(paramValue); paramValue = strdup(s);}

private:
   char * paramName;
   char * paramValue;
   bool   hasBeenReadFlag;
};

class ParameterStack {
public:
   ParameterStack(int maxCount);
   virtual ~ParameterStack();

   int push(Parameter * param);
   Parameter * pop();
   Parameter * peek(int index)   { return parameters[index]; }
   int size()                    { return count; }
   int outputStack(FILE * fp, int indentation);

private:
   int count;
   int maxCount;
   Parameter ** parameters;
};

class ParameterArrayStack {
public:
   ParameterArrayStack(int initialCount);
   virtual ~ParameterArrayStack();
   int push(ParameterArray * array);
   int size() {return count;}
   ParameterArray * peek(int index) {return index>=0 && index<count ? parameterArrays[index] : NULL; }

private:
   int count; // Number of ParameterArrays
   int allocation; // Size of buffer
   ParameterArray ** parameterArrays;

};

class ParameterStringStack {
public:
   ParameterStringStack(int initialCount);
   virtual ~ParameterStringStack();

   int push(ParameterString * param);
   ParameterString * pop();
   ParameterString * peek(int index)    { return index>=0 && index<count ? parameterStrings[index] : NULL; }
   int size()                           { return count; }
   const char * lookup(const char * targetname);
   int outputStack(FILE * fp, int indentation);

private:
   int count;
   int allocation;
   ParameterString ** parameterStrings;
};

class ParameterGroup {
public:
#ifdef OBSOLETE // Marked obsolete Aug 10, 2012.  String parameters should be handled on an equal footing with numerical parameters
   ParameterGroup(char * name, ParameterStack * stack, int rank=0);
#endif // OBSOLETE
   ParameterGroup(char * name, ParameterStack * stack, ParameterArrayStack * array_stack, ParameterStringStack * string_stack, int rank=0);
   virtual ~ParameterGroup();

   const char * name()   { return groupName; }
   const char * getGroupKeyword() { return groupKeyword; }
   int setGroupKeyword(const char * keyword);
   int setStringStack(ParameterStringStack * stringStack);
   int   present(const char * name);
   double value  (const char * name);
   int   arrayPresent(const char * name);
   const float * arrayValues(const char * name, int * size);
   const double * arrayValuesDbl(const char * name, int * size);
   int   stringPresent(const char * stringName);
   const char * stringValue(const char * stringName);
   int warnUnread();
   int clearHasBeenReadFlags();
   int outputGroup(FILE * fp);
   int pushNumerical(Parameter * param);
   int pushString(ParameterString * param);
   int setValue(const char * param_name, double value);
   int setStringValue(const char * param_name, const char * svalue);

private:
   char * groupName;
   char * groupKeyword;
   ParameterStack * stack;
   ParameterArrayStack * arrayStack;
   ParameterStringStack * stringStack;
   int processRank;
};

enum ParameterSweepType {
   PARAMSWEEP_UNDEF = 0,
   PARAMSWEEP_NUMBER  = 1,
   PARAMSWEEP_STRING  = 2
};

class ParameterSweep {
public:
   ParameterSweep();
   virtual ~ParameterSweep();

   int setGroupAndParameter(const char * groupname, const char * paramname);
   int pushNumericValue(float val);
   int pushStringValue(const char * sval);
   int getNumValues() {return numValues;}
   ParameterSweepType getType() {return type;}
   int getNumericValue(int n, float * val);
   const char * getStringValue(int n);
   const char * getGroupName() {return groupName;}
   const char * getParamName() {return paramName;}

private:
   char * groupName;
   char * paramName;
   ParameterSweepType type;
   int numValues;
   int currentBufferSize;
   float * valuesNumber;
   char ** valuesString;
};

#ifdef OBSOLETE // Marked obsolete Aug 9, 2012.  No one uses this, and filenames can be defined as string parameters in parameter groups
// FilenameDef and FilenameStack deprecated Oct 27, 2011
class FilenameDef {
public:
   FilenameDef(char * newKey, char * newValue);
   virtual ~FilenameDef();

   const char * getKey() { return key; };
   const char * getValue() { return value; };

private:
   char * key;
   char * value;
};

// FilenameDef and FilenameStack deprecated Oct 27, 2011
class FilenameStack {
public:
   FilenameStack(unsigned int maxCount);
   virtual ~FilenameStack();

   unsigned int getMaxCount() { return maxCount; };
   unsigned int getCount() { return count; };
   FilenameDef * getFilenameDef(unsigned int index);
   FilenameDef * getFilenameDefByKey(const char * searchKey);
   int push(FilenameDef * newfilenamedef);
   FilenameDef * pop();
private:
   unsigned int maxCount;
   unsigned int count;
   FilenameDef ** filenamedefs;
};
#endif // OBSOLETE

class PVParams {
public:
   PVParams(int initialSize, InterColComm * icComm); // TODO Should be const InterColComm * comm
   PVParams(const char * filename, int initialSize, InterColComm * icComm);
   virtual ~PVParams();

   bool getParseStatus() { return parseStatus; }
   int   present(const char * groupName, const char * paramName);
   double value  (const char * groupName, const char * paramName);
   double value  (const char * groupName, const char * paramName, float initialValue, bool warnIfAbsent=true);
   const float * arrayValues(const char * groupName, const char * paramName, int * arraySize);
   const double * arrayValuesDbl(const char * groupName, const char * paramName, int * arraySize);
   int   stringPresent(const char * groupName, const char * paramStringName);
   const char * stringValue(const char * groupName, const char * paramStringName, bool warnIfAbsent=true);
   ParameterGroup * group(const char * groupName);
   const char * groupNameFromIndex(int index);
   const char * groupKeywordFromIndex(int index);
#ifdef OBSOLETE // Marked obsolete Aug 9, 2012.  No one uses this, and filenames can be defined as string parameters in parameter groups
   const char * getFilename(const char * id);
#endif // OBSOLETE
   int warnUnread();
   int outputParams(FILE *);
   int setSweepValues(int n);

   void action_pvparams_directive(char * id, double val);
   void action_parameter_group(char * keyword, char * name);
   void action_parameter_def(char * id, double val);
   void action_parameter_array(char * id);
   void action_parameter_array_value(double val);
   void action_parameter_string_def(const char * id, const char * stringval);
   void action_parameter_filename_def(const char * id, const char * stringval);
   void action_include_directive(const char * stringval);
   void action_parameter_sweep(const char * id, const char * groupname, const char * paramname);
   void action_sweep_values_number(double val);
   void action_sweep_values_string(const char * stringval);
   void action_sweep_values_filename(const char * stringval);

   int numberOfGroups() {return numGroups;}
   InterColComm * getInterColComm() {return icComm;}
   int numberOfSweeps() {return numParamSweeps;}
   int getSweepSize() {return sweepSize;}

private:
   int parseStatus;
   int numGroups;
   int groupArraySize;
   // int maxGroups;
   ParameterGroup ** groups;
   ParameterStack * stack;
   ParameterArrayStack * arrayStack;
   ParameterStringStack * stringStack;
#ifdef OBSOLETE // Marked obsolete Aug 9, 2012.  No one uses this, and filenames can be defined as string parameters in parameter groups
   FilenameStack * fnstack; // Deprecated Oct 27, 2011
#endif // OBSOLETE
   bool debugParsing;
   bool disable;
   InterColComm * icComm;
   int getRank() {return icComm->commRank();}

   ParameterArray * currentParamArray;

   int numParamSweeps; // The number of different parameters that are changed during the sweep.
   ParameterSweep ** paramSweeps;
   ParameterSweep * activeParamSweep;
   int sweepSize; // The number of parameter value sets in the sweep.  Each ParameterSweep group in the params file must contain the same number of values, which is sweepSize.

   int initialize(int initialSize, InterColComm * icComm);
   int parsefile(const char * filename);
   int setSweepSize();
   void addGroup(char * keyword, char * name);
   void addActiveParamSweep(const char * group_name, const char * param_name);
   int checkDuplicates(const char * paramName);
   int newActiveParamSweep();
   int clearHasBeenReadFlags();
   static char * stripQuotationMarks(const char *s);
};

}

#endif /* PVPARAMS_HPP_ */
<commit_msg>Bugfix to PVParams::setValue<commit_after>/*
 * PVParams.hpp
 *
 *  Created on: Nov 27, 2008
 *      Author: rasmussn
 */

#ifndef PVPARAMS_HPP_
#define PVPARAMS_HPP_

#include "../include/pv_common.h"
#include "../columns/HyPerCol.hpp"
#include <string.h>

// TODO - make MAX_PARAMS dynamic
#define MAX_PARAMS 100  // maximum number of parameters in a group

#undef HAS_MAIN   // define if provides a main function

namespace PV {

class Parameter {
public:
   Parameter(const char * name, double value);
   virtual ~Parameter();

   const char * name()      { return paramName; }
   double value()           { hasBeenReadFlag = true; return paramDblValue; }
   const float * valuePtr() { hasBeenReadFlag = true; return &paramValue; }
   const double * valueDblPtr() { hasBeenReadFlag = true; return &paramDblValue; }
   bool hasBeenRead()       { return hasBeenReadFlag; }
   int outputParam(FILE * fp, int indentation);
   void clearHasBeenRead()    { hasBeenReadFlag = false; }
   void setValue(double v)  { paramValue = (float) v; paramDblValue = v;}

private:
   char * paramName;
   float paramValue;
   double paramDblValue;
   bool   hasBeenReadFlag;
};

class ParameterArray {
public:
   ParameterArray(int initialSize);
   virtual ~ParameterArray();
   int getArraySize() {return arraySize;}
   const char * name() {return paramName;}
   int setName(const char * name);
   const float * getValues(int * sz) { hasBeenReadFlag = true; *sz = arraySize; return values;}
   const double * getValuesDbl(int * sz) { hasBeenReadFlag = true; *sz = arraySize; return valuesDbl;}
   int pushValue(double value);
   bool hasBeenRead() { return hasBeenReadFlag; }
   void clearHasBeenRead() { hasBeenReadFlag = false; }

private:
   bool paramNameSet;
   char * paramName;
   int arraySize; // The number of values that have been pushed
   int bufferSize; // The size of the buffer in memory
   double * valuesDbl;
   float * values;
   bool hasBeenReadFlag;
};

class ParameterString {
public:
   ParameterString(const char * name, const char * value);
   virtual ~ParameterString();

   const char * getName()      { return paramName; }
   const char * getValue()     { hasBeenReadFlag = true; return paramValue; }
   bool hasBeenRead()          { return hasBeenReadFlag; }
   int outputString(FILE * fp, int indentation);
   void clearHasBeenRead()     { hasBeenReadFlag = false; }
   void setValue(const char * s) { free(paramValue); paramValue = strdup(s);}

private:
   char * paramName;
   char * paramValue;
   bool   hasBeenReadFlag;
};

class ParameterStack {
public:
   ParameterStack(int maxCount);
   virtual ~ParameterStack();

   int push(Parameter * param);
   Parameter * pop();
   Parameter * peek(int index)   { return parameters[index]; }
   int size()                    { return count; }
   int outputStack(FILE * fp, int indentation);

private:
   int count;
   int maxCount;
   Parameter ** parameters;
};

class ParameterArrayStack {
public:
   ParameterArrayStack(int initialCount);
   virtual ~ParameterArrayStack();
   int push(ParameterArray * array);
   int size() {return count;}
   ParameterArray * peek(int index) {return index>=0 && index<count ? parameterArrays[index] : NULL; }

private:
   int count; // Number of ParameterArrays
   int allocation; // Size of buffer
   ParameterArray ** parameterArrays;

};

class ParameterStringStack {
public:
   ParameterStringStack(int initialCount);
   virtual ~ParameterStringStack();

   int push(ParameterString * param);
   ParameterString * pop();
   ParameterString * peek(int index)    { return index>=0 && index<count ? parameterStrings[index] : NULL; }
   int size()                           { return count; }
   const char * lookup(const char * targetname);
   int outputStack(FILE * fp, int indentation);

private:
   int count;
   int allocation;
   ParameterString ** parameterStrings;
};

class ParameterGroup {
public:
#ifdef OBSOLETE // Marked obsolete Aug 10, 2012.  String parameters should be handled on an equal footing with numerical parameters
   ParameterGroup(char * name, ParameterStack * stack, int rank=0);
#endif // OBSOLETE
   ParameterGroup(char * name, ParameterStack * stack, ParameterArrayStack * array_stack, ParameterStringStack * string_stack, int rank=0);
   virtual ~ParameterGroup();

   const char * name()   { return groupName; }
   const char * getGroupKeyword() { return groupKeyword; }
   int setGroupKeyword(const char * keyword);
   int setStringStack(ParameterStringStack * stringStack);
   int   present(const char * name);
   double value  (const char * name);
   int   arrayPresent(const char * name);
   const float * arrayValues(const char * name, int * size);
   const double * arrayValuesDbl(const char * name, int * size);
   int   stringPresent(const char * stringName);
   const char * stringValue(const char * stringName);
   int warnUnread();
   int clearHasBeenReadFlags();
   int outputGroup(FILE * fp);
   int pushNumerical(Parameter * param);
   int pushString(ParameterString * param);
   int setValue(const char * param_name, double value);
   int setStringValue(const char * param_name, const char * svalue);

private:
   char * groupName;
   char * groupKeyword;
   ParameterStack * stack;
   ParameterArrayStack * arrayStack;
   ParameterStringStack * stringStack;
   int processRank;
};

enum ParameterSweepType {
   PARAMSWEEP_UNDEF = 0,
   PARAMSWEEP_NUMBER  = 1,
   PARAMSWEEP_STRING  = 2
};

class ParameterSweep {
public:
   ParameterSweep();
   virtual ~ParameterSweep();

   int setGroupAndParameter(const char * groupname, const char * paramname);
   int pushNumericValue(float val);
   int pushStringValue(const char * sval);
   int getNumValues() {return numValues;}
   ParameterSweepType getType() {return type;}
   int getNumericValue(int n, float * val);
   const char * getStringValue(int n);
   const char * getGroupName() {return groupName;}
   const char * getParamName() {return paramName;}

private:
   char * groupName;
   char * paramName;
   ParameterSweepType type;
   int numValues;
   int currentBufferSize;
   float * valuesNumber;
   char ** valuesString;
};

#ifdef OBSOLETE // Marked obsolete Aug 9, 2012.  No one uses this, and filenames can be defined as string parameters in parameter groups
// FilenameDef and FilenameStack deprecated Oct 27, 2011
class FilenameDef {
public:
   FilenameDef(char * newKey, char * newValue);
   virtual ~FilenameDef();

   const char * getKey() { return key; };
   const char * getValue() { return value; };

private:
   char * key;
   char * value;
};

// FilenameDef and FilenameStack deprecated Oct 27, 2011
class FilenameStack {
public:
   FilenameStack(unsigned int maxCount);
   virtual ~FilenameStack();

   unsigned int getMaxCount() { return maxCount; };
   unsigned int getCount() { return count; };
   FilenameDef * getFilenameDef(unsigned int index);
   FilenameDef * getFilenameDefByKey(const char * searchKey);
   int push(FilenameDef * newfilenamedef);
   FilenameDef * pop();
private:
   unsigned int maxCount;
   unsigned int count;
   FilenameDef ** filenamedefs;
};
#endif // OBSOLETE

class PVParams {
public:
   PVParams(int initialSize, InterColComm * icComm); // TODO Should be const InterColComm * comm
   PVParams(const char * filename, int initialSize, InterColComm * icComm);
   virtual ~PVParams();

   bool getParseStatus() { return parseStatus; }
   int   present(const char * groupName, const char * paramName);
   double value  (const char * groupName, const char * paramName);
   double value  (const char * groupName, const char * paramName, float initialValue, bool warnIfAbsent=true);
   const float * arrayValues(const char * groupName, const char * paramName, int * arraySize);
   const double * arrayValuesDbl(const char * groupName, const char * paramName, int * arraySize);
   int   stringPresent(const char * groupName, const char * paramStringName);
   const char * stringValue(const char * groupName, const char * paramStringName, bool warnIfAbsent=true);
   ParameterGroup * group(const char * groupName);
   const char * groupNameFromIndex(int index);
   const char * groupKeywordFromIndex(int index);
#ifdef OBSOLETE // Marked obsolete Aug 9, 2012.  No one uses this, and filenames can be defined as string parameters in parameter groups
   const char * getFilename(const char * id);
#endif // OBSOLETE
   int warnUnread();
   int outputParams(FILE *);
   int setSweepValues(int n);

   void action_pvparams_directive(char * id, double val);
   void action_parameter_group(char * keyword, char * name);
   void action_parameter_def(char * id, double val);
   void action_parameter_array(char * id);
   void action_parameter_array_value(double val);
   void action_parameter_string_def(const char * id, const char * stringval);
   void action_parameter_filename_def(const char * id, const char * stringval);
   void action_include_directive(const char * stringval);
   void action_parameter_sweep(const char * id, const char * groupname, const char * paramname);
   void action_sweep_values_number(double val);
   void action_sweep_values_string(const char * stringval);
   void action_sweep_values_filename(const char * stringval);

   int numberOfGroups() {return numGroups;}
   InterColComm * getInterColComm() {return icComm;}
   int numberOfSweeps() {return numParamSweeps;}
   int getSweepSize() {return sweepSize;}

private:
   int parseStatus;
   int numGroups;
   int groupArraySize;
   // int maxGroups;
   ParameterGroup ** groups;
   ParameterStack * stack;
   ParameterArrayStack * arrayStack;
   ParameterStringStack * stringStack;
#ifdef OBSOLETE // Marked obsolete Aug 9, 2012.  No one uses this, and filenames can be defined as string parameters in parameter groups
   FilenameStack * fnstack; // Deprecated Oct 27, 2011
#endif // OBSOLETE
   bool debugParsing;
   bool disable;
   InterColComm * icComm;
   int getRank() {return icComm->commRank();}

   ParameterArray * currentParamArray;

   int numParamSweeps; // The number of different parameters that are changed during the sweep.
   ParameterSweep ** paramSweeps;
   ParameterSweep * activeParamSweep;
   int sweepSize; // The number of parameter value sets in the sweep.  Each ParameterSweep group in the params file must contain the same number of values, which is sweepSize.

   int initialize(int initialSize, InterColComm * icComm);
   int parsefile(const char * filename);
   int setSweepSize();
   void addGroup(char * keyword, char * name);
   void addActiveParamSweep(const char * group_name, const char * param_name);
   int checkDuplicates(const char * paramName);
   int newActiveParamSweep();
   int clearHasBeenReadFlags();
   static char * stripQuotationMarks(const char *s);
};

}

#endif /* PVPARAMS_HPP_ */
<|endoftext|>


<commit_before>//===--- SIL.cpp - Implements random SIL functionality --------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/SIL/FormalLinkage.h"
#include "swift/SIL/SILModule.h"
#include "swift/SIL/SILBuilder.h"
#include "swift/SIL/SILDeclRef.h"
#include "swift/SIL/SILType.h"
#include "swift/SIL/SILUndef.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/AnyFunctionRef.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Pattern.h"
#include "swift/AST/ProtocolConformance.h"
#include "swift/ClangImporter/ClangModule.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"

using namespace swift;

SILUndef *SILUndef::get(SILType Ty, SILModule *M) {
  // Unique these.
  SILUndef *&Entry = M->UndefValues[Ty];
  if (Entry == nullptr)
    Entry = new (*M) SILUndef(Ty);
  return Entry;
}

FormalLinkage swift::getDeclLinkage(const ValueDecl *D) {
  const DeclContext *fileContext = D->getDeclContext()->getModuleScopeContext();

  // Clang declarations are public and can't be assured of having a
  // unique defining location.
  if (isa<ClangModuleUnit>(fileContext))
    return FormalLinkage::PublicNonUnique;

  switch (D->getEffectiveAccess()) {
  case AccessLevel::Public:
  case AccessLevel::Open:
    return FormalLinkage::PublicUnique;
  case AccessLevel::Internal:
    return FormalLinkage::HiddenUnique;
  case AccessLevel::FilePrivate:
  case AccessLevel::Private:
    return FormalLinkage::Private;
  }

  llvm_unreachable("Unhandled access level in switch.");
}

SILLinkage swift::getSILLinkage(FormalLinkage linkage,
                                ForDefinition_t forDefinition) {
  switch (linkage) {
  case FormalLinkage::PublicUnique:
    return (forDefinition ? SILLinkage::Public : SILLinkage::PublicExternal);

  case FormalLinkage::PublicNonUnique:
    // FIXME: any place we have to do this that actually requires
    // uniqueness is buggy.
    return (forDefinition ? SILLinkage::Shared : SILLinkage::PublicExternal);

  case FormalLinkage::HiddenUnique:
    return (forDefinition ? SILLinkage::Hidden : SILLinkage::HiddenExternal);

  case FormalLinkage::Private:
    return SILLinkage::Private;
  }
  llvm_unreachable("bad formal linkage");
}

SILLinkage
swift::getLinkageForProtocolConformance(const NormalProtocolConformance *C,
                                        ForDefinition_t definition) {
  // Behavior conformances are always private.
  if (C->isBehaviorConformance())
    return (definition ? SILLinkage::Private : SILLinkage::PrivateExternal);

  // If the conformance was synthesized by the ClangImporter, give it
  // shared linkage.
  if (isa<ClangModuleUnit>(C->getDeclContext()->getModuleScopeContext()))
    return SILLinkage::Shared;

  auto typeDecl = C->getType()->getNominalOrBoundGenericNominal();
  AccessLevel access = std::min(C->getProtocol()->getEffectiveAccess(),
                                typeDecl->getEffectiveAccess());
  switch (access) {
    case AccessLevel::Private:
    case AccessLevel::FilePrivate:
      return (definition ? SILLinkage::Private : SILLinkage::PrivateExternal);

    case AccessLevel::Internal:
      return (definition ? SILLinkage::Hidden : SILLinkage::HiddenExternal);

    default:
      return (definition ? SILLinkage::Public : SILLinkage::PublicExternal);
  }
}

bool SILModule::isTypeMetadataAccessible(CanType type) {
  assert(type->isLegalFormalType());

  return !type.findIf([&](CanType type) {
    // Note that this function returns true if the type is *illegal* to use.

    // Ignore non-nominal types.
    auto decl = type.getNominalOrBoundGenericNominal();
    if (!decl)
      return false;

    // Check whether the declaration is inaccessible from the current context.
    switch (getDeclLinkage(decl)) {

    // Public declarations are accessible from everywhere.
    case FormalLinkage::PublicUnique:
    case FormalLinkage::PublicNonUnique:
      return false;

    // Hidden declarations are inaccessible from different modules.
    case FormalLinkage::HiddenUnique:
      return (decl->getModuleContext() != getSwiftModule());

    // Private declarations are inaccessible from different files unless
    // this is WMO and we're in the same module.
    case FormalLinkage::Private: {
      // The only time we don't have an associated DC is in the
      // integrated REPL, where we also don't have a concept of other
      // source files within the current module.
      if (!AssociatedDeclContext)
        return (decl->getModuleContext() != getSwiftModule());

      // The associated DC should be either a SourceFile or, in WMO mode,
      // a ModuleDecl.  In the WMO modes, IRGen will ensure that private
      // declarations are usable throughout the module.  Therefore, in
      // either case we just need to make sure that the declaration comes
      // from within the associated DC.
      auto declDC = decl->getDeclContext();
      return !(declDC == AssociatedDeclContext ||
               declDC->isChildContextOf(AssociatedDeclContext));
    }
    }
    llvm_unreachable("bad linkage");
  });
}

/// Answer whether IRGen's emitTypeMetadataForLayout can fetch metadata for
/// a type, which is the necessary condition for being able to do value
/// operations on the type using dynamic metadata.
static bool isTypeMetadataForLayoutAccessible(SILModule &M, SILType type) {
  // Look through types that aren't necessarily legal formal types:

  //   - tuples
  if (auto tupleType = type.getAs<TupleType>()) {
    for (auto index : indices(tupleType.getElementTypes())) {
      if (!isTypeMetadataForLayoutAccessible(M, type.getTupleElementType(index)))
        return false;
    }
    return true;
  }

  //   - optionals
  if (auto objType = type.getOptionalObjectType()) {
    return isTypeMetadataForLayoutAccessible(M, objType);
  }

  //   - function types
  if (type.is<SILFunctionType>())
    return true;

  //   - metatypes
  if (type.is<AnyMetatypeType>())
    return true;

  // Otherwise, check that we can fetch the type metadata.
  return M.isTypeMetadataAccessible(type.getASTType());

}

/// Can we perform value operations on the given type?  We have no way
/// of doing value operations on resilient-layout types from other modules
/// that are ABI-private to their defining module.  But if the type is not
/// ABI-private, we can always at least fetch its metadata and use the
/// value witness table stored there.
bool SILModule::isTypeABIAccessible(SILType type) {
  // Fixed-ABI types can have value operations done without metadata.
  if (Types.getTypeLowering(type).isFixedABI())
    return true;

  assert(!type.is<ReferenceStorageType>() &&
         !type.is<SILFunctionType>() &&
         !type.is<AnyMetatypeType>() &&
         "unexpected SIL lowered-only type with non-fixed layout");

  // Otherwise, we need to be able to fetch layout-metadata for the type.
  return isTypeMetadataForLayoutAccessible(*this, type);
}
<commit_msg>[SIL] Relax isTypeMetadataAccessible() for debugger-produced modules.<commit_after>//===--- SIL.cpp - Implements random SIL functionality --------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/SIL/FormalLinkage.h"
#include "swift/SIL/SILModule.h"
#include "swift/SIL/SILBuilder.h"
#include "swift/SIL/SILDeclRef.h"
#include "swift/SIL/SILType.h"
#include "swift/SIL/SILUndef.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/AnyFunctionRef.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Pattern.h"
#include "swift/AST/ProtocolConformance.h"
#include "swift/ClangImporter/ClangModule.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"

using namespace swift;

SILUndef *SILUndef::get(SILType Ty, SILModule *M) {
  // Unique these.
  SILUndef *&Entry = M->UndefValues[Ty];
  if (Entry == nullptr)
    Entry = new (*M) SILUndef(Ty);
  return Entry;
}

FormalLinkage swift::getDeclLinkage(const ValueDecl *D) {
  const DeclContext *fileContext = D->getDeclContext()->getModuleScopeContext();

  // Clang declarations are public and can't be assured of having a
  // unique defining location.
  if (isa<ClangModuleUnit>(fileContext))
    return FormalLinkage::PublicNonUnique;

  switch (D->getEffectiveAccess()) {
  case AccessLevel::Public:
  case AccessLevel::Open:
    return FormalLinkage::PublicUnique;
  case AccessLevel::Internal:
    return FormalLinkage::HiddenUnique;
  case AccessLevel::FilePrivate:
  case AccessLevel::Private:
    return FormalLinkage::Private;
  }

  llvm_unreachable("Unhandled access level in switch.");
}

SILLinkage swift::getSILLinkage(FormalLinkage linkage,
                                ForDefinition_t forDefinition) {
  switch (linkage) {
  case FormalLinkage::PublicUnique:
    return (forDefinition ? SILLinkage::Public : SILLinkage::PublicExternal);

  case FormalLinkage::PublicNonUnique:
    // FIXME: any place we have to do this that actually requires
    // uniqueness is buggy.
    return (forDefinition ? SILLinkage::Shared : SILLinkage::PublicExternal);

  case FormalLinkage::HiddenUnique:
    return (forDefinition ? SILLinkage::Hidden : SILLinkage::HiddenExternal);

  case FormalLinkage::Private:
    return SILLinkage::Private;
  }
  llvm_unreachable("bad formal linkage");
}

SILLinkage
swift::getLinkageForProtocolConformance(const NormalProtocolConformance *C,
                                        ForDefinition_t definition) {
  // Behavior conformances are always private.
  if (C->isBehaviorConformance())
    return (definition ? SILLinkage::Private : SILLinkage::PrivateExternal);

  // If the conformance was synthesized by the ClangImporter, give it
  // shared linkage.
  if (isa<ClangModuleUnit>(C->getDeclContext()->getModuleScopeContext()))
    return SILLinkage::Shared;

  auto typeDecl = C->getType()->getNominalOrBoundGenericNominal();
  AccessLevel access = std::min(C->getProtocol()->getEffectiveAccess(),
                                typeDecl->getEffectiveAccess());
  switch (access) {
    case AccessLevel::Private:
    case AccessLevel::FilePrivate:
      return (definition ? SILLinkage::Private : SILLinkage::PrivateExternal);

    case AccessLevel::Internal:
      return (definition ? SILLinkage::Hidden : SILLinkage::HiddenExternal);

    default:
      return (definition ? SILLinkage::Public : SILLinkage::PublicExternal);
  }
}

bool SILModule::isTypeMetadataAccessible(CanType type) {
  // SILModules built for the debugger have special powers to access metadata
  // for types in other files/modules.
  if (getASTContext().LangOpts.DebuggerSupport)
    return true;

  assert(type->isLegalFormalType());

  return !type.findIf([&](CanType type) {
    // Note that this function returns true if the type is *illegal* to use.

    // Ignore non-nominal types.
    auto decl = type.getNominalOrBoundGenericNominal();
    if (!decl)
      return false;

    // Check whether the declaration is inaccessible from the current context.
    switch (getDeclLinkage(decl)) {

    // Public declarations are accessible from everywhere.
    case FormalLinkage::PublicUnique:
    case FormalLinkage::PublicNonUnique:
      return false;

    // Hidden declarations are inaccessible from different modules.
    case FormalLinkage::HiddenUnique:
      return (decl->getModuleContext() != getSwiftModule());

    // Private declarations are inaccessible from different files unless
    // this is WMO and we're in the same module.
    case FormalLinkage::Private: {
      // The only time we don't have an associated DC is in the
      // integrated REPL, where we also don't have a concept of other
      // source files within the current module.
      if (!AssociatedDeclContext)
        return (decl->getModuleContext() != getSwiftModule());

      // The associated DC should be either a SourceFile or, in WMO mode,
      // a ModuleDecl.  In the WMO modes, IRGen will ensure that private
      // declarations are usable throughout the module.  Therefore, in
      // either case we just need to make sure that the declaration comes
      // from within the associated DC.
      auto declDC = decl->getDeclContext();
      return !(declDC == AssociatedDeclContext ||
               declDC->isChildContextOf(AssociatedDeclContext));
    }
    }
    llvm_unreachable("bad linkage");
  });
}

/// Answer whether IRGen's emitTypeMetadataForLayout can fetch metadata for
/// a type, which is the necessary condition for being able to do value
/// operations on the type using dynamic metadata.
static bool isTypeMetadataForLayoutAccessible(SILModule &M, SILType type) {
  // Look through types that aren't necessarily legal formal types:

  //   - tuples
  if (auto tupleType = type.getAs<TupleType>()) {
    for (auto index : indices(tupleType.getElementTypes())) {
      if (!isTypeMetadataForLayoutAccessible(M, type.getTupleElementType(index)))
        return false;
    }
    return true;
  }

  //   - optionals
  if (auto objType = type.getOptionalObjectType()) {
    return isTypeMetadataForLayoutAccessible(M, objType);
  }

  //   - function types
  if (type.is<SILFunctionType>())
    return true;

  //   - metatypes
  if (type.is<AnyMetatypeType>())
    return true;

  // Otherwise, check that we can fetch the type metadata.
  return M.isTypeMetadataAccessible(type.getASTType());

}

/// Can we perform value operations on the given type?  We have no way
/// of doing value operations on resilient-layout types from other modules
/// that are ABI-private to their defining module.  But if the type is not
/// ABI-private, we can always at least fetch its metadata and use the
/// value witness table stored there.
bool SILModule::isTypeABIAccessible(SILType type) {
  // Fixed-ABI types can have value operations done without metadata.
  if (Types.getTypeLowering(type).isFixedABI())
    return true;

  assert(!type.is<ReferenceStorageType>() &&
         !type.is<SILFunctionType>() &&
         !type.is<AnyMetatypeType>() &&
         "unexpected SIL lowered-only type with non-fixed layout");

  // Otherwise, we need to be able to fetch layout-metadata for the type.
  return isTypeMetadataForLayoutAccessible(*this, type);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2000-2001, The University of Queensland
 * Copyright (C) 2001, Sun Microsystems, Inc
 * Copyright (C) 2002, Trent Waddington
 *
 * See the file "LICENSE.TERMS" for information on usage and
 * redistribution of this file, and for a DISCLAIMER OF ALL
 * WARRANTIES.
 *
 */

/*==============================================================================
 * FILE:       util.cc
 * OVERVIEW:   This file contains miscellaneous functions that don't belong to
 *             any particular subsystem of UQBT.
 *============================================================================*/

/*
 * $Revision$
 *
 * 05 Sep 00 - Mike: moved getCodeInfo here from translate2c.cc
 * 21 Sep 00 - Mike: getTempType handles tmph, tmpb now
 * 27 Sep 00 - Mike: getCodeInfo() was not setting parameter last correctly,
 *              and was not rejecting addresses outside the code section
 * 04 Dec 00 - Mike: Added #ifndef NOFRILLS for complex functions, so we can
 *              use simple things like str() and string::operator+ in
 *              PAL/parsepatterns without linking in BINARYFILE/?? etc
 * 11 Feb 01 - Nathan: Removed getCodeInfo and getTempType to prog.cc & type.cc
 * 22 Feb 01 - Nathan: Moved changeExt here from driver.cc
 * 25 Feb 01 - Nathan: Removed NOFRILLS (no longer applicable)
 * 16 Apr 01 - Brian: added hasExt() procedure.
 * 14 Aug 01 - Mike: Added upperStr() to replace Doug's use of transform();
 *              gcc v3 no longer allows the use of char* for an iterator
 * 10 Apr 02 - Mike: Mods for boomerang; put expSimplify here
 */

#include <assert.h>
#if defined(_MSC_VER) && _MSC_VER <= 1200
#pragma warning(disable:4786)
#endif

#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include "util.h"
#include <unistd.h>
#include <fcntl.h>

/*==============================================================================
 * FUNCTION:      string::operator+(string, int)
 * OVERVIEW:      Append an int to a string
 * PARAMETERS:    s: the string to append to
 *				  i: the integer whose ascii representation is to be appended
 * RETURNS:       A copy of the modified string
 *============================================================================*/
std::string operator+(const std::string& s, int i)
{
	static char buf[50];
	std::string ret(s);

	sprintf(buf,"%d",i);
	return ret.append(buf);
}

/*==============================================================================
 * FUNCTION:      initCapital
 * OVERVIEW:      Return a string the same as the input string, but with the
 *					first character capitalised
 * PARAMETERS:    s: the string to capitalise
 * RETURNS:       A copy of the modified string
 *============================================================================*/
std::string initCapital(const std::string& s)
{
	std::string res(s);
    res[0] = toupper(res[0]);
	return res;
}

/*==============================================================================
 * FUNCTION:      hasExt
 * OVERVIEW:      Returns true if the given file name has the given extension
 *                and false otherwise.
 * PARAMETERS:    s: string representing a file name (e.g. string("foo.c"))
 *                e: the extension (e.g. ".o")
 * RETURNS:       Boolean indicating whether the file name has the extension.
 *============================================================================*/
bool hasExt(const std::string& s, const char* ext)
{
    std::string tailStr = std::string(".") + std::string(ext);
    unsigned int i = s.rfind(tailStr);
    if (i == std::string::npos) {
        return false;
    } else {
        unsigned int sLen = s.length();
        unsigned int tailStrLen = tailStr.length();
        return ((i + tailStrLen) == sLen);
    }
}

/*==============================================================================
 * FUNCTION:      changeExt
 * OVERVIEW:      Change the extension of the given file name
 * PARAMETERS:    s: string representing the file name to be modified
 *                  (e.g. string("foo.c"))
 *                e: the new extension (e.g. ".o")
 * RETURNS:       The converted string (e.g. "foo.o")
 *============================================================================*/
std::string changeExt(const std::string& s, const char* ext)
{
    size_t i = s.rfind(".");
    if (i == std::string::npos) {
        return s + ext;
    }
    else {
        return s.substr(0, i) + ext;
    }
}

/*==============================================================================
 * FUNCTION:      searchAndReplace
 * OVERVIEW:      returns a copy of a string will all occurances of match
 *                replaced with rep. (simple version of s/match/rep/g)
 * PARAMETERS:    in: the source string
 *                match: the search string
 *                rep: the string to replace match with.
 * RETURNS:       The updated string.
 *============================================================================*/
std::string searchAndReplace( const std::string &in, const std::string &match,
                              const std::string &rep )
{
    std::string result;
    for( int n = 0; n != -1; ) {
        int l = in.find(match,n);
        result.append( in.substr(n,(l==-1?in.length() : l )-n) );
        if( l != -1 ) {
            result.append( rep );
            l+=match.length();
        }
        n = l;
    }
    return result;
}

/*==============================================================================
 * FUNCTION:      upperStr
 * OVERVIEW:      Uppercase a C string
 * PARAMETERS:    s: the string (char*) to start with
 *                d: the string (char*) to write to (can be the same string)
 * RETURNS:       Nothing; the string is modified as a side effect
 *============================================================================*/
void upperStr(const char* s, char* d)
{
    int len = strlen(s);
    for (int i=0; i < len; i++)
       d[i] = toupper(s[i]);
    d[len] = '\0';
}

int lockFileRead(const char *fname)
{
    struct flock fl;
    int fd;

    fl.l_type   = F_RDLCK;  /* F_RDLCK, F_WRLCK, F_UNLCK    */
    fl.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */
    fl.l_start  = 0;        /* Offset from l_whence         */
    fl.l_len    = 0;        /* length, 0 = to EOF           */
    fl.l_pid    = getpid(); /* our PID                      */

    fd = open("filename", O_RDONLY);  /* get the file descriptor */
    fcntl(fd, F_SETLKW, &fl);  /* set the lock, waiting if necessary */

    return fd;
}

int lockFileWrite(const char *fname)
{
    struct flock fl;
    int fd;

    fl.l_type   = F_WRLCK;  /* F_RDLCK, F_WRLCK, F_UNLCK    */
    fl.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */
    fl.l_start  = 0;        /* Offset from l_whence         */
    fl.l_len    = 0;        /* length, 0 = to EOF           */
    fl.l_pid    = getpid(); /* our PID                      */

    fd = open("filename", O_WRONLY);  /* get the file descriptor */
    fcntl(fd, F_SETLKW, &fl);  /* set the lock, waiting if necessary */

    return fd;
}

void unlockFile(int fd)
{
    struct flock fl;
    fl.l_type   = F_UNLCK;  /* tell it to unlock the region */
    fcntl(fd, F_SETLK, &fl); /* set the region to unlocked */
    close(fd);
}

void escapeXMLChars(std::string &s)
{
    std::string bad = "<>&";
    const char *replace[] = { "<", ">", "&" };
    for (int i = 0; i < s.size(); i++) {
        int n = bad.find(s[i]);
        if (n != std::string::npos) {
            s.replace(i, 1, replace[n]);
        }
    }
}

<commit_msg>Silenced two warnings<commit_after>/*
 * Copyright (C) 2000-2001, The University of Queensland
 * Copyright (C) 2001, Sun Microsystems, Inc
 * Copyright (C) 2002, Trent Waddington
 *
 * See the file "LICENSE.TERMS" for information on usage and
 * redistribution of this file, and for a DISCLAIMER OF ALL
 * WARRANTIES.
 *
 */

/*==============================================================================
 * FILE:       util.cc
 * OVERVIEW:   This file contains miscellaneous functions that don't belong to
 *             any particular subsystem of UQBT.
 *============================================================================*/

/*
 * $Revision$
 *
 * 05 Sep 00 - Mike: moved getCodeInfo here from translate2c.cc
 * 21 Sep 00 - Mike: getTempType handles tmph, tmpb now
 * 27 Sep 00 - Mike: getCodeInfo() was not setting parameter last correctly,
 *              and was not rejecting addresses outside the code section
 * 04 Dec 00 - Mike: Added #ifndef NOFRILLS for complex functions, so we can
 *              use simple things like str() and string::operator+ in
 *              PAL/parsepatterns without linking in BINARYFILE/?? etc
 * 11 Feb 01 - Nathan: Removed getCodeInfo and getTempType to prog.cc & type.cc
 * 22 Feb 01 - Nathan: Moved changeExt here from driver.cc
 * 25 Feb 01 - Nathan: Removed NOFRILLS (no longer applicable)
 * 16 Apr 01 - Brian: added hasExt() procedure.
 * 14 Aug 01 - Mike: Added upperStr() to replace Doug's use of transform();
 *              gcc v3 no longer allows the use of char* for an iterator
 * 10 Apr 02 - Mike: Mods for boomerang; put expSimplify here
 */

#include <assert.h>
#if defined(_MSC_VER) && _MSC_VER <= 1200
#pragma warning(disable:4786)
#endif

#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include "util.h"
#include <unistd.h>
#include <fcntl.h>

/*==============================================================================
 * FUNCTION:      string::operator+(string, int)
 * OVERVIEW:      Append an int to a string
 * PARAMETERS:    s: the string to append to
 *				  i: the integer whose ascii representation is to be appended
 * RETURNS:       A copy of the modified string
 *============================================================================*/
std::string operator+(const std::string& s, int i)
{
	static char buf[50];
	std::string ret(s);

	sprintf(buf,"%d",i);
	return ret.append(buf);
}

/*==============================================================================
 * FUNCTION:      initCapital
 * OVERVIEW:      Return a string the same as the input string, but with the
 *					first character capitalised
 * PARAMETERS:    s: the string to capitalise
 * RETURNS:       A copy of the modified string
 *============================================================================*/
std::string initCapital(const std::string& s)
{
	std::string res(s);
    res[0] = toupper(res[0]);
	return res;
}

/*==============================================================================
 * FUNCTION:      hasExt
 * OVERVIEW:      Returns true if the given file name has the given extension
 *                and false otherwise.
 * PARAMETERS:    s: string representing a file name (e.g. string("foo.c"))
 *                e: the extension (e.g. ".o")
 * RETURNS:       Boolean indicating whether the file name has the extension.
 *============================================================================*/
bool hasExt(const std::string& s, const char* ext)
{
    std::string tailStr = std::string(".") + std::string(ext);
    unsigned int i = s.rfind(tailStr);
    if (i == std::string::npos) {
        return false;
    } else {
        unsigned int sLen = s.length();
        unsigned int tailStrLen = tailStr.length();
        return ((i + tailStrLen) == sLen);
    }
}

/*==============================================================================
 * FUNCTION:      changeExt
 * OVERVIEW:      Change the extension of the given file name
 * PARAMETERS:    s: string representing the file name to be modified
 *                  (e.g. string("foo.c"))
 *                e: the new extension (e.g. ".o")
 * RETURNS:       The converted string (e.g. "foo.o")
 *============================================================================*/
std::string changeExt(const std::string& s, const char* ext)
{
    size_t i = s.rfind(".");
    if (i == std::string::npos) {
        return s + ext;
    }
    else {
        return s.substr(0, i) + ext;
    }
}

/*==============================================================================
 * FUNCTION:      searchAndReplace
 * OVERVIEW:      returns a copy of a string will all occurances of match
 *                replaced with rep. (simple version of s/match/rep/g)
 * PARAMETERS:    in: the source string
 *                match: the search string
 *                rep: the string to replace match with.
 * RETURNS:       The updated string.
 *============================================================================*/
std::string searchAndReplace( const std::string &in, const std::string &match,
                              const std::string &rep )
{
    std::string result;
    for( int n = 0; n != -1; ) {
        int l = in.find(match,n);
        result.append( in.substr(n,(l==-1?in.length() : l )-n) );
        if( l != -1 ) {
            result.append( rep );
            l+=match.length();
        }
        n = l;
    }
    return result;
}

/*==============================================================================
 * FUNCTION:      upperStr
 * OVERVIEW:      Uppercase a C string
 * PARAMETERS:    s: the string (char*) to start with
 *                d: the string (char*) to write to (can be the same string)
 * RETURNS:       Nothing; the string is modified as a side effect
 *============================================================================*/
void upperStr(const char* s, char* d)
{
    int len = strlen(s);
    for (int i=0; i < len; i++)
       d[i] = toupper(s[i]);
    d[len] = '\0';
}

int lockFileRead(const char *fname)
{
    struct flock fl;
    int fd;

    fl.l_type   = F_RDLCK;  /* F_RDLCK, F_WRLCK, F_UNLCK    */
    fl.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */
    fl.l_start  = 0;        /* Offset from l_whence         */
    fl.l_len    = 0;        /* length, 0 = to EOF           */
    fl.l_pid    = getpid(); /* our PID                      */

    fd = open("filename", O_RDONLY);  /* get the file descriptor */
    fcntl(fd, F_SETLKW, &fl);  /* set the lock, waiting if necessary */

    return fd;
}

int lockFileWrite(const char *fname)
{
    struct flock fl;
    int fd;

    fl.l_type   = F_WRLCK;  /* F_RDLCK, F_WRLCK, F_UNLCK    */
    fl.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */
    fl.l_start  = 0;        /* Offset from l_whence         */
    fl.l_len    = 0;        /* length, 0 = to EOF           */
    fl.l_pid    = getpid(); /* our PID                      */

    fd = open("filename", O_WRONLY);  /* get the file descriptor */
    fcntl(fd, F_SETLKW, &fl);  /* set the lock, waiting if necessary */

    return fd;
}

void unlockFile(int fd)
{
    struct flock fl;
    fl.l_type   = F_UNLCK;  /* tell it to unlock the region */
    fcntl(fd, F_SETLK, &fl); /* set the region to unlocked */
    close(fd);
}

void escapeXMLChars(std::string &s)
{
    std::string bad = "<>&";
    const char *replace[] = { "<", ">", "&" };
    for (unsigned i = 0; i < s.size(); i++) {
        unsigned n = bad.find(s[i]);
        if (n != std::string::npos) {
            s.replace(i, 1, replace[n]);
        }
    }
}

<|endoftext|>


<commit_before>#include <miopen.h>
#include "test.hpp"
#include <array>
#include <iterator>
#include <memory>
#include <utility>
#include <iostream>
#include <miopen/tensor.hpp>
#include <miopen/convolution.hpp>
#include <limits>

// #include "network_data.hpp"
#include "tensor_holder.hpp"
#include "verify.hpp"
#include "driver.hpp"
#include "get_handle.hpp"

template<class T>
tensor<T> get_output_tensor(const miopen::ConvolutionDescriptor& filter, const tensor<T>& input, const tensor<T>& weights)
{
    assert(filter.GetBackwardOutputTensor(filter.GetForwardOutputTensor(input.desc, weights.desc), weights.desc) == input.desc);
    return tensor<T>{filter.GetForwardOutputTensor(input.desc, weights.desc)};
}

template<class T>
struct conv_base
{
    tensor<T> input;
    tensor<T> weights;
    tensor<T> out;
    miopen::ConvolutionDescriptor filter;
    int bias;

    void fail(float=0)
    {
        std::cout << "Input tensor: " << input.desc.ToString() << std::endl;
        std::cout << "Weights tensor: " << weights.desc.ToString() << std::endl;
        std::cout << "Output tensor: " << out.desc.ToString() << std::endl;
        std::cout << "Filter: " << filter << std::endl;
    }
};

template<class T>
struct verify_forward_conv : conv_base<T>
{
    using conv_base<T>::input;
    using conv_base<T>::weights;
    using conv_base<T>::out;
    using conv_base<T>::filter;
    using conv_base<T>::bias;

    verify_forward_conv(const tensor<T>& pinput, const tensor<T>& pweights, const miopen::ConvolutionDescriptor& pfilter, int pbias = 0)
    {
        input = pinput;
        weights = pweights;
        filter = pfilter;
        bias = pbias;
    }

    tensor<T> cpu()
    {
        out = get_output_tensor(filter, input, weights);

        int in_h, in_w;
        std::tie(std::ignore, std::ignore, in_h, in_w) = miopen::tie4(input.desc.GetLengths());

        int wei_c, wei_h, wei_w;
        std::tie(std::ignore, wei_c, wei_h, wei_w) = miopen::tie4(weights.desc.GetLengths());

        out.par_for_each([&](int o, int w, int i, int j)
        {
            const int start_x = i * filter.v - filter.pad_h;
            const int start_y = j * filter.u - filter.pad_w;

            double acc = bias;
            ford(wei_c, wei_h, wei_w)([&](int k, int x, int y)
            {
                const int in_x = start_x + x;
                const int in_y = start_y + y;
                if(in_x >= 0 && in_x < in_h && in_y >= 0 && in_y < in_w) {
                    acc += input(o, k, in_x, in_y) * weights(w, k, x, y);
                }
            });
            out(o, w, i, j) = acc;
        });
        return out;
    }

    tensor<T> gpu()
    {
        auto&& handle = get_handle();
        out = get_output_tensor(filter, input, weights);

        auto in_dev = handle.Write(input.data);
        auto wei_dev = handle.Write(weights.data);
        auto out_dev = handle.Write(out.data);

		size_t workspace_size = filter.ForwardGetWorkSpaceSize(weights.desc, input.desc, out.desc);

		std::vector<char> workspace(workspace_size);
		auto workspace_dev = workspace_size != 0 ? handle.Write(workspace) : nullptr;

        int ret_algo_count;
        miopenConvAlgoPerf_t perf;

        int alpha = 1, beta = 1;

        filter.FindConvFwdAlgorithm(handle,
            input.desc,
            in_dev.get(),
            weights.desc,
            wei_dev.get(),
            out.desc,
            out_dev.get(),
            1,
            &ret_algo_count,
            &perf,
            workspace_dev.get(),
            workspace_size,
            0); // MD: Not performing exhaustiveSearch by default for now

        filter.ConvolutionForward(handle,
            &alpha,
            input.desc,
            in_dev.get(),
            weights.desc,
            wei_dev.get(),
            perf.fwd_algo,
            &beta,
            out.desc,
            out_dev.get(),
            workspace_dev.get(),
            workspace_size);

        out.data = handle.Read<T>(out_dev, out.data.size());
        return out;
    }

    void fail(float=0)
    {
        std::cout << "Forward convolution: " << std::endl;
        this->conv_base<T>::fail();
    }

};

template<class T>
struct verify_backward_conv : conv_base<T>
{
    using conv_base<T>::input;
    using conv_base<T>::weights;
    using conv_base<T>::out;
    using conv_base<T>::filter;
    using conv_base<T>::bias;

    verify_backward_conv(const tensor<T>& pinput, const tensor<T>& pweights, const tensor<T>& pout, const miopen::ConvolutionDescriptor& pfilter, int pbias = 0)
    {
        input = pinput;
        weights = pweights;
        out = pout;
        filter = pfilter;
        bias = pbias;
    }

    tensor<T> cpu()
    {
        std::fill(input.begin(), input.end(), 0);

        int in_h, in_w;
        std::tie(std::ignore, std::ignore, in_h, in_w) = miopen::tie4(input.desc.GetLengths());

        int wei_c, wei_h, wei_w;
        std::tie(std::ignore, wei_c, wei_h, wei_w) = miopen::tie4(weights.desc.GetLengths());

        int out_n, out_c, out_h, out_w;
        std::tie(out_n, out_c, out_h, out_w) = miopen::tie4(out.desc.GetLengths());

        par_ford(out_n, wei_c)([&](int o, int k)
        {
            ford(out_c, out_h, out_w, wei_h, wei_w)([&](int w, int i, int j, int x, int y)
            {
                const int start_x = i * filter.v - filter.pad_h;
                const int start_y = j * filter.u - filter.pad_w;
                const int in_x = start_x + x;
                const int in_y = start_y + y;
                if(in_x >= 0 && in_x < in_h && in_y >= 0 && in_y < in_w) {
                    input(o, k, in_x, in_y) += out(o, w, i, j) * weights(w, k, x, y);
                }
            });
        });
        return input;
    }

    tensor<T> gpu()
    {
        auto&& handle = get_handle();
        std::fill(input.begin(), input.end(), 0);

        auto out_dev = handle.Write(out.data);
        auto wei_dev = handle.Write(weights.data);
        auto in_dev = handle.Write(input.data);

        int ret_algo_count;
        miopenConvAlgoPerf_t perf;

        int alpha = 1, beta = 1;

        filter.FindConvBwdDataAlgorithm(handle,
            out.desc,
            out_dev.get(),
            weights.desc,
            wei_dev.get(),
            input.desc,
            in_dev.get(),
            1,
            &ret_algo_count,
            &perf,
            nullptr,
            10,
            0); // MD: Not performing exhaustiveSearch by default for now

        filter.ConvolutionBackwardData(handle,
            &alpha,
            out.desc,
            out_dev.get(),
            weights.desc,
            wei_dev.get(),
            perf.bwd_data_algo,
            &beta,
            input.desc,
            in_dev.get(),
            nullptr,
            0);

        input.data = handle.Read<T>(in_dev, input.data.size());
        return input;
    }

    void fail(float)
    {
        std::cout << "Backward convolution: " << std::endl;
        this->conv_base<T>::fail();
    }

};

template<class T>
struct verify_backward_weights_conv : conv_base<T>
{
    using conv_base<T>::input;
    using conv_base<T>::weights;
    using conv_base<T>::out;
    using conv_base<T>::filter;
    using conv_base<T>::bias;

    verify_backward_weights_conv(const tensor<T>& pinput, const tensor<T>& pweights, const tensor<T>& pout, const miopen::ConvolutionDescriptor& pfilter, int pbias = 0)
    {
        input = pinput;
        weights = pweights;
        out = pout;
        filter = pfilter;
        bias = pbias;
    }

    tensor<T> cpu()
    {
        std::fill(weights.begin(), weights.end(), 0);

        int in_h, in_w;
        std::tie(std::ignore, std::ignore, in_h, in_w) = miopen::tie4(input.desc.GetLengths());

        int wei_c, wei_h, wei_w;
        std::tie(std::ignore, wei_c, wei_h, wei_w) = miopen::tie4(weights.desc.GetLengths());

        int out_n, out_c, out_h, out_w;
        std::tie(out_n, out_c, out_h, out_w) = miopen::tie4(out.desc.GetLengths());

        par_ford(out_c, wei_c, wei_h, wei_w)([&](int w, int k, int x, int y)
        {
            double acc = 0.0;
            ford(out_n, out_h, out_w)([&](int o, int i, int j)
            {
                const int start_x = i * filter.v - filter.pad_h;
                const int start_y = j * filter.u - filter.pad_w;
                const int in_x = start_x + x;
                const int in_y = start_y + y;
                if(in_x >= 0 && in_x < in_h && in_y >= 0 && in_y < in_w) {
                    acc += input(o, k, in_x, in_y) * out(o, w, i, j);
                }
            });
            weights(w, k, x, y) = acc;
        });
        return weights;
    }

    tensor<T> gpu()
    {
        auto&& handle = get_handle();
        std::fill(weights.begin(), weights.end(), 0);

        auto out_dev = handle.Write(out.data);
        auto wei_dev = handle.Write(weights.data);
        auto in_dev = handle.Write(input.data);

        std::size_t workspace_size = filter.ConvolutionBackwardWeightsGetWorkSpaceSize(out.desc, input.desc, weights.desc);

        std::vector<char> workspace(workspace_size);
        auto workspace_dev = handle.Write(workspace);

        int ret_algo_count;
        miopenConvAlgoPerf_t perf;

        int alpha = 1, beta = 1;
        filter.FindConvBwdWeightsAlgorithm(handle,
            out.desc,
            out_dev.get(),
            input.desc,
            in_dev.get(),
            weights.desc,
            wei_dev.get(),
            1,
            &ret_algo_count,
            &perf,
            workspace_dev.get(),
            workspace_size,
            0); // MD: Not performing exhaustiveSearch by default for now

        filter.ConvolutionBackwardWeights(handle,
            &alpha,
            out.desc,
            out_dev.get(),
            input.desc,
            in_dev.get(),
            perf.bwd_weights_algo,
            &beta,
            weights.desc,
            wei_dev.get(),
            workspace_dev.get(),
            workspace_size);

        weights.data = handle.Read<T>(wei_dev, weights.data.size());
        return weights;
    }

    void fail(float)
    {
        std::cout << "Backward weights convolution: " << std::endl;
        this->conv_base<T>::fail();
    }

};

template<class T>
struct conv_driver : test_driver
{
    tensor<T> input;
    tensor<T> weights;
    miopen::ConvolutionDescriptor filter;
    bool enable_backward_weights = false;

    conv_driver()
    {
        add(input, "input", get_input_tensor());
        add(weights, "weights", get_weights_tensor());
        add(filter, "filter", generate_data(get_filters()));
        add(enable_backward_weights, "enable-backward-weights", flag());
    }

    std::vector<miopen::ConvolutionDescriptor> get_filters()
    {
        return {
            miopen::ConvolutionDescriptor{ 0, 0, 1, 1 },
            // miopen::ConvolutionDescriptor{ 0, 0, 2, 2 },
            // miopen::ConvolutionDescriptor{ 1, 1, 1, 1 },
            // This configuration only works on opencl
            // miopen::ConvolutionDescriptor{ 1, 1, 2, 2 },
            miopen::ConvolutionDescriptor{ 2, 2, 1, 1 },
            // This configuration only works on opencl
            // miopen::ConvolutionDescriptor{ 3, 3, 2, 2 }
        };
    }

    void run()
    {
        int wei_h, wei_w;
        std::tie(std::ignore, std::ignore, wei_h, wei_w) = miopen::tie4(weights.desc.GetLengths());
        if (input.desc.GetLengths().at(1) == weights.desc.GetLengths().at(1) &&
            wei_h > 2*filter.pad_h &&
            wei_w > 2*filter.pad_w
        )
        {
            auto out_p = verify(verify_forward_conv<T>{input, weights, filter});
            for(auto& x:out_p.first) x = (long(x+1)*2) % 17; // Clamp big numbers
            verify(verify_backward_conv<T>{input, weights, out_p.first, filter});
            if(enable_backward_weights or MIOPEN_USE_TINYGEMM)
            {
                verify(verify_backward_weights_conv<T>{input, weights, out_p.first, filter});
            }
        }
    }
};

int main(int argc, const char *argv[])
{
    test_drive<conv_driver<float>>(argc, argv);
}
<commit_msg>Renable configs that work on opencl<commit_after>#include <miopen.h>
#include "test.hpp"
#include <array>
#include <iterator>
#include <memory>
#include <utility>
#include <iostream>
#include <miopen/tensor.hpp>
#include <miopen/convolution.hpp>
#include <limits>

// #include "network_data.hpp"
#include "tensor_holder.hpp"
#include "verify.hpp"
#include "driver.hpp"
#include "get_handle.hpp"

template<class T>
tensor<T> get_output_tensor(const miopen::ConvolutionDescriptor& filter, const tensor<T>& input, const tensor<T>& weights)
{
    assert(filter.GetBackwardOutputTensor(filter.GetForwardOutputTensor(input.desc, weights.desc), weights.desc) == input.desc);
    return tensor<T>{filter.GetForwardOutputTensor(input.desc, weights.desc)};
}

template<class T>
struct conv_base
{
    tensor<T> input;
    tensor<T> weights;
    tensor<T> out;
    miopen::ConvolutionDescriptor filter;
    int bias;

    void fail(float=0)
    {
        std::cout << "Input tensor: " << input.desc.ToString() << std::endl;
        std::cout << "Weights tensor: " << weights.desc.ToString() << std::endl;
        std::cout << "Output tensor: " << out.desc.ToString() << std::endl;
        std::cout << "Filter: " << filter << std::endl;
    }
};

template<class T>
struct verify_forward_conv : conv_base<T>
{
    using conv_base<T>::input;
    using conv_base<T>::weights;
    using conv_base<T>::out;
    using conv_base<T>::filter;
    using conv_base<T>::bias;

    verify_forward_conv(const tensor<T>& pinput, const tensor<T>& pweights, const miopen::ConvolutionDescriptor& pfilter, int pbias = 0)
    {
        input = pinput;
        weights = pweights;
        filter = pfilter;
        bias = pbias;
    }

    tensor<T> cpu()
    {
        out = get_output_tensor(filter, input, weights);

        int in_h, in_w;
        std::tie(std::ignore, std::ignore, in_h, in_w) = miopen::tie4(input.desc.GetLengths());

        int wei_c, wei_h, wei_w;
        std::tie(std::ignore, wei_c, wei_h, wei_w) = miopen::tie4(weights.desc.GetLengths());

        out.par_for_each([&](int o, int w, int i, int j)
        {
            const int start_x = i * filter.v - filter.pad_h;
            const int start_y = j * filter.u - filter.pad_w;

            double acc = bias;
            ford(wei_c, wei_h, wei_w)([&](int k, int x, int y)
            {
                const int in_x = start_x + x;
                const int in_y = start_y + y;
                if(in_x >= 0 && in_x < in_h && in_y >= 0 && in_y < in_w) {
                    acc += input(o, k, in_x, in_y) * weights(w, k, x, y);
                }
            });
            out(o, w, i, j) = acc;
        });
        return out;
    }

    tensor<T> gpu()
    {
        auto&& handle = get_handle();
        out = get_output_tensor(filter, input, weights);

        auto in_dev = handle.Write(input.data);
        auto wei_dev = handle.Write(weights.data);
        auto out_dev = handle.Write(out.data);

		size_t workspace_size = filter.ForwardGetWorkSpaceSize(weights.desc, input.desc, out.desc);

		std::vector<char> workspace(workspace_size);
		auto workspace_dev = workspace_size != 0 ? handle.Write(workspace) : nullptr;

        int ret_algo_count;
        miopenConvAlgoPerf_t perf;

        int alpha = 1, beta = 1;

        filter.FindConvFwdAlgorithm(handle,
            input.desc,
            in_dev.get(),
            weights.desc,
            wei_dev.get(),
            out.desc,
            out_dev.get(),
            1,
            &ret_algo_count,
            &perf,
            workspace_dev.get(),
            workspace_size,
            0); // MD: Not performing exhaustiveSearch by default for now

        filter.ConvolutionForward(handle,
            &alpha,
            input.desc,
            in_dev.get(),
            weights.desc,
            wei_dev.get(),
            perf.fwd_algo,
            &beta,
            out.desc,
            out_dev.get(),
            workspace_dev.get(),
            workspace_size);

        out.data = handle.Read<T>(out_dev, out.data.size());
        return out;
    }

    void fail(float=0)
    {
        std::cout << "Forward convolution: " << std::endl;
        this->conv_base<T>::fail();
    }

};

template<class T>
struct verify_backward_conv : conv_base<T>
{
    using conv_base<T>::input;
    using conv_base<T>::weights;
    using conv_base<T>::out;
    using conv_base<T>::filter;
    using conv_base<T>::bias;

    verify_backward_conv(const tensor<T>& pinput, const tensor<T>& pweights, const tensor<T>& pout, const miopen::ConvolutionDescriptor& pfilter, int pbias = 0)
    {
        input = pinput;
        weights = pweights;
        out = pout;
        filter = pfilter;
        bias = pbias;
    }

    tensor<T> cpu()
    {
        std::fill(input.begin(), input.end(), 0);

        int in_h, in_w;
        std::tie(std::ignore, std::ignore, in_h, in_w) = miopen::tie4(input.desc.GetLengths());

        int wei_c, wei_h, wei_w;
        std::tie(std::ignore, wei_c, wei_h, wei_w) = miopen::tie4(weights.desc.GetLengths());

        int out_n, out_c, out_h, out_w;
        std::tie(out_n, out_c, out_h, out_w) = miopen::tie4(out.desc.GetLengths());

        par_ford(out_n, wei_c)([&](int o, int k)
        {
            ford(out_c, out_h, out_w, wei_h, wei_w)([&](int w, int i, int j, int x, int y)
            {
                const int start_x = i * filter.v - filter.pad_h;
                const int start_y = j * filter.u - filter.pad_w;
                const int in_x = start_x + x;
                const int in_y = start_y + y;
                if(in_x >= 0 && in_x < in_h && in_y >= 0 && in_y < in_w) {
                    input(o, k, in_x, in_y) += out(o, w, i, j) * weights(w, k, x, y);
                }
            });
        });
        return input;
    }

    tensor<T> gpu()
    {
        auto&& handle = get_handle();
        std::fill(input.begin(), input.end(), 0);

        auto out_dev = handle.Write(out.data);
        auto wei_dev = handle.Write(weights.data);
        auto in_dev = handle.Write(input.data);

        int ret_algo_count;
        miopenConvAlgoPerf_t perf;

        int alpha = 1, beta = 1;

        filter.FindConvBwdDataAlgorithm(handle,
            out.desc,
            out_dev.get(),
            weights.desc,
            wei_dev.get(),
            input.desc,
            in_dev.get(),
            1,
            &ret_algo_count,
            &perf,
            nullptr,
            10,
            0); // MD: Not performing exhaustiveSearch by default for now

        filter.ConvolutionBackwardData(handle,
            &alpha,
            out.desc,
            out_dev.get(),
            weights.desc,
            wei_dev.get(),
            perf.bwd_data_algo,
            &beta,
            input.desc,
            in_dev.get(),
            nullptr,
            0);

        input.data = handle.Read<T>(in_dev, input.data.size());
        return input;
    }

    void fail(float)
    {
        std::cout << "Backward convolution: " << std::endl;
        this->conv_base<T>::fail();
    }

};

template<class T>
struct verify_backward_weights_conv : conv_base<T>
{
    using conv_base<T>::input;
    using conv_base<T>::weights;
    using conv_base<T>::out;
    using conv_base<T>::filter;
    using conv_base<T>::bias;

    verify_backward_weights_conv(const tensor<T>& pinput, const tensor<T>& pweights, const tensor<T>& pout, const miopen::ConvolutionDescriptor& pfilter, int pbias = 0)
    {
        input = pinput;
        weights = pweights;
        out = pout;
        filter = pfilter;
        bias = pbias;
    }

    tensor<T> cpu()
    {
        std::fill(weights.begin(), weights.end(), 0);

        int in_h, in_w;
        std::tie(std::ignore, std::ignore, in_h, in_w) = miopen::tie4(input.desc.GetLengths());

        int wei_c, wei_h, wei_w;
        std::tie(std::ignore, wei_c, wei_h, wei_w) = miopen::tie4(weights.desc.GetLengths());

        int out_n, out_c, out_h, out_w;
        std::tie(out_n, out_c, out_h, out_w) = miopen::tie4(out.desc.GetLengths());

        par_ford(out_c, wei_c, wei_h, wei_w)([&](int w, int k, int x, int y)
        {
            double acc = 0.0;
            ford(out_n, out_h, out_w)([&](int o, int i, int j)
            {
                const int start_x = i * filter.v - filter.pad_h;
                const int start_y = j * filter.u - filter.pad_w;
                const int in_x = start_x + x;
                const int in_y = start_y + y;
                if(in_x >= 0 && in_x < in_h && in_y >= 0 && in_y < in_w) {
                    acc += input(o, k, in_x, in_y) * out(o, w, i, j);
                }
            });
            weights(w, k, x, y) = acc;
        });
        return weights;
    }

    tensor<T> gpu()
    {
        auto&& handle = get_handle();
        std::fill(weights.begin(), weights.end(), 0);

        auto out_dev = handle.Write(out.data);
        auto wei_dev = handle.Write(weights.data);
        auto in_dev = handle.Write(input.data);

        std::size_t workspace_size = filter.ConvolutionBackwardWeightsGetWorkSpaceSize(out.desc, input.desc, weights.desc);

        std::vector<char> workspace(workspace_size);
        auto workspace_dev = handle.Write(workspace);

        int ret_algo_count;
        miopenConvAlgoPerf_t perf;

        int alpha = 1, beta = 1;
        filter.FindConvBwdWeightsAlgorithm(handle,
            out.desc,
            out_dev.get(),
            input.desc,
            in_dev.get(),
            weights.desc,
            wei_dev.get(),
            1,
            &ret_algo_count,
            &perf,
            workspace_dev.get(),
            workspace_size,
            0); // MD: Not performing exhaustiveSearch by default for now

        filter.ConvolutionBackwardWeights(handle,
            &alpha,
            out.desc,
            out_dev.get(),
            input.desc,
            in_dev.get(),
            perf.bwd_weights_algo,
            &beta,
            weights.desc,
            wei_dev.get(),
            workspace_dev.get(),
            workspace_size);

        weights.data = handle.Read<T>(wei_dev, weights.data.size());
        return weights;
    }

    void fail(float)
    {
        std::cout << "Backward weights convolution: " << std::endl;
        this->conv_base<T>::fail();
    }

};

template<class T>
struct conv_driver : test_driver
{
    tensor<T> input;
    tensor<T> weights;
    miopen::ConvolutionDescriptor filter;
    bool enable_backward_weights = false;

    conv_driver()
    {
        add(input, "input", get_input_tensor());
        add(weights, "weights", get_weights_tensor());
        add(filter, "filter", generate_data(get_filters()));
        add(enable_backward_weights, "enable-backward-weights", flag());
    }

    std::vector<miopen::ConvolutionDescriptor> get_filters()
    {
        return {
            miopen::ConvolutionDescriptor{ 0, 0, 1, 1 },
            // miopen::ConvolutionDescriptor{ 0, 0, 2, 2 },
            // miopen::ConvolutionDescriptor{ 1, 1, 1, 1 },
            miopen::ConvolutionDescriptor{ 1, 1, 2, 2 },
            miopen::ConvolutionDescriptor{ 2, 2, 1, 1 },
            miopen::ConvolutionDescriptor{ 3, 3, 2, 2 }
        };
    }

    void run()
    {
        int wei_h, wei_w;
        std::tie(std::ignore, std::ignore, wei_h, wei_w) = miopen::tie4(weights.desc.GetLengths());
        if (input.desc.GetLengths().at(1) == weights.desc.GetLengths().at(1) &&
            wei_h > 2*filter.pad_h &&
            wei_w > 2*filter.pad_w
        )
        {
            auto out_p = verify(verify_forward_conv<T>{input, weights, filter});
            for(auto& x:out_p.first) x = (long(x+1)*2) % 17; // Clamp big numbers
            verify(verify_backward_conv<T>{input, weights, out_p.first, filter});
            if(enable_backward_weights or MIOPEN_USE_TINYGEMM)
            {
                verify(verify_backward_weights_conv<T>{input, weights, out_p.first, filter});
            }
        }
    }
};

int main(int argc, const char *argv[])
{
    test_drive<conv_driver<float>>(argc, argv);
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program 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
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include "hash.hpp"

#include <boost/test/unit_test.hpp>
#include <bitcoin/bitcoin.hpp>

using namespace bc;

BOOST_AUTO_TEST_SUITE(hash_tests)

BOOST_AUTO_TEST_CASE(sha1_hash_test)
{
    for (const hash_result& result: sha1_tests)
    {
        data_chunk data;
        BOOST_REQUIRE(decode_base16(data, result.input));
        BOOST_REQUIRE_EQUAL(encode_hex(sha1_hash(data)), result.result);
    }
}

BOOST_AUTO_TEST_CASE(ripemd_hash_test)
{
    for (const hash_result& result: ripemd_tests)
    {
        data_chunk data;
        BOOST_REQUIRE(decode_base16(data, result.input));
        BOOST_REQUIRE_EQUAL(encode_base16(ripemd160_hash(data)),
            result.result);
    }
    auto ripemd_hash = bitcoin_short_hash(to_byte(110));
    BOOST_REQUIRE_EQUAL(encode_base16(ripemd_hash),
        "17d040b739d639c729daaf627eaff88cfe4207f4");
    auto foo = bitcoin_short_hash(base16_literal(
        "020641fde3a85beb8321033516de7ec01c35de96e945bf76c3768784a905471986"));
    BOOST_REQUIRE_EQUAL(encode_base16(foo),
        "c23e37c6fad06deab545f952992c8f28cb02bbe5");
}

BOOST_AUTO_TEST_CASE(sha256_hash_test)
{
    for (const hash_result& result: sha256_tests)
    {
        data_chunk data;
        BOOST_REQUIRE(decode_base16(data, result.input));
        BOOST_REQUIRE_EQUAL(encode_base16(sha256_hash(data)), result.result);
    }

    // This changes based on ENABLE_TESTNET, so the test condition must vary.
    auto genesis = genesis_block();
    auto genesis_hash = hash_block_header(genesis.header);

#ifdef ENABLE_TESTNET
    BOOST_REQUIRE_EQUAL(encode_hash(genesis_hash),
        "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943");
#else
    BOOST_REQUIRE_EQUAL(encode_hash(genesis_hash),
        "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
#endif
}

BOOST_AUTO_TEST_CASE(hmac_sha256_hash_test)
{
    data_chunk chunk{'d', 'a', 't', 'a'};
    data_chunk key{'k', 'e', 'y'};

    auto hash = hmac_sha256_hash(chunk, key);
    BOOST_REQUIRE_EQUAL(encode_base16(hash),
        "5031fe3d989c6d1537a013fa6e739da23463fdaec3b70137d828e36ace221bd0");
}

BOOST_AUTO_TEST_CASE(hmac_sha512_hash_test)
{
    data_chunk chunk{'d', 'a', 't', 'a'};
    data_chunk key{'k', 'e', 'y'};

    auto long_hash = hmac_sha512_hash(chunk, key);
    BOOST_REQUIRE_EQUAL(encode_base16(long_hash),
        "3c5953a18f7303ec653ba170ae334fafa08e3846f2efe317b87efce82376253c"
        "b52a8c31ddcde5a3a2eee183c2b34cb91f85e64ddbc325f7692b199473579c58");
}

BOOST_AUTO_TEST_CASE(sha512_hash_test)
{
    data_chunk chunk{'d', 'a', 't', 'a'};

    auto long_hash = sha512_hash(chunk);
    BOOST_REQUIRE_EQUAL(encode_base16(long_hash),
        "77c7ce9a5d86bb386d443bb96390faa120633158699c8844c30b13ab0bf92760"
        "b7e4416aea397db91b4ac0e5dd56b8ef7e4b066162ab1fdc088319ce6defc876");
}

BOOST_AUTO_TEST_CASE(pkcs5_pbkdf2_hmac_sha512_test)
{
    for (const pkcs5_pbkdf2_hmac_sha512_result& result:
             pkcs5_pbkdf2_hmac_sha512_tests)
    {
        auto hash = pkcs5_pbkdf2_hmac_sha512(
            to_data_chunk(result.passphrase), to_data_chunk(result.salt),
            result.iterations);
        BOOST_REQUIRE_EQUAL(encode_base16(hash), result.result);
    }
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Use const.<commit_after>/*
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program 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
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include "hash.hpp"

#include <boost/test/unit_test.hpp>
#include <bitcoin/bitcoin.hpp>

using namespace bc;

BOOST_AUTO_TEST_SUITE(hash_tests)

BOOST_AUTO_TEST_CASE(sha1_hash_test)
{
    for (const hash_result& result: sha1_tests)
    {
        data_chunk data;
        BOOST_REQUIRE(decode_base16(data, result.input));
        BOOST_REQUIRE_EQUAL(encode_hex(sha1_hash(data)), result.result);
    }
}

BOOST_AUTO_TEST_CASE(ripemd_hash_test)
{
    for (const hash_result& result: ripemd_tests)
    {
        data_chunk data;
        BOOST_REQUIRE(decode_base16(data, result.input));
        BOOST_REQUIRE_EQUAL(encode_base16(ripemd160_hash(data)),
            result.result);
    }

    auto ripemd_hash = bitcoin_short_hash(to_byte(110));
    BOOST_REQUIRE_EQUAL(encode_base16(ripemd_hash),
        "17d040b739d639c729daaf627eaff88cfe4207f4");

    ripemd_hash = bitcoin_short_hash(base16_literal(
        "020641fde3a85beb8321033516de7ec01c35de96e945bf76c3768784a905471986"));
    BOOST_REQUIRE_EQUAL(encode_base16(ripemd_hash),
        "c23e37c6fad06deab545f952992c8f28cb02bbe5");
}

BOOST_AUTO_TEST_CASE(sha256_hash_test)
{
    for (const hash_result& result: sha256_tests)
    {
        data_chunk data;
        BOOST_REQUIRE(decode_base16(data, result.input));
        BOOST_REQUIRE_EQUAL(encode_base16(sha256_hash(data)), result.result);
    }

    // This changes based on ENABLE_TESTNET, so the test condition must vary.
    const auto genesis = genesis_block();
    const auto genesis_hash = hash_block_header(genesis.header);

#ifdef ENABLE_TESTNET
    BOOST_REQUIRE_EQUAL(encode_hash(genesis_hash),
        "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943");
#else
    BOOST_REQUIRE_EQUAL(encode_hash(genesis_hash),
        "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
#endif
}

BOOST_AUTO_TEST_CASE(hmac_sha256_hash_test)
{
    const data_chunk chunk{ 'd', 'a', 't', 'a' };
    const data_chunk key{ 'k', 'e', 'y' };

    const auto hash = hmac_sha256_hash(chunk, key);
    BOOST_REQUIRE_EQUAL(encode_base16(hash),
        "5031fe3d989c6d1537a013fa6e739da23463fdaec3b70137d828e36ace221bd0");
}

BOOST_AUTO_TEST_CASE(hmac_sha512_hash_test)
{
    const data_chunk chunk{ 'd', 'a', 't', 'a' };
    const data_chunk key{ 'k', 'e', 'y' };

    const auto long_hash = hmac_sha512_hash(chunk, key);
    BOOST_REQUIRE_EQUAL(encode_base16(long_hash),
        "3c5953a18f7303ec653ba170ae334fafa08e3846f2efe317b87efce82376253c"
        "b52a8c31ddcde5a3a2eee183c2b34cb91f85e64ddbc325f7692b199473579c58");
}

BOOST_AUTO_TEST_CASE(sha512_hash_test)
{
    const data_chunk chunk{ 'd', 'a', 't', 'a' };

    const auto long_hash = sha512_hash(chunk);
    BOOST_REQUIRE_EQUAL(encode_base16(long_hash),
        "77c7ce9a5d86bb386d443bb96390faa120633158699c8844c30b13ab0bf92760"
        "b7e4416aea397db91b4ac0e5dd56b8ef7e4b066162ab1fdc088319ce6defc876");
}

BOOST_AUTO_TEST_CASE(pkcs5_pbkdf2_hmac_sha512_test)
{
    for (const pkcs5_pbkdf2_hmac_sha512_result& result:
            pkcs5_pbkdf2_hmac_sha512_tests)
    {
        const auto hash = pkcs5_pbkdf2_hmac_sha512(
            to_data_chunk(result.passphrase), to_data_chunk(result.salt),
            result.iterations);
        BOOST_REQUIRE_EQUAL(encode_base16(hash), result.result);
    }
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2003 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef _WIN32
#pragma warning( 4: 4786)
#endif

#include <stdio.h>
#include <iostream>
#include <map>
#include <string>

#include "BZAdminClient.h"
#include "BZAdminUI.h"
#include "OptionParser.h"
#include "ServerLink.h"
#include "UIMap.h"

// causes persistent rebuilding to obtain build versioning
#include "version.h"

/** @file
    This is the main file for bzadmin, the bzflag text client.
*/

int main(int argc, char** argv) {

#ifdef _WIN32
  // startup winsock
  {
    static const int major = 2, minor = 2;
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(major, minor), &wsaData)) {
      return 1;
    }
    if (LOBYTE(wsaData.wVersion) != major ||
	HIBYTE(wsaData.wVersion) != minor) {
      WSACleanup();
      return 1;
    }
  }
#endif
  // command line options
  std::string uiName("curses");

  // no curses, use stdboth as default instead
  const UIMap& interfaces = UIMap::getInstance();
  if (interfaces.find("curses") == interfaces.end())
    uiName = "stdboth";

  // build a usage string with all interfaces
  UIMap::const_iterator uiIter;
  std::string uiUsage;
  for (uiIter = interfaces.begin(); uiIter != interfaces.end(); ++uiIter)
    uiUsage += uiIter->first + '|';
  uiUsage = std::string("[-ui ") + uiUsage.substr(0, uiUsage.size() - 1) + ']';

  // register and parse command line arguments
  OptionParser op(std::string("bzadmin ") + getAppVersion(),
		  "CALLSIGN@HOST[:PORT] [COMMAND] [COMMAND] ...");

  const std::string uiOption("ui");
  const std::string uiMsg = "choose a user interface";
  op.registerVariable(uiOption, uiName, uiUsage, uiMsg);
  if (!op.parse(argc, argv))
    return 1;

  // check that we have callsign and host in the right format and extract them
  if (op.getParameters().size() == 0) {
    std::cerr<<"You have to specify callsign@host."<<std::endl;
    return 1;
  }
  const std::string& namehost = op.getParameters()[0];
  int atPos = namehost.find('@');
  if (atPos == -1) {
    std::cerr<<"You have to specify callsign@host."<<std::endl;
    return 1;
  }
  std::string name = namehost.substr(0, atPos);
  std::string host = namehost.substr(atPos + 1);
  int port = ServerPort;
  int cPos = host.find(':');
  if (cPos != -1) {
    port = atoi(host.substr(cPos + 1).c_str());
    host = host.substr(0, cPos);
  }

  // check that the ui is valid
  uiIter = UIMap::getInstance().find(uiName);
  if (uiIter == UIMap::getInstance().end()) {
    std::cerr<<"There is no interface called \""<<uiName<<"\"."<<std::endl;
    return 1;
  }

  // try to connect
  BZAdminClient client(name, host, port);
  if (!client.isValid())
    return 1;

  // if we got commands as arguments, send them and exit
  if (op.getParameters().size() > 1) {
    for (unsigned int i = 1; i < op.getParameters().size(); ++i)
      client.sendMessage(op.getParameters()[i], AllPlayers);
    client.waitForServer();
    return 0;
  }

  // create UI and run the main loop
  BZAdminUI*  ui = uiIter->second(client.getPlayers(), client.getMyId());
  client.setUI(ui);
  client.runLoop();
  delete ui;

  return 0;
}

// Local variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>Whitespace and code compactification<commit_after>/* bzflag
 * Copyright (c) 1993 - 2003 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef _WIN32
#pragma warning( 4: 4786)
#endif

#include <stdio.h>
#include <iostream>
#include <map>
#include <string>

#include "BZAdminClient.h"
#include "BZAdminUI.h"
#include "OptionParser.h"
#include "ServerLink.h"
#include "UIMap.h"

// causes persistent rebuilding to obtain build versioning
#include "version.h"

/** @file
    This is the main file for bzadmin, the bzflag text client.
*/

int main(int argc, char** argv) {

#ifdef _WIN32
  // startup winsock
  {
    static const int major = 2, minor = 2;
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(major, minor), &wsaData)) {
      return 1;
    }
    if (LOBYTE(wsaData.wVersion) != major ||
	HIBYTE(wsaData.wVersion) != minor) {
      WSACleanup();
      return 1;
    }
  }
#endif
  // command line options
  std::string uiName("curses");

  // no curses, use stdboth as default instead
  const UIMap& interfaces = UIMap::getInstance();
  if (interfaces.find("curses") == interfaces.end())
    uiName = "stdboth";

  // build a usage string with all interfaces
  UIMap::const_iterator uiIter;
  std::string uiUsage;
  for (uiIter = interfaces.begin(); uiIter != interfaces.end(); ++uiIter)
    uiUsage += uiIter->first + '|';
  uiUsage = std::string("[-ui ") + uiUsage.substr(0, uiUsage.size() - 1) + ']';

  // register and parse command line arguments
  OptionParser op(std::string("bzadmin ") + getAppVersion(),
		  "CALLSIGN@HOST[:PORT] [COMMAND] [COMMAND] ...");
  const std::string uiOption("ui");
  const std::string uiMsg = "choose a user interface";
  op.registerVariable(uiOption, uiName, uiUsage, uiMsg);
  if (!op.parse(argc, argv))
    return 1;

  // check that we have callsign and host in the right format and extract them
  int atPos;
  if (!(op.getParameters().size() > 0 &&
	(atPos = op.getParameters()[0].find('@')) > 0)) {
    std::cerr<<"You have to specify callsign@host."<<std::endl;
    return 1;
  }
  std::string name = op.getParameters()[0].substr(0, atPos);
  std::string host = op.getParameters()[0].substr(atPos + 1);
  int port = ServerPort;
  int cPos = host.find(':');
  if (cPos != -1) {
    port = atoi(host.substr(cPos + 1).c_str());
    host = host.substr(0, cPos);
  }

  // check that the ui is valid
  uiIter = UIMap::getInstance().find(uiName);
  if (uiIter == UIMap::getInstance().end()) {
    std::cerr<<"There is no interface called \""<<uiName<<"\"."<<std::endl;
    return 1;
  }

  // try to connect
  BZAdminClient client(name, host, port);
  if (!client.isValid())
    return 1;

  // if we got commands as arguments, send them and exit
  if (op.getParameters().size() > 1) {
    for (unsigned int i = 1; i < op.getParameters().size(); ++i)
      client.sendMessage(op.getParameters()[i], AllPlayers);
    client.waitForServer();
    return 0;
  }

  // create UI and run the main loop
  BZAdminUI*  ui = uiIter->second(client.getPlayers(), client.getMyId());
  client.setUI(ui);
  client.runLoop();
  delete ui;

  return 0;
}

// Local variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>