NDArrayViewPtr Variable::Value() const { if (!IsConstant() && !IsParameter()) LogicError("Only Variables of kind Parameter and Constant have a Value!"); if (m_dataFields->m_value == nullptr) { assert(m_dataFields->m_valueInitializer); assert(m_dataFields->m_valueInitializationDevice); switch (GetDataType()) { case DataType::Float: { m_dataFields->m_value = CreateValueFromParameterInitializer<float>(Shape(), *m_dataFields->m_valueInitializer, *m_dataFields->m_valueInitializationDevice); break; } case DataType::Double: { m_dataFields->m_value = CreateValueFromParameterInitializer<double>(Shape(), *m_dataFields->m_valueInitializer, *m_dataFields->m_valueInitializationDevice); break; } default: LogicError("Unsupported DataType %s", DataTypeName(GetDataType())); break; } m_dataFields->m_valueInitializer = nullptr; m_dataFields->m_valueInitializationDevice = nullptr; } assert(m_dataFields->m_value != nullptr); return m_dataFields->m_value; }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void SimpleDeadCodeElimination::RemoveDeadVariables(Function* function) { SparseBitVector liveVars; // Scan every instruction in the function and mark any local variable // that appears as an operand. All variables that are not marked are deleted. function->ForEachInstruction([&liveVars](Instruction* instr) -> bool { for(int i = 0; i < instr->SourceOpCount(); i++) { if(auto variableRef = instr->GetSourceOp(i)->As<VariableReference>()) { auto variable = variableRef->GetVariable(); // Only local variables. if(variable && (variable->IsParameter() == false)) { liveVars.SetBit(variable->Id()); } } } return true; }); // Now removed all unused variables. for(int i = 0; i < function->VariableCount(); i++) { auto variable = function->Variables()[i]; if(liveVars.IsSet(variable->Id()) == false) { function->RemoveVariable(variable); i--; } } }
void Variable::SetValue(const NDArrayViewPtr& value) { if (!IsParameter()) LogicError("Variable::SetValue can be only invoked on a Parameter variable!"); else if (GetDataType() != value->GetDataType()) LogicError("Variable::SetValue: 'source' and 'destination' have different data types!"); else if (Shape() != value->Shape() && (AsTensorShape(Shape()) != AsTensorShape(value->Shape()))) LogicError("Variable::SetValue: 'source' and 'destination' have different shapes!"); bool alreadySet = false; if (m_dataFields->m_initValueFlag) { // In the case of lazy initialization, try to avoid the redundant call to the initializer. std::call_once(*m_dataFields->m_initValueFlag, [=, &value, &alreadySet] { // If the variable hasn't been initialized yet, clone the content of the supplied value and delete the initializer. m_dataFields->m_value = value->DeepClone(*m_dataFields->m_valueInitializationDevice, false); m_dataFields->m_valueInitializer = nullptr; m_dataFields->m_valueInitializationDevice = nullptr; alreadySet = true; }); } assert(m_dataFields->m_value != nullptr); if (!alreadySet) { // alreadySet is false, the lambda above wasn't called and the variable has been initialized before, // get a pointer to its value and simply copy the content of the supplied value. m_dataFields->m_value->CopyFrom(*value); } }
/*virtual*/ Dictionary Variable::Serialize() const { if (IsOutput()) { LogicError("Output variables cannot be saved"); } Dictionary dict; dict[versionKey] = CurrentVersion(); dict[typeKey] = s_variableTypeValue; dict[uidKey] = Uid(); dict[kindKey] = static_cast<size_t>(Kind()); dict[dataTypeKey] = static_cast<size_t>(GetDataType()); const auto& dynamicAxes = DynamicAxes(); vector<DictionaryValue> dictionaryValueVector; dictionaryValueVector.reserve(dynamicAxes.size()); for (const auto& axis : dynamicAxes) dictionaryValueVector.push_back(axis); dict[dynamicAxisKey] = dictionaryValueVector; dict[isSparseKey] = IsSparse(); if (!Name().empty()) dict[nameKey] = Name(); dict[needsGradientKey] = NeedsGradient(); dict[shapeKey] = Shape(); if (IsParameter() || IsConstant()) { NDArrayView* value = Value().get(); if (value == nullptr) { LogicError("Uninitialized Parameter variable cannot be saved"); } // TODO: add a dictionary value constructor with an rvalue parameter. dict[valueKey] = DictionaryValue(*value); } return dict; }
int QCArrayClass::CheckArrayAllocate(int &arrayid, int nindex, int indexarray[]) const { int i; int number; int indextype, number_type; int b1, b2, e1, e2; int rtnvalue=0; if (arrayid<=0) arrayid=-arrayid; else arrayid=getidnumber(arrayid); if (arrayid==-1) { outerror(glno, "array or scalar does not exist."); return -2; } if (nindex!=arraynindex[arrayid]) { outerror(glno, "CheckArrayAllocate: nindex doesn't match."); return -2; } for (i=0; i<nindex; i++) { if (indexarray[i]!=WILDCARD_INDICATOR) /* * */ { number=Variable.getidnumber(indexarray[i]); number_type = Variable.getidtype(number); indexarray[i] = number+1; // Return (Fortran) index rather than id. if (number==-1) { outerror(glno, "index not defined."); return -1; } indextype = Variable.getidtype(arrayindex[arrayid][i]); if (number_type != indextype) { printf("Variable.getidtype(number) = %d\n", Variable.getidtype(number)); printf("Variable.getidtype(arrayindex[arrayid][i]) = %d\n", Variable.getidtype(arrayindex[arrayid][i])); outerror(glno, "index types do not match."); return -1; } /*continue;*/ b1=Variable.getbegrange(number); e1=Variable.getendrange(number); b2=Variable.getbegrange(arrayindex[arrayid][i]); e2=Variable.getendrange(arrayindex[arrayid][i]); if (!IsParameter(b2) && !IsParameter(e2)) { if (b1!=b2) { if ((b2==-bocc &&b1==-bvirt)|| (b2==-baocc&&b1==-bavirt)|| (b2==-bbocc&&b1==-bbvirt)|| b2==1) { /*should be ok, but warning*/ } else { outerror(glno, "QCArrayClass::CheckArrayAllocate"); outerror(glno, "index beginning ranges do not match."); printf(" In array '%s', index %d, using variable '%s', beginning value: ", getidname(arrayid).c_str(), i, Variable.getidname(number).c_str()); if (b1<=0) printf("%s; ", keywords[-b1]); else printf("%1d; ", b1); printf("\n By definition: variable '%s', beginning value: ", Variable.getidname(arrayindex[arrayid][i]).c_str()); if (b2<=0) printf("%s.", keywords[-b2]); else printf("%1d.", b2); printf("\n"); rtnvalue=-1; continue; } } /* b1 != b2 */ if (e1!=e2) { if ((e1==-eocc &&e2==- evirt)|| (e1==-eaocc&&e2==-eavirt)|| (e1==-ebocc&&e2==-ebvirt)|| (e1==-eocc &&e2==-norb)|| (e1==-eaocc&&e2==-norb)|| (e1==-ebocc&&e2==-norb)|| (e1==-evirt&&e2==-norb)|| (e1==-eavirt&&e2==-norb)|| (e1==-ebvirt&&e2==-norb)|| /*question about it, but should be ok*/ (e1==e2) ) { /*should be ok, but warning*/ } else { outerror(glno, "index ending ranges do not match."); printf(" In array '%s', index %d, using variable '%s', ending value: ", getidname(arrayid).c_str(), i, Variable.getidname(number).c_str()); if (e1<=0) printf("%s; ", keywords[-e1]); else printf("%1d; ", e1); printf("\n By definition: variable '%s', ending value: ", Variable.getidname(arrayindex[arrayid][i]).c_str()); if (e2<=0) printf("%s.", keywords[-e2]); else printf("%1d.", e2); printf("\n"); rtnvalue=-1; continue; /* printf("number=%d, arrayid=%d, i=%d, ",number, arrayid, i); printf("arrayindex[arrayid][i]=%d, %d, %d\n", arrayindex[arrayid][i], e1, e2); outerror(glno, "index ranges do not match."); return -1; */ } } /* e1 != e2 */ } /* !IsParameter */ } /* else indexarray[i] != WILDCARD_INDICATOR */ } /*end of for*/ return rtnvalue; }
int QCArrayClass::CheckArray(int &arrayid, int nindex, int indexarray[]) const { int i; int number; int indextype, number_type; int b1, b2, e1, e2; int rtnvalue=0; int superindex, subindex_flag; if (arrayid<=0) arrayid=-arrayid; else arrayid=getidnumber(arrayid); if (arrayid==-1) { outerror(glno, "array or scalar does not exist."); return -2; } if (nindex!=arraynindex[arrayid]) { outerror(glno, "CheckArray: nindex doesn't match."); return -2; } for (i=0; i<nindex; i++) { number=Variable.getidnumber(indexarray[i]); number_type = Variable.getidtype(number); indexarray[i]=number; if (number==-1) { outerror(glno, "index not defined."); return -1; } if (number_type == subindex) { // Look up the type of the superindex instead of the subindex. superindex = Variable.getrange1(indexarray[i]); number_type = Variable.getidtype(superindex); number = superindex; } indextype = Variable.getidtype(arrayindex[arrayid][i]); if (indextype == subindex) { // Look up the type of the superindex instead of the subindex. superindex = Variable.getrange1(arrayindex[arrayid][i]); indextype = Variable.getidtype(superindex); subindex_flag = 1; } else { subindex_flag = 0; } if (number_type!= indextype) { printf("Variable.getidtype(number) = %d\n",Variable.getidtype(number)); printf("Variable.getidtype(arrayindex[arrayid][i]) = %d\n", Variable.getidtype(arrayindex[arrayid][i])); outerror(glno, "!!! index types do not match."); return -1; } /*continue;*/ b1=Variable.getbegrange(number); e1=Variable.getendrange(number); if (subindex_flag) { b2 = Variable.getbegrange(superindex); e2 = Variable.getendrange(superindex); } else { b2=Variable.getbegrange(arrayindex[arrayid][i]); e2=Variable.getendrange(arrayindex[arrayid][i]); } if (!IsParameter(b2) && !IsParameter(e2)) { if (b1!=b2) { if ((b2==-bocc &&b1==-bvirt)|| (b2==-baocc&&b1==-bavirt)|| (b2==-bbocc&&b1==-bbvirt)|| b2==1) { /*should be ok, but warning*/ } else { outerror(glno, "QCArrayClass::CheckArray #1"); outerror(glno, "index beginning ranges do not match."); printf(" In array '%s', index %d, using variable '%s', beginning value: ", getidname(arrayid).c_str(), i, Variable.getidname(number).c_str()); if (b1<=0) printf("%s; ", keywords[-b1]); else printf("%1d; ", b1); printf("\n By definition: variable '%s', beginning value: ", Variable.getidname(arrayindex[arrayid][i]).c_str()); if (b2<=0) printf("%s.", keywords[-b2]); else printf("%1d.", b2); printf("\n"); rtnvalue=-1; continue; } } /* b1 != b2 */ if (e1!=e2) { if ((e1==-eocc &&e2==- evirt)|| (e1==-eaocc&&e2==-eavirt)|| (e1==-ebocc&&e2==-ebvirt)|| (e1==-eocc &&e2==-norb)|| (e1==-eaocc&&e2==-norb)|| (e1==-ebocc&&e2==-norb)|| (e1==-evirt&&e2==-norb)|| (e1==-eavirt&&e2==-norb)|| (e1==-ebvirt&&e2==-norb)|| /*question about it, but should be ok*/ (e1==e2) ) { /*should be ok, but warning*/ } else { outerror(glno, "QCArray::CheckArray #2"); outerror(glno, "index ending range does not match."); printf(" In array '%s', index %d, using variable '%s', ending value: ", getidname(arrayid).c_str(), i, Variable.getidname(number).c_str()); if (e1<=0) printf("%s; ", keywords[-e1]); else printf("%1d; ", e1); printf("\n By definition: variable '%s', ending value: ", Variable.getidname(arrayindex[arrayid][i]).c_str()); if (e2<=0) printf("%s.", keywords[-e2]); else printf("%1d.", e2); printf("\n"); rtnvalue=-1; continue; /* printf("number=%d, arrayid=%d, i=%d, ",number, arrayid, i); printf("arrayindex[arrayid][i]=%d, %d, %d\n", arrayindex[arrayid][i], e1, e2); outerror(glno, "index ranges do not match."); return -1; */ } } /* e1 != e2 */ } /* !IsParameter... */ } return rtnvalue; }