DIRECTORY Basics, Convert, Core, FS, IO, Random, Real, RealFns, Rope, RTCoreUtil, SC, SCInstUtil, SCNetUtil, SCPrivate, SCPlaceUtil, SCWidthUtil, SCRowUtil, SCUtil, TerminalIO; SCSAPlaceImpl: CEDAR PROGRAM IMPORTS Convert, FS, IO, Random, Real, RealFns, Rope, RTCoreUtil, SC, SCInstUtil, SCNetUtil, SCPlaceUtil, SCRowUtil, SCWidthUtil, SCUtil, TerminalIO EXPORTS SCPrivate SHARES SC = { debug: BOOLEAN _ FALSE; verbose: BOOLEAN _ TRUE; InstCounts: TYPE = REF InstCountsRec; InstCountsRec: TYPE = ARRAY SCPrivate.MaxInstanceSr OF INT _ ALL[0]; ExchDescription: TYPE = RECORD [ inst1, inst2: SCPrivate.Instance _ NIL]; tableSize: NAT = 500; ZTabSize: TYPE = NAT[0 .. tableSize]; TabSize: TYPE = NAT[1 .. tableSize]; ScoreHandle: TYPE = REF ScoreHandleRec; ScoreHandleRec: TYPE = RECORD [ size, index, numActiveEntries: ZTabSize _ 0, varianceLimit: REAL _ 0.1, mean, variance: REAL _ 0.0, entry, sum, sumSq: ARRAY TabSize OF REAL _ ALL[0]]; InitScoreHandle: PROCEDURE [sh: ScoreHandle, varianceLimit: REAL] = { sh.index _ sh.size; sh.numActiveEntries _ 0; sh.varianceLimit _ varianceLimit; FOR index: TabSize IN TabSize DO sh.entry[index] _ 0; sh.sum[index] _ 0; sh.sumSq[index] _ 0; ENDLOOP}; IncScoreHandle: PROCEDURE [score: REAL, sh: ScoreHandle] RETURNS [BOOLEAN] = { meanSq, exSq: REAL; oldIndex: TabSize _ sh.index; sh.index _ IF sh.index < sh.size THEN sh.index + 1 ELSE 1; sh.numActiveEntries _ IF sh.numActiveEntries < sh.size THEN sh.numActiveEntries + 1 ELSE sh.size; sh.sum[sh.index] _ sh.sum[oldIndex] - sh.entry[sh.index] + score; sh.sumSq[sh.index] _ sh.sumSq[oldIndex] - sh.entry[sh.index]*sh.entry[sh.index] + score*score; sh.entry[sh.index] _ score; IF sh.numActiveEntries < sh.size THEN RETURN[FALSE]; sh.mean _ sh.sum[sh.index]/sh.numActiveEntries; meanSq _ sh.mean*sh.mean; exSq _ sh.sumSq[sh.index]/sh.numActiveEntries; sh.variance _ MAX[0.0, exSq - meanSq]; RETURN[RealFns.SqRt[sh.variance] < sh.mean*sh.varianceLimit]}; Frozen: PROCEDURE [score: REAL, sh: ScoreHandle] RETURNS [BOOLEAN] = INLINE { RETURN[IncScoreHandle[score, sh]]}; Equilibrium: PROCEDURE [score: REAL, sh: ScoreHandle] RETURNS [BOOLEAN] = INLINE { RETURN[IncScoreHandle[score, sh]]}; Select: PROCEDURE [handle: SC.Handle, selectStream: Random.RandomStream] RETURNS [exch: ExchDescription _ [NIL, NIL]] = { inst1: SCPrivate.Instance _ GetInstance[handle, selectStream]; inst2: SCPrivate.Instance; IF inst1 = NIL THEN RETURN; SELECT inst1.whichClass FROM io => { inst2 _ GetIo[handle, inst1, selectStream]; IF inst2 = NIL THEN RETURN}; logic => { inst2 _ GetLogic[handle, inst1, selectStream]; IF inst2 = NIL THEN RETURN}; ENDCASE => SC.Error[programmingError, "Invalid instance index."]; IF inst2.whichClass # inst1.whichClass THEN SC.Error[programmingError, "Invalid instance selection."]; RETURN[[inst1, inst2]]}; Exchange: PROCEDURE [handle: SC.Handle, exch: ExchDescription, rowWidthLimit: SC.Number] RETURNS [didIt: BOOLEAN _ TRUE] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; inst1: SCPrivate.Instance _ exch.inst1; inst2: SCPrivate.Instance _ exch.inst2; IF inst1 = NIL OR inst2 = NIL THEN RETURN[FALSE]; IF inst1.whichClass # inst2.whichClass THEN SC.Error[programmingError, "Invalid exchange selection."]; SELECT inst1.whichClass FROM logic => { row1: SCPrivate.LgRow _ layoutData.lgRows.rows[inst1.curRow]; row2: SCPrivate.LgRow _ layoutData.lgRows.rows[inst2.curRow]; lengthRow1: SC.Number _ row1.size.p - SCInstUtil.InstWidth[inst1] + SCInstUtil.InstWidth[inst2]; lengthRow2: SC.Number _ row2.size.p - SCInstUtil.InstWidth[inst2] + SCInstUtil.InstWidth[inst1]; IF lengthRow1 > rowWidthLimit OR lengthRow2 > rowWidthLimit THEN RETURN [FALSE]; IF row1.fnlLgFxd OR row2.fnlLgFxd THEN RETURN [FALSE]; IF inst1.fnlRow # 0 AND inst2.curRow # inst1.fnlRow THEN RETURN [FALSE]; IF inst2.fnlRow # 0 AND inst1.curRow # inst2.fnlRow THEN RETURN [FALSE]; }; io => { side1: SCPrivate.BpRow _ layoutData.bpRows[inst1.curSide]; side2: SCPrivate.BpRow _ layoutData.bpRows[inst2.curSide]; IF side1.fnlBpFxd OR side2.fnlBpFxd THEN RETURN [FALSE]; IF inst1.fnlSide # none AND inst2.curSide # inst1.fnlSide THEN RETURN [FALSE]; IF inst2.fnlSide # none AND inst1.curSide # inst2.fnlSide THEN RETURN [FALSE]}; ENDCASE; SCPlaceUtil.ExchInsts[handle, inst1, inst2]}; GetInstance: PROCEDURE [handle: SC.Handle, selectStream: Random.RandomStream] RETURNS [instance: SCPrivate.Instance _ NIL]= { structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; numInstances: SCPrivate.ZMaxInstanceSr _ structureData.instances.numLogics + structureData.instances.numIOs; index: SCPrivate.ZMaxInstanceSr _ Random.ChooseInt[selectStream, 1, numInstances]; instance _ structureData.instances.inst[index]; RETURN[instance]}; GetIo: PROCEDURE [handle: SC.Handle, inst1: SCPrivate.Instance, selectStream: Random.RandomStream] RETURNS [inst2: SCPrivate.Instance _ NIL]= { structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; numIOs: SCPrivate.ZMaxInstanceSr _ structureData.instances.numIOs; index: SCPrivate.MaxInstanceSr; IF numIOs <= 1 THEN RETURN; WHILE inst2 = NIL OR inst1 = inst2 DO index _ Random.ChooseInt[selectStream, 1, numIOs]; IF index < 1 OR index > numIOs THEN SC.Signal[programmingError, "Invalid io exchange"]; inst2 _ structureData.instances.inst[index]; ENDLOOP; IF inst2.whichClass # io THEN SC.Error[programmingError, "Invalid io instance"]; RETURN[inst2]}; GetLogic: PROCEDURE [handle: SC.Handle, inst1: SCPrivate.Instance, selectStream: Random.RandomStream] RETURNS [inst2: SCPrivate.Instance _ NIL]= { structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; index: SCPrivate.MaxInstanceSr; numIOs: SCPrivate.ZMaxInstanceSr _ structureData.instances.numIOs; numInstances: SCPrivate.ZMaxInstanceSr _ structureData.instances.numLogics + numIOs; IF numInstances - numIOs <= 1 THEN RETURN; WHILE inst2 = NIL OR inst1 = inst2 DO index _ Random.ChooseInt[selectStream, numIOs + 1, numInstances]; IF index <= numIOs OR index > numInstances THEN SC.Signal[programmingError, NIL]; inst2 _ structureData.instances.inst[index]; ENDLOOP; IF inst2.whichClass # logic THEN SC.Error[programmingError, "Invalid logic instance"]; RETURN[inst2]}; FullScore: PROCEDURE [handle: SC.Handle, trial: INT] RETURNS [score: REAL _ 0] = { DoPin: SCNetUtil.EachPinProc = { loc: SCPrivate.PQPos _ SCInstUtil.InstPosOf[handle, netPin.instance, netPin.pin]; left _ MIN[left, loc.p]; bottom _ MIN[bottom, loc.q]; right _ MAX[right, loc.p]; top _ MAX[top, loc.q]}; ScoreNet: SCNetUtil.EachNetProc = { netScore: REAL; right _ top _ -LAST[INT]; left _ bottom _ LAST[INT]; [] _ SCNetUtil.EnumeratePinsOnNet[net, DoPin]; netScore _ (right - left) + (top - bottom); score _ score + netScore; net.score _ net.oldScore _ netScore; net.updatedOnTrial _ trial}; right, top, left, bottom: SC.Number; [] _ SCNetUtil.EnumerateNets[handle, ScoreNet]}; CheckScore: PROCEDURE [handle: SC.Handle, trial: INT] RETURNS [score: REAL _ 0] = { DoPin: SCNetUtil.EachPinProc = { loc: SCPrivate.PQPos _ SCInstUtil.InstPosOf[handle, netPin.instance, netPin.pin]; left _ MIN[left, loc.p]; bottom _ MIN[bottom, loc.q]; right _ MAX[right, loc.p]; top _ MAX[top, loc.q]}; ScoreNet: SCNetUtil.EachNetProc = { netScore: REAL; right _ top _ -LAST[INT]; left _ bottom _ LAST[INT]; [] _ SCNetUtil.EnumeratePinsOnNet[net, DoPin]; netScore _ (right - left) + (top - bottom); score _ score + netScore; IF netScore # net.score THEN { SC.Signal[programmingError, "Not suppose to happen."]; net.score _ netScore}; net.oldScore _ netScore; net.updatedOnTrial _ trial}; right, top, left, bottom: SC.Number; [] _ SCNetUtil.EnumerateNets[handle, ScoreNet]}; ModScore: PROCEDURE [handle: SC.Handle, exch: ExchDescription, oldScore: REAL, trial: INT] RETURNS [score: REAL] = { DoPin: SCNetUtil.EachPinProc = { loc _ SCInstUtil.InstPosOf[handle, netPin.instance, netPin.pin]; left _ MIN[left, loc.p]; bottom _ MIN[bottom, loc.q]; right _ MAX[right, loc.p]; top _ MAX[top, loc.q]}; EachPin: SCInstUtil.EachPinProc ~ { IF netPin.net # NIL THEN { IF netPin.net.updatedOnTrial # trial THEN { right _ top _ -LAST[INT]; left _ bottom _ LAST[INT]; net _ netPin.net; [] _ SCNetUtil.EnumeratePinsOnNet[net, DoPin]; netScore _ (right - left) + (top - bottom); oldNetScore _ net.score; IF netScore < 0 THEN ERROR; score _ score + netScore - oldNetScore; net.score _ netScore; net.oldScore _ oldNetScore; net.updatedOnTrial _ trial}}}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; loc: SCPrivate.PQPos; right, top, left, bottom: SC.Number; netScore, oldNetScore: REAL; net: SCPrivate.Net; lgRow: SCPrivate.LgRow; score _ oldScore; SELECT exch.inst1.whichClass FROM logic,ft =>{ lgRow _ layoutData.lgRows.rows[exch.inst1.curRow]; FOR inst: NAT IN [1 .. lgRow.nLgsOnRow] DO [] _ SCInstUtil.EnumeratePinsOnInst[lgRow.lgsOnRow[inst], EachPin]; ENDLOOP; IF exch.inst1.curRow # exch.inst2.curRow THEN { lgRow _ layoutData.lgRows.rows[exch.inst2.curRow]; FOR inst: NAT IN [1 .. lgRow.nLgsOnRow] DO [] _ SCInstUtil.EnumeratePinsOnInst[lgRow.lgsOnRow[inst], EachPin]; ENDLOOP}}; io =>{ bpRow: SCPrivate.BpRow _ layoutData.bpRows[exch.inst1.curSide]; FOR inst: NAT IN [1 .. bpRow.nBpsOnSide] DO [] _ SCInstUtil.EnumeratePinsOnInst[bpRow.bpsOnSide[inst], EachPin]; ENDLOOP; IF exch.inst1.curSide # exch.inst2.curSide THEN { bpRow _ layoutData.bpRows[exch.inst2.curSide]; FOR inst: NAT IN [1 .. bpRow.nBpsOnSide] DO [] _ SCInstUtil.EnumeratePinsOnInst[bpRow.bpsOnSide[inst], EachPin]; ENDLOOP}}; ENDCASE; IF score < 0 THEN SC.Signal[programmingError, "Should not happen."]}; RestoreScore: PROCEDURE [handle: SC.Handle, exch: ExchDescription, oldScore: REAL, trial: INT] RETURNS [score: REAL] = { EachPin: SCInstUtil.EachPinProc ~ { IF netPin.net # NIL THEN { IF netPin.net.updatedOnTrial = trial THEN { net _ netPin.net; oldNetScore _ net.oldScore; score _ score + oldNetScore - net.score; net.score _ oldNetScore; net.updatedOnTrial _ 0}}}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; net: SCPrivate.Net; oldNetScore: REAL; lgRow: SCPrivate.LgRow; score _ oldScore; SELECT exch.inst1.whichClass FROM logic,ft =>{ lgRow _ layoutData.lgRows.rows[exch.inst1.curRow]; FOR inst: NAT IN [1 .. lgRow.nLgsOnRow] DO [] _ SCInstUtil.EnumeratePinsOnInst[lgRow.lgsOnRow[inst], EachPin]; ENDLOOP; IF exch.inst1.curRow # exch.inst2.curRow THEN { lgRow _ layoutData.lgRows.rows[exch.inst2.curRow]; FOR inst: NAT IN [1 .. lgRow.nLgsOnRow] DO [] _ SCInstUtil.EnumeratePinsOnInst[lgRow.lgsOnRow[inst], EachPin]; ENDLOOP}}; io =>{ bpRow: SCPrivate.BpRow _ layoutData.bpRows[exch.inst1.curSide]; FOR inst: NAT IN [1 .. bpRow.nBpsOnSide] DO [] _ SCInstUtil.EnumeratePinsOnInst[bpRow.bpsOnSide[inst], EachPin]; ENDLOOP; IF exch.inst1.curSide # exch.inst2.curSide THEN { bpRow _ layoutData.bpRows[exch.inst2.curSide]; FOR inst: NAT IN [1 .. bpRow.nBpsOnSide] DO [] _ SCInstUtil.EnumeratePinsOnInst[bpRow.bpsOnSide[inst], EachPin]; ENDLOOP}}; ENDCASE; IF score < 0 THEN SC.Signal[programmingError, "Should not happen."] }; InitStream: PROC [handle: SC.Handle, append, variables: Rope.ROPE] RETURNS [graph: FS.STREAM] ~ { name: Rope.ROPE _ Rope.Cat[handle.name, append]; graph _ FS.StreamOpen[name, $create]; IO.PutRope[graph, Rope.Cat["-- file: ", name, "\n"]]; IO.Put[graph, IO.rope["-- created: "], IO.time[], IO.rope["\n"]]; IO.PutRope[graph, Rope.Cat["variables: \n\n", variables, "\nvalues:\n\n"]]}; ThrowDice: PROC [deltaScore, temprature: REAL, choiceStream: Random.RandomStream] RETURNS [BOOLEAN] ~ { maxRandom: INT _ LAST[INT] - 1; -- Ain't this a kicker? random0To1: REAL _ Real.Float[Random.ChooseInt[choiceStream, 0, maxRandom]]/Real.Float[maxRandom]; RETURN[random0To1 < RealFns.Exp[-deltaScore / temprature]]; }; SAInitialPlace: PUBLIC PROCEDURE [handle: SC.Handle, seed: INT] RETURNS [initialResult: SC.SAInitialResult] = { structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; selectStream: Random.RandomStream _ Random.Create[LAST[INT], seed]; score: REAL _ FullScore[handle, 0]; stop: BOOLEAN _ FALSE; rowWidthLimit: SC.Number _ layoutData.lgRows.maxRowWidth; numTrials: INT _ structureData.instances.count*2; cycles: INT _ 0; initialResult.numTotal _ initialResult.numDecrease _ initialResult.numIncrease _ initialResult.numNeutral _ 0; initialResult.minScore _ initialResult.maxScore _ score; initialResult.minDelta _ initialResult.maxDelta _ initialResult.avgDelta _ 0.0; UNTIL cycles >= numTrials OR stop DO exch: ExchDescription _ Select[handle, selectStream]; cycles _ cycles + 1; IF Exchange[handle, exch, rowWidthLimit] THEN { newScore, deltaScore: REAL; initialResult.numTotal _ initialResult.numTotal + 1; newScore _ ModScore[handle, exch, score, initialResult.numTotal]; deltaScore _ newScore - score; IF deltaScore < 0 THEN { score _ newScore; initialResult.minScore _ MIN[initialResult.minScore, score]; initialResult.numDecrease _ initialResult.numDecrease + 1; } ELSE IF deltaScore > 0 THEN { score _ newScore; initialResult.maxScore _ MAX[initialResult.maxScore, score]; initialResult.maxDelta _ MAX[initialResult.maxDelta, deltaScore]; initialResult.minDelta _ MIN[initialResult.minDelta, deltaScore]; initialResult.avgDelta _ initialResult.avgDelta + deltaScore; initialResult.numIncrease _ initialResult.numIncrease + 1; } ELSE { -- deltaScore = 0 initialResult.numNeutral _ initialResult.numNeutral + 1; }}; ENDLOOP; IF initialResult.numTotal <= 0 THEN initialResult.avgDelta _ (initialResult.maxScore + initialResult.minScore)/2 ELSE initialResult.avgDelta _ initialResult.avgDelta/initialResult.numTotal; TerminalIO.WriteRope[Rope.Cat[Rope.Cat[" total trials: ", Convert.RopeFromInt[initialResult.numTotal]], Rope.Cat[", final Score: ", Convert.RopeFromReal[score], "\n"]]]; TerminalIO.WriteRope[Rope.Cat[Rope.Cat[" decreased: ", Convert.RopeFromInt[initialResult.numDecrease], ", increased: ", Convert.RopeFromInt[initialResult.numIncrease]], Rope.Cat[", neutral: ", Convert.RopeFromInt[initialResult.numNeutral], "\n"]]]; TerminalIO.WriteRope[Rope.Cat[" min Score: ", Convert.RopeFromReal[initialResult.minScore], ", max Score: ", Convert.RopeFromReal[initialResult.maxScore], "\n"]]; TerminalIO.WriteRope[Rope.Cat[Rope.Cat[" min delta: ", Convert.RopeFromReal[initialResult.minDelta], ", max delta: ", Convert.RopeFromReal[initialResult.maxDelta]], Rope.Cat[" avg delta: ", Convert.RopeFromReal[initialResult.avgDelta], "\n"]]]; IF debug THEN SCPlaceUtil.WriteCurPlace[handle]}; SAGetParms: PUBLIC PROCEDURE [handle: SC.Handle, initialResult: SC.SAInitialResult, cellType: Core.CellType] RETURNS [saParms: SC.SAParms] = { structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; investment: SC.HowLongToWork _ SCUtil.GetCoreInvestmentProp[cellType, SC.investmentProp]; acceptance: REAL; SELECT investment FROM veryLong => { acceptance _ 0.94; saParms.t0 _ IF initialResult.numTotal <= 0 THEN 0.0 ELSE -initialResult.avgDelta/RealFns.Ln[acceptance]; saParms.alpha _ 0.96; saParms.eqVarLimit _ 0.04; saParms.fzVarLimit _ 0.03; saParms.eqTabSize _ MIN[tableSize, MAX[200, structureData.instances.count*3]]; saParms.fzTabSize _ MIN[tableSize, MAX[100, structureData.instances.count]]}; long => { acceptance _ 0.91; saParms.t0 _ IF initialResult.numTotal <= 0 THEN 0.0 ELSE -initialResult.avgDelta/RealFns.Ln[acceptance]; saParms.alpha _ 0.94; saParms.eqVarLimit _ 0.05; saParms.fzVarLimit _ 0.04; saParms.eqTabSize _ MIN[tableSize, MAX[100, structureData.instances.count*2]]; saParms.fzTabSize _ MIN[tableSize, MAX[50, structureData.instances.count/2]]}; medium => { acceptance _ 0.88; saParms.t0 _ IF initialResult.numTotal <= 0 THEN 0.0 ELSE -initialResult.avgDelta/RealFns.Ln[acceptance]; saParms.alpha _ 0.92; saParms.eqVarLimit _ 0.07; saParms.fzVarLimit _ 0.07; saParms.eqTabSize _ MIN[tableSize, MAX[100, structureData.instances.count]]; saParms.fzTabSize _ MIN[tableSize, MAX[50, structureData.instances.count/3]]}; short => { acceptance _ 0.85; saParms.t0 _ IF initialResult.numTotal <= 0 THEN 0.0 ELSE -initialResult.avgDelta/RealFns.Ln[acceptance]; saParms.alpha _ 0.89; saParms.eqVarLimit _ 0.08; saParms.fzVarLimit _ 0.07; saParms.eqTabSize _ MIN[tableSize, MAX[100, structureData.instances.count]]; saParms.fzTabSize _ MIN[tableSize, MAX[50, structureData.instances.count/3]]}; veryShort => { acceptance _ 0.82; saParms.t0 _ IF initialResult.numTotal <= 0 THEN 0.0 ELSE -initialResult.avgDelta/RealFns.Ln[acceptance]; saParms.alpha _ 0.82; saParms.eqVarLimit _ 0.1; saParms.fzVarLimit _ 0.07; saParms.eqTabSize _ MIN[tableSize, MAX[100, structureData.instances.count]]; saParms.fzTabSize _ MIN[tableSize, MAX[50, structureData.instances.count/3]]}; ENDCASE => { acceptance _ 0.90; saParms.t0 _ RTCoreUtil.GetCoreRealProp[cellType, SC.t0SA, IF initialResult.numTotal <= 0 THEN 0.0 ELSE -initialResult.avgDelta/RealFns.Ln[acceptance]]; saParms.alpha _ RTCoreUtil.GetCoreRealProp[cellType, SC.alphaSA, 0.90]; saParms.eqVarLimit _ RTCoreUtil.GetCoreRealProp[cellType, SC.eqVarLimitSA, 0.1]; saParms.fzVarLimit _ RTCoreUtil.GetCoreRealProp[cellType, SC.fzVarLimitSA, 0.07]; saParms.eqTabSize _ MIN[tableSize, RTCoreUtil.GetCoreIntProp[cellType, SC.eqTabSizeSA, structureData.instances.count]]; saParms.fzTabSize _ MIN[tableSize, RTCoreUtil.GetCoreIntProp[cellType, SC.fzTabSizeSA, structureData.instances.count]]}; }; SAPlaceImprove: PUBLIC PROCEDURE [handle: SC.Handle, saParms: SC.SAParms, seed: INT] = { InitNewTemp: PROCEDURE [] = { TerminalIO.WriteRope[Rope.Cat["Temp: ", Convert.RopeFromReal[temprature], "\n"]]; numTotal _ numDecrease _ numIncrease _ numNeutral _ 0; minScore _ maxScore _ score _ CheckScore[handle, numTotal]}; FinishTemp: PROCEDURE [sh: ScoreHandle] = { IF verbose THEN { TerminalIO.WriteRope[Rope.Cat[Rope.Cat[" Trials: tot: ", Convert.RopeFromInt[numTotal]], Rope.Cat[" dec: ", Convert.RopeFromInt[numDecrease], ", inc: ", Convert.RopeFromInt[numIncrease]], Rope.Cat[", neut: ", Convert.RopeFromInt[numNeutral], ", rej: ", Convert.RopeFromInt[numTotal - numDecrease - numIncrease - numNeutral], "\n"]]]; TerminalIO.WriteRope[Rope.Cat[Rope.Cat[" Scores: fin: ", Convert.RopeFromReal[score]], Rope.Cat[", min: ", Convert.RopeFromReal[minScore], ", max: ", Convert.RopeFromReal[maxScore]], Rope.Cat[", mean: ", Convert.RopeFromReal[sh.mean], "\n"]]]}; IF ~RealFns.AlmostZero[temprature, -100] THEN { IO.PutRope[graph, Rope.Cat[Convert.RopeFromReal[RealFns.Ln[temprature]], " ", Convert.RopeFromReal[minScore], " "]]; IO.PutRope[graph, Rope.Cat[Convert.RopeFromReal[sh.mean], " ", Convert.RopeFromReal[maxScore], "\n"]]}}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; selectStream: Random.RandomStream _ Random.Create[LAST[INT], seed]; choiceStream: Random.RandomStream _ Random.Create[LAST[INT], seed]; startArea: SC.Number; temprature: REAL _ saParms.t0; frozenHandle: ScoreHandle _ NEW[ScoreHandleRec _ [size: saParms.fzTabSize]]; equilibriumHandle: ScoreHandle _ NEW[ScoreHandleRec _ [size: saParms.eqTabSize]]; numTotal, numDecrease, numIncrease, numNeutral: INT _ 0; minScore, maxScore, score: REAL; graph: FS.STREAM _ InitStream[handle, "SA.list", "\"Temp\" \"Min Score\" \"Mean Score\" \"Max Score\""]; stop: BOOLEAN _ FALSE; rowWidthLimit: SC.Number; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; rowWidthLimit _ lgRows.maxRowWidth; SCWidthUtil.AllChanWidths[handle, areaFom]; SCInstUtil.AsgnChanPos[handle]; score _ FullScore[handle, numTotal]; startArea _ SCUtil.WriteResults["Placement improvement\n starting area:", handle, 0]; TerminalIO.WriteRope[Rope.Cat["Starting score: ", Convert.RopeFromReal[score], "\n"]]; InitScoreHandle[frozenHandle, saParms.fzVarLimit]; UNTIL Frozen[score, frozenHandle] OR stop DO InitScoreHandle[equilibriumHandle, saParms.eqVarLimit]; InitNewTemp[]; UNTIL Equilibrium[score, equilibriumHandle] OR stop DO exch: ExchDescription _ Select[handle, selectStream]; IF Exchange[handle, exch, rowWidthLimit] THEN { trialScore, deltaScore: REAL; numTotal _ numTotal + 1; trialScore _ ModScore[handle, exch, score, numTotal]; deltaScore _ trialScore - score; IF deltaScore < 0 THEN { score _ trialScore; minScore _ MIN[minScore, score]; numDecrease _ numDecrease + 1; } ELSE IF deltaScore > 0 THEN { accept: BOOLEAN; accept _ ThrowDice[deltaScore, temprature, choiceStream ! Real.RealException => {accept _ FALSE; CONTINUE}]; IF accept THEN { score _ trialScore; maxScore _ MAX[maxScore, score]; numIncrease _ numIncrease + 1; } ELSE { didIt: BOOLEAN _ Exchange[handle, exch, LAST[INT]]; restoredScore: REAL _ RestoreScore[handle, exch, trialScore, numTotal]; IF ~RealFns.AlmostEqual[restoredScore, score, -15] OR ~didIt THEN { TerminalIO.WriteRope[Rope.Cat["Loss of REAL precision fixed: ", Convert.RopeFromReal[restoredScore], ", ", Convert.RopeFromReal[score]]]; score _ FullScore[handle, numTotal]; -- SC.Signal[other, "Loss of precision."]; }}} ELSE { -- deltaScore = 0 numNeutral _ numNeutral + 1; }; }; ENDLOOP; FinishTemp[equilibriumHandle]; temprature _ Real.FMul[saParms.alpha, temprature ! Real.RealException => {temprature _ 0.0; CONTINUE}]; ENDLOOP; SCInstUtil.AllOffsets[handle]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCWidthUtil.AllChanWidths[handle, areaFom]; SCInstUtil.AsgnChanPos[handle]; [] _ SCUtil.WriteResults["End placement improvement\n ending area:", handle, startArea]; IO.Flush[graph]; IO.Close[graph]; IF debug THEN SCPlaceUtil.WriteCurPlace[handle]}; SCRandomTest: PUBLIC PROCEDURE [handle: SC.Handle, trials, seed: INT] = { StorePair: PROCEDURE [exch: ExchDescription] = { inst1[exch.inst1.num] _ inst1[exch.inst1.num] +1; inst2[exch.inst2.num] _ inst2[exch.inst2.num] +1; IO.PutRope[scatterGraph, Rope.Cat[Convert.RopeFromInt[exch.inst1.num], " ", Convert.RopeFromInt[exch.inst2.num], "\n"]]}; WriteDat: PROCEDURE [] = { EachInst: SCInstUtil.EachInstanceProc ~ { IO.PutRope[histGraph, Rope.Cat[Convert.RopeFromInt[instance.num], " "]]; IO.PutRope[histGraph, Rope.Cat[Convert.RopeFromInt[inst1[instance.num]], " ", Convert.RopeFromInt[inst2[instance.num]], "\n"]]}; [] _ SCInstUtil.EnumerateAllInstances[handle, EachInst]}; selectStream: Random.RandomStream _ Random.Create[LAST[INT], seed]; choiceStream: Random.RandomStream _ Random.Create[LAST[INT], seed]; inst1: InstCounts _ NEW[InstCountsRec]; inst2: InstCounts _ NEW[InstCountsRec]; numTotal: INT _ 0; histGraph: FS.STREAM _ InitStream[handle, "Random.list", "\"Bin\" \"Instance 1\" \"Instance 2\""]; scatterGraph: FS.STREAM _ InitStream[handle, "Scatter.list", "\"Instance 1\" \"Instance 2\""]; stop: BOOLEAN _ FALSE; TerminalIO.WriteRope[Rope.Cat["Random Test: ", "\n"]]; UNTIL numTotal > trials OR stop DO exch: ExchDescription _ Select[handle, selectStream]; IF Exchange[handle, exch, LAST[INT]] THEN { numTotal _ numTotal + 1; StorePair[exch]}; ENDLOOP; WriteDat[]; TerminalIO.WriteRope["End Random Test\n"]; IO.Flush[histGraph]; IO.Close[histGraph]; IO.Flush[scatterGraph]; IO.Close[scatterGraph]; }; }. ¼file: SCSAPlaceImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. got an IO, get another IO got a logic, get another logic no constraint check for now IF debug THEN TerminalIO.WriteRope[Rope.Cat["Exchange ", inst1.name, " and ", inst2.name, "\n"]]; NB: This procedure accounts for 75% of the placement time! It MUST be efficient; hence, the stilted style. Compute the new score for the placement by enumerating the altered nets. determine the bounding box of the pins on the net evaluate the nets attached to the pins Restore the previous score for the placement by enumerating the altered nets. Efficiency dictates the stilted stucture. IF newScore # CheckScore[handle, initialResult.numTotal] THEN SC.Signal[programmingError, "Should not happen."]; IF debug THEN { TerminalIO.WriteRope[Rope.Cat["Score decreased: ", Convert.RopeFromReal[trialScore]]]; TerminalIO.WriteRope[Rope.Cat[", Exchange ", exch.inst1.name, " and ", exch.inst2.name, "\n"]]} IF debug THEN { TerminalIO.WriteRope[Rope.Cat["Score increased ", Convert.RopeFromReal[trialScore], ", accepted"]]; TerminalIO.WriteRope[Rope.Cat[", Exchange ", exch.inst1.name, " and ", exch.inst2.name, "\n"]]} IF debug THEN { TerminalIO.WriteRope[Rope.Cat["Neutral exchange accepted: ", Convert.RopeFromReal[trialScore]]]; TerminalIO.WriteRope[Rope.Cat[". Exchange ", exch.inst1.name, " and ", exch.inst2.name, "\n"]]} determine parameters for simulated placement. IF debug THEN { TerminalIO.WriteRope[Rope.Cat["Score decreased: ", Convert.RopeFromReal[trialScore]]]; TerminalIO.WriteRope[Rope.Cat[", Exchange ", exch.inst1.name, " and ", exch.inst2.name, "\n"]]} accept an increased score IF debug THEN { TerminalIO.WriteRope[Rope.Cat["Score increased ", Convert.RopeFromReal[trialScore], ", accepted"]]; TerminalIO.WriteRope[Rope.Cat[", Exchange ", exch.inst1.name, " and ", exch.inst2.name, "\n"]]} reject increased score, restore previous placement IF debug THEN { TerminalIO.WriteRope[Rope.Cat["Neutral exchange accepted: ", Convert.RopeFromReal[trialScore]]]; TerminalIO.WriteRope[Rope.Cat[". Exchange ", exch.inst1.name, " and ", exch.inst2.name, "\n"]]} IF score # CheckScore[handle, numTotal] THEN SC.Signal[other, "Loss of precision."] ÊÒ˜šœ™Icodešœ Ïmœ0™;—J˜šÏk ˜ Jš œžœžœžœ žœ\˜¦J˜—šÏn œžœž˜J˜Jšžœ žœžœ)žœP˜”Jšžœ ˜Jšžœžœ˜J˜Jšœžœžœ˜Jšœ žœžœ˜J˜Jšœ žœžœ˜%Jš œžœžœžœžœžœ˜DJ˜šœžœžœ˜ Jšœ#žœ˜(—J˜Jšœ žœ˜Jšœ žœžœ˜%Jšœ žœžœ˜$Jšœ žœžœ˜'šœžœžœ˜Jšœ,˜,Jšœžœ˜Jšœžœ˜Jš œžœ žœžœžœ˜3—J˜šŸœž œ"žœ˜EJšœ˜Jšœ˜Jšœ!˜!šžœžœ žœ˜!Jšœ˜Jšœ˜Jšœ˜Jšžœ˜ —J˜—š Ÿœž œ žœžœžœ˜NJ˜Jšœžœ˜Jšœ˜Jšœ žœžœžœ˜:Jšœžœžœžœ ˜aJšœA˜AJšœ^˜^Jšœ˜Jšžœžœžœžœ˜4Jšœ/˜/Jšœ˜Jšœ.˜.Jšœžœ˜&Jšžœ8˜>J˜—š Ÿœž œ žœžœžœžœ˜MJšžœ˜#J˜—š Ÿ œž œ žœžœžœžœ˜RJšžœ˜#J˜—š Ÿœž œ žœ,žœžœžœ˜yJ˜Jšœ>˜>Jšœ˜Jšžœ žœžœžœ˜šžœž˜šœ˜Jšœ™Jšœ+˜+Jšžœ žœžœžœ˜—šœ ˜ Jšœ™Jšœ.˜.Jšžœ žœžœžœ˜——Jšžœžœ4˜BJšžœ%žœžœ8˜fJšžœ˜J˜—šŸœž œ žœ/žœ žœ žœžœ˜|Jšœ™Jšœ#žœ˜=Jšœ'˜'Jšœ'˜'Jšžœ žœžœ žœžœžœžœ˜1Jšžœ%žœžœ8˜fšžœž˜˜ Jšœ=˜=Jšœ=˜=Jšœ žœR˜`Jšœ žœR˜`Jš žœžœžœžœžœ˜PJš žœžœžœžœžœ˜6Jš žœžœžœžœžœ˜HJš žœžœžœžœžœ˜HJšœ˜—˜Jšœ:˜:Jšœ:˜:Jš žœžœžœžœžœ˜9Jš žœžœžœžœžœ˜NJš žœžœžœžœžœ˜O—Kšžœ˜—Jšœa™aJ˜Jšœ-˜-J˜—š Ÿ œž œ žœ,žœ!žœ˜}Jšœ)žœ˜FJšœl˜lJšœR˜RJšœ/˜/Jšžœ ˜J˜—š Ÿœž œ žœGžœžœ˜Jšœ)žœ˜FJšœB˜BJšœ˜Jšžœ žœžœ˜šžœ žœžœžœ˜&Jšœ2˜2Jšžœ žœžœžœ1˜WJšœ,˜,Jšžœ˜—Jšžœžœžœ0˜PJšžœ ˜J˜—š Ÿœž œ žœGžœžœ˜’Jšœ)žœ˜FJšœ˜JšœB˜BJšœT˜TJšžœžœžœ˜*šžœ žœžœžœ˜&JšœA˜AJš žœžœžœžœžœ˜QJšœ,˜,Jšžœ˜—Jšžœžœžœ3˜VJšžœ ˜J˜—š Ÿ œž œ žœžœžœ žœ ˜RJ˜šŸœ˜ JšœQ˜QJšœžœ˜Jšœ žœ˜Jšœžœ˜Jšœžœ˜J˜—šŸœ˜#Jšœ žœ˜Jšœžœžœ˜Jšœžœžœ˜J˜Jšœ.˜.Jšœ+˜+Jšœ˜Jšœ$˜$Jšœ˜—J˜Jšœžœ˜$Jšœ0˜0J˜—š Ÿ œž œ žœžœžœ žœ ˜SJ˜šŸœ˜ JšœQ˜QJšœžœ˜Jšœ žœ˜Jšœžœ˜Jšœžœ˜J˜—šŸœ˜#Jšœ žœ˜Jšœžœžœ˜Jšœžœžœ˜J˜Jšœ.˜.Jšœ+˜+Jšœ˜šžœžœ˜Kšžœ4˜6Kšœ˜—Jšœ˜Jšœ˜—J˜Jšœžœ˜$Jšœ0˜0J˜—šŸœž œ žœ*žœ žœžœ žœ˜tJ™Jšœm™mJ™HJ˜šŸœ˜ Jšœ1™1Jšœ@˜@Jšœžœ˜Jšœ žœ˜Jšœžœ˜Jšœžœ˜J˜—šŸœ˜#Jšœ&™&šžœžœžœ˜šžœ#žœ˜+Jšœžœžœ˜Jšœžœžœ˜Jšœ˜Jšœ.˜.Jšœ+˜+Jšœ˜Kšžœžœžœ˜Jšœ'˜'Jšœ˜Jšœ˜Jšœ˜———J˜Kšœ#žœ˜=Jšœ˜Jšœžœ˜$Jšœžœ˜Jšœ˜Kšœ˜Jšœ˜K˜šžœž˜!˜ Kšœ2˜2šžœžœžœžœ˜+JšœC˜CJšžœ˜—šžœ'žœ˜/Kšœ2˜2šžœžœžœžœ˜+JšœC˜CJšžœ˜ ———˜Kšœ?˜?šžœžœžœžœ˜,JšœD˜DJšžœ˜—šžœ)žœ˜1Kšœ.˜.šžœžœžœžœ˜,JšœD˜DJšžœ˜ ———Kšžœ˜—Kšžœ žœžœ1˜EJ˜—šŸ œž œ žœ*žœ žœžœ žœ˜xJ˜J™MJ™)šŸœ˜#šžœžœžœ˜Kšžœ#žœ˜+Jšœ˜Jšœ˜Jšœ(˜(Jšœ˜Jšœ˜——J˜Kšœ#žœ˜=Jšœ˜Jšœ žœ˜Kšœ˜K˜Jšœ˜šžœž˜!˜ Kšœ2˜2šžœžœžœžœ˜+JšœC˜CJšžœ˜—šžœ'žœ˜/Kšœ2˜2šžœžœžœžœ˜+JšœC˜CJšžœ˜ ———˜Kšœ?˜?šžœžœžœžœ˜,JšœD˜DJšžœ˜—šžœ)žœ˜1Kšœ.˜.šžœžœžœžœ˜,JšœD˜DJšžœ˜ ———Kšžœ˜—Kšžœ žœžœ/˜CJšœ˜J˜—šŸ œžœ žœ!žœžœ žœžœ˜aKšœ žœ!˜0Kšœžœ˜%Kšžœ3˜5Kšžœ žœžœ žœ ˜AKšžœJ˜LK˜—š Ÿ œžœžœ%žœžœ˜gJ˜Jšœ žœžœžœÏc˜8Kšœ žœR˜bKšžœ5˜;K˜K˜—šŸœžœž œ žœžœžœžœ˜oJ˜Jšœ)žœ˜FJšœ#žœ˜=Jšœ2žœžœ ˜CJšœžœ˜#Jšœžœžœ˜Jšœžœ(˜9Jšœ žœ#˜1Jšœžœ˜J˜Jšœn˜nJšœ8˜8JšœO˜OJ˜šžœžœž˜$Jšœ5˜5J˜šžœ'žœ˜/Jšœžœ˜Jšœ4˜4JšœA˜AJšžœ7žœžœ0™pJšœ˜šžœžœ˜Jšœ˜Jšœžœ ˜