CUSPICE Integration from scratch

This commit is contained in:
Francesco Lannutti 2014-04-26 20:09:21 +02:00 committed by rlar
parent 86a5d92047
commit 619536c781
104 changed files with 16521 additions and 7 deletions

View File

@ -207,7 +207,64 @@ if test "x$enable_klu" = xyes; then
AC_DEFINE(KLU, [], [Define if we want KLU linear systems solver])
AC_MSG_WARN([KLU solver enabled])
fi
AM_CONDITIONAL([KLU_WANTED], [test "x$enable_klu" = xyes])
AM_CONDITIONAL([KLU_WANTED], [test "x$enable_klu" = xyes || test "x$enable_cuspice" = xyes])
# --enable-cuspice: Use CUSPICE (NGSPICE on CUDA Platforms)
AC_ARG_ENABLE([cuspice],
[AS_HELP_STRING([--enable-cuspice], [Use CUSPICE (NGSPICE on CUDA Platforms)])])
# Add CUSPICE (NGSPICE on CUDA Platforms) to NGSPICE
if test "x$enable_cuspice" = xyes; then
AC_DEFINE(USE_CUSPICE, [], [Define if we want CUSPICE (NGSPICE on CUDA Platforms) enabled])
AC_MSG_WARN(CUSPICE (NGSPICE on CUDA Platforms) enabled)
AC_ARG_WITH([cuda],
[AS_HELP_STRING([--with-cuda=PATH], [Define the prefix where cuda is installed (default=/usr/local/cuda)])])
ARCH=`uname -m`
if test -n "$with_cuda"
then
CUDA_CPPFLAGS="-I$with_cuda/include"
if [[ $ARCH == "x86_64" ]]
then
CUDA_LIBS="-L$with_cuda/lib64 -lcuda -lcudart"
else
CUDA_LIBS="-L$with_cuda/lib -lcuda -lcudart"
fi
NVCC="$with_cuda/bin/nvcc"
else
CUDA_CPPFLAGS="-I/usr/local/cuda/include"
if [[ $ARCH == "x86_64" ]]
then
CUDA_LIBS="-L/usr/local/cuda/lib64 -lcuda -lcudart"
else
CUDA_LIBS="-L/usr/local/cuda/lib -lcuda -lcudart"
fi
AC_PATH_PROG(NVCC, nvcc, "no")
AS_IF([test "x$NVCC" = xno],
[AC_MSG_ERROR([NVCC compiler not found!])])
NVCC="nvcc"
fi
AC_SUBST(CUDA_CPPFLAGS)
AC_SUBST(CUDA_LIBS)
AC_SUBST(NVCC)
# NVCC Compilation Flags
CUDA_CFLAGS="-gencode arch=compute_20,\"code=sm_20\""
CUDA_CFLAGS+=" -gencode arch=compute_30,\"code=sm_30\""
CUDA_CFLAGS+=" -gencode arch=compute_32,\"code=sm_32\""
CUDA_CFLAGS+=" -gencode arch=compute_35,\"code=sm_35\""
CUDA_CFLAGS+=" -gencode arch=compute_50,\"code=sm_50\""
CUDA_CFLAGS+=" -DCOMPILED_BY_NVCC"
if test "x$enable_debug" = xno; then
CUDA_CFLAGS+=" -O2"
else
CUDA_CFLAGS+=" -g -O1 -G"
fi
AC_SUBST(CUDA_CFLAGS)
AC_DEFINE(KLU, [], [Define if we want KLU linear systems solver])
AC_MSG_WARN([KLU solver enabled, because CUSPICE needs it])
fi
AM_CONDITIONAL([USE_CUSPICE_WANTED], [test "x$enable_cuspice" = xyes])
# Enable maintainer commands only if requested

1
examples/CUSPICE/Circuits Symbolic link
View File

@ -0,0 +1 @@
../klu/Circuits

View File

@ -0,0 +1,10 @@
* Test Current Source Model
I1 0 1 pulse(0 1 0p 200p 200p 1n 2n)
R1 0 1 1k
R2 1 2 0.5k
R3 2 0 0.2k
.tran 1ps 1ns
.print tran all
.end

View File

@ -0,0 +1,9 @@
* Test Inductor Model
V1 0 1 pulse(0 1 0p 200p 200p 1n 2n)
R1 1 2 10
L1 2 0 10
.tran 1ps 1ns
.print tran all
.end

View File

@ -0,0 +1,11 @@
* Test Mutual Inductor Model
V1 0 1 pulse(0 1 0p 200p 200p 1n 2n)
R1 1 2 10
L1 2 0 10
L2 3 0 10
K1 L1 L2 0.5
.tran 1ps 1ns
.print tran all
.end

View File

@ -189,6 +189,10 @@ com_version(wordlist *wl)
"** Compiled with Sparse Direct Linear Solver\n"
#endif
#ifdef USE_CUSPICE
"** Compiled with CUSPICE (NGSPICE on CUDA Platforms)\n"
#endif
"** The U. C. Berkeley CAD Group\n"
"** Copyright 1985-1994, Regents of the University of California.\n"
"** %s\n",
@ -229,6 +233,10 @@ com_version(wordlist *wl)
"** Compiled with Sparse Direct Linear Solver\n"
#endif
#ifdef USE_CUSPICE
"** Compiled with CUSPICE (NGSPICE on CUDA Platforms)\n"
#endif
"** The U. C. Berkeley CAD Group\n"
"** Copyright 1985-1994, Regents of the University of California.\n"
"** %s\n",

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
int cuCKTcsrmv (CKTcircuit *) ;
int cuCKTflush (CKTcircuit *) ;
int cuCKTnonconUpdateHtoD (CKTcircuit *) ;
int cuCKTnonconUpdateDtoH (CKTcircuit *) ;
int cuCKTrhsOldFlush (CKTcircuit *) ;
int cuCKTrhsOldUpdateHtoD (CKTcircuit *) ;
int cuCKTrhsOldUpdateDtoH (CKTcircuit *) ;
int cuCKTsetup (CKTcircuit *) ;
int cuCKTsystemDtoH (CKTcircuit *) ;
int cuCKTstatesFlush (CKTcircuit *) ;
int cuCKTstatesUpdateDtoH (CKTcircuit *) ;
int cuCKTstate0UpdateHtoD (CKTcircuit *) ;
int cuCKTstate0UpdateDtoH (CKTcircuit *) ;
int cuCKTstate01copy (CKTcircuit *) ;
int cuCKTstatesCircularBuffer (CKTcircuit *) ;
int cuCKTstate123copy (CKTcircuit *) ;
int cuBSIM4v7destroy (GENmodel *) ;
int cuBSIM4v7getic (GENmodel *) ;
int cuBSIM4v7load (GENmodel *, CKTcircuit *) ;
int cuBSIM4v7setup (GENmodel *) ;
int cuBSIM4v7temp (GENmodel *) ;
int cuCAPdestroy (GENmodel *) ;
int cuCAPgetic (GENmodel *) ;
int cuCAPload (GENmodel *, CKTcircuit *) ;
int cuCAPsetup (GENmodel *) ;
int cuCAPtemp (GENmodel *) ;
int cuINDdestroy (GENmodel *) ;
int cuINDload (GENmodel *, CKTcircuit *) ;
int cuINDsetup (GENmodel *) ;
int cuINDtemp (GENmodel *) ;
int cuISRCdestroy (GENmodel *) ;
int cuISRCload (GENmodel *, CKTcircuit *) ;
int cuISRCsetup (GENmodel *) ;
int cuISRCtemp (GENmodel *) ;
int cuMUTdestroy (GENmodel *) ;
int cuMUTload (GENmodel *, CKTcircuit *) ;
int cuMUTsetup (GENmodel *) ;
int cuMUTtemp (GENmodel *) ;
int cuRESdestroy (GENmodel *) ;
int cuRESload (GENmodel *, CKTcircuit *) ;
int cuRESsetup (GENmodel *) ;
int cuREStemp (GENmodel *) ;
int cuVSRCdestroy (GENmodel *) ;
int cuVSRCload (GENmodel *, CKTcircuit *) ;
int cuVSRCsetup (GENmodel *) ;
int cuVSRCtemp (GENmodel *) ;

View File

@ -0,0 +1,36 @@
#include <stdio.h>
#include "ngspice/sperror.h"
extern "C"
__device__
static
int
cuNIintegrate_device_kernel
(
double *CKTstate_0, double *CKTstate_1, double *geq, double *ceq,
double value, int charge, double CKTag_0, double CKTag_1, int CKTorder
)
{
#define current charge+1
switch (CKTorder)
{
case 1:
CKTstate_0 [current] = CKTag_0 * (CKTstate_0 [charge]) + CKTag_1 * (CKTstate_1 [charge]) ;
break ;
case 2:
CKTstate_0 [current] = -CKTstate_1 [current] * CKTag_1 + CKTag_0 * (CKTstate_0 [charge] - CKTstate_1 [charge]) ;
break ;
default:
printf ("Error inside the integration formula\n") ;
return (E_ORDER) ;
}
*ceq = CKTstate_0 [current] - CKTag_0 * CKTstate_0 [charge] ;
*geq = CKTag_0 * value ;
return (OK) ;
}

View File

@ -2,7 +2,9 @@
#define ngspice_BOOL_H
//typedef unsigned char bool;
#ifndef COMPILED_BY_NVCC
typedef int bool;
#endif
typedef int BOOL ;

View File

@ -303,6 +303,45 @@ struct CKTcircuit {
#ifdef KLU
unsigned int CKTkluMODE:1;
#endif
#ifdef USE_CUSPICE
double *(d_CKTstates[8]);
#define d_CKTstate0 d_CKTstates[0]
#define d_CKTstate1 d_CKTstates[1]
#define d_CKTstate2 d_CKTstates[2]
#define d_CKTstate3 d_CKTstates[3]
#define d_CKTstate4 d_CKTstates[4]
#define d_CKTstate5 d_CKTstates[5]
#define d_CKTstate6 d_CKTstates[6]
#define d_CKTstate7 d_CKTstates[7]
double *d_CKTrhsOld;
int *d_CKTnoncon;
int d_MatrixSize;
int CKTdiagElements;
int total_n_values;
int total_n_Ptr;
double *d_CKTloadOutput;
int *CKTtopologyMatrixCOOi;
int *CKTtopologyMatrixCOOj;
double *CKTtopologyMatrixCOOx;
int *CKTtopologyMatrixCSRp;
int *d_CKTtopologyMatrixCSRp;
int *d_CKTtopologyMatrixCSRj;
double *d_CKTtopologyMatrixCSRx;
int total_n_valuesRHS;
int total_n_PtrRHS;
double *d_CKTloadOutputRHS;
int *CKTtopologyMatrixCOOiRHS;
int *CKTtopologyMatrixCOOjRHS;
double *CKTtopologyMatrixCOOxRHS;
int *CKTtopologyMatrixCSRpRHS;
int *d_CKTtopologyMatrixCSRpRHS;
int *d_CKTtopologyMatrixCSRjRHS;
double *d_CKTtopologyMatrixCSRxRHS;
#endif
};

View File

@ -123,6 +123,13 @@ typedef struct SPICEdev {
/* routine to convert Complex CSC array to Real CSC array */
#endif
#ifdef USE_CUSPICE
int (*cuDEVdestroy)(GENmodel *) ;
/* routine to Destroy the CUSPICE allocations */
int (*DEVtopology)(GENmodel *, CKTcircuit *, int *, int *) ;
/* routine to create the Topology Matrix */
#endif
} SPICEdev; /* instance of structure for each possible type of device */

View File

@ -49,6 +49,14 @@ typedef struct sSMPmatrix {
#define CKTkluOFF 0 /* KLU MODE OFF definition */
#endif
#ifdef USE_CUSPICE
double *d_CKTkluAx ;
double *d_CKTrhs ;
void *CKTcsrmvHandle ;
void *CKTcsrmvDescr ;
#endif
} SMPmatrix ;

View File

@ -0,0 +1,58 @@
#!/usr/bin/tclsh
if {$argc == 0} {
puts "Usage: 'libtool_wrapper_for_cuda.tcl' 'filename' 'compilation line'"
exit 1
}
# Rename object file .lo in .o
set filename_lo [lindex $argv 0]
set filename_o [file rootname $filename_lo].o
# Determine where the object file has to be created and the NVCC compilation command
if {[lindex $argv 1] == "-static"} {
set filename $filename_o
set command [lrange $argv 2 end]
append command " -o $filename"
} else {
file mkdir .libs
set filename ".libs/${filename_o}"
set command [lrange $argv 2 end]
append command " -Xcompiler -fPIC"
append command " -o $filename"
}
# Compile
exec /bin/sh -c $command
# Determine the libtool version (including compiler version)
catch {exec libtool --help} output
set output [split $output "\n"]
foreach elem $output {
if {[regexp -- {libtool:\t(.+)$} $elem -> version]} {
break
}
}
# Generate the .lo libtool object file
set fid [open $filename_lo w]
puts $fid "# $filename_lo - a libtool object file"
puts $fid "# Generated by libtool $version"
puts $fid "#"
puts $fid "# Please DO NOT delete this file!"
puts $fid "# It is necessary for linking the library."
puts $fid ""
if {[lindex $argv 1] == "-static"} {
puts $fid "# Name of the PIC object."
puts $fid "pic_object=none"
puts $fid ""
puts $fid "# Name of the non-PIC object"
puts $fid "non_pic_object='[file tail $filename]'"
} else {
puts $fid "# Name of the PIC object."
puts $fid "pic_object='[file tail $filename]'"
puts $fid ""
puts $fid "# Name of the non-PIC object"
puts $fid "non_pic_object=none"
}
close $fid

View File

@ -50,6 +50,13 @@ NIinit(CKTcircuit *ckt)
klu_defaults (ckt->CKTmatrix->CKTkluCommon) ;
#endif
#ifdef USE_CUSPICE
ckt->CKTmatrix->d_CKTkluAx = NULL ;
ckt->CKTmatrix->d_CKTrhs = NULL ;
ckt->CKTmatrix->CKTcsrmvHandle = NULL ;
ckt->CKTmatrix->CKTcsrmvDescr = NULL ;
#endif
ckt->CKTniState = NIUNINITIALIZED;
return SMPnewMatrix(ckt->CKTmatrix, 0);
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "ngspice/cktdefs.h"
#include "ngspice/sperror.h"
#include "cuda_runtime_api.h"
#include "ngspice/CUSPICE/CUSPICE.h"
int
cuCKTflush
(
CKTcircuit *ckt
)
{
long unsigned int m, mRHS ;
m = (long unsigned int)(ckt->total_n_values + 1) ; // + 1 because of CKTdiagGmin
mRHS = (long unsigned int)ckt->total_n_valuesRHS ;
/* Clean-up the CKTloadOutput */
cudaMemset (ckt->d_CKTloadOutput, 0, m * sizeof(double)) ;
/* Clean-up the CKTloadOutputRHS */
cudaMemset (ckt->d_CKTloadOutputRHS, 0, mRHS * sizeof(double)) ;
return (OK) ;
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "ngspice/cktdefs.h"
#include "ngspice/sperror.h"
#include "cuda_runtime_api.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuCKTnonconUpdate routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuCKTnonconUpdateHtoD
(
CKTcircuit *ckt
)
{
cudaError_t status ;
status = cudaMemcpy (ckt->d_CKTnoncon, &(ckt->CKTnoncon), sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (ckt->d_CKTnoncon, 1, int, status)
return (OK) ;
}
int
cuCKTnonconUpdateDtoH
(
CKTcircuit *ckt
)
{
cudaError_t status ;
status = cudaMemcpy (&(ckt->CKTnoncon), ckt->d_CKTnoncon, sizeof(int), cudaMemcpyDeviceToHost) ;
CUDAMEMCPYCHECK (&(ckt->CKTnoncon), 1, int, status)
return (OK) ;
}

View File

@ -0,0 +1,86 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "ngspice/cktdefs.h"
#include "ngspice/sperror.h"
#include "cuda_runtime_api.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuCKTrhsOldUpdate routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuCKTrhsOldFlush
(
CKTcircuit *ckt
)
{
long unsigned int size ;
size = (long unsigned int)(ckt->d_MatrixSize + 1) ;
cudaMemset (ckt->d_CKTrhsOld, 0, size * sizeof(double)) ;
return (OK) ;
}
int
cuCKTrhsOldUpdateHtoD
(
CKTcircuit *ckt
)
{
long unsigned int size ;
cudaError_t status ;
size = (long unsigned int)(ckt->d_MatrixSize + 1) ;
status = cudaMemcpy (ckt->d_CKTrhsOld, ckt->CKTrhsOld, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (ckt->d_CKTrhsOld, size, double, status)
return (OK) ;
}
int
cuCKTrhsOldUpdateDtoH
(
CKTcircuit *ckt
)
{
long unsigned int size ;
cudaError_t status ;
size = (long unsigned int)(ckt->d_MatrixSize + 1) ;
status = cudaMemcpy (ckt->CKTrhsOld, ckt->d_CKTrhsOld, size * sizeof(double), cudaMemcpyDeviceToHost) ;
CUDAMEMCPYCHECK (ckt->CKTrhsOld, size, double, status)
return (OK) ;
}

View File

@ -0,0 +1,145 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "ngspice/cktdefs.h"
#include "ngspice/sperror.h"
#include "cuda_runtime_api.h"
#include "ngspice/CUSPICE/CUSPICE.h"
#define MAX(a,b) ((a) > (b) ? (a) : (b))
/* cudaMalloc MACRO to check it for errors --> CUDAMALLOCCHECK(name of pointer, dimension, type, status) */
#define CUDAMALLOCCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuCKTsetup routine...\n") ; \
fprintf (stderr, "Error: cudaMalloc failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuCKTsetup routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuCKTsetup
(
CKTcircuit *ckt
)
{
int i ;
long unsigned int m, mRHS, n, nz, TopologyNNZ, TopologyNNZRHS, size1, size2 ;
cudaError_t status ;
n = (long unsigned int)ckt->CKTmatrix->CKTkluN ;
nz = (long unsigned int)ckt->CKTmatrix->CKTklunz ;
m = (long unsigned int)(ckt->total_n_values + 1) ; // + 1 because of CKTdiagGmin
TopologyNNZ = (long unsigned int)(ckt->total_n_Ptr + ckt->CKTdiagElements) ; // + n because of CKTdiagGmin
// without the zeroes along the diagonal
mRHS = (long unsigned int)ckt->total_n_valuesRHS ;
TopologyNNZRHS = (long unsigned int)ckt->total_n_PtrRHS ;
size1 = (long unsigned int)(ckt->d_MatrixSize + 1) ;
size2 = (long unsigned int)ckt->CKTnumStates ;
/* Topology Matrix Handling */
status = cudaMalloc ((void **)&(ckt->CKTmatrix->d_CKTrhs), (n + 1) * sizeof(double)) ;
CUDAMALLOCCHECK (ckt->CKTmatrix->d_CKTrhs, (n + 1), double, status)
status = cudaMalloc ((void **)&(ckt->CKTmatrix->d_CKTkluAx), nz * sizeof(double)) ;
CUDAMALLOCCHECK (ckt->CKTmatrix->d_CKTkluAx, nz, double, status)
status = cudaMalloc ((void **)&(ckt->d_CKTloadOutput), m * sizeof(double)) ;
CUDAMALLOCCHECK (ckt->d_CKTloadOutput, m, double, status)
status = cudaMalloc ((void **)&(ckt->d_CKTloadOutputRHS), mRHS * sizeof(double)) ;
CUDAMALLOCCHECK (ckt->d_CKTloadOutputRHS, mRHS, double, status)
status = cudaMalloc ((void **)&(ckt->d_CKTtopologyMatrixCSRp), (nz + 1) * sizeof(int)) ;
CUDAMALLOCCHECK (ckt->d_CKTtopologyMatrixCSRp, (nz + 1), int, status)
status = cudaMalloc ((void **)&(ckt->d_CKTtopologyMatrixCSRj), TopologyNNZ * sizeof(int)) ;
CUDAMALLOCCHECK (ckt->d_CKTtopologyMatrixCSRj, TopologyNNZ, int, status)
status = cudaMalloc ((void **)&(ckt->d_CKTtopologyMatrixCSRx), TopologyNNZ * sizeof(double)) ;
CUDAMALLOCCHECK (ckt->d_CKTtopologyMatrixCSRx, TopologyNNZ, double, status)
status = cudaMalloc ((void **)&(ckt->d_CKTtopologyMatrixCSRpRHS), ((n + 1) + 1) * sizeof(int)) ;
CUDAMALLOCCHECK (ckt->d_CKTtopologyMatrixCSRpRHS, ((n + 1) + 1), int, status)
status = cudaMalloc ((void **)&(ckt->d_CKTtopologyMatrixCSRjRHS), TopologyNNZRHS * sizeof(int)) ;
CUDAMALLOCCHECK (ckt->d_CKTtopologyMatrixCSRjRHS, TopologyNNZRHS, int, status)
status = cudaMalloc ((void **)&(ckt->d_CKTtopologyMatrixCSRxRHS), TopologyNNZRHS * sizeof(double)) ;
CUDAMALLOCCHECK (ckt->d_CKTtopologyMatrixCSRxRHS, TopologyNNZRHS, double, status)
cudaMemset (ckt->d_CKTloadOutput + ckt->total_n_values, 0, sizeof(double)) ; //DiagGmin is 0 at the beginning
status = cudaMemcpy (ckt->d_CKTtopologyMatrixCSRp, ckt->CKTtopologyMatrixCSRp, (nz + 1) * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (ckt->d_CKTtopologyMatrixCSRp, (nz + 1), int, status)
status = cudaMemcpy (ckt->d_CKTtopologyMatrixCSRj, ckt->CKTtopologyMatrixCOOj, TopologyNNZ * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (ckt->d_CKTtopologyMatrixCSRj, TopologyNNZ, int, status)
status = cudaMemcpy (ckt->d_CKTtopologyMatrixCSRx, ckt->CKTtopologyMatrixCOOx, TopologyNNZ * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (ckt->d_CKTtopologyMatrixCSRx, TopologyNNZ, double, status)
status = cudaMemcpy (ckt->d_CKTtopologyMatrixCSRpRHS, ckt->CKTtopologyMatrixCSRpRHS, ((n + 1) + 1) * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (ckt->d_CKTtopologyMatrixCSRpRHS, ((n + 1) + 1), int, status)
status = cudaMemcpy (ckt->d_CKTtopologyMatrixCSRjRHS, ckt->CKTtopologyMatrixCOOjRHS, TopologyNNZRHS * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (ckt->d_CKTtopologyMatrixCSRjRHS, TopologyNNZRHS, int, status)
status = cudaMemcpy (ckt->d_CKTtopologyMatrixCSRxRHS, ckt->CKTtopologyMatrixCOOxRHS, TopologyNNZRHS * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (ckt->d_CKTtopologyMatrixCSRxRHS, TopologyNNZRHS, double, status)
/* ------------------------ */
status = cudaMalloc ((void **)&(ckt->d_CKTnoncon), sizeof(int)) ;
CUDAMALLOCCHECK (ckt->d_CKTnoncon, 1, int, status)
status = cudaMalloc ((void **)&(ckt->d_CKTrhsOld), size1 * sizeof(double)) ;
CUDAMALLOCCHECK (ckt->d_CKTrhsOld, size1, double, status)
for (i = 0 ; i <= MAX (2, ckt->CKTmaxOrder) + 1 ; i++) /* dctran needs 3 states at least */
{
status = cudaMalloc ((void **)&(ckt->d_CKTstates[i]), size2 * sizeof(double)) ;
CUDAMALLOCCHECK (ckt->d_CKTstates[i], size2, double, status)
}
return (OK) ;
}

View File

@ -0,0 +1,164 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "ngspice/cktdefs.h"
#include "ngspice/sperror.h"
#include "cuda_runtime_api.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuCKTstatesUpdate routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuCKTstatesUpdateDtoH
(
CKTcircuit *ckt
)
{
int i ;
long unsigned int size ;
cudaError_t status ;
size = (long unsigned int)ckt->CKTnumStates ;
for (i = 0 ; i < 8 ; i++)
{
if (ckt->CKTstates[i] != NULL)
{
status = cudaMemcpy (ckt->CKTstates[i], ckt->d_CKTstates[i], size * sizeof(double), cudaMemcpyDeviceToHost) ;
CUDAMEMCPYCHECK (ckt->CKTstates[i], size, double, status)
}
}
return (OK) ;
}
int
cuCKTstatesFlush
(
CKTcircuit *ckt
)
{
long unsigned int size ;
size = (long unsigned int)ckt->CKTnumStates ;
cudaMemset (ckt->d_CKTstate0, 0, size * sizeof(double)) ;
return (OK) ;
}
int
cuCKTstate0UpdateHtoD
(
CKTcircuit *ckt
)
{
long unsigned int size ;
cudaError_t status ;
size = (long unsigned int)ckt->CKTnumStates ;
status = cudaMemcpy (ckt->d_CKTstate0, ckt->CKTstate0, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (ckt->d_CKTstate0, size, double, status)
return (OK) ;
}
int
cuCKTstate0UpdateDtoH
(
CKTcircuit *ckt
)
{
long unsigned int size ;
cudaError_t status ;
size = (long unsigned int)ckt->CKTnumStates ;
status = cudaMemcpy (ckt->CKTstate0, ckt->d_CKTstate0, size * sizeof(double), cudaMemcpyDeviceToHost) ;
CUDAMEMCPYCHECK (ckt->CKTstate0, size, double, status)
return (OK) ;
}
int
cuCKTstate01copy
(
CKTcircuit *ckt
)
{
long unsigned int size ;
cudaError_t status ;
size = (long unsigned int)ckt->CKTnumStates ;
status = cudaMemcpy (ckt->d_CKTstate1, ckt->d_CKTstate0, size * sizeof(double), cudaMemcpyDeviceToDevice) ;
CUDAMEMCPYCHECK (ckt->d_CKTstate1, size, double, status)
return (OK) ;
}
int
cuCKTstatesCircularBuffer
(
CKTcircuit *ckt
)
{
int i ;
double *temp ;
temp = ckt->d_CKTstates [ckt->CKTmaxOrder + 1] ;
for (i = ckt->CKTmaxOrder ; i >= 0 ; i--)
ckt->d_CKTstates [i + 1] = ckt->d_CKTstates [i] ;
ckt->d_CKTstates [0] = temp ;
return (OK) ;
}
int
cuCKTstate123copy
(
CKTcircuit *ckt
)
{
long unsigned int size ;
cudaError_t status ;
size = (long unsigned int)ckt->CKTnumStates ;
status = cudaMemcpy (ckt->d_CKTstate2, ckt->d_CKTstate1, size * sizeof(double), cudaMemcpyDeviceToDevice) ;
CUDAMEMCPYCHECK (ckt->d_CKTstate2, size, double, status)
status = cudaMemcpy (ckt->d_CKTstate3, ckt->d_CKTstate1, size * sizeof(double), cudaMemcpyDeviceToDevice) ;
CUDAMEMCPYCHECK (ckt->d_CKTstate3, size, double, status)
return (OK) ;
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "ngspice/cktdefs.h"
#include "ngspice/sperror.h"
#include "cuda_runtime_api.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuCKTsystem routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuCKTsystemDtoH
(
CKTcircuit *ckt
)
{
long unsigned int nz, n ;
cudaError_t status ;
nz = (long unsigned int)ckt->CKTmatrix->CKTklunz ;
n = (long unsigned int)ckt->CKTmatrix->CKTkluN ;
/* Copy back the Matrix */
status = cudaMemcpy (ckt->CKTmatrix->CKTkluAx, ckt->CKTmatrix->d_CKTkluAx, nz * sizeof(double), cudaMemcpyDeviceToHost) ;
CUDAMEMCPYCHECK (ckt->CKTmatrix->CKTkluAx, nz, double, status)
/* Copy back the RHS */
status = cudaMemcpy (ckt->CKTrhs, ckt->CKTmatrix->d_CKTrhs, (n + 1) * sizeof(double), cudaMemcpyDeviceToHost) ;
CUDAMEMCPYCHECK (ckt->CKTrhs, (n + 1), double, status)
return (OK) ;
}

View File

@ -109,4 +109,19 @@ endif
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices
AM_CFLAGS = $(STATIC)
if USE_CUSPICE_WANTED
libckt_la_SOURCES += \
CUSPICE/cucktflush.c \
CUSPICE/cucktnonconupdate.c \
CUSPICE/cucktrhsoldupdate.c \
CUSPICE/cucktsetup.c \
CUSPICE/cucktstatesupdate.c \
CUSPICE/cucktsystem.c
AM_CPPFLAGS += $(CUDA_CPPFLAGS)
AM_LDFLAGS = $(CUDA_LIBS) -lcusparse
endif
MAINTAINERCLEANFILES = Makefile.in

View File

@ -40,6 +40,11 @@ CKTdestroy(CKTcircuit *ckt)
for (i = 0; i < DEVmaxnum; i++)
if (DEVices[i]) {
GENmodel *model = ckt->CKThead[i];
#warning "this needs to be reviewed, due to rebase onto newer master!"
#ifdef USE_CUSPICE
if (DEVices[i]->cuDEVdestroy && model)
DEVices[i]->cuDEVdestroy(model);
#endif
while (model) {
GENmodel *next_model = model->GENnextModel;
GENinstance *inst = model->GENinstances;

View File

@ -18,6 +18,23 @@ Modified: 2000 AlansFixes
#include "ngspice/devdefs.h"
#include "ngspice/sperror.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#include "cuda_runtime.h"
#include "cusparse_v2.h"
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuCKTload routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
#endif
#ifdef XSPICE
#include "ngspice/enh.h"
/* gtri - add - wbk - 11/26/90 - add include for MIF global data */
@ -30,8 +47,17 @@ static int ZeroNoncurRow(SMPmatrix *matrix, CKTnode *nodes, int rownum);
int
CKTload(CKTcircuit *ckt)
{
#ifdef USE_CUSPICE
cusparseStatus_t cusparseStatus ;
double alpha, beta ;
int status ;
alpha = 1.0 ;
beta = 0.0 ;
#else
int size ;
#endif
int i;
int size;
double startTime;
CKTnode *node;
int error;
@ -50,18 +76,43 @@ CKTload(CKTcircuit *ckt)
#endif
startTime = SPfrontEnd->IFseconds();
#ifdef USE_CUSPICE
status = cuCKTflush (ckt) ;
if (status != 0)
return (E_NOMEM) ;
#else
size = SMPmatSize(ckt->CKTmatrix);
for (i = 0; i <= size; i++) {
ckt->CKTrhs[i] = 0;
}
SMPclear(ckt->CKTmatrix);
#endif
#ifdef STEPDEBUG
noncon = ckt->CKTnoncon;
#endif /* STEPDEBUG */
#ifdef USE_CUSPICE
status = cuCKTnonconUpdateHtoD (ckt) ;
if (status != 0)
return (E_NOMEM) ;
status = cuCKTrhsOldUpdateHtoD (ckt) ;
if (status != 0)
return (E_NOMEM) ;
#endif
for (i = 0; i < DEVmaxnum; i++) {
if (DEVices[i] && DEVices[i]->DEVload && ckt->CKThead[i]) {
error = DEVices[i]->DEVload (ckt->CKThead[i], ckt);
#ifdef USE_CUSPICE
status = cuCKTnonconUpdateDtoH (ckt) ;
if (status != 0)
return (E_NOMEM) ;
#endif
if (ckt->CKTnoncon)
ckt->CKTtroubleNode = 0;
#ifdef STEPDEBUG
@ -75,6 +126,48 @@ CKTload(CKTcircuit *ckt)
}
}
#ifdef USE_CUSPICE
/* Copy the CKTdiagGmin value to the GPU */
status = cudaMemcpy (ckt->d_CKTloadOutput + ckt->total_n_values, &(ckt->CKTdiagGmin), sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (ckt->d_CKTloadOutput + ckt->total_n_values, 1, double, status)
/* Performing CSRMV for the Sparse Matrix using CUSPARSE */
cusparseStatus = cusparseDcsrmv ((cusparseHandle_t)(ckt->CKTmatrix->CKTcsrmvHandle),
CUSPARSE_OPERATION_NON_TRANSPOSE,
ckt->CKTmatrix->CKTklunz, ckt->total_n_values + 1,
ckt->total_n_Ptr + ckt->CKTdiagElements,
&alpha, (cusparseMatDescr_t)(ckt->CKTmatrix->CKTcsrmvDescr),
ckt->d_CKTtopologyMatrixCSRx, ckt->d_CKTtopologyMatrixCSRp,
ckt->d_CKTtopologyMatrixCSRj, ckt->d_CKTloadOutput, &beta,
ckt->CKTmatrix->d_CKTkluAx) ;
if (cusparseStatus != CUSPARSE_STATUS_SUCCESS)
{
fprintf (stderr, "CUSPARSE MATRIX Call Error\n") ;
return (E_NOMEM) ;
}
/* Performing CSRMV for the RHS using CUSPARSE */
cusparseStatus = cusparseDcsrmv ((cusparseHandle_t)(ckt->CKTmatrix->CKTcsrmvHandle),
CUSPARSE_OPERATION_NON_TRANSPOSE,
ckt->CKTmatrix->CKTkluN + 1, ckt->total_n_valuesRHS, ckt->total_n_PtrRHS,
&alpha, (cusparseMatDescr_t)(ckt->CKTmatrix->CKTcsrmvDescr),
ckt->d_CKTtopologyMatrixCSRxRHS, ckt->d_CKTtopologyMatrixCSRpRHS,
ckt->d_CKTtopologyMatrixCSRjRHS, ckt->d_CKTloadOutputRHS, &beta,
ckt->CKTmatrix->d_CKTrhs) ;
if (cusparseStatus != CUSPARSE_STATUS_SUCCESS)
{
fprintf (stderr, "CUSPARSE RHS Call Error\n") ;
return (E_NOMEM) ;
}
cudaDeviceSynchronize () ;
status = cuCKTsystemDtoH (ckt) ;
if (status != 0)
return (E_NOMEM) ;
#endif
#ifdef XSPICE
/* gtri - add - wbk - 11/26/90 - reset the MIF init flags */

View File

@ -20,6 +20,10 @@ static int spice3_gmin(CKTcircuit *, long int, long int, int);
static int gillespie_src(CKTcircuit *, long int, long int, int);
static int spice3_src(CKTcircuit *, long int, long int, int);
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
int
CKTop (CKTcircuit *ckt, long int firstmode, long int continuemode,
@ -127,6 +131,10 @@ static int
dynamic_gmin (CKTcircuit *ckt, long int firstmode,
long int continuemode, int iterlim)
{
#ifdef USE_CUSPICE
int status ;
#endif
double OldGmin, gtarget, factor;
int converged;
@ -150,6 +158,12 @@ dynamic_gmin (CKTcircuit *ckt, long int firstmode,
for (i = 0; i < ckt->CKTnumStates; i++)
ckt->CKTstate0 [i] = 0;
#ifdef USE_CUSPICE
status = cuCKTstatesFlush (ckt) ;
if (status != 0)
return (E_NOMEM) ;
#endif
factor = ckt->CKTgminFactor;
OldGmin = 1e-2;
ckt->CKTdiagGmin = OldGmin / factor;
@ -173,6 +187,12 @@ dynamic_gmin (CKTcircuit *ckt, long int firstmode,
for (i = 0, n = ckt->CKTnodes; n; n = n->next)
OldRhsOld[i++] = ckt->CKTrhsOld[n->number];
#ifdef USE_CUSPICE
status = cuCKTstate0UpdateDtoH (ckt) ;
if (status != 0)
return (E_NOMEM) ;
#endif
memcpy(OldCKTstate0, ckt->CKTstate0,
(size_t) ckt->CKTnumStates * sizeof(double));
@ -207,6 +227,13 @@ dynamic_gmin (CKTcircuit *ckt, long int firstmode,
memcpy(ckt->CKTstate0, OldCKTstate0,
(size_t) ckt->CKTnumStates * sizeof(double));
#ifdef USE_CUSPICE
status = cuCKTstate0UpdateHtoD (ckt) ;
if (status != 0)
return (E_NOMEM) ;
#endif
}
}
@ -320,6 +347,10 @@ static int
gillespie_src (CKTcircuit *ckt, long int firstmode,
long int continuemode, int iterlim)
{
#ifdef USE_CUSPICE
int status ;
#endif
int converged, i, iters;
double ConvFact;
CKTnode *n;
@ -338,6 +369,12 @@ gillespie_src (CKTcircuit *ckt, long int firstmode,
for (i = 0; i < ckt->CKTnumStates; i++)
ckt->CKTstate0[i] = 0;
#ifdef USE_CUSPICE
status = cuCKTstatesFlush (ckt) ;
if (status != 0)
return (E_NOMEM) ;
#endif
/* First, try a straight solution with all sources at zero */
fprintf (stderr, "Supplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
@ -398,6 +435,12 @@ gillespie_src (CKTcircuit *ckt, long int firstmode,
for (i = 0, n = ckt->CKTnodes; n; n = n->next)
OldRhsOld[i++] = ckt->CKTrhsOld[n->number];
#ifdef USE_CUSPICE
status = cuCKTstate0UpdateDtoH (ckt) ;
if (status != 0)
return (E_NOMEM) ;
#endif
memcpy(OldCKTstate0, ckt->CKTstate0,
(size_t) ckt->CKTnumStates * sizeof(double));
@ -425,6 +468,12 @@ gillespie_src (CKTcircuit *ckt, long int firstmode,
for (i = 0, n = ckt->CKTnodes; n; n = n->next)
OldRhsOld[i++] = ckt->CKTrhsOld[n->number];
#ifdef USE_CUSPICE
status = cuCKTstate0UpdateDtoH (ckt) ;
if (status != 0)
return (E_NOMEM) ;
#endif
memcpy(OldCKTstate0, ckt->CKTstate0,
(size_t) ckt->CKTnumStates * sizeof(double));
@ -460,6 +509,12 @@ gillespie_src (CKTcircuit *ckt, long int firstmode,
memcpy(ckt->CKTstate0, OldCKTstate0,
(size_t) ckt->CKTnumStates * sizeof(double));
#ifdef USE_CUSPICE
status = cuCKTstate0UpdateHtoD (ckt) ;
if (status != 0)
return (E_NOMEM) ;
#endif
}
if (ckt->CKTsrcFact > 1)

View File

@ -19,6 +19,11 @@ Author: 1985 Thomas L. Quarles
#include "ngspice/enh.h"
#endif
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#include "cusparse_v2.h"
#endif
#ifdef USE_OMP
#include <omp.h>
#include "ngspice/cpextern.h"
@ -45,9 +50,62 @@ BindCompare (const void *a, const void *b)
}
#endif
#ifdef USE_CUSPICE
typedef struct sElement {
int row ;
int col ;
double val ;
} Element ;
static
int
Compare (const void *a, const void *b)
{
Element *A, *B ;
A = (Element *)a ;
B = (Element *)b ;
return (A->row - B->row) ;
}
static
int
Compress (int *Ai, int *Bp, int num_rows, int n_COO)
{
int i, j ;
for (i = 0 ; i <= Ai [0] ; i++)
Bp [i] = 0 ;
j = Ai [0] + 1 ;
for (i = 1 ; i < n_COO ; i++)
{
if (Ai [i] == Ai [i - 1] + 1)
{
Bp [j] = i ;
j++ ;
}
else if (Ai [i] > Ai [i - 1] + 1)
{
for ( ; j <= Ai [i] ; j++)
Bp [j] = i ;
}
}
for ( ; j <= num_rows ; j++)
Bp [j] = i ;
return 0 ;
}
#endif
int
CKTsetup(CKTcircuit *ckt)
{
#ifdef USE_CUSPICE
int status ;
cusparseStatus_t cusparseStatus ;
#endif
int i;
int error;
#ifdef XSPICE
@ -143,6 +201,124 @@ CKTsetup(CKTcircuit *ckt)
DEVices [i]->DEVbindCSC (ckt->CKThead [i], ckt) ;
ckt->CKTmatrix->CKTkluMatrixIsComplex = CKTkluMatrixReal ;
#ifdef USE_CUSPICE
fprintf (stderr, "Using CUSPICE (NGSPICE on CUDA Platforms)\n") ;
/* In the DEVsetup the Position Vectors must be assigned and copied to the GPU */
int j, k, u, TopologyNNZ ;
int uRHS, TopologyNNZRHS ;
int ret ;
/* CKTloadOutput Vector allocation - DIRECTLY in the GPU memory */
/* CKTloadOutput for the RHS Vector allocation - DIRECTLY in the GPU memory */
/* Diagonal Elements Counting */
j = 0 ;
for (i = 0 ; i < n ; i++)
if (ckt->CKTmatrix->CKTdiag_CSC [i] != NULL)
j++ ;
ckt->CKTdiagElements = j ;
/* Topology Matrix Pre-Allocation in COO format */
TopologyNNZ = ckt->total_n_Ptr + ckt->CKTdiagElements ; // + ckt->CKTdiagElements because of CKTdiagGmin
// without the zeroes along the diagonal
ckt->CKTtopologyMatrixCOOi = TMALLOC (int, TopologyNNZ) ;
ckt->CKTtopologyMatrixCOOj = TMALLOC (int, TopologyNNZ) ;
ckt->CKTtopologyMatrixCOOx = TMALLOC (double, TopologyNNZ) ;
/* Topology Matrix for the RHS Pre-Allocation in COO format */
TopologyNNZRHS = ckt->total_n_PtrRHS ;
ckt->CKTtopologyMatrixCOOiRHS = TMALLOC (int, TopologyNNZRHS) ;
ckt->CKTtopologyMatrixCOOjRHS = TMALLOC (int, TopologyNNZRHS) ;
ckt->CKTtopologyMatrixCOOxRHS = TMALLOC (double, TopologyNNZRHS) ;
/* Topology Matrix Pre-Allocation in CSR format */
ckt->CKTtopologyMatrixCSRp = TMALLOC (int, nz + 1) ;
/* Topology Matrix for the RHS Pre-Allocation in CSR format */
ckt->CKTtopologyMatrixCSRpRHS = TMALLOC (int, (n + 1) + 1) ;
/* Topology Matrix Construction & Topology Matrix for the RHS Construction */
u = 0 ;
uRHS = 0 ;
for (i = 0 ; i < DEVmaxnum ; i++)
if (DEVices [i] && DEVices [i]->DEVtopology && ckt->CKThead [i])
DEVices [i]->DEVtopology (ckt->CKThead [i], ckt, &u, &uRHS) ;
/* CKTdiagGmin Contribute Addition to the Topology Matrix */
k = u ;
for (j = 0 ; j < n ; j++)
{
if (ckt->CKTmatrix->CKTdiag_CSC [j] >= ckt->CKTmatrix->CKTkluAx)
{
ckt->CKTtopologyMatrixCOOi [k] = (int)(ckt->CKTmatrix->CKTdiag_CSC [j] - ckt->CKTmatrix->CKTkluAx) ;
ckt->CKTtopologyMatrixCOOj [k] = ckt->total_n_values ;
ckt->CKTtopologyMatrixCOOx [k] = 1 ;
k++ ;
}
}
/* Copy the Topology Matrix to the GPU in COO format */
/* COO format to CSR format Conversion using Quick Sort */
Element *TopologyStruct ;
TopologyStruct = TMALLOC (Element, TopologyNNZ) ;
for (i = 0 ; i < TopologyNNZ ; i++)
{
TopologyStruct [i].row = ckt->CKTtopologyMatrixCOOi [i] ;
TopologyStruct [i].col = ckt->CKTtopologyMatrixCOOj [i] ;
TopologyStruct [i].val = ckt->CKTtopologyMatrixCOOx [i] ;
}
qsort (TopologyStruct, (size_t)TopologyNNZ, sizeof(Element), Compare) ;
for (i = 0 ; i < TopologyNNZ ; i++)
{
ckt->CKTtopologyMatrixCOOi [i] = TopologyStruct [i].row ;
ckt->CKTtopologyMatrixCOOj [i] = TopologyStruct [i].col ;
ckt->CKTtopologyMatrixCOOx [i] = TopologyStruct [i].val ;
}
ret = Compress (ckt->CKTtopologyMatrixCOOi, ckt->CKTtopologyMatrixCSRp, nz, TopologyNNZ) ;
/* COO format to CSR format Conversion for the RHS using Quick Sort */
Element *TopologyStructRHS ;
TopologyStructRHS = TMALLOC (Element, TopologyNNZRHS) ;
for (i = 0 ; i < TopologyNNZRHS ; i++)
{
TopologyStructRHS [i].row = ckt->CKTtopologyMatrixCOOiRHS [i] ;
TopologyStructRHS [i].col = ckt->CKTtopologyMatrixCOOjRHS [i] ;
TopologyStructRHS [i].val = ckt->CKTtopologyMatrixCOOxRHS [i] ;
}
qsort (TopologyStructRHS, (size_t)TopologyNNZRHS, sizeof(Element), Compare) ;
for (i = 0 ; i < TopologyNNZRHS ; i++)
{
ckt->CKTtopologyMatrixCOOiRHS [i] = TopologyStructRHS [i].row ;
ckt->CKTtopologyMatrixCOOjRHS [i] = TopologyStructRHS [i].col ;
ckt->CKTtopologyMatrixCOOxRHS [i] = TopologyStructRHS [i].val ;
}
ret = Compress (ckt->CKTtopologyMatrixCOOiRHS, ckt->CKTtopologyMatrixCSRpRHS, n + 1, TopologyNNZRHS) ;
/* Multiply the Topology Matrix by the M Vector to build the Final CSC Matrix - after the CKTload Call */
#endif
} else {
fprintf (stderr, "Using SPARSE 1.3 as Direct Linear Solver\n") ;
}
@ -151,6 +327,34 @@ CKTsetup(CKTcircuit *ckt)
for(i=0;i<=MAX(2,ckt->CKTmaxOrder)+1;i++) { /* dctran needs 3 states as minimum */
CKALLOC(ckt->CKTstates[i],ckt->CKTnumStates,double);
}
#ifdef USE_CUSPICE
ckt->d_MatrixSize = SMPmatSize (ckt->CKTmatrix) ;
status = cuCKTsetup (ckt) ;
if (status != 0)
return (E_NOMEM) ;
/* CUSPARSE Handle Creation */
cusparseStatus = cusparseCreate ((cusparseHandle_t *)(&(ckt->CKTmatrix->CKTcsrmvHandle))) ;
if (cusparseStatus != CUSPARSE_STATUS_SUCCESS)
{
fprintf (stderr, "CUSPARSE Handle Setup Error\n") ;
return (E_NOMEM) ;
}
/* CUSPARSE Matrix Descriptor Creation */
cusparseStatus = cusparseCreateMatDescr ((cusparseMatDescr_t *)(&(ckt->CKTmatrix->CKTcsrmvDescr))) ;
if (cusparseStatus != CUSPARSE_STATUS_SUCCESS)
{
fprintf (stderr, "CUSPARSE Matrix Descriptor Setup Error\n") ;
return (E_NOMEM) ;
}
/* CUSPARSE Matrix Properties Definition */
cusparseSetMatType ((cusparseMatDescr_t)(ckt->CKTmatrix->CKTcsrmvDescr), CUSPARSE_MATRIX_TYPE_GENERAL) ;
cusparseSetMatIndexBase ((cusparseMatDescr_t)(ckt->CKTmatrix->CKTcsrmvDescr), CUSPARSE_INDEX_BASE_ZERO) ;
#endif
#ifdef WANT_SENSE2
if(ckt->CKTsenInfo){
/* to allocate memory to sensitivity structures if

View File

@ -62,18 +62,27 @@ do { \
ckt->CKTstat->STATtranSyncTime += ckt->CKTstat->STATsyncTime - startkTime; \
} while(0)
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
int
DCtran(CKTcircuit *ckt,
int restart) /* forced restart flag */
{
#ifdef USE_CUSPICE
int status ;
#else
double *temp ;
#endif
TRANan *job = (TRANan *) ckt->CKTcurJob;
int i;
double olddelta;
double delta;
double newdelta;
double *temp;
double startdTime;
double startsTime;
double startlTime;
@ -340,8 +349,15 @@ DCtran(CKTcircuit *ckt,
ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODETRAN | MODEINITTRAN;
/* modeinittran set here */
ckt->CKTag[0]=ckt->CKTag[1]=0;
#ifdef USE_CUSPICE
status = cuCKTstate01copy (ckt) ;
if (status != 0)
return (E_NOMEM) ;
#else
memcpy(ckt->CKTstate1, ckt->CKTstate0,
(size_t) ckt->CKTnumStates * sizeof(double));
#endif
#ifdef WANT_SENSE2
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){
@ -705,11 +721,17 @@ resume:
ckt->CKTdeltaOld[i+1] = ckt->CKTdeltaOld[i];
ckt->CKTdeltaOld[0] = ckt->CKTdelta;
#ifdef USE_CUSPICE
status = cuCKTstatesCircularBuffer (ckt) ;
if (status != 0)
return (E_NOMEM) ;
#else
temp = ckt->CKTstates[ckt->CKTmaxOrder+1];
for(i=ckt->CKTmaxOrder;i>=0;i--) {
ckt->CKTstates[i+1] = ckt->CKTstates[i];
}
ckt->CKTstates[0] = temp;
#endif
/* 600 */
for (;;) {
@ -780,10 +802,18 @@ resume:
ckt->CKTstat->STATtimePts ++;
ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITPRED;
if(firsttime) {
#ifdef USE_CUSPICE
status = cuCKTstate123copy (ckt) ;
if (status != 0)
return (E_NOMEM) ;
#else
memcpy(ckt->CKTstate2, ckt->CKTstate1,
(size_t) ckt->CKTnumStates * sizeof(double));
memcpy(ckt->CKTstate3, ckt->CKTstate1,
(size_t) ckt->CKTnumStates * sizeof(double));
#endif
}
/* txl, cpl addition */
if (converged == 1111) {
@ -853,6 +883,13 @@ resume:
goto chkStep;
#endif
}
#ifdef USE_CUSPICE
status = cuCKTstatesUpdateDtoH (ckt) ;
if (status != 0)
return (E_NOMEM) ;
#endif
newdelta = ckt->CKTdelta;
error = CKTtrunc(ckt,&newdelta);
if(error) {

View File

@ -0,0 +1,844 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "bsim4v7def.h"
#include "ngspice/sperror.h"
#define TopologyMatrixInsert(Ptr, instance_ID, offset, Value, global_ID) \
ckt->CKTtopologyMatrixCOOi [global_ID] = (int)(here->Ptr - basePtr) ; \
ckt->CKTtopologyMatrixCOOj [global_ID] = model->PositionVector [instance_ID] + offset ; \
ckt->CKTtopologyMatrixCOOx [global_ID] = Value ;
#define TopologyMatrixInsertRHS(offset, instance_ID, offsetRHS, Value, global_ID) \
ckt->CKTtopologyMatrixCOOiRHS [global_ID] = here->offset ; \
ckt->CKTtopologyMatrixCOOjRHS [global_ID] = model->PositionVectorRHS [instance_ID] + offsetRHS ; \
ckt->CKTtopologyMatrixCOOxRHS [global_ID] = Value ;
int
BSIM4v7topology (GENmodel *inModel, CKTcircuit *ckt, int *i, int *j)
{
BSIM4v7model *model = (BSIM4v7model *)inModel ;
BSIM4v7instance *here ;
int k, total_offset, total_offsetRHS ;
double *basePtr ;
basePtr = ckt->CKTmatrix->CKTkluAx ;
/* loop through all the capacitor models */
for ( ; model != NULL ; model = BSIM4v7nextModel(model))
{
k = 0 ;
/* loop through all the instances of the model */
for (here = BSIM4v7instances(model); here != NULL ; here = BSIM4v7nextInstance(here))
{
total_offset = 0 ;
total_offsetRHS = 0 ;
/* For the Matrix */
if (here->BSIM4v7rgateMod == 1)
{
/* m * geltd */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7gNodeExt != 0))
{
TopologyMatrixInsert (BSIM4v7GEgePtr, k, 0, 1, *i) ;
(*i)++ ;
}
/* m * geltd */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7gNodeExt != 0))
{
TopologyMatrixInsert (BSIM4v7GPgePtr, k, 0, -1, *i) ;
(*i)++ ;
}
/* m * geltd */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GEgpPtr, k, 0, -1, *i) ;
(*i)++ ;
}
/* m * (gcggb + geltd - ggtg + gIgtotg) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GPgpPtr, k, 1, 1, *i) ;
(*i)++ ;
}
/* m * (gcgdb - ggtd + gIgtotd) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GPdpPtr, k, 2, 1, *i) ;
(*i)++ ;
}
/* m * (gcgsb - ggts + gIgtots) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GPspPtr, k, 3, 1, *i) ;
(*i)++ ;
}
/* m * (gcgbb - ggtb + gIgtotb) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GPbpPtr, k, 4, 1, *i) ;
(*i)++ ;
}
total_offset += 5 ;
}
else if (here->BSIM4v7rgateMod == 2)
{
/* m * gcrg */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7gNodeExt != 0))
{
TopologyMatrixInsert (BSIM4v7GEgePtr, k, 0, 1, *i) ;
(*i)++ ;
}
/* m * gcrgg */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GEgpPtr, k, 1, 1, *i) ;
(*i)++ ;
}
/* m * gcrgd */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GEdpPtr, k, 2, 1, *i) ;
(*i)++ ;
}
/* m * gcrgs */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GEspPtr, k, 3, 1, *i) ;
(*i)++ ;
}
/* m * gcrgb */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GEbpPtr, k, 4, 1, *i) ;
(*i)++ ;
}
/* m * gcrg */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7gNodeExt != 0))
{
TopologyMatrixInsert (BSIM4v7GPgePtr, k, 0, -1, *i) ;
(*i)++ ;
}
/* m * (gcggb - gcrgg - ggtg + gIgtotg) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GPgpPtr, k, 5, 1, *i) ;
(*i)++ ;
}
/* m * (gcgdb - gcrgd - ggtd + gIgtotd) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GPdpPtr, k, 6, 1, *i) ;
(*i)++ ;
}
/* m * (gcgsb - gcrgs - ggts + gIgtots) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GPspPtr, k, 7, 1, *i) ;
(*i)++ ;
}
/* m * (gcgbb - gcrgb - ggtb + gIgtotb) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GPbpPtr, k, 8, 1, *i) ;
(*i)++ ;
}
total_offset += 9 ;
}
else if (here->BSIM4v7rgateMod == 3)
{
/* m * geltd */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7gNodeExt != 0))
{
TopologyMatrixInsert (BSIM4v7GEgePtr, k, 0, 1, *i) ;
(*i)++ ;
}
/* m * geltd */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7gNodeMid != 0))
{
TopologyMatrixInsert (BSIM4v7GEgmPtr, k, 0, -1, *i) ;
(*i)++ ;
}
/* m * geltd */
if ((here->BSIM4v7gNodeMid != 0) && (here->BSIM4v7gNodeExt != 0))
{
TopologyMatrixInsert (BSIM4v7GMgePtr, k, 0, -1, *i) ;
(*i)++ ;
}
/* m * (geltd + gcrg + gcgmgmb) */
if ((here->BSIM4v7gNodeMid != 0) && (here->BSIM4v7gNodeMid != 0))
{
TopologyMatrixInsert (BSIM4v7GMgmPtr, k, 1, 1, *i) ;
(*i)++ ;
}
/* m * (gcrgd + gcgmdb) */
if ((here->BSIM4v7gNodeMid != 0) && (here->BSIM4v7dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GMdpPtr, k, 2, 1, *i) ;
(*i)++ ;
}
/* m * gcrgg */
if ((here->BSIM4v7gNodeMid != 0) && (here->BSIM4v7gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GMgpPtr, k, 3, 1, *i) ;
(*i)++ ;
}
/* m * (gcrgs + gcgmsb) */
if ((here->BSIM4v7gNodeMid != 0) && (here->BSIM4v7sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GMspPtr, k, 4, 1, *i) ;
(*i)++ ;
}
/* m * (gcrgb + gcgmbb) */
if ((here->BSIM4v7gNodeMid != 0) && (here->BSIM4v7bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GMbpPtr, k, 5, 1, *i) ;
(*i)++ ;
}
/* m * gcdgmb */
if ((here->BSIM4v7dNodePrime != 0) && (here->BSIM4v7gNodeMid != 0))
{
TopologyMatrixInsert (BSIM4v7DPgmPtr, k, 6, 1, *i) ;
(*i)++ ;
}
/* m * gcrg */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7gNodeMid != 0))
{
TopologyMatrixInsert (BSIM4v7GPgmPtr, k, 7, -1, *i) ;
(*i)++ ;
}
/* m * gcsgmb */
if ((here->BSIM4v7sNodePrime != 0) && (here->BSIM4v7gNodeMid != 0))
{
TopologyMatrixInsert (BSIM4v7SPgmPtr, k, 8, 1, *i) ;
(*i)++ ;
}
/* m * gcbgmb */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7gNodeMid != 0))
{
TopologyMatrixInsert (BSIM4v7BPgmPtr, k, 9, 1, *i) ;
(*i)++ ;
}
/* m * (gcggb - gcrgg - ggtg + gIgtotg) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GPgpPtr, k, 10, 1, *i) ;
(*i)++ ;
}
/* m * (gcgdb - gcrgd - ggtd + gIgtotd) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GPdpPtr, k, 11, 1, *i) ;
(*i)++ ;
}
/* m * (gcgsb - gcrgs - ggts + gIgtots) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GPspPtr, k, 12, 1, *i) ;
(*i)++ ;
}
/* m * (gcgbb - gcrgb - ggtb + gIgtotb) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GPbpPtr, k, 13, 1, *i) ;
(*i)++ ;
}
total_offset += 14 ;
} else {
/* m * (gcggb - ggtg + gIgtotg) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GPgpPtr, k, 0, 1, *i) ;
(*i)++ ;
}
/* m * (gcgdb - ggtd + gIgtotd) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GPdpPtr, k, 1, 1, *i) ;
(*i)++ ;
}
/* m * (gcgsb - ggts + gIgtots) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GPspPtr, k, 2, 1, *i) ;
(*i)++ ;
}
/* m * (gcgbb - ggtb + gIgtotb) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7GPbpPtr, k, 3, 1, *i) ;
(*i)++ ;
}
total_offset += 4 ;
}
if (model->BSIM4v7rdsMod)
{
/* m * gdtotg */
if ((here->BSIM4v7dNode != 0) && (here->BSIM4v7gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7DgpPtr, k, total_offset + 0, 1, *i) ;
(*i)++ ;
}
/* m * gdtots */
if ((here->BSIM4v7dNode != 0) && (here->BSIM4v7sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7DspPtr, k, total_offset + 1, 1, *i) ;
(*i)++ ;
}
/* m * gdtotb */
if ((here->BSIM4v7dNode != 0) && (here->BSIM4v7bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7DbpPtr, k, total_offset + 2, 1, *i) ;
(*i)++ ;
}
/* m * gstotd */
if ((here->BSIM4v7sNode != 0) && (here->BSIM4v7dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7SdpPtr, k, total_offset + 3, 1, *i) ;
(*i)++ ;
}
/* m * gstotg */
if ((here->BSIM4v7sNode != 0) && (here->BSIM4v7gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7SgpPtr, k, total_offset + 0, 1, *i) ;
(*i)++ ;
}
/* m * gstotb */
if ((here->BSIM4v7sNode != 0) && (here->BSIM4v7bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7SbpPtr, k, total_offset + 2, 1, *i) ;
(*i)++ ;
}
total_offset += 4 ;
}
/* m * (gdpr + here->BSIM4v7gds + here->BSIM4v7gbd + T1 * ddxpart_dVd -
gdtotd + RevSum + gcddb + gbdpdp + dxpart * ggtd - gIdtotd) + m * ggidld */
if ((here->BSIM4v7dNodePrime != 0) && (here->BSIM4v7dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7DPdpPtr, k, total_offset + 0, 1, *i) ;
(*i)++ ;
}
/* m * (gdpr + gdtot) */
if ((here->BSIM4v7dNodePrime != 0) && (here->BSIM4v7dNode != 0))
{
TopologyMatrixInsert (BSIM4v7DPdPtr, k, total_offset + 1, -1, *i) ;
(*i)++ ;
}
/* m * (Gm + gcdgb - gdtotg + gbdpg - gIdtotg + dxpart * ggtg + T1 * ddxpart_dVg) + m * ggidlg */
if ((here->BSIM4v7dNodePrime != 0) && (here->BSIM4v7gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7DPgpPtr, k, total_offset + 2, 1, *i) ;
(*i)++ ;
}
/* m * (here->BSIM4v7gds + gdtots - dxpart * ggts + gIdtots -
T1 * ddxpart_dVs + FwdSum - gcdsb - gbdpsp) + m * (ggidlg + ggidld + ggidlb) */
if ((here->BSIM4v7dNodePrime != 0) && (here->BSIM4v7sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7DPspPtr, k, total_offset + 3, -1, *i) ;
(*i)++ ;
}
/* m * (gjbd + gdtotb - Gmbs - gcdbb - gbdpb + gIdtotb - T1 * ddxpart_dVb - dxpart * ggtb) - m * ggidlb */
if ((here->BSIM4v7dNodePrime != 0) && (here->BSIM4v7bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7DPbpPtr, k, total_offset + 4, -1, *i) ;
(*i)++ ;
}
/* m * (gdpr - gdtotd) */
if ((here->BSIM4v7dNode != 0) && (here->BSIM4v7dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7DdpPtr, k, total_offset + 5, -1, *i) ;
(*i)++ ;
}
/* m * (gdpr + gdtot) */
if ((here->BSIM4v7dNode != 0) && (here->BSIM4v7dNode != 0))
{
TopologyMatrixInsert (BSIM4v7DdPtr, k, total_offset + 1, 1, *i) ;
(*i)++ ;
}
/* m * (here->BSIM4v7gds + gstotd + RevSum - gcsdb - gbspdp -
T1 * dsxpart_dVd - sxpart * ggtd + gIstotd) + m * (ggisls + ggislg + ggislb) */
if ((here->BSIM4v7sNodePrime != 0) && (here->BSIM4v7dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7SPdpPtr, k, total_offset + 6, -1, *i) ;
(*i)++ ;
}
/* m * (gcsgb - Gm - gstotg + gbspg + sxpart * ggtg + T1 * dsxpart_dVg - gIstotg) + m * ggislg */
if ((here->BSIM4v7sNodePrime != 0) && (here->BSIM4v7gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7SPgpPtr, k, total_offset + 7, 1, *i) ;
(*i)++ ;
}
/* m * (gspr + here->BSIM4v7gds + here->BSIM4v7gbs + T1 * dsxpart_dVs -
gstots + FwdSum + gcssb + gbspsp + sxpart * ggts - gIstots) + m * ggisls */
if ((here->BSIM4v7sNodePrime != 0) && (here->BSIM4v7sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7SPspPtr, k, total_offset + 8, 1, *i) ;
(*i)++ ;
}
/* m * (gspr + gstot) */
if ((here->BSIM4v7sNodePrime != 0) && (here->BSIM4v7sNode != 0))
{
TopologyMatrixInsert (BSIM4v7SPsPtr, k, total_offset + 9, -1, *i) ;
(*i)++ ;
}
/* m * (gjbs + gstotb + Gmbs - gcsbb - gbspb - sxpart * ggtb - T1 * dsxpart_dVb + gIstotb) - m * ggislb */
if ((here->BSIM4v7sNodePrime != 0) && (here->BSIM4v7bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7SPbpPtr, k, total_offset + 10, -1, *i) ;
(*i)++ ;
}
/* m * (gspr - gstots) */
if ((here->BSIM4v7sNode != 0) && (here->BSIM4v7sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7SspPtr, k, total_offset + 11, -1, *i) ;
(*i)++ ;
}
/* m * (gspr + gstot) */
if ((here->BSIM4v7sNode != 0) && (here->BSIM4v7sNode != 0))
{
TopologyMatrixInsert (BSIM4v7SsPtr, k, total_offset + 9, 1, *i) ;
(*i)++ ;
}
/* m * (gcbdb - gjbd + gbbdp - gIbtotd) - m * ggidld + m * (ggislg + ggisls + ggislb) */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7BPdpPtr, k, total_offset + 12, 1, *i) ;
(*i)++ ;
}
/* m * (gcbgb - here->BSIM4v7gbgs - gIbtotg) - m * ggidlg - m * ggislg */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7BPgpPtr, k, total_offset + 13, 1, *i) ;
(*i)++ ;
}
/* m * (gcbsb - gjbs + gbbsp - gIbtots) + m * (ggidlg + ggidld + ggidlb) - m * ggisls */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7BPspPtr, k, total_offset + 14, 1, *i) ;
(*i)++ ;
}
/* m * (gjbd + gjbs + gcbbb - here->BSIM4v7gbbs - gIbtotb) - m * ggidlb - m * ggislb */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7BPbpPtr, k, total_offset + 15, 1, *i) ;
(*i)++ ;
}
total_offset += 16 ;
/* stamp gidl included above */
/* stamp gisl included above */
if (here->BSIM4v7rbodyMod)
{
/* m * (gcdbdb - here->BSIM4v7gbd) */
if ((here->BSIM4v7dNodePrime != 0) && (here->BSIM4v7dbNode != 0))
{
TopologyMatrixInsert (BSIM4v7DPdbPtr, k, total_offset + 0, 1, *i) ;
(*i)++ ;
}
/* m * (here->BSIM4v7gbs - gcsbsb) */
if ((here->BSIM4v7sNodePrime != 0) && (here->BSIM4v7sbNode != 0))
{
TopologyMatrixInsert (BSIM4v7SPsbPtr, k, total_offset + 1, -1, *i) ;
(*i)++ ;
}
/* m * (gcdbdb - here->BSIM4v7gbd) */
if ((here->BSIM4v7dbNode != 0) && (here->BSIM4v7dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7DBdpPtr, k, total_offset + 0, 1, *i) ;
(*i)++ ;
}
/* m * (here->BSIM4v7gbd - gcdbdb + here->BSIM4v7grbpd + here->BSIM4v7grbdb) */
if ((here->BSIM4v7dbNode != 0) && (here->BSIM4v7dbNode != 0))
{
TopologyMatrixInsert (BSIM4v7DBdbPtr, k, total_offset + 2, 1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4v7grbpd */
if ((here->BSIM4v7dbNode != 0) && (here->BSIM4v7bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7DBbpPtr, k, total_offset + 3, -1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4v7grbdb */
if ((here->BSIM4v7dbNode != 0) && (here->BSIM4v7bNode != 0))
{
TopologyMatrixInsert (BSIM4v7DBbPtr, k, total_offset + 4, -1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4v7grbpd */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7dbNode != 0))
{
TopologyMatrixInsert (BSIM4v7BPdbPtr, k, total_offset + 3, -1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4v7grbpb */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7bNode != 0))
{
TopologyMatrixInsert (BSIM4v7BPbPtr, k, total_offset + 5, -1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4v7grbps */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7sbNode != 0))
{
TopologyMatrixInsert (BSIM4v7BPsbPtr, k, total_offset + 6, -1, *i) ;
(*i)++ ;
}
/* m * (here->BSIM4v7grbpd + here->BSIM4v7grbps + here->BSIM4v7grbpb) */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7BPbpPtr, k, total_offset + 7, 1, *i) ;
(*i)++ ;
}
/* m * (gcsbsb - here->BSIM4v7gbs) */
if ((here->BSIM4v7sbNode != 0) && (here->BSIM4v7sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7SBspPtr, k, total_offset + 8, 1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4v7grbps */
if ((here->BSIM4v7sbNode != 0) && (here->BSIM4v7bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7SBbpPtr, k, total_offset + 6, -1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4v7grbsb */
if ((here->BSIM4v7sbNode != 0) && (here->BSIM4v7bNode != 0))
{
TopologyMatrixInsert (BSIM4v7SBbPtr, k, total_offset + 9, -1, *i) ;
(*i)++ ;
}
/* m * (here->BSIM4v7gbs - gcsbsb + here->BSIM4v7grbps + here->BSIM4v7grbsb) */
if ((here->BSIM4v7sbNode != 0) && (here->BSIM4v7sbNode != 0))
{
TopologyMatrixInsert (BSIM4v7SBsbPtr, k, total_offset + 10, 1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4v7grbdb */
if ((here->BSIM4v7bNode != 0) && (here->BSIM4v7dbNode != 0))
{
TopologyMatrixInsert (BSIM4v7BdbPtr, k, total_offset + 4, -1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4v7grbpb */
if ((here->BSIM4v7bNode != 0) && (here->BSIM4v7bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7BbpPtr, k, total_offset + 5, -1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4v7grbsb */
if ((here->BSIM4v7bNode != 0) && (here->BSIM4v7sbNode != 0))
{
TopologyMatrixInsert (BSIM4v7BsbPtr, k, total_offset + 9, -1, *i) ;
(*i)++ ;
}
/* m * (here->BSIM4v7grbsb + here->BSIM4v7grbdb + here->BSIM4v7grbpb) */
if ((here->BSIM4v7bNode != 0) && (here->BSIM4v7bNode != 0))
{
TopologyMatrixInsert (BSIM4v7BbPtr, k, total_offset + 11, 1, *i) ;
(*i)++ ;
}
total_offset += 12 ;
}
if (here->BSIM4v7trnqsMod)
{
/* m * (gqdef + here->BSIM4v7gtau) */
if ((here->BSIM4v7qNode != 0) && (here->BSIM4v7qNode != 0))
{
TopologyMatrixInsert (BSIM4v7QqPtr, k, total_offset + 0, 1, *i) ;
(*i)++ ;
}
/* m * (ggtg - gcqgb) */
if ((here->BSIM4v7qNode != 0) && (here->BSIM4v7gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7QgpPtr, k, total_offset + 1, 1, *i) ;
(*i)++ ;
}
/* m * (ggtd - gcqdb) */
if ((here->BSIM4v7qNode != 0) && (here->BSIM4v7dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7QdpPtr, k, total_offset + 2, 1, *i) ;
(*i)++ ;
}
/* m * (ggts - gcqsb) */
if ((here->BSIM4v7qNode != 0) && (here->BSIM4v7sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7QspPtr, k, total_offset + 3, 1, *i) ;
(*i)++ ;
}
/* m * (ggtb - gcqbb) */
if ((here->BSIM4v7qNode != 0) && (here->BSIM4v7bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4v7QbpPtr, k, total_offset + 4, 1, *i) ;
(*i)++ ;
}
/* m * dxpart * here->BSIM4v7gtau */
if ((here->BSIM4v7dNodePrime != 0) && (here->BSIM4v7qNode != 0))
{
TopologyMatrixInsert (BSIM4v7DPqPtr, k, total_offset + 5, 1, *i) ;
(*i)++ ;
}
/* m * sxpart * here->BSIM4v7gtau */
if ((here->BSIM4v7sNodePrime != 0) && (here->BSIM4v7qNode != 0))
{
TopologyMatrixInsert (BSIM4v7SPqPtr, k, total_offset + 6, 1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4v7gtau */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7qNode != 0))
{
TopologyMatrixInsert (BSIM4v7GPqPtr, k, total_offset + 7, -1, *i) ;
(*i)++ ;
}
}
/* For the RHS */
/* m * (ceqjd - ceqbd + ceqgdtot - ceqdrn - ceqqd + Idtoteq) */
if (here->BSIM4v7dNodePrime != 0)
{
TopologyMatrixInsertRHS (BSIM4v7dNodePrime, k, total_offsetRHS + 0, 1, *j) ;
(*j)++ ;
}
/* m * (ceqqg - ceqgcrg + Igtoteq) */
if (here->BSIM4v7gNodePrime != 0)
{
TopologyMatrixInsertRHS (BSIM4v7gNodePrime, k, total_offsetRHS + 1, -1, *j) ;
(*j)++ ;
}
total_offsetRHS += 2 ;
if (here->BSIM4v7rgateMod == 2)
{
/* m * ceqgcrg */
if (here->BSIM4v7gNodeExt != 0)
{
TopologyMatrixInsertRHS (BSIM4v7gNodeExt, k, total_offsetRHS + 0, -1, *j) ;
(*j)++ ;
}
total_offsetRHS += 1 ;
}
else if (here->BSIM4v7rgateMod == 3)
{
/* m * (ceqqgmid + ceqgcrg) */
if (here->BSIM4v7gNodeMid != 0)
{
TopologyMatrixInsertRHS (BSIM4v7gNodeMid, k, total_offsetRHS + 0, -1, *j) ;
(*j)++ ;
}
total_offsetRHS += 1 ;
}
if (!here->BSIM4v7rbodyMod)
{
/* m * (ceqbd + ceqbs - ceqjd - ceqjs - ceqqb + Ibtoteq) */
if (here->BSIM4v7bNodePrime != 0)
{
TopologyMatrixInsertRHS (BSIM4v7bNodePrime, k, total_offsetRHS + 0, 1, *j) ;
(*j)++ ;
}
/* m * (ceqdrn - ceqbs + ceqjs + ceqqg + ceqqb + ceqqd + ceqqgmid - ceqgstot + Istoteq) */
if (here->BSIM4v7sNodePrime != 0)
{
TopologyMatrixInsertRHS (BSIM4v7sNodePrime, k, total_offsetRHS + 1, 1, *j) ;
(*j)++ ;
}
total_offsetRHS += 2 ;
} else {
/* m * (ceqjd + ceqqjd) */
if (here->BSIM4v7dbNode != 0)
{
TopologyMatrixInsertRHS (BSIM4v7dbNode, k, total_offsetRHS + 0, -1, *j) ;
(*j)++ ;
}
/* m * (ceqbd + ceqbs - ceqqb + Ibtoteq) */
if (here->BSIM4v7bNodePrime != 0)
{
TopologyMatrixInsertRHS (BSIM4v7bNodePrime, k, total_offsetRHS + 1, 1, *j) ;
(*j)++ ;
}
/* m * (ceqjs + ceqqjs) */
if (here->BSIM4v7sbNode != 0)
{
TopologyMatrixInsertRHS (BSIM4v7sbNode, k, total_offsetRHS + 2, -1, *j) ;
(*j)++ ;
}
/* m * (ceqdrn - ceqbs + ceqjs + ceqqd + ceqqg + ceqqb +
ceqqjd + ceqqjs + ceqqgmid - ceqgstot + Istoteq) */
if (here->BSIM4v7sNodePrime != 0)
{
TopologyMatrixInsertRHS (BSIM4v7sNodePrime, k, total_offsetRHS + 3, 1, *j) ;
(*j)++ ;
}
total_offsetRHS += 4 ;
}
if (model->BSIM4v7rdsMod)
{
/* m * ceqgdtot */
if (here->BSIM4v7dNode != 0)
{
TopologyMatrixInsertRHS (BSIM4v7dNode, k, total_offsetRHS + 0, -1, *j) ;
(*j)++ ;
}
/* m * ceqgstot */
if (here->BSIM4v7sNode != 0)
{
TopologyMatrixInsertRHS (BSIM4v7sNode, k, total_offsetRHS + 1, 1, *j) ;
(*j)++ ;
}
total_offsetRHS += 2 ;
}
if (here->BSIM4v7trnqsMod)
{
/* m * (cqcheq - cqdef) */
if (here->BSIM4v7qNode != 0)
{
TopologyMatrixInsertRHS (BSIM4v7qNode, k, total_offsetRHS + 0, 1, *j) ;
(*j)++ ;
}
}
k++ ;
}
}
return (OK) ;
}

View File

@ -0,0 +1,845 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "bsim4v7def.h"
#include "ngspice/CUSPICE/CUSPICE.h"
int
cuBSIM4v7destroy
(
GENmodel *inModel
)
{
BSIM4v7model *model = (BSIM4v7model *)inModel ;
BSIM4v7instance *here ;
int i ;
for ( ; model != NULL ; model = BSIM4v7nextModel(model))
{
/* Special case here->d_pParam */
i = 0 ;
for (here = BSIM4v7instances(model); here != NULL ; here = BSIM4v7nextInstance(here))
{
if (here->pParam != NULL)
cudaFree (model->pParamHost [i]) ;
i++ ;
}
free (model->pParamHost) ;
cudaFree (model->d_pParam) ;
/* DOUBLE */
free (model->BSIM4v7paramCPU.BSIM4v7gbsRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gbsRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cbsRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cbsRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gbdRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gbdRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cbdRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cbdRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7vonRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7vonRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7vdsatRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7vdsatRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7csubRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7csubRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gdsRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gdsRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gmRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gmRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gmbsRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gmbsRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gcrgRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gcrgRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7IgidlRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7IgidlRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7IgislRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7IgislRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7IgcsRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7IgcsRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7IgcdRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7IgcdRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7IgsRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7IgsRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7IgdRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7IgdRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7IgbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7IgbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cdRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cdRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7qinvRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7qinvRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cggbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cggbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cgsbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cgsbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cgdbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cgdbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cdgbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cdgbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cdsbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cdsbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cddbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cddbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cbgbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cbgbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cbsbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cbsbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cbdbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cbdbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7csgbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7csgbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cssbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cssbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7csdbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7csdbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cgbbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cgbbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7csbbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7csbbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cdbbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cdbbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cbbbRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cbbbRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gtauRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gtauRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7qgateRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7qgateRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7qbulkRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7qbulkRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7qdrnRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7qdrnRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7qsrcRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7qsrcRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7capbsRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7capbsRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7capbdRWArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7capbdRWArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7icVDSArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7icVDSArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7icVGSArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7icVGSArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7icVBSArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7icVBSArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7vth0Array) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7vth0Array) ;
free (model->BSIM4v7paramCPU.BSIM4v7gbbsArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gbbsArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7ggidlbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7ggidlbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gbgsArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gbgsArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7ggidlgArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7ggidlgArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gbdsArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gbdsArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7ggidldArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7ggidldArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7ggislsArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7ggislsArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7ggislgArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7ggislgArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7ggislbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7ggislbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gIgsgArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gIgsgArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gIgcsgArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gIgcsgArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gIgcsdArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gIgcsdArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gIgcsbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gIgcsbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gIgdgArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gIgdgArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gIgcdgArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gIgcdgArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gIgcddArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gIgcddArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gIgcdbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gIgcdbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gIgbgArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gIgbgArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gIgbdArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gIgbdArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gIgbbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gIgbbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7ggidlsArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7ggidlsArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7ggisldArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7ggisldArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gstotArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gstotArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gstotdArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gstotdArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gstotgArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gstotgArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gstotbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gstotbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gdtotArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gdtotArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gdtotdArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gdtotdArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gdtotgArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gdtotgArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gdtotbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gdtotbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cgdoArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cgdoArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7qgdoArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7qgdoArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cgsoArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cgsoArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7qgsoArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7qgsoArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7AseffArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7AseffArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7PseffArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7PseffArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7nfArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7nfArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7XExpBVSArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7XExpBVSArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7vjsmFwdArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7vjsmFwdArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7IVjsmFwdArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7IVjsmFwdArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7vjsmRevArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7vjsmRevArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7IVjsmRevArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7IVjsmRevArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SslpRevArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SslpRevArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SslpFwdArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SslpFwdArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7AdeffArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7AdeffArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7PdeffArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7PdeffArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7XExpBVDArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7XExpBVDArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7vjdmFwdArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7vjdmFwdArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7IVjdmFwdArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7IVjdmFwdArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7vjdmRevArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7vjdmRevArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7IVjdmRevArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7IVjdmRevArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DslpRevArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DslpRevArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DslpFwdArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DslpFwdArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SjctTempRevSatCurArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SjctTempRevSatCurArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SswTempRevSatCurArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SswTempRevSatCurArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SswgTempRevSatCurArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SswgTempRevSatCurArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DjctTempRevSatCurArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DjctTempRevSatCurArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DswTempRevSatCurArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DswTempRevSatCurArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DswgTempRevSatCurArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DswgTempRevSatCurArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7vbscArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7vbscArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7thetavthArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7thetavthArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7eta0Array) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7eta0Array) ;
free (model->BSIM4v7paramCPU.BSIM4v7k2oxArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7k2oxArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7nstarArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7nstarArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7vfbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7vfbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7vgs_effArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7vgs_effArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7vgd_effArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7vgd_effArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7dvgs_eff_dvgArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7dvgs_eff_dvgArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7dvgd_eff_dvgArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7dvgd_eff_dvgArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7VgsteffArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7VgsteffArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7grdswArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7grdswArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7AbulkArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7AbulkArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7vtfbphi1Array) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7vtfbphi1Array) ;
free (model->BSIM4v7paramCPU.BSIM4v7ueffArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7ueffArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7u0tempArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7u0tempArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7vsattempArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7vsattempArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7EsatLArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7EsatLArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7VdseffArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7VdseffArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7vtfbphi2Array) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7vtfbphi2Array) ;
free (model->BSIM4v7paramCPU.BSIM4v7CoxeffArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7CoxeffArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7AbovVgst2VtmArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7AbovVgst2VtmArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7IdovVdsArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7IdovVdsArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gcrgdArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gcrgdArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gcrgbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gcrgbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gcrggArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gcrggArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7grgeltdArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7grgeltdArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gcrgsArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gcrgsArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7sourceConductanceArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7sourceConductanceArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7drainConductanceArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7drainConductanceArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gstotsArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gstotsArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gdtotsArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gdtotsArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7vfbzbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7vfbzbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gIgssArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gIgssArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gIgddArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gIgddArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gIgbsArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gIgbsArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gIgcssArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gIgcssArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gIgcdsArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gIgcdsArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7noiGd0Array) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7noiGd0Array) ;
free (model->BSIM4v7paramCPU.BSIM4v7cqdbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cqdbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cqsbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cqsbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cqgbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cqgbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7qchqsArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7qchqsArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7cqbbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7cqbbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7taunetArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7taunetArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gtgArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gtgArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gtdArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gtdArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gtsArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gtsArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gtbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gtbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7mArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7mArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7grbpdArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7grbpdArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7grbdbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7grbdbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7grbpbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7grbpbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7grbpsArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7grbpsArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7grbsbArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7grbsbArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7dNodePrimeRHSValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7dNodePrimeRHSValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gNodePrimeRHSValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gNodePrimeRHSValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gNodeExtRHSValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gNodeExtRHSValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gNodeMidRHSValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gNodeMidRHSValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7bNodePrimeRHSValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7bNodePrimeRHSValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7sNodePrimeRHSValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7sNodePrimeRHSValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7dbNodeRHSValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7dbNodeRHSValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7sbNodeRHSValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7sbNodeRHSValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7dNodeRHSValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7dNodeRHSValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7sNodeRHSValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7sNodeRHSValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7qNodeRHSValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7qNodeRHSValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GEgeValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GEgeValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GPgeValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GPgeValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GEgpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GEgpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GPgpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GPgpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GPdpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GPdpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GPspValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GPspValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GPbpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GPbpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GEdpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GEdpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GEspValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GEspValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GEbpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GEbpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GEgmValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GEgmValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GMgeValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GMgeValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GMgmValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GMgmValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GMdpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GMdpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GMgpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GMgpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GMspValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GMspValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GMbpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GMbpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DPgmValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DPgmValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GPgmValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GPgmValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SPgmValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SPgmValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7BPgmValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7BPgmValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DgpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DgpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DspValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DspValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DbpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DbpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SdpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SdpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SgpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SgpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SbpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SbpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DPdpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DPdpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DPdValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DPdValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DPgpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DPgpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DPspValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DPspValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DPbpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DPbpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DdpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DdpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DdValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DdValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SPdpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SPdpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SPgpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SPgpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SPspValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SPspValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SPsValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SPsValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SPbpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SPbpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SspValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SspValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SsValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SsValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7BPdpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7BPdpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7BPgpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7BPgpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7BPspValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7BPspValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7BPbpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7BPbpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DPdbValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DPdbValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SPsbValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SPsbValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DBdpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DBdpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DBdbValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DBdbValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DBbpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DBbpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DBbValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DBbValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7BPdbValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7BPdbValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7BPbValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7BPbValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7BPsbValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7BPsbValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7BPbpIFValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7BPbpIFValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SBspValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SBspValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SBbpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SBbpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SBbValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SBbValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SBsbValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SBsbValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7BdbValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7BdbValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7BbpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7BbpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7BsbValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7BsbValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7BbValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7BbValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7QqValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7QqValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7QgpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7QgpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7QdpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7QdpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7QspValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7QspValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7QbpValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7QbpValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7DPqValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7DPqValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7SPqValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7SPqValueArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7GPqValueArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7GPqValueArray) ;
/* INT */
free (model->BSIM4v7paramCPU.BSIM4v7offArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7offArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7dNodePrimeArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7dNodePrimeArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7sNodePrimeArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7sNodePrimeArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gNodePrimeArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gNodePrimeArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7bNodePrimeArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7bNodePrimeArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gNodeExtArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gNodeExtArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7gNodeMidArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7gNodeMidArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7dbNodeArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7dbNodeArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7sbNodeArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7sbNodeArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7sNodeArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7sNodeArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7dNodeArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7dNodeArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7qNodeArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7qNodeArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7rbodyModArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7rbodyModArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7modeArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7modeArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7rgateModArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7rgateModArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7trnqsModArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7trnqsModArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7acnqsModArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7acnqsModArray) ;
free (model->BSIM4v7paramCPU.BSIM4v7statesArray) ;
cudaFree (model->BSIM4v7paramGPU.d_BSIM4v7statesArray) ;
}
return (OK) ;
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "bsim4v7def.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuBSIM4v7getic routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuBSIM4v7getic
(
GENmodel *inModel
)
{
long unsigned int size ;
cudaError_t status ;
BSIM4v7model *model = (BSIM4v7model *)inModel ;
size = (long unsigned int) model->n_instances;
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7icVDSArray, model->BSIM4v7paramCPU.BSIM4v7icVDSArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7icVDSArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7icVGSArray, model->BSIM4v7paramCPU.BSIM4v7icVGSArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7icVGSArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7icVBSArray, model->BSIM4v7paramCPU.BSIM4v7icVBSArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7icVBSArray, size, double, status)
return (OK) ;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,633 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "bsim4v7def.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMalloc MACRO to check it for errors --> CUDAMALLOCCHECK(name of pointer, dimension, type, status) */
#define CUDAMALLOCCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuBSIM4v7temp routine...\n") ; \
fprintf (stderr, "Error: cudaMalloc failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuBSIM4v7temp routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuBSIM4v7temp
(
GENmodel *inModel
)
{
int i ;
long unsigned int size ;
cudaError_t status ;
BSIM4v7model *model = (BSIM4v7model *)inModel ;
BSIM4v7instance *here ;
size = (long unsigned int) model->n_instances;
/* Special case here->d_pParam */
model->pParamHost = (struct bsim4SizeDependParam **) malloc (size * sizeof(struct bsim4SizeDependParam *)) ;
status = cudaMalloc ((void **)&(model->d_pParam), size * sizeof(struct bsim4SizeDependParam *)) ;
CUDAMALLOCCHECK (model->d_pParam, size, struct bsim4SizeDependParam *, status)
i = 0 ;
for (here = BSIM4v7instances(model); here != NULL ; here = BSIM4v7nextInstance(here))
{
if (here->pParam != NULL)
{
status = cudaMalloc ((void **)&(model->pParamHost [i]), sizeof(struct bsim4SizeDependParam)) ;
CUDAMALLOCCHECK (model->pParamHost [i], 1, struct bsim4SizeDependParam, status)
status = cudaMemcpy (model->pParamHost [i], here->pParam, sizeof(struct bsim4SizeDependParam), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->pParamHost [i], 1, struct bsim4SizeDependParam, status)
}
else
model->pParamHost [i] = NULL ;
i++ ;
}
/* Structure pointer vectors in GPU */
status = cudaMemcpy (model->d_pParam, model->pParamHost, size * sizeof(struct bsim4SizeDependParam *), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->d_pParam, size, struct bsim4SizeDependParam *, status)
/* -------------------------------- */
/* DOUBLE */
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gbsRWArray, model->BSIM4v7paramCPU.BSIM4v7gbsRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gbsRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cbsRWArray, model->BSIM4v7paramCPU.BSIM4v7cbsRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cbsRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gbdRWArray, model->BSIM4v7paramCPU.BSIM4v7gbdRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gbdRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cbdRWArray, model->BSIM4v7paramCPU.BSIM4v7cbdRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cbdRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7vonRWArray, model->BSIM4v7paramCPU.BSIM4v7vonRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7vonRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7vdsatRWArray, model->BSIM4v7paramCPU.BSIM4v7vdsatRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7vdsatRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7csubRWArray, model->BSIM4v7paramCPU.BSIM4v7csubRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7csubRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gdsRWArray, model->BSIM4v7paramCPU.BSIM4v7gdsRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gdsRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gmRWArray, model->BSIM4v7paramCPU.BSIM4v7gmRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gmRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gmbsRWArray, model->BSIM4v7paramCPU.BSIM4v7gmbsRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gmbsRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gcrgRWArray, model->BSIM4v7paramCPU.BSIM4v7gcrgRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gcrgRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7IgidlRWArray, model->BSIM4v7paramCPU.BSIM4v7IgidlRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7IgidlRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7IgislRWArray, model->BSIM4v7paramCPU.BSIM4v7IgislRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7IgislRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7IgcsRWArray, model->BSIM4v7paramCPU.BSIM4v7IgcsRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7IgcsRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7IgcdRWArray, model->BSIM4v7paramCPU.BSIM4v7IgcdRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7IgcdRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7IgsRWArray, model->BSIM4v7paramCPU.BSIM4v7IgsRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7IgsRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7IgdRWArray, model->BSIM4v7paramCPU.BSIM4v7IgdRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7IgdRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7IgbRWArray, model->BSIM4v7paramCPU.BSIM4v7IgbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7IgbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cdRWArray, model->BSIM4v7paramCPU.BSIM4v7cdRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cdRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7qinvRWArray, model->BSIM4v7paramCPU.BSIM4v7qinvRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7qinvRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cggbRWArray, model->BSIM4v7paramCPU.BSIM4v7cggbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cggbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cgsbRWArray, model->BSIM4v7paramCPU.BSIM4v7cgsbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cgsbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cgdbRWArray, model->BSIM4v7paramCPU.BSIM4v7cgdbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cgdbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cdgbRWArray, model->BSIM4v7paramCPU.BSIM4v7cdgbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cdgbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cdsbRWArray, model->BSIM4v7paramCPU.BSIM4v7cdsbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cdsbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cddbRWArray, model->BSIM4v7paramCPU.BSIM4v7cddbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cddbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cbgbRWArray, model->BSIM4v7paramCPU.BSIM4v7cbgbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cbgbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cbsbRWArray, model->BSIM4v7paramCPU.BSIM4v7cbsbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cbsbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cbdbRWArray, model->BSIM4v7paramCPU.BSIM4v7cbdbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cbdbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7csgbRWArray, model->BSIM4v7paramCPU.BSIM4v7csgbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7csgbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cssbRWArray, model->BSIM4v7paramCPU.BSIM4v7cssbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cssbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7csdbRWArray, model->BSIM4v7paramCPU.BSIM4v7csdbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7csdbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cgbbRWArray, model->BSIM4v7paramCPU.BSIM4v7cgbbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cgbbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7csbbRWArray, model->BSIM4v7paramCPU.BSIM4v7csbbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7csbbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cdbbRWArray, model->BSIM4v7paramCPU.BSIM4v7cdbbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cdbbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cbbbRWArray, model->BSIM4v7paramCPU.BSIM4v7cbbbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cbbbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gtauRWArray, model->BSIM4v7paramCPU.BSIM4v7gtauRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gtauRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7qgateRWArray, model->BSIM4v7paramCPU.BSIM4v7qgateRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7qgateRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7qbulkRWArray, model->BSIM4v7paramCPU.BSIM4v7qbulkRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7qbulkRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7qdrnRWArray, model->BSIM4v7paramCPU.BSIM4v7qdrnRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7qdrnRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7qsrcRWArray, model->BSIM4v7paramCPU.BSIM4v7qsrcRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7qsrcRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7capbsRWArray, model->BSIM4v7paramCPU.BSIM4v7capbsRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7capbsRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7capbdRWArray, model->BSIM4v7paramCPU.BSIM4v7capbdRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7capbdRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7icVDSArray, model->BSIM4v7paramCPU.BSIM4v7icVDSArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7icVDSArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7icVGSArray, model->BSIM4v7paramCPU.BSIM4v7icVGSArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7icVGSArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7icVBSArray, model->BSIM4v7paramCPU.BSIM4v7icVBSArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7icVBSArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7vth0Array, model->BSIM4v7paramCPU.BSIM4v7vth0Array, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7vth0Array, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gbbsArray, model->BSIM4v7paramCPU.BSIM4v7gbbsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gbbsArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7ggidlbArray, model->BSIM4v7paramCPU.BSIM4v7ggidlbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7ggidlbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gbgsArray, model->BSIM4v7paramCPU.BSIM4v7gbgsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gbgsArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7ggidlgArray, model->BSIM4v7paramCPU.BSIM4v7ggidlgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7ggidlgArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gbdsArray, model->BSIM4v7paramCPU.BSIM4v7gbdsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gbdsArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7ggidldArray, model->BSIM4v7paramCPU.BSIM4v7ggidldArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7ggidldArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7ggislsArray, model->BSIM4v7paramCPU.BSIM4v7ggislsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7ggislsArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7ggislgArray, model->BSIM4v7paramCPU.BSIM4v7ggislgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7ggislgArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7ggislbArray, model->BSIM4v7paramCPU.BSIM4v7ggislbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7ggislbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gIgsgArray, model->BSIM4v7paramCPU.BSIM4v7gIgsgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gIgsgArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gIgcsgArray, model->BSIM4v7paramCPU.BSIM4v7gIgcsgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gIgcsgArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gIgcsdArray, model->BSIM4v7paramCPU.BSIM4v7gIgcsdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gIgcsdArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gIgcsbArray, model->BSIM4v7paramCPU.BSIM4v7gIgcsbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gIgcsbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gIgdgArray, model->BSIM4v7paramCPU.BSIM4v7gIgdgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gIgdgArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gIgcdgArray, model->BSIM4v7paramCPU.BSIM4v7gIgcdgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gIgcdgArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gIgcddArray, model->BSIM4v7paramCPU.BSIM4v7gIgcddArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gIgcddArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gIgcdbArray, model->BSIM4v7paramCPU.BSIM4v7gIgcdbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gIgcdbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gIgbgArray, model->BSIM4v7paramCPU.BSIM4v7gIgbgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gIgbgArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gIgbdArray, model->BSIM4v7paramCPU.BSIM4v7gIgbdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gIgbdArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gIgbbArray, model->BSIM4v7paramCPU.BSIM4v7gIgbbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gIgbbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7ggidlsArray, model->BSIM4v7paramCPU.BSIM4v7ggidlsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7ggidlsArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7ggisldArray, model->BSIM4v7paramCPU.BSIM4v7ggisldArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7ggisldArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gstotArray, model->BSIM4v7paramCPU.BSIM4v7gstotArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gstotArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gstotdArray, model->BSIM4v7paramCPU.BSIM4v7gstotdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gstotdArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gstotgArray, model->BSIM4v7paramCPU.BSIM4v7gstotgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gstotgArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gstotbArray, model->BSIM4v7paramCPU.BSIM4v7gstotbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gstotbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gdtotArray, model->BSIM4v7paramCPU.BSIM4v7gdtotArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gdtotArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gdtotdArray, model->BSIM4v7paramCPU.BSIM4v7gdtotdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gdtotdArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gdtotgArray, model->BSIM4v7paramCPU.BSIM4v7gdtotgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gdtotgArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gdtotbArray, model->BSIM4v7paramCPU.BSIM4v7gdtotbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gdtotbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cgdoArray, model->BSIM4v7paramCPU.BSIM4v7cgdoArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cgdoArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7qgdoArray, model->BSIM4v7paramCPU.BSIM4v7qgdoArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7qgdoArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cgsoArray, model->BSIM4v7paramCPU.BSIM4v7cgsoArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cgsoArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7qgsoArray, model->BSIM4v7paramCPU.BSIM4v7qgsoArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7qgsoArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7AseffArray, model->BSIM4v7paramCPU.BSIM4v7AseffArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7AseffArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7PseffArray, model->BSIM4v7paramCPU.BSIM4v7PseffArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7PseffArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7nfArray, model->BSIM4v7paramCPU.BSIM4v7nfArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7nfArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7XExpBVSArray, model->BSIM4v7paramCPU.BSIM4v7XExpBVSArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7XExpBVSArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7vjsmFwdArray, model->BSIM4v7paramCPU.BSIM4v7vjsmFwdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7vjsmFwdArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7IVjsmFwdArray, model->BSIM4v7paramCPU.BSIM4v7IVjsmFwdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7IVjsmFwdArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7vjsmRevArray, model->BSIM4v7paramCPU.BSIM4v7vjsmRevArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7vjsmRevArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7IVjsmRevArray, model->BSIM4v7paramCPU.BSIM4v7IVjsmRevArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7IVjsmRevArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7SslpRevArray, model->BSIM4v7paramCPU.BSIM4v7SslpRevArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7SslpRevArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7SslpFwdArray, model->BSIM4v7paramCPU.BSIM4v7SslpFwdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7SslpFwdArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7AdeffArray, model->BSIM4v7paramCPU.BSIM4v7AdeffArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7AdeffArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7PdeffArray, model->BSIM4v7paramCPU.BSIM4v7PdeffArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7PdeffArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7XExpBVDArray, model->BSIM4v7paramCPU.BSIM4v7XExpBVDArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7XExpBVDArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7vjdmFwdArray, model->BSIM4v7paramCPU.BSIM4v7vjdmFwdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7vjdmFwdArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7IVjdmFwdArray, model->BSIM4v7paramCPU.BSIM4v7IVjdmFwdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7IVjdmFwdArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7vjdmRevArray, model->BSIM4v7paramCPU.BSIM4v7vjdmRevArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7vjdmRevArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7IVjdmRevArray, model->BSIM4v7paramCPU.BSIM4v7IVjdmRevArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7IVjdmRevArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7DslpRevArray, model->BSIM4v7paramCPU.BSIM4v7DslpRevArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7DslpRevArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7DslpFwdArray, model->BSIM4v7paramCPU.BSIM4v7DslpFwdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7DslpFwdArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7SjctTempRevSatCurArray, model->BSIM4v7paramCPU.BSIM4v7SjctTempRevSatCurArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7SjctTempRevSatCurArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7SswTempRevSatCurArray, model->BSIM4v7paramCPU.BSIM4v7SswTempRevSatCurArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7SswTempRevSatCurArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7SswgTempRevSatCurArray, model->BSIM4v7paramCPU.BSIM4v7SswgTempRevSatCurArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7SswgTempRevSatCurArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7DjctTempRevSatCurArray, model->BSIM4v7paramCPU.BSIM4v7DjctTempRevSatCurArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7DjctTempRevSatCurArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7DswTempRevSatCurArray, model->BSIM4v7paramCPU.BSIM4v7DswTempRevSatCurArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7DswTempRevSatCurArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7DswgTempRevSatCurArray, model->BSIM4v7paramCPU.BSIM4v7DswgTempRevSatCurArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7DswgTempRevSatCurArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7vbscArray, model->BSIM4v7paramCPU.BSIM4v7vbscArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7vbscArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7thetavthArray, model->BSIM4v7paramCPU.BSIM4v7thetavthArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7thetavthArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7eta0Array, model->BSIM4v7paramCPU.BSIM4v7eta0Array, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7eta0Array, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7k2oxArray, model->BSIM4v7paramCPU.BSIM4v7k2oxArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7k2oxArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7nstarArray, model->BSIM4v7paramCPU.BSIM4v7nstarArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7nstarArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7vfbArray, model->BSIM4v7paramCPU.BSIM4v7vfbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7vfbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7vgs_effArray, model->BSIM4v7paramCPU.BSIM4v7vgs_effArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7vgs_effArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7vgd_effArray, model->BSIM4v7paramCPU.BSIM4v7vgd_effArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7vgd_effArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7dvgs_eff_dvgArray, model->BSIM4v7paramCPU.BSIM4v7dvgs_eff_dvgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7dvgs_eff_dvgArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7dvgd_eff_dvgArray, model->BSIM4v7paramCPU.BSIM4v7dvgd_eff_dvgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7dvgd_eff_dvgArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7VgsteffArray, model->BSIM4v7paramCPU.BSIM4v7VgsteffArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7VgsteffArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7grdswArray, model->BSIM4v7paramCPU.BSIM4v7grdswArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7grdswArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7AbulkArray, model->BSIM4v7paramCPU.BSIM4v7AbulkArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7AbulkArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7vtfbphi1Array, model->BSIM4v7paramCPU.BSIM4v7vtfbphi1Array, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7vtfbphi1Array, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7ueffArray, model->BSIM4v7paramCPU.BSIM4v7ueffArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7ueffArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7u0tempArray, model->BSIM4v7paramCPU.BSIM4v7u0tempArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7u0tempArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7vsattempArray, model->BSIM4v7paramCPU.BSIM4v7vsattempArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7vsattempArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7EsatLArray, model->BSIM4v7paramCPU.BSIM4v7EsatLArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7EsatLArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7VdseffArray, model->BSIM4v7paramCPU.BSIM4v7VdseffArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7VdseffArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7vtfbphi2Array, model->BSIM4v7paramCPU.BSIM4v7vtfbphi2Array, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7vtfbphi2Array, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7CoxeffArray, model->BSIM4v7paramCPU.BSIM4v7CoxeffArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7CoxeffArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7AbovVgst2VtmArray, model->BSIM4v7paramCPU.BSIM4v7AbovVgst2VtmArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7AbovVgst2VtmArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7IdovVdsArray, model->BSIM4v7paramCPU.BSIM4v7IdovVdsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7IdovVdsArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gcrgdArray, model->BSIM4v7paramCPU.BSIM4v7gcrgdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gcrgdArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gcrgbArray, model->BSIM4v7paramCPU.BSIM4v7gcrgbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gcrgbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gcrggArray, model->BSIM4v7paramCPU.BSIM4v7gcrggArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gcrggArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7grgeltdArray, model->BSIM4v7paramCPU.BSIM4v7grgeltdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7grgeltdArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gcrgsArray, model->BSIM4v7paramCPU.BSIM4v7gcrgsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gcrgsArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7sourceConductanceArray, model->BSIM4v7paramCPU.BSIM4v7sourceConductanceArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7sourceConductanceArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7drainConductanceArray, model->BSIM4v7paramCPU.BSIM4v7drainConductanceArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7drainConductanceArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gstotsArray, model->BSIM4v7paramCPU.BSIM4v7gstotsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gstotsArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gdtotsArray, model->BSIM4v7paramCPU.BSIM4v7gdtotsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gdtotsArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7vfbzbArray, model->BSIM4v7paramCPU.BSIM4v7vfbzbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7vfbzbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gIgssArray, model->BSIM4v7paramCPU.BSIM4v7gIgssArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gIgssArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gIgddArray, model->BSIM4v7paramCPU.BSIM4v7gIgddArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gIgddArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gIgbsArray, model->BSIM4v7paramCPU.BSIM4v7gIgbsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gIgbsArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gIgcssArray, model->BSIM4v7paramCPU.BSIM4v7gIgcssArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gIgcssArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gIgcdsArray, model->BSIM4v7paramCPU.BSIM4v7gIgcdsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gIgcdsArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7noiGd0Array, model->BSIM4v7paramCPU.BSIM4v7noiGd0Array, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7noiGd0Array, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cqdbArray, model->BSIM4v7paramCPU.BSIM4v7cqdbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cqdbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cqsbArray, model->BSIM4v7paramCPU.BSIM4v7cqsbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cqsbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cqgbArray, model->BSIM4v7paramCPU.BSIM4v7cqgbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cqgbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7qchqsArray, model->BSIM4v7paramCPU.BSIM4v7qchqsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7qchqsArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7cqbbArray, model->BSIM4v7paramCPU.BSIM4v7cqbbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7cqbbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7taunetArray, model->BSIM4v7paramCPU.BSIM4v7taunetArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7taunetArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gtgArray, model->BSIM4v7paramCPU.BSIM4v7gtgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gtgArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gtdArray, model->BSIM4v7paramCPU.BSIM4v7gtdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gtdArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gtsArray, model->BSIM4v7paramCPU.BSIM4v7gtsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gtsArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gtbArray, model->BSIM4v7paramCPU.BSIM4v7gtbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gtbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7mArray, model->BSIM4v7paramCPU.BSIM4v7mArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7mArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7grbpdArray, model->BSIM4v7paramCPU.BSIM4v7grbpdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7grbpdArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7grbdbArray, model->BSIM4v7paramCPU.BSIM4v7grbdbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7grbdbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7grbpbArray, model->BSIM4v7paramCPU.BSIM4v7grbpbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7grbpbArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7grbpsArray, model->BSIM4v7paramCPU.BSIM4v7grbpsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7grbpsArray, size, double, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7grbsbArray, model->BSIM4v7paramCPU.BSIM4v7grbsbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7grbsbArray, size, double, status)
/* INT */
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7offArray, model->BSIM4v7paramCPU.BSIM4v7offArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7offArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7dNodePrimeArray, model->BSIM4v7paramCPU.BSIM4v7dNodePrimeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7dNodePrimeArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7sNodePrimeArray, model->BSIM4v7paramCPU.BSIM4v7sNodePrimeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7sNodePrimeArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gNodePrimeArray, model->BSIM4v7paramCPU.BSIM4v7gNodePrimeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gNodePrimeArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7bNodePrimeArray, model->BSIM4v7paramCPU.BSIM4v7bNodePrimeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7bNodePrimeArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gNodeExtArray, model->BSIM4v7paramCPU.BSIM4v7gNodeExtArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gNodeExtArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7gNodeMidArray, model->BSIM4v7paramCPU.BSIM4v7gNodeMidArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7gNodeMidArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7dbNodeArray, model->BSIM4v7paramCPU.BSIM4v7dbNodeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7dbNodeArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7sbNodeArray, model->BSIM4v7paramCPU.BSIM4v7sbNodeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7sbNodeArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7sNodeArray, model->BSIM4v7paramCPU.BSIM4v7sNodeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7sNodeArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7dNodeArray, model->BSIM4v7paramCPU.BSIM4v7dNodeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7dNodeArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7qNodeArray, model->BSIM4v7paramCPU.BSIM4v7qNodeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7qNodeArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7rbodyModArray, model->BSIM4v7paramCPU.BSIM4v7rbodyModArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7rbodyModArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7modeArray, model->BSIM4v7paramCPU.BSIM4v7modeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7modeArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7rgateModArray, model->BSIM4v7paramCPU.BSIM4v7rgateModArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7rgateModArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7trnqsModArray, model->BSIM4v7paramCPU.BSIM4v7trnqsModArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7trnqsModArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7acnqsModArray, model->BSIM4v7paramCPU.BSIM4v7acnqsModArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.d_BSIM4v7acnqsModArray, size, int, status)
status = cudaMemcpy (model->BSIM4v7paramGPU.d_BSIM4v7statesArray, model->BSIM4v7paramCPU.BSIM4v7statesArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4v7paramGPU.BSIM4v7statesArray, size, int, status)
return (OK) ;
}

View File

@ -37,6 +37,21 @@ endif
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
AM_CFLAGS = $(STATIC)
if USE_CUSPICE_WANTED
.cu.lo:
$(AM_V_GEN)$(top_srcdir)/src/libtool_wrapper_for_cuda.tcl $@ $(AM_CFLAGS) $(NVCC) $(CUDA_CFLAGS) $(AM_CPPFLAGS) -c $<
libbsim4v7_la_SOURCES += \
CUSPICE/b4v7topology.c \
CUSPICE/cubsim4v7free.c \
CUSPICE/cubsim4v7getic.c \
CUSPICE/cubsim4v7load.cu \
CUSPICE/cubsim4v7setup.c \
CUSPICE/cubsim4v7temp.c
AM_CPPFLAGS += $(CUDA_CPPFLAGS)
endif
MAINTAINERCLEANFILES = Makefile.in
EXTRA_DIST = B4TERMS_OF_USE

View File

@ -16,6 +16,10 @@
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
int
BSIM4v7getic(
@ -25,8 +29,17 @@ CKTcircuit *ckt)
BSIM4v7model *model = (BSIM4v7model*)inModel;
BSIM4v7instance *here;
for (; model ; model = BSIM4v7nextModel(model))
{ for (here = BSIM4v7instances(model); here; here = BSIM4v7nextInstance(here))
#ifdef USE_CUSPICE
int i, status;
#endif
for (; model; model = BSIM4v7nextModel(model)) {
#ifdef USE_CUSPICE
i = 0;
#endif
for (here = BSIM4v7instances(model); here; here = BSIM4v7nextInstance(here))
{
if (!here->BSIM4v7icVDSGiven)
{ here->BSIM4v7icVDS = *(ckt->CKTrhs + here->BSIM4v7dNode)
@ -40,7 +53,23 @@ BSIM4v7instance *here;
{ here->BSIM4v7icVBS = *(ckt->CKTrhs + here->BSIM4v7bNode)
- *(ckt->CKTrhs + here->BSIM4v7sNode);
}
#ifdef USE_CUSPICE
model->BSIM4v7paramCPU.BSIM4v7icVDSArray [i] = here->BSIM4v7icVDS;
model->BSIM4v7paramCPU.BSIM4v7icVGSArray [i] = here->BSIM4v7icVGS;
model->BSIM4v7paramCPU.BSIM4v7icVBSArray [i] = here->BSIM4v7icVBS;
i++;
#endif
}
#ifdef USE_CUSPICE
status = cuBSIM4v7getic ((GENmodel *)model);
if (status != 0)
return E_NOMEM;
#endif
}
return(OK);
}

View File

@ -35,6 +35,10 @@
#include "ngspice/cpextern.h"
#endif
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
#define MAX_EXP 5.834617425e14
#define MIN_EXP 1.713908431e-15
#define EXP_THRESHOLD 34.0
@ -2582,6 +2586,568 @@ do { if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NUL
}
}
#ifdef USE_CUSPICE
int i, j, jRHS, l, lRHS, status ;
/* Counting the instances */
for (model = (BSIM4v7model *)inModel ; model != NULL ; model = BSIM4v7nextModel(model))
{
i = 0 ;
for (here = BSIM4v7instances(model); here != NULL ; here = BSIM4v7nextInstance(here))
{
i++ ;
}
/* How much instances we have */
model->n_instances = i ;
}
/* loop through all the BSIM4v7 models */
for (model = (BSIM4v7model *)inModel ; model != NULL ; model = BSIM4v7nextModel(model))
{
/* Position Vector Allocation */
model->PositionVector = TMALLOC (int, model->n_instances) ;
/* Position Vector Allocation for the RHS */
model->PositionVectorRHS = TMALLOC (int, model->n_instances) ;
model->offset = ckt->total_n_values ;
model->offsetRHS = ckt->total_n_valuesRHS ;
i = 0 ;
j = 0 ;
jRHS = 0 ;
l = 0 ;
lRHS = 0 ;
/* loop through all the instances of the model */
for (here = BSIM4v7instances(model); here != NULL ; here = BSIM4v7nextInstance(here))
{
/* Position Vector Assignment */
model->PositionVector [i] = model->offset + l ;
/* Position Vector Assignment for the RHS */
model->PositionVectorRHS [i] = model->offsetRHS + lRHS ;
/* For the Matrix */
if (here->BSIM4v7rgateMod == 1)
{
/* m * geltd */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7gNodeExt != 0))
j++ ;
/* m * geltd */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7gNodeExt != 0))
j++ ;
/* m * geltd */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7gNodePrime != 0))
j++ ;
/* m * (gcggb + geltd - ggtg + gIgtotg) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7gNodePrime != 0))
j++ ;
/* m * (gcgdb - ggtd + gIgtotd) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7dNodePrime != 0))
j++ ;
/* m * (gcgsb - ggts + gIgtots) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7sNodePrime != 0))
j++ ;
/* m * (gcgbb - ggtb + gIgtotb) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7bNodePrime != 0))
j++ ;
/* Different Values for the CKTloadOutput */
l += 5 ;
}
else if (here->BSIM4v7rgateMod == 2)
{
/* m * gcrg */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7gNodeExt != 0))
j++ ;
/* m * gcrgg */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7gNodePrime != 0))
j++ ;
/* m * gcrgd */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7dNodePrime != 0))
j++ ;
/* m * gcrgs */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7sNodePrime != 0))
j++ ;
/* m * gcrgb */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7bNodePrime != 0))
j++ ;
/* m * gcrg */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7gNodeExt != 0))
j++ ;
/* m * (gcggb - gcrgg - ggtg + gIgtotg) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7gNodePrime != 0))
j++ ;
/* m * (gcgdb - gcrgd - ggtd + gIgtotd) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7dNodePrime != 0))
j++ ;
/* m * (gcgsb - gcrgs - ggts + gIgtots) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7sNodePrime != 0))
j++ ;
/* m * (gcgbb - gcrgb - ggtb + gIgtotb) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7bNodePrime != 0))
j++ ;
/* Different Values for the CKTloadOutput */
l += 9 ;
}
else if (here->BSIM4v7rgateMod == 3)
{
/* m * geltd */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7gNodeExt != 0))
j++ ;
/* m * geltd */
if ((here->BSIM4v7gNodeExt != 0) && (here->BSIM4v7gNodeMid != 0))
j++ ;
/* m * geltd */
if ((here->BSIM4v7gNodeMid != 0) && (here->BSIM4v7gNodeExt != 0))
j++ ;
/* m * (geltd + gcrg + gcgmgmb) */
if ((here->BSIM4v7gNodeMid != 0) && (here->BSIM4v7gNodeMid != 0))
j++ ;
/* m * (gcrgd + gcgmdb) */
if ((here->BSIM4v7gNodeMid != 0) && (here->BSIM4v7dNodePrime != 0))
j++ ;
/* m * gcrgg */
if ((here->BSIM4v7gNodeMid != 0) && (here->BSIM4v7gNodePrime != 0))
j++ ;
/* m * (gcrgs + gcgmsb) */
if ((here->BSIM4v7gNodeMid != 0) && (here->BSIM4v7sNodePrime != 0))
j++ ;
/* m * (gcrgb + gcgmbb) */
if ((here->BSIM4v7gNodeMid != 0) && (here->BSIM4v7bNodePrime != 0))
j++ ;
/* m * gcdgmb */
if ((here->BSIM4v7dNodePrime != 0) && (here->BSIM4v7gNodeMid != 0))
j++ ;
/* m * gcrg */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7gNodeMid != 0))
j++ ;
/* m * gcsgmb */
if ((here->BSIM4v7sNodePrime != 0) && (here->BSIM4v7gNodeMid != 0))
j++ ;
/* m * gcbgmb */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7gNodeMid != 0))
j++ ;
/* m * (gcggb - gcrgg - ggtg + gIgtotg) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7gNodePrime != 0))
j++ ;
/* m * (gcgdb - gcrgd - ggtd + gIgtotd) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7dNodePrime != 0))
j++ ;
/* m * (gcgsb - gcrgs - ggts + gIgtots) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7sNodePrime != 0))
j++ ;
/* m * (gcgbb - gcrgb - ggtb + gIgtotb) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7bNodePrime != 0))
j++ ;
/* Different Values for the CKTloadOutput */
l += 14 ;
} else {
/* m * (gcggb - ggtg + gIgtotg) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7gNodePrime != 0))
j++ ;
/* m * (gcgdb - ggtd + gIgtotd) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7dNodePrime != 0))
j++ ;
/* m * (gcgsb - ggts + gIgtots) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7sNodePrime != 0))
j++ ;
/* m * (gcgbb - ggtb + gIgtotb) */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7bNodePrime != 0))
j++ ;
/* Different Values for the CKTloadOutput */
l += 4 ;
}
if (model->BSIM4v7rdsMod)
{
/* m * gdtotg */
if ((here->BSIM4v7dNode != 0) && (here->BSIM4v7gNodePrime != 0))
j++ ;
/* m * gdtots */
if ((here->BSIM4v7dNode != 0) && (here->BSIM4v7sNodePrime != 0))
j++ ;
/* m * gdtotb */
if ((here->BSIM4v7dNode != 0) && (here->BSIM4v7bNodePrime != 0))
j++ ;
/* m * gstotd */
if ((here->BSIM4v7sNode != 0) && (here->BSIM4v7dNodePrime != 0))
j++ ;
/* m * gstotg */
if ((here->BSIM4v7sNode != 0) && (here->BSIM4v7gNodePrime != 0))
j++ ;
/* m * gstotb */
if ((here->BSIM4v7sNode != 0) && (here->BSIM4v7bNodePrime != 0))
j++ ;
/* Different Values for the CKTloadOutput */
l += 4 ;
}
/* m * (gdpr + here->BSIM4v7gds + here->BSIM4v7gbd + T1 * ddxpart_dVd -
gdtotd + RevSum + gcddb + gbdpdp + dxpart * ggtd - gIdtotd) + m * ggidld */
if ((here->BSIM4v7dNodePrime != 0) && (here->BSIM4v7dNodePrime != 0))
j++ ;
/* m * (gdpr + gdtot) */
if ((here->BSIM4v7dNodePrime != 0) && (here->BSIM4v7dNode != 0))
j++ ;
/* m * (Gm + gcdgb - gdtotg + gbdpg - gIdtotg + dxpart * ggtg + T1 * ddxpart_dVg) + m * ggidlg */
if ((here->BSIM4v7dNodePrime != 0) && (here->BSIM4v7gNodePrime != 0))
j++ ;
/* m * (here->BSIM4v7gds + gdtots - dxpart * ggts + gIdtots -
T1 * ddxpart_dVs + FwdSum - gcdsb - gbdpsp) + m * (ggidlg + ggidld + ggidlb) */
if ((here->BSIM4v7dNodePrime != 0) && (here->BSIM4v7sNodePrime != 0))
j++ ;
/* m * (gjbd + gdtotb - Gmbs - gcdbb - gbdpb + gIdtotb - T1 * ddxpart_dVb - dxpart * ggtb) - m * ggidlb */
if ((here->BSIM4v7dNodePrime != 0) && (here->BSIM4v7bNodePrime != 0))
j++ ;
/* m * (gdpr - gdtotd) */
if ((here->BSIM4v7dNode != 0) && (here->BSIM4v7dNodePrime != 0))
j++ ;
/* m * (gdpr + gdtot) */
if ((here->BSIM4v7dNode != 0) && (here->BSIM4v7dNode != 0))
j++ ;
/* m * (here->BSIM4v7gds + gstotd + RevSum - gcsdb - gbspdp -
T1 * dsxpart_dVd - sxpart * ggtd + gIstotd) + m * (ggisls + ggislg + ggislb) */
if ((here->BSIM4v7sNodePrime != 0) && (here->BSIM4v7dNodePrime != 0))
j++ ;
/* m * (gcsgb - Gm - gstotg + gbspg + sxpart * ggtg + T1 * dsxpart_dVg - gIstotg) + m * ggislg */
if ((here->BSIM4v7sNodePrime != 0) && (here->BSIM4v7gNodePrime != 0))
j++ ;
/* m * (gspr + here->BSIM4v7gds + here->BSIM4v7gbs + T1 * dsxpart_dVs -
gstots + FwdSum + gcssb + gbspsp + sxpart * ggts - gIstots) + m * ggisls */
if ((here->BSIM4v7sNodePrime != 0) && (here->BSIM4v7sNodePrime != 0))
j++ ;
/* m * (gspr + gstot) */
if ((here->BSIM4v7sNodePrime != 0) && (here->BSIM4v7sNode != 0))
j++ ;
/* m * (gjbs + gstotb + Gmbs - gcsbb - gbspb - sxpart * ggtb - T1 * dsxpart_dVb + gIstotb) - m * ggislb */
if ((here->BSIM4v7sNodePrime != 0) && (here->BSIM4v7bNodePrime != 0))
j++ ;
/* m * (gspr - gstots) */
if ((here->BSIM4v7sNode != 0) && (here->BSIM4v7sNodePrime != 0))
j++ ;
/* m * (gspr + gstot) */
if ((here->BSIM4v7sNode != 0) && (here->BSIM4v7sNode != 0))
j++ ;
/* m * (gcbdb - gjbd + gbbdp - gIbtotd) - m * ggidld + m * (ggislg + ggisls + ggislb) */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7dNodePrime != 0))
j++ ;
/* m * (gcbgb - here->BSIM4v7gbgs - gIbtotg) - m * ggidlg - m * ggislg */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7gNodePrime != 0))
j++ ;
/* m * (gcbsb - gjbs + gbbsp - gIbtots) + m * (ggidlg + ggidld + ggidlb) - m * ggisls */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7sNodePrime != 0))
j++ ;
/* m * (gjbd + gjbs + gcbbb - here->BSIM4v7gbbs - gIbtotb) - m * ggidlb - m * ggislb */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7bNodePrime != 0))
j++ ;
/* Different Values for the CKTloadOutput */
l += 16 ;
if (here->BSIM4v7rbodyMod)
{
/* m * (gcdbdb - here->BSIM4v7gbd) */
if ((here->BSIM4v7dNodePrime != 0) && (here->BSIM4v7dbNode != 0))
j++ ;
/* m * (here->BSIM4v7gbs - gcsbsb) */
if ((here->BSIM4v7sNodePrime != 0) && (here->BSIM4v7sbNode != 0))
j++ ;
/* m * (gcdbdb - here->BSIM4v7gbd) */
if ((here->BSIM4v7dbNode != 0) && (here->BSIM4v7dNodePrime != 0))
j++ ;
/* m * (here->BSIM4v7gbd - gcdbdb + here->BSIM4v7grbpd + here->BSIM4v7grbdb) */
if ((here->BSIM4v7dbNode != 0) && (here->BSIM4v7dbNode != 0))
j++ ;
/* m * here->BSIM4v7grbpd */
if ((here->BSIM4v7dbNode != 0) && (here->BSIM4v7bNodePrime != 0))
j++ ;
/* m * here->BSIM4v7grbdb */
if ((here->BSIM4v7dbNode != 0) && (here->BSIM4v7bNode != 0))
j++ ;
/* m * here->BSIM4v7grbpd */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7dbNode != 0))
j++ ;
/* m * here->BSIM4v7grbpb */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7bNode != 0))
j++ ;
/* m * here->BSIM4v7grbps */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7sbNode != 0))
j++ ;
/* m * (here->BSIM4v7grbpd + here->BSIM4v7grbps + here->BSIM4v7grbpb) */
if ((here->BSIM4v7bNodePrime != 0) && (here->BSIM4v7bNodePrime != 0))
j++ ;
/* m * (gcsbsb - here->BSIM4v7gbs) */
if ((here->BSIM4v7sbNode != 0) && (here->BSIM4v7sNodePrime != 0))
j++ ;
/* m * here->BSIM4v7grbps */
if ((here->BSIM4v7sbNode != 0) && (here->BSIM4v7bNodePrime != 0))
j++ ;
/* m * here->BSIM4v7grbsb */
if ((here->BSIM4v7sbNode != 0) && (here->BSIM4v7bNode != 0))
j++ ;
/* m * (here->BSIM4v7gbs - gcsbsb + here->BSIM4v7grbps + here->BSIM4v7grbsb) */
if ((here->BSIM4v7sbNode != 0) && (here->BSIM4v7sbNode != 0))
j++ ;
/* m * here->BSIM4v7grbdb */
if ((here->BSIM4v7bNode != 0) && (here->BSIM4v7dbNode != 0))
j++ ;
/* m * here->BSIM4v7grbpb */
if ((here->BSIM4v7bNode != 0) && (here->BSIM4v7bNodePrime != 0))
j++ ;
/* m * here->BSIM4v7grbsb */
if ((here->BSIM4v7bNode != 0) && (here->BSIM4v7sbNode != 0))
j++ ;
/* m * (here->BSIM4v7grbsb + here->BSIM4v7grbdb + here->BSIM4v7grbpb) */
if ((here->BSIM4v7bNode != 0) && (here->BSIM4v7bNode != 0))
j++ ;
/* Different Values for the CKTloadOutput */
l += 12 ;
}
if (here->BSIM4v7trnqsMod)
{
/* m * (gqdef + here->BSIM4v7gtau) */
if ((here->BSIM4v7qNode != 0) && (here->BSIM4v7qNode != 0))
j++ ;
/* m * (ggtg - gcqgb) */
if ((here->BSIM4v7qNode != 0) && (here->BSIM4v7gNodePrime != 0))
j++ ;
/* m * (ggtd - gcqdb) */
if ((here->BSIM4v7qNode != 0) && (here->BSIM4v7dNodePrime != 0))
j++ ;
/* m * (ggts - gcqsb) */
if ((here->BSIM4v7qNode != 0) && (here->BSIM4v7sNodePrime != 0))
j++ ;
/* m * (ggtb - gcqbb) */
if ((here->BSIM4v7qNode != 0) && (here->BSIM4v7bNodePrime != 0))
j++ ;
/* m * dxpart * here->BSIM4v7gtau */
if ((here->BSIM4v7dNodePrime != 0) && (here->BSIM4v7qNode != 0))
j++ ;
/* m * sxpart * here->BSIM4v7gtau */
if ((here->BSIM4v7sNodePrime != 0) && (here->BSIM4v7qNode != 0))
j++ ;
/* m * here->BSIM4v7gtau */
if ((here->BSIM4v7gNodePrime != 0) && (here->BSIM4v7qNode != 0))
j++ ;
/* Different Values for the CKTloadOutput */
l += 8 ;
}
/* For the RHS */
/* m * (ceqjd - ceqbd + ceqgdtot - ceqdrn - ceqqd + Idtoteq) */
if (here->BSIM4v7dNodePrime != 0)
jRHS++ ;
/* m * (ceqqg - ceqgcrg + Igtoteq) */
if (here->BSIM4v7gNodePrime != 0)
jRHS++ ;
/* Different Values for the CKTloadOutputRHS */
lRHS += 2 ;
if (here->BSIM4v7rgateMod == 2)
{
/* m * ceqgcrg */
if (here->BSIM4v7gNodeExt != 0)
jRHS++ ;
/* Different Values for the CKTloadOutputRHS */
lRHS += 1 ;
}
else if (here->BSIM4v7rgateMod == 3)
{
/* m * (ceqqgmid + ceqgcrg) */
if (here->BSIM4v7gNodeMid != 0)
jRHS++ ;
/* Different Values for the CKTloadOutputRHS */
lRHS += 1 ;
}
if (!here->BSIM4v7rbodyMod)
{
/* m * (ceqbd + ceqbs - ceqjd - ceqjs - ceqqb + Ibtoteq) */
if (here->BSIM4v7bNodePrime != 0)
jRHS++ ;
/* m * (ceqdrn - ceqbs + ceqjs + ceqqg + ceqqb + ceqqd + ceqqgmid - ceqgstot + Istoteq) */
if (here->BSIM4v7sNodePrime != 0)
jRHS++ ;
/* Different Values for the CKTloadOutputRHS */
lRHS += 2 ;
} else {
/* m * (ceqjd + ceqqjd) */
if (here->BSIM4v7dbNode != 0)
jRHS++ ;
/* m * (ceqbd + ceqbs - ceqqb + Ibtoteq) */
if (here->BSIM4v7bNodePrime != 0)
jRHS++ ;
/* m * (ceqjs + ceqqjs) */
if (here->BSIM4v7sbNode != 0)
jRHS++ ;
/* m * (ceqdrn - ceqbs + ceqjs + ceqqd + ceqqg + ceqqb +
ceqqjd + ceqqjs + ceqqgmid - ceqgstot + Istoteq) */
if (here->BSIM4v7sNodePrime != 0)
jRHS++ ;
/* Different Values for the CKTloadOutputRHS */
lRHS += 4 ;
}
if (model->BSIM4v7rdsMod)
{
/* m * ceqgdtot */
if (here->BSIM4v7dNode != 0)
jRHS++ ;
/* m * ceqgstot */
if (here->BSIM4v7sNode != 0)
jRHS++ ;
/* Different Values for the CKTloadOutputRHS */
lRHS += 2 ;
}
if (here->BSIM4v7trnqsMod)
{
/* m * (cqcheq - cqdef) */
if (here->BSIM4v7qNode != 0)
jRHS++ ;
/* Different Values for the CKTloadOutputRHS */
lRHS += 1 ;
}
i++ ;
}
model->n_values = l ;
ckt->total_n_values += model->n_values ;
model->n_Ptr = j ;
ckt->total_n_Ptr += model->n_Ptr ;
model->n_valuesRHS = lRHS ;
ckt->total_n_valuesRHS += model->n_valuesRHS ;
model->n_PtrRHS = jRHS ;
ckt->total_n_PtrRHS += model->n_PtrRHS ;
}
/* loop through all the BSIM4v7 models */
for (model = (BSIM4v7model *)inModel ; model != NULL ; model = BSIM4v7nextModel(model))
{
status = cuBSIM4v7setup ((GENmodel *)model) ;
if (status != 0)
return (E_NOMEM) ;
}
#endif
#ifdef USE_OMP
InstCount = 0;
model = (BSIM4v7model*)inModel;

View File

@ -30,6 +30,10 @@
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
#define Kb 1.3806226e-23
#define KboQ 8.617087e-5
#define EPS0 8.85418e-12
@ -91,6 +95,10 @@ double vtfbphi2eot, phieot, TempRatioeot, Vtm0eot, Vtmeot,vbieot;
int Size_Not_Found, i;
#ifdef USE_CUSPICE
int j, status;
#endif
/* loop through all the BSIM4v7 device models */
for (; model != NULL; model = BSIM4v7nextModel(model))
{ Temp = ckt->CKTtemp;
@ -404,6 +412,9 @@ int Size_Not_Found, i;
fprintf(stderr, "BVS reset to %g.\n", model->BSIM4v7bvs);
}
#ifdef USE_CUSPICE
j = 0;
#endif
/* loop through all the instances of the model */
for (here = BSIM4v7instances(model); here != NULL;
@ -2309,7 +2320,199 @@ int Size_Not_Found, i;
SPfrontEnd->IFerrorf (ERR_FATAL, "Fatal error(s) detected during BSIM4v7.6.0 parameter checking for %s in model %s", model->BSIM4v7modName, here->BSIM4v7name);
return(E_BADPARM);
}
#ifdef USE_CUSPICE
model->BSIM4v7paramCPU.BSIM4v7gbsRWArray [j] = here->BSIM4v7gbs;
model->BSIM4v7paramCPU.BSIM4v7cbsRWArray [j] = here->BSIM4v7cbs;
model->BSIM4v7paramCPU.BSIM4v7gbdRWArray [j] = here->BSIM4v7gbd;
model->BSIM4v7paramCPU.BSIM4v7cbdRWArray [j] = here->BSIM4v7cbd;
model->BSIM4v7paramCPU.BSIM4v7vonRWArray [j] = here->BSIM4v7von;
model->BSIM4v7paramCPU.BSIM4v7vdsatRWArray [j] = here->BSIM4v7vdsat;
model->BSIM4v7paramCPU.BSIM4v7csubRWArray [j] = here->BSIM4v7csub;
model->BSIM4v7paramCPU.BSIM4v7gdsRWArray [j] = here->BSIM4v7gds;
model->BSIM4v7paramCPU.BSIM4v7gmRWArray [j] = here->BSIM4v7gm;
model->BSIM4v7paramCPU.BSIM4v7gmbsRWArray [j] = here->BSIM4v7gmbs;
model->BSIM4v7paramCPU.BSIM4v7gcrgRWArray [j] = here->BSIM4v7gcrg;
model->BSIM4v7paramCPU.BSIM4v7IgidlRWArray [j] = here->BSIM4v7Igidl;
model->BSIM4v7paramCPU.BSIM4v7IgislRWArray [j] = here->BSIM4v7Igisl;
model->BSIM4v7paramCPU.BSIM4v7IgcsRWArray [j] = here->BSIM4v7Igcs;
model->BSIM4v7paramCPU.BSIM4v7IgcdRWArray [j] = here->BSIM4v7Igcd;
model->BSIM4v7paramCPU.BSIM4v7IgsRWArray [j] = here->BSIM4v7Igs;
model->BSIM4v7paramCPU.BSIM4v7IgdRWArray [j] = here->BSIM4v7Igd;
model->BSIM4v7paramCPU.BSIM4v7IgbRWArray [j] = here->BSIM4v7Igb;
model->BSIM4v7paramCPU.BSIM4v7cdRWArray [j] = here->BSIM4v7cd;
model->BSIM4v7paramCPU.BSIM4v7qinvRWArray [j] = here->BSIM4v7qinv;
model->BSIM4v7paramCPU.BSIM4v7cggbRWArray [j] = here->BSIM4v7cggb;
model->BSIM4v7paramCPU.BSIM4v7cgsbRWArray [j] = here->BSIM4v7cgsb;
model->BSIM4v7paramCPU.BSIM4v7cgdbRWArray [j] = here->BSIM4v7cgdb;
model->BSIM4v7paramCPU.BSIM4v7cdgbRWArray [j] = here->BSIM4v7cdgb;
model->BSIM4v7paramCPU.BSIM4v7cdsbRWArray [j] = here->BSIM4v7cdsb;
model->BSIM4v7paramCPU.BSIM4v7cddbRWArray [j] = here->BSIM4v7cddb;
model->BSIM4v7paramCPU.BSIM4v7cbgbRWArray [j] = here->BSIM4v7cbgb;
model->BSIM4v7paramCPU.BSIM4v7cbsbRWArray [j] = here->BSIM4v7cbsb;
model->BSIM4v7paramCPU.BSIM4v7cbdbRWArray [j] = here->BSIM4v7cbdb;
model->BSIM4v7paramCPU.BSIM4v7csgbRWArray [j] = here->BSIM4v7csgb;
model->BSIM4v7paramCPU.BSIM4v7cssbRWArray [j] = here->BSIM4v7cssb;
model->BSIM4v7paramCPU.BSIM4v7csdbRWArray [j] = here->BSIM4v7csdb;
model->BSIM4v7paramCPU.BSIM4v7cgbbRWArray [j] = here->BSIM4v7cgbb;
model->BSIM4v7paramCPU.BSIM4v7csbbRWArray [j] = here->BSIM4v7csbb;
model->BSIM4v7paramCPU.BSIM4v7cdbbRWArray [j] = here->BSIM4v7cdbb;
model->BSIM4v7paramCPU.BSIM4v7cbbbRWArray [j] = here->BSIM4v7cbbb;
model->BSIM4v7paramCPU.BSIM4v7gtauRWArray [j] = here->BSIM4v7gtau;
model->BSIM4v7paramCPU.BSIM4v7qgateRWArray [j] = here->BSIM4v7qgate;
model->BSIM4v7paramCPU.BSIM4v7qbulkRWArray [j] = here->BSIM4v7qbulk;
model->BSIM4v7paramCPU.BSIM4v7qdrnRWArray [j] = here->BSIM4v7qdrn;
model->BSIM4v7paramCPU.BSIM4v7qsrcRWArray [j] = here->BSIM4v7qsrc;
model->BSIM4v7paramCPU.BSIM4v7capbsRWArray [j] = here->BSIM4v7capbs;
model->BSIM4v7paramCPU.BSIM4v7capbdRWArray [j] = here->BSIM4v7capbd;
model->BSIM4v7paramCPU.BSIM4v7icVDSArray [j] = here->BSIM4v7icVDS;
model->BSIM4v7paramCPU.BSIM4v7icVGSArray [j] = here->BSIM4v7icVGS;
model->BSIM4v7paramCPU.BSIM4v7icVBSArray [j] = here->BSIM4v7icVBS;
model->BSIM4v7paramCPU.BSIM4v7vth0Array [j] = here->BSIM4v7vth0;
model->BSIM4v7paramCPU.BSIM4v7gbbsArray [j] = here->BSIM4v7gbbs;
model->BSIM4v7paramCPU.BSIM4v7ggidlbArray [j] = here->BSIM4v7ggidlb;
model->BSIM4v7paramCPU.BSIM4v7gbgsArray [j] = here->BSIM4v7gbgs;
model->BSIM4v7paramCPU.BSIM4v7ggidlgArray [j] = here->BSIM4v7ggidlg;
model->BSIM4v7paramCPU.BSIM4v7gbdsArray [j] = here->BSIM4v7gbds;
model->BSIM4v7paramCPU.BSIM4v7ggidldArray [j] = here->BSIM4v7ggidld;
model->BSIM4v7paramCPU.BSIM4v7ggislsArray [j] = here->BSIM4v7ggisls;
model->BSIM4v7paramCPU.BSIM4v7ggislgArray [j] = here->BSIM4v7ggislg;
model->BSIM4v7paramCPU.BSIM4v7ggislbArray [j] = here->BSIM4v7ggislb;
model->BSIM4v7paramCPU.BSIM4v7gIgsgArray [j] = here->BSIM4v7gIgsg;
model->BSIM4v7paramCPU.BSIM4v7gIgcsgArray [j] = here->BSIM4v7gIgcsg;
model->BSIM4v7paramCPU.BSIM4v7gIgcsdArray [j] = here->BSIM4v7gIgcsd;
model->BSIM4v7paramCPU.BSIM4v7gIgcsbArray [j] = here->BSIM4v7gIgcsb;
model->BSIM4v7paramCPU.BSIM4v7gIgdgArray [j] = here->BSIM4v7gIgdg;
model->BSIM4v7paramCPU.BSIM4v7gIgcdgArray [j] = here->BSIM4v7gIgcdg;
model->BSIM4v7paramCPU.BSIM4v7gIgcddArray [j] = here->BSIM4v7gIgcdd;
model->BSIM4v7paramCPU.BSIM4v7gIgcdbArray [j] = here->BSIM4v7gIgcdb;
model->BSIM4v7paramCPU.BSIM4v7gIgbgArray [j] = here->BSIM4v7gIgbg;
model->BSIM4v7paramCPU.BSIM4v7gIgbdArray [j] = here->BSIM4v7gIgbd;
model->BSIM4v7paramCPU.BSIM4v7gIgbbArray [j] = here->BSIM4v7gIgbb;
model->BSIM4v7paramCPU.BSIM4v7ggidlsArray [j] = here->BSIM4v7ggidls;
model->BSIM4v7paramCPU.BSIM4v7ggisldArray [j] = here->BSIM4v7ggisld;
model->BSIM4v7paramCPU.BSIM4v7gstotArray [j] = here->BSIM4v7gstot;
model->BSIM4v7paramCPU.BSIM4v7gstotdArray [j] = here->BSIM4v7gstotd;
model->BSIM4v7paramCPU.BSIM4v7gstotgArray [j] = here->BSIM4v7gstotg;
model->BSIM4v7paramCPU.BSIM4v7gstotbArray [j] = here->BSIM4v7gstotb;
model->BSIM4v7paramCPU.BSIM4v7gdtotArray [j] = here->BSIM4v7gdtot;
model->BSIM4v7paramCPU.BSIM4v7gdtotdArray [j] = here->BSIM4v7gdtotd;
model->BSIM4v7paramCPU.BSIM4v7gdtotgArray [j] = here->BSIM4v7gdtotg;
model->BSIM4v7paramCPU.BSIM4v7gdtotbArray [j] = here->BSIM4v7gdtotb;
model->BSIM4v7paramCPU.BSIM4v7cgdoArray [j] = here->BSIM4v7cgdo;
model->BSIM4v7paramCPU.BSIM4v7qgdoArray [j] = here->BSIM4v7qgdo;
model->BSIM4v7paramCPU.BSIM4v7cgsoArray [j] = here->BSIM4v7cgso;
model->BSIM4v7paramCPU.BSIM4v7qgsoArray [j] = here->BSIM4v7qgso;
model->BSIM4v7paramCPU.BSIM4v7AseffArray [j] = here->BSIM4v7Aseff;
model->BSIM4v7paramCPU.BSIM4v7PseffArray [j] = here->BSIM4v7Pseff;
model->BSIM4v7paramCPU.BSIM4v7nfArray [j] = here->BSIM4v7nf;
model->BSIM4v7paramCPU.BSIM4v7XExpBVSArray [j] = here->BSIM4v7XExpBVS;
model->BSIM4v7paramCPU.BSIM4v7vjsmFwdArray [j] = here->BSIM4v7vjsmFwd;
model->BSIM4v7paramCPU.BSIM4v7IVjsmFwdArray [j] = here->BSIM4v7IVjsmFwd;
model->BSIM4v7paramCPU.BSIM4v7vjsmRevArray [j] = here->BSIM4v7vjsmRev;
model->BSIM4v7paramCPU.BSIM4v7IVjsmRevArray [j] = here->BSIM4v7IVjsmRev;
model->BSIM4v7paramCPU.BSIM4v7SslpRevArray [j] = here->BSIM4v7SslpRev;
model->BSIM4v7paramCPU.BSIM4v7SslpFwdArray [j] = here->BSIM4v7SslpFwd;
model->BSIM4v7paramCPU.BSIM4v7AdeffArray [j] = here->BSIM4v7Adeff;
model->BSIM4v7paramCPU.BSIM4v7PdeffArray [j] = here->BSIM4v7Pdeff;
model->BSIM4v7paramCPU.BSIM4v7XExpBVDArray [j] = here->BSIM4v7XExpBVD;
model->BSIM4v7paramCPU.BSIM4v7vjdmFwdArray [j] = here->BSIM4v7vjdmFwd;
model->BSIM4v7paramCPU.BSIM4v7IVjdmFwdArray [j] = here->BSIM4v7IVjdmFwd;
model->BSIM4v7paramCPU.BSIM4v7vjdmRevArray [j] = here->BSIM4v7vjdmRev;
model->BSIM4v7paramCPU.BSIM4v7IVjdmRevArray [j] = here->BSIM4v7IVjdmRev;
model->BSIM4v7paramCPU.BSIM4v7DslpRevArray [j] = here->BSIM4v7DslpRev;
model->BSIM4v7paramCPU.BSIM4v7DslpFwdArray [j] = here->BSIM4v7DslpFwd;
model->BSIM4v7paramCPU.BSIM4v7SjctTempRevSatCurArray [j] = here->BSIM4v7SjctTempRevSatCur;
model->BSIM4v7paramCPU.BSIM4v7SswTempRevSatCurArray [j] = here->BSIM4v7SswTempRevSatCur;
model->BSIM4v7paramCPU.BSIM4v7SswgTempRevSatCurArray [j] = here->BSIM4v7SswgTempRevSatCur;
model->BSIM4v7paramCPU.BSIM4v7DjctTempRevSatCurArray [j] = here->BSIM4v7DjctTempRevSatCur;
model->BSIM4v7paramCPU.BSIM4v7DswTempRevSatCurArray [j] = here->BSIM4v7DswTempRevSatCur;
model->BSIM4v7paramCPU.BSIM4v7DswgTempRevSatCurArray [j] = here->BSIM4v7DswgTempRevSatCur;
model->BSIM4v7paramCPU.BSIM4v7vbscArray [j] = here->BSIM4v7vbsc;
model->BSIM4v7paramCPU.BSIM4v7thetavthArray [j] = here->BSIM4v7thetavth;
model->BSIM4v7paramCPU.BSIM4v7eta0Array [j] = here->BSIM4v7eta0;
model->BSIM4v7paramCPU.BSIM4v7k2oxArray [j] = here->BSIM4v7k2ox;
model->BSIM4v7paramCPU.BSIM4v7nstarArray [j] = here->BSIM4v7nstar;
model->BSIM4v7paramCPU.BSIM4v7vfbArray [j] = here->BSIM4v7vfb;
model->BSIM4v7paramCPU.BSIM4v7vgs_effArray [j] = here->BSIM4v7vgs_eff;
model->BSIM4v7paramCPU.BSIM4v7vgd_effArray [j] = here->BSIM4v7vgd_eff;
model->BSIM4v7paramCPU.BSIM4v7dvgs_eff_dvgArray [j] = here->BSIM4v7dvgs_eff_dvg;
model->BSIM4v7paramCPU.BSIM4v7dvgd_eff_dvgArray [j] = here->BSIM4v7dvgd_eff_dvg;
model->BSIM4v7paramCPU.BSIM4v7VgsteffArray [j] = here->BSIM4v7Vgsteff;
model->BSIM4v7paramCPU.BSIM4v7grdswArray [j] = here->BSIM4v7grdsw;
model->BSIM4v7paramCPU.BSIM4v7AbulkArray [j] = here->BSIM4v7Abulk;
model->BSIM4v7paramCPU.BSIM4v7vtfbphi1Array [j] = here->BSIM4v7vtfbphi1;
model->BSIM4v7paramCPU.BSIM4v7ueffArray [j] = here->BSIM4v7ueff;
model->BSIM4v7paramCPU.BSIM4v7u0tempArray [j] = here->BSIM4v7u0temp;
model->BSIM4v7paramCPU.BSIM4v7vsattempArray [j] = here->BSIM4v7vsattemp;
model->BSIM4v7paramCPU.BSIM4v7EsatLArray [j] = here->BSIM4v7EsatL;
model->BSIM4v7paramCPU.BSIM4v7VdseffArray [j] = here->BSIM4v7Vdseff;
model->BSIM4v7paramCPU.BSIM4v7vtfbphi2Array [j] = here->BSIM4v7vtfbphi2;
model->BSIM4v7paramCPU.BSIM4v7CoxeffArray [j] = here->BSIM4v7Coxeff;
model->BSIM4v7paramCPU.BSIM4v7AbovVgst2VtmArray [j] = here->BSIM4v7AbovVgst2Vtm;
model->BSIM4v7paramCPU.BSIM4v7IdovVdsArray [j] = here->BSIM4v7IdovVds;
model->BSIM4v7paramCPU.BSIM4v7gcrgdArray [j] = here->BSIM4v7gcrgd;
model->BSIM4v7paramCPU.BSIM4v7gcrgbArray [j] = here->BSIM4v7gcrgb;
model->BSIM4v7paramCPU.BSIM4v7gcrggArray [j] = here->BSIM4v7gcrgg;
model->BSIM4v7paramCPU.BSIM4v7grgeltdArray [j] = here->BSIM4v7grgeltd;
model->BSIM4v7paramCPU.BSIM4v7gcrgsArray [j] = here->BSIM4v7gcrgs;
model->BSIM4v7paramCPU.BSIM4v7sourceConductanceArray [j] = here->BSIM4v7sourceConductance;
model->BSIM4v7paramCPU.BSIM4v7drainConductanceArray [j] = here->BSIM4v7drainConductance;
model->BSIM4v7paramCPU.BSIM4v7gstotsArray [j] = here->BSIM4v7gstots;
model->BSIM4v7paramCPU.BSIM4v7gdtotsArray [j] = here->BSIM4v7gdtots;
model->BSIM4v7paramCPU.BSIM4v7vfbzbArray [j] = here->BSIM4v7vfbzb;
model->BSIM4v7paramCPU.BSIM4v7gIgssArray [j] = here->BSIM4v7gIgss;
model->BSIM4v7paramCPU.BSIM4v7gIgddArray [j] = here->BSIM4v7gIgdd;
model->BSIM4v7paramCPU.BSIM4v7gIgbsArray [j] = here->BSIM4v7gIgbs;
model->BSIM4v7paramCPU.BSIM4v7gIgcssArray [j] = here->BSIM4v7gIgcss;
model->BSIM4v7paramCPU.BSIM4v7gIgcdsArray [j] = here->BSIM4v7gIgcds;
model->BSIM4v7paramCPU.BSIM4v7noiGd0Array [j] = here->BSIM4v7noiGd0;
model->BSIM4v7paramCPU.BSIM4v7cqdbArray [j] = here->BSIM4v7cqdb;
model->BSIM4v7paramCPU.BSIM4v7cqsbArray [j] = here->BSIM4v7cqsb;
model->BSIM4v7paramCPU.BSIM4v7cqgbArray [j] = here->BSIM4v7cqgb;
model->BSIM4v7paramCPU.BSIM4v7qchqsArray [j] = here->BSIM4v7qchqs;
model->BSIM4v7paramCPU.BSIM4v7cqbbArray [j] = here->BSIM4v7cqbb;
model->BSIM4v7paramCPU.BSIM4v7taunetArray [j] = here->BSIM4v7taunet;
model->BSIM4v7paramCPU.BSIM4v7gtgArray [j] = here->BSIM4v7gtg;
model->BSIM4v7paramCPU.BSIM4v7gtdArray [j] = here->BSIM4v7gtd;
model->BSIM4v7paramCPU.BSIM4v7gtsArray [j] = here->BSIM4v7gts;
model->BSIM4v7paramCPU.BSIM4v7gtbArray [j] = here->BSIM4v7gtb;
model->BSIM4v7paramCPU.BSIM4v7mArray [j] = here->BSIM4v7m;
model->BSIM4v7paramCPU.BSIM4v7grbpdArray [j] = here->BSIM4v7grbpd;
model->BSIM4v7paramCPU.BSIM4v7grbdbArray [j] = here->BSIM4v7grbdb;
model->BSIM4v7paramCPU.BSIM4v7grbpbArray [j] = here->BSIM4v7grbpb;
model->BSIM4v7paramCPU.BSIM4v7grbpsArray [j] = here->BSIM4v7grbps;
model->BSIM4v7paramCPU.BSIM4v7grbsbArray [j] = here->BSIM4v7grbsb;
model->BSIM4v7paramCPU.BSIM4v7offArray [j] = here->BSIM4v7off;
model->BSIM4v7paramCPU.BSIM4v7dNodePrimeArray [j] = here->BSIM4v7dNodePrime;
model->BSIM4v7paramCPU.BSIM4v7sNodePrimeArray [j] = here->BSIM4v7sNodePrime;
model->BSIM4v7paramCPU.BSIM4v7gNodePrimeArray [j] = here->BSIM4v7gNodePrime;
model->BSIM4v7paramCPU.BSIM4v7bNodePrimeArray [j] = here->BSIM4v7bNodePrime;
model->BSIM4v7paramCPU.BSIM4v7gNodeExtArray [j] = here->BSIM4v7gNodeExt;
model->BSIM4v7paramCPU.BSIM4v7gNodeMidArray [j] = here->BSIM4v7gNodeMid;
model->BSIM4v7paramCPU.BSIM4v7dbNodeArray [j] = here->BSIM4v7dbNode;
model->BSIM4v7paramCPU.BSIM4v7sbNodeArray [j] = here->BSIM4v7sbNode;
model->BSIM4v7paramCPU.BSIM4v7sNodeArray [j] = here->BSIM4v7sNode;
model->BSIM4v7paramCPU.BSIM4v7dNodeArray [j] = here->BSIM4v7dNode;
model->BSIM4v7paramCPU.BSIM4v7qNodeArray [j] = here->BSIM4v7qNode;
model->BSIM4v7paramCPU.BSIM4v7rbodyModArray [j] = here->BSIM4v7rbodyMod;
model->BSIM4v7paramCPU.BSIM4v7modeArray [j] = here->BSIM4v7mode;
model->BSIM4v7paramCPU.BSIM4v7rgateModArray [j] = here->BSIM4v7rgateMod;
model->BSIM4v7paramCPU.BSIM4v7trnqsModArray [j] = here->BSIM4v7trnqsMod;
model->BSIM4v7paramCPU.BSIM4v7acnqsModArray [j] = here->BSIM4v7acnqsMod;
model->BSIM4v7paramCPU.BSIM4v7statesArray [j] = here->BSIM4v7states;
j++;
#endif
} /* End instance */
#ifdef USE_CUSPICE
status = cuBSIM4v7temp ((GENmodel *)model);
if (status != 0)
return E_NOMEM;
#endif
}
return(OK);
}

View File

@ -887,6 +887,543 @@ struct bsim4SizeDependParam
struct bsim4SizeDependParam *pNext;
};
#ifdef USE_CUSPICE
typedef struct sBSIM4v7paramCPUstruct {
double *BSIM4v7cpuPointersD [243];
#define BSIM4v7gbsRWArray BSIM4v7cpuPointersD[0]
#define BSIM4v7cbsRWArray BSIM4v7cpuPointersD[1]
#define BSIM4v7gbdRWArray BSIM4v7cpuPointersD[2]
#define BSIM4v7cbdRWArray BSIM4v7cpuPointersD[3]
#define BSIM4v7vonRWArray BSIM4v7cpuPointersD[4]
#define BSIM4v7vdsatRWArray BSIM4v7cpuPointersD[5]
#define BSIM4v7csubRWArray BSIM4v7cpuPointersD[6]
#define BSIM4v7gdsRWArray BSIM4v7cpuPointersD[7]
#define BSIM4v7gmRWArray BSIM4v7cpuPointersD[8]
#define BSIM4v7gmbsRWArray BSIM4v7cpuPointersD[9]
#define BSIM4v7gcrgRWArray BSIM4v7cpuPointersD[10]
#define BSIM4v7IgidlRWArray BSIM4v7cpuPointersD[11]
#define BSIM4v7IgislRWArray BSIM4v7cpuPointersD[12]
#define BSIM4v7IgcsRWArray BSIM4v7cpuPointersD[13]
#define BSIM4v7IgcdRWArray BSIM4v7cpuPointersD[14]
#define BSIM4v7IgsRWArray BSIM4v7cpuPointersD[15]
#define BSIM4v7IgdRWArray BSIM4v7cpuPointersD[16]
#define BSIM4v7IgbRWArray BSIM4v7cpuPointersD[17]
#define BSIM4v7cdRWArray BSIM4v7cpuPointersD[18]
#define BSIM4v7qinvRWArray BSIM4v7cpuPointersD[19]
#define BSIM4v7cggbRWArray BSIM4v7cpuPointersD[20]
#define BSIM4v7cgsbRWArray BSIM4v7cpuPointersD[21]
#define BSIM4v7cgdbRWArray BSIM4v7cpuPointersD[22]
#define BSIM4v7cdgbRWArray BSIM4v7cpuPointersD[23]
#define BSIM4v7cdsbRWArray BSIM4v7cpuPointersD[24]
#define BSIM4v7cddbRWArray BSIM4v7cpuPointersD[25]
#define BSIM4v7cbgbRWArray BSIM4v7cpuPointersD[26]
#define BSIM4v7cbsbRWArray BSIM4v7cpuPointersD[27]
#define BSIM4v7cbdbRWArray BSIM4v7cpuPointersD[28]
#define BSIM4v7csgbRWArray BSIM4v7cpuPointersD[29]
#define BSIM4v7cssbRWArray BSIM4v7cpuPointersD[30]
#define BSIM4v7csdbRWArray BSIM4v7cpuPointersD[31]
#define BSIM4v7cgbbRWArray BSIM4v7cpuPointersD[32]
#define BSIM4v7csbbRWArray BSIM4v7cpuPointersD[33]
#define BSIM4v7cdbbRWArray BSIM4v7cpuPointersD[34]
#define BSIM4v7cbbbRWArray BSIM4v7cpuPointersD[35]
#define BSIM4v7gtauRWArray BSIM4v7cpuPointersD[36]
#define BSIM4v7qgateRWArray BSIM4v7cpuPointersD[37]
#define BSIM4v7qbulkRWArray BSIM4v7cpuPointersD[38]
#define BSIM4v7qdrnRWArray BSIM4v7cpuPointersD[39]
#define BSIM4v7qsrcRWArray BSIM4v7cpuPointersD[40]
#define BSIM4v7capbsRWArray BSIM4v7cpuPointersD[41]
#define BSIM4v7capbdRWArray BSIM4v7cpuPointersD[42]
#define BSIM4v7icVDSArray BSIM4v7cpuPointersD[43]
#define BSIM4v7icVGSArray BSIM4v7cpuPointersD[44]
#define BSIM4v7icVBSArray BSIM4v7cpuPointersD[45]
#define BSIM4v7vth0Array BSIM4v7cpuPointersD[46]
#define BSIM4v7gbbsArray BSIM4v7cpuPointersD[47]
#define BSIM4v7ggidlbArray BSIM4v7cpuPointersD[48]
#define BSIM4v7gbgsArray BSIM4v7cpuPointersD[49]
#define BSIM4v7ggidlgArray BSIM4v7cpuPointersD[50]
#define BSIM4v7gbdsArray BSIM4v7cpuPointersD[51]
#define BSIM4v7ggidldArray BSIM4v7cpuPointersD[52]
#define BSIM4v7ggislsArray BSIM4v7cpuPointersD[53]
#define BSIM4v7ggislgArray BSIM4v7cpuPointersD[54]
#define BSIM4v7ggislbArray BSIM4v7cpuPointersD[55]
#define BSIM4v7gIgsgArray BSIM4v7cpuPointersD[56]
#define BSIM4v7gIgcsgArray BSIM4v7cpuPointersD[57]
#define BSIM4v7gIgcsdArray BSIM4v7cpuPointersD[58]
#define BSIM4v7gIgcsbArray BSIM4v7cpuPointersD[59]
#define BSIM4v7gIgdgArray BSIM4v7cpuPointersD[60]
#define BSIM4v7gIgcdgArray BSIM4v7cpuPointersD[61]
#define BSIM4v7gIgcddArray BSIM4v7cpuPointersD[62]
#define BSIM4v7gIgcdbArray BSIM4v7cpuPointersD[63]
#define BSIM4v7gIgbgArray BSIM4v7cpuPointersD[64]
#define BSIM4v7gIgbdArray BSIM4v7cpuPointersD[65]
#define BSIM4v7gIgbbArray BSIM4v7cpuPointersD[66]
#define BSIM4v7ggidlsArray BSIM4v7cpuPointersD[67]
#define BSIM4v7ggisldArray BSIM4v7cpuPointersD[68]
#define BSIM4v7gstotArray BSIM4v7cpuPointersD[69]
#define BSIM4v7gstotdArray BSIM4v7cpuPointersD[70]
#define BSIM4v7gstotgArray BSIM4v7cpuPointersD[71]
#define BSIM4v7gstotbArray BSIM4v7cpuPointersD[72]
#define BSIM4v7gdtotArray BSIM4v7cpuPointersD[73]
#define BSIM4v7gdtotdArray BSIM4v7cpuPointersD[74]
#define BSIM4v7gdtotgArray BSIM4v7cpuPointersD[75]
#define BSIM4v7gdtotbArray BSIM4v7cpuPointersD[76]
#define BSIM4v7cgdoArray BSIM4v7cpuPointersD[77]
#define BSIM4v7qgdoArray BSIM4v7cpuPointersD[78]
#define BSIM4v7cgsoArray BSIM4v7cpuPointersD[79]
#define BSIM4v7qgsoArray BSIM4v7cpuPointersD[80]
#define BSIM4v7AseffArray BSIM4v7cpuPointersD[81]
#define BSIM4v7PseffArray BSIM4v7cpuPointersD[82]
#define BSIM4v7nfArray BSIM4v7cpuPointersD[83]
#define BSIM4v7XExpBVSArray BSIM4v7cpuPointersD[84]
#define BSIM4v7vjsmFwdArray BSIM4v7cpuPointersD[85]
#define BSIM4v7IVjsmFwdArray BSIM4v7cpuPointersD[86]
#define BSIM4v7vjsmRevArray BSIM4v7cpuPointersD[87]
#define BSIM4v7IVjsmRevArray BSIM4v7cpuPointersD[88]
#define BSIM4v7SslpRevArray BSIM4v7cpuPointersD[89]
#define BSIM4v7SslpFwdArray BSIM4v7cpuPointersD[90]
#define BSIM4v7AdeffArray BSIM4v7cpuPointersD[91]
#define BSIM4v7PdeffArray BSIM4v7cpuPointersD[92]
#define BSIM4v7XExpBVDArray BSIM4v7cpuPointersD[93]
#define BSIM4v7vjdmFwdArray BSIM4v7cpuPointersD[94]
#define BSIM4v7IVjdmFwdArray BSIM4v7cpuPointersD[95]
#define BSIM4v7vjdmRevArray BSIM4v7cpuPointersD[96]
#define BSIM4v7IVjdmRevArray BSIM4v7cpuPointersD[97]
#define BSIM4v7DslpRevArray BSIM4v7cpuPointersD[98]
#define BSIM4v7DslpFwdArray BSIM4v7cpuPointersD[99]
#define BSIM4v7SjctTempRevSatCurArray BSIM4v7cpuPointersD[100]
#define BSIM4v7SswTempRevSatCurArray BSIM4v7cpuPointersD[101]
#define BSIM4v7SswgTempRevSatCurArray BSIM4v7cpuPointersD[102]
#define BSIM4v7DjctTempRevSatCurArray BSIM4v7cpuPointersD[103]
#define BSIM4v7DswTempRevSatCurArray BSIM4v7cpuPointersD[104]
#define BSIM4v7DswgTempRevSatCurArray BSIM4v7cpuPointersD[105]
#define BSIM4v7vbscArray BSIM4v7cpuPointersD[106]
#define BSIM4v7thetavthArray BSIM4v7cpuPointersD[107]
#define BSIM4v7eta0Array BSIM4v7cpuPointersD[108]
#define BSIM4v7k2oxArray BSIM4v7cpuPointersD[109]
#define BSIM4v7nstarArray BSIM4v7cpuPointersD[110]
#define BSIM4v7vfbArray BSIM4v7cpuPointersD[111]
#define BSIM4v7vgs_effArray BSIM4v7cpuPointersD[112]
#define BSIM4v7vgd_effArray BSIM4v7cpuPointersD[113]
#define BSIM4v7dvgs_eff_dvgArray BSIM4v7cpuPointersD[114]
#define BSIM4v7dvgd_eff_dvgArray BSIM4v7cpuPointersD[115]
#define BSIM4v7VgsteffArray BSIM4v7cpuPointersD[116]
#define BSIM4v7grdswArray BSIM4v7cpuPointersD[117]
#define BSIM4v7AbulkArray BSIM4v7cpuPointersD[118]
#define BSIM4v7vtfbphi1Array BSIM4v7cpuPointersD[119]
#define BSIM4v7ueffArray BSIM4v7cpuPointersD[120]
#define BSIM4v7u0tempArray BSIM4v7cpuPointersD[121]
#define BSIM4v7vsattempArray BSIM4v7cpuPointersD[122]
#define BSIM4v7EsatLArray BSIM4v7cpuPointersD[123]
#define BSIM4v7VdseffArray BSIM4v7cpuPointersD[124]
#define BSIM4v7vtfbphi2Array BSIM4v7cpuPointersD[125]
#define BSIM4v7CoxeffArray BSIM4v7cpuPointersD[126]
#define BSIM4v7AbovVgst2VtmArray BSIM4v7cpuPointersD[127]
#define BSIM4v7IdovVdsArray BSIM4v7cpuPointersD[128]
#define BSIM4v7gcrgdArray BSIM4v7cpuPointersD[129]
#define BSIM4v7gcrgbArray BSIM4v7cpuPointersD[130]
#define BSIM4v7gcrggArray BSIM4v7cpuPointersD[131]
#define BSIM4v7grgeltdArray BSIM4v7cpuPointersD[132]
#define BSIM4v7gcrgsArray BSIM4v7cpuPointersD[133]
#define BSIM4v7sourceConductanceArray BSIM4v7cpuPointersD[134]
#define BSIM4v7drainConductanceArray BSIM4v7cpuPointersD[135]
#define BSIM4v7gstotsArray BSIM4v7cpuPointersD[136]
#define BSIM4v7gdtotsArray BSIM4v7cpuPointersD[137]
#define BSIM4v7vfbzbArray BSIM4v7cpuPointersD[138]
#define BSIM4v7gIgssArray BSIM4v7cpuPointersD[139]
#define BSIM4v7gIgddArray BSIM4v7cpuPointersD[140]
#define BSIM4v7gIgbsArray BSIM4v7cpuPointersD[141]
#define BSIM4v7gIgcssArray BSIM4v7cpuPointersD[142]
#define BSIM4v7gIgcdsArray BSIM4v7cpuPointersD[143]
#define BSIM4v7noiGd0Array BSIM4v7cpuPointersD[144]
#define BSIM4v7cqdbArray BSIM4v7cpuPointersD[145]
#define BSIM4v7cqsbArray BSIM4v7cpuPointersD[146]
#define BSIM4v7cqgbArray BSIM4v7cpuPointersD[147]
#define BSIM4v7qchqsArray BSIM4v7cpuPointersD[148]
#define BSIM4v7cqbbArray BSIM4v7cpuPointersD[149]
#define BSIM4v7taunetArray BSIM4v7cpuPointersD[150]
#define BSIM4v7gtgArray BSIM4v7cpuPointersD[151]
#define BSIM4v7gtdArray BSIM4v7cpuPointersD[152]
#define BSIM4v7gtsArray BSIM4v7cpuPointersD[153]
#define BSIM4v7gtbArray BSIM4v7cpuPointersD[154]
#define BSIM4v7mArray BSIM4v7cpuPointersD[155]
#define BSIM4v7grbpdArray BSIM4v7cpuPointersD[156]
#define BSIM4v7grbdbArray BSIM4v7cpuPointersD[157]
#define BSIM4v7grbpbArray BSIM4v7cpuPointersD[158]
#define BSIM4v7grbpsArray BSIM4v7cpuPointersD[159]
#define BSIM4v7grbsbArray BSIM4v7cpuPointersD[160]
#define BSIM4v7dNodePrimeRHSValueArray BSIM4v7cpuPointersD[161]
#define BSIM4v7gNodePrimeRHSValueArray BSIM4v7cpuPointersD[162]
#define BSIM4v7gNodeExtRHSValueArray BSIM4v7cpuPointersD[163]
#define BSIM4v7gNodeMidRHSValueArray BSIM4v7cpuPointersD[164]
#define BSIM4v7bNodePrimeRHSValueArray BSIM4v7cpuPointersD[165]
#define BSIM4v7sNodePrimeRHSValueArray BSIM4v7cpuPointersD[166]
#define BSIM4v7dbNodeRHSValueArray BSIM4v7cpuPointersD[167]
#define BSIM4v7sbNodeRHSValueArray BSIM4v7cpuPointersD[168]
#define BSIM4v7dNodeRHSValueArray BSIM4v7cpuPointersD[169]
#define BSIM4v7sNodeRHSValueArray BSIM4v7cpuPointersD[170]
#define BSIM4v7qNodeRHSValueArray BSIM4v7cpuPointersD[171]
#define BSIM4v7GEgeValueArray BSIM4v7cpuPointersD[172]
#define BSIM4v7GPgeValueArray BSIM4v7cpuPointersD[173]
#define BSIM4v7GEgpValueArray BSIM4v7cpuPointersD[174]
#define BSIM4v7GPgpValueArray BSIM4v7cpuPointersD[175]
#define BSIM4v7GPdpValueArray BSIM4v7cpuPointersD[176]
#define BSIM4v7GPspValueArray BSIM4v7cpuPointersD[177]
#define BSIM4v7GPbpValueArray BSIM4v7cpuPointersD[178]
#define BSIM4v7GEdpValueArray BSIM4v7cpuPointersD[179]
#define BSIM4v7GEspValueArray BSIM4v7cpuPointersD[180]
#define BSIM4v7GEbpValueArray BSIM4v7cpuPointersD[181]
#define BSIM4v7GEgmValueArray BSIM4v7cpuPointersD[182]
#define BSIM4v7GMgeValueArray BSIM4v7cpuPointersD[183]
#define BSIM4v7GMgmValueArray BSIM4v7cpuPointersD[184]
#define BSIM4v7GMdpValueArray BSIM4v7cpuPointersD[185]
#define BSIM4v7GMgpValueArray BSIM4v7cpuPointersD[186]
#define BSIM4v7GMspValueArray BSIM4v7cpuPointersD[187]
#define BSIM4v7GMbpValueArray BSIM4v7cpuPointersD[188]
#define BSIM4v7DPgmValueArray BSIM4v7cpuPointersD[189]
#define BSIM4v7GPgmValueArray BSIM4v7cpuPointersD[190]
#define BSIM4v7SPgmValueArray BSIM4v7cpuPointersD[191]
#define BSIM4v7BPgmValueArray BSIM4v7cpuPointersD[192]
#define BSIM4v7DgpValueArray BSIM4v7cpuPointersD[193]
#define BSIM4v7DspValueArray BSIM4v7cpuPointersD[194]
#define BSIM4v7DbpValueArray BSIM4v7cpuPointersD[195]
#define BSIM4v7SdpValueArray BSIM4v7cpuPointersD[196]
#define BSIM4v7SgpValueArray BSIM4v7cpuPointersD[197]
#define BSIM4v7SbpValueArray BSIM4v7cpuPointersD[198]
#define BSIM4v7DPdpValueArray BSIM4v7cpuPointersD[199]
#define BSIM4v7DPdValueArray BSIM4v7cpuPointersD[200]
#define BSIM4v7DPgpValueArray BSIM4v7cpuPointersD[201]
#define BSIM4v7DPspValueArray BSIM4v7cpuPointersD[202]
#define BSIM4v7DPbpValueArray BSIM4v7cpuPointersD[203]
#define BSIM4v7DdpValueArray BSIM4v7cpuPointersD[204]
#define BSIM4v7DdValueArray BSIM4v7cpuPointersD[205]
#define BSIM4v7SPdpValueArray BSIM4v7cpuPointersD[206]
#define BSIM4v7SPgpValueArray BSIM4v7cpuPointersD[207]
#define BSIM4v7SPspValueArray BSIM4v7cpuPointersD[208]
#define BSIM4v7SPsValueArray BSIM4v7cpuPointersD[209]
#define BSIM4v7SPbpValueArray BSIM4v7cpuPointersD[210]
#define BSIM4v7SspValueArray BSIM4v7cpuPointersD[211]
#define BSIM4v7SsValueArray BSIM4v7cpuPointersD[212]
#define BSIM4v7BPdpValueArray BSIM4v7cpuPointersD[213]
#define BSIM4v7BPgpValueArray BSIM4v7cpuPointersD[214]
#define BSIM4v7BPspValueArray BSIM4v7cpuPointersD[215]
#define BSIM4v7BPbpValueArray BSIM4v7cpuPointersD[216]
#define BSIM4v7DPdbValueArray BSIM4v7cpuPointersD[217]
#define BSIM4v7SPsbValueArray BSIM4v7cpuPointersD[218]
#define BSIM4v7DBdpValueArray BSIM4v7cpuPointersD[219]
#define BSIM4v7DBdbValueArray BSIM4v7cpuPointersD[220]
#define BSIM4v7DBbpValueArray BSIM4v7cpuPointersD[221]
#define BSIM4v7DBbValueArray BSIM4v7cpuPointersD[222]
#define BSIM4v7BPdbValueArray BSIM4v7cpuPointersD[223]
#define BSIM4v7BPbValueArray BSIM4v7cpuPointersD[224]
#define BSIM4v7BPsbValueArray BSIM4v7cpuPointersD[225]
#define BSIM4v7BPbpIFValueArray BSIM4v7cpuPointersD[226]
#define BSIM4v7SBspValueArray BSIM4v7cpuPointersD[227]
#define BSIM4v7SBbpValueArray BSIM4v7cpuPointersD[228]
#define BSIM4v7SBbValueArray BSIM4v7cpuPointersD[229]
#define BSIM4v7SBsbValueArray BSIM4v7cpuPointersD[230]
#define BSIM4v7BdbValueArray BSIM4v7cpuPointersD[231]
#define BSIM4v7BbpValueArray BSIM4v7cpuPointersD[232]
#define BSIM4v7BsbValueArray BSIM4v7cpuPointersD[233]
#define BSIM4v7BbValueArray BSIM4v7cpuPointersD[234]
#define BSIM4v7QqValueArray BSIM4v7cpuPointersD[235]
#define BSIM4v7QgpValueArray BSIM4v7cpuPointersD[236]
#define BSIM4v7QdpValueArray BSIM4v7cpuPointersD[237]
#define BSIM4v7QspValueArray BSIM4v7cpuPointersD[238]
#define BSIM4v7QbpValueArray BSIM4v7cpuPointersD[239]
#define BSIM4v7DPqValueArray BSIM4v7cpuPointersD[240]
#define BSIM4v7SPqValueArray BSIM4v7cpuPointersD[241]
#define BSIM4v7GPqValueArray BSIM4v7cpuPointersD[242]
int *BSIM4v7cpuPointersI [18];
#define BSIM4v7offArray BSIM4v7cpuPointersI[0]
#define BSIM4v7dNodePrimeArray BSIM4v7cpuPointersI[1]
#define BSIM4v7sNodePrimeArray BSIM4v7cpuPointersI[2]
#define BSIM4v7gNodePrimeArray BSIM4v7cpuPointersI[3]
#define BSIM4v7bNodePrimeArray BSIM4v7cpuPointersI[4]
#define BSIM4v7gNodeExtArray BSIM4v7cpuPointersI[5]
#define BSIM4v7gNodeMidArray BSIM4v7cpuPointersI[6]
#define BSIM4v7dbNodeArray BSIM4v7cpuPointersI[7]
#define BSIM4v7sbNodeArray BSIM4v7cpuPointersI[8]
#define BSIM4v7sNodeArray BSIM4v7cpuPointersI[9]
#define BSIM4v7dNodeArray BSIM4v7cpuPointersI[10]
#define BSIM4v7qNodeArray BSIM4v7cpuPointersI[11]
#define BSIM4v7rbodyModArray BSIM4v7cpuPointersI[12]
#define BSIM4v7modeArray BSIM4v7cpuPointersI[13]
#define BSIM4v7rgateModArray BSIM4v7cpuPointersI[14]
#define BSIM4v7trnqsModArray BSIM4v7cpuPointersI[15]
#define BSIM4v7acnqsModArray BSIM4v7cpuPointersI[16]
#define BSIM4v7statesArray BSIM4v7cpuPointersI[17]
} BSIM4v7paramCPUstruct ;
typedef struct sBSIM4v7paramGPUstruct {
double *BSIM4v7cudaPointersD [243];
#define d_BSIM4v7gbsRWArray BSIM4v7cudaPointersD[0]
#define d_BSIM4v7cbsRWArray BSIM4v7cudaPointersD[1]
#define d_BSIM4v7gbdRWArray BSIM4v7cudaPointersD[2]
#define d_BSIM4v7cbdRWArray BSIM4v7cudaPointersD[3]
#define d_BSIM4v7vonRWArray BSIM4v7cudaPointersD[4]
#define d_BSIM4v7vdsatRWArray BSIM4v7cudaPointersD[5]
#define d_BSIM4v7csubRWArray BSIM4v7cudaPointersD[6]
#define d_BSIM4v7gdsRWArray BSIM4v7cudaPointersD[7]
#define d_BSIM4v7gmRWArray BSIM4v7cudaPointersD[8]
#define d_BSIM4v7gmbsRWArray BSIM4v7cudaPointersD[9]
#define d_BSIM4v7gcrgRWArray BSIM4v7cudaPointersD[10]
#define d_BSIM4v7IgidlRWArray BSIM4v7cudaPointersD[11]
#define d_BSIM4v7IgislRWArray BSIM4v7cudaPointersD[12]
#define d_BSIM4v7IgcsRWArray BSIM4v7cudaPointersD[13]
#define d_BSIM4v7IgcdRWArray BSIM4v7cudaPointersD[14]
#define d_BSIM4v7IgsRWArray BSIM4v7cudaPointersD[15]
#define d_BSIM4v7IgdRWArray BSIM4v7cudaPointersD[16]
#define d_BSIM4v7IgbRWArray BSIM4v7cudaPointersD[17]
#define d_BSIM4v7cdRWArray BSIM4v7cudaPointersD[18]
#define d_BSIM4v7qinvRWArray BSIM4v7cudaPointersD[19]
#define d_BSIM4v7cggbRWArray BSIM4v7cudaPointersD[20]
#define d_BSIM4v7cgsbRWArray BSIM4v7cudaPointersD[21]
#define d_BSIM4v7cgdbRWArray BSIM4v7cudaPointersD[22]
#define d_BSIM4v7cdgbRWArray BSIM4v7cudaPointersD[23]
#define d_BSIM4v7cdsbRWArray BSIM4v7cudaPointersD[24]
#define d_BSIM4v7cddbRWArray BSIM4v7cudaPointersD[25]
#define d_BSIM4v7cbgbRWArray BSIM4v7cudaPointersD[26]
#define d_BSIM4v7cbsbRWArray BSIM4v7cudaPointersD[27]
#define d_BSIM4v7cbdbRWArray BSIM4v7cudaPointersD[28]
#define d_BSIM4v7csgbRWArray BSIM4v7cudaPointersD[29]
#define d_BSIM4v7cssbRWArray BSIM4v7cudaPointersD[30]
#define d_BSIM4v7csdbRWArray BSIM4v7cudaPointersD[31]
#define d_BSIM4v7cgbbRWArray BSIM4v7cudaPointersD[32]
#define d_BSIM4v7csbbRWArray BSIM4v7cudaPointersD[33]
#define d_BSIM4v7cdbbRWArray BSIM4v7cudaPointersD[34]
#define d_BSIM4v7cbbbRWArray BSIM4v7cudaPointersD[35]
#define d_BSIM4v7gtauRWArray BSIM4v7cudaPointersD[36]
#define d_BSIM4v7qgateRWArray BSIM4v7cudaPointersD[37]
#define d_BSIM4v7qbulkRWArray BSIM4v7cudaPointersD[38]
#define d_BSIM4v7qdrnRWArray BSIM4v7cudaPointersD[39]
#define d_BSIM4v7qsrcRWArray BSIM4v7cudaPointersD[40]
#define d_BSIM4v7capbsRWArray BSIM4v7cudaPointersD[41]
#define d_BSIM4v7capbdRWArray BSIM4v7cudaPointersD[42]
#define d_BSIM4v7icVDSArray BSIM4v7cudaPointersD[43]
#define d_BSIM4v7icVGSArray BSIM4v7cudaPointersD[44]
#define d_BSIM4v7icVBSArray BSIM4v7cudaPointersD[45]
#define d_BSIM4v7vth0Array BSIM4v7cudaPointersD[46]
#define d_BSIM4v7gbbsArray BSIM4v7cudaPointersD[47]
#define d_BSIM4v7ggidlbArray BSIM4v7cudaPointersD[48]
#define d_BSIM4v7gbgsArray BSIM4v7cudaPointersD[49]
#define d_BSIM4v7ggidlgArray BSIM4v7cudaPointersD[50]
#define d_BSIM4v7gbdsArray BSIM4v7cudaPointersD[51]
#define d_BSIM4v7ggidldArray BSIM4v7cudaPointersD[52]
#define d_BSIM4v7ggislsArray BSIM4v7cudaPointersD[53]
#define d_BSIM4v7ggislgArray BSIM4v7cudaPointersD[54]
#define d_BSIM4v7ggislbArray BSIM4v7cudaPointersD[55]
#define d_BSIM4v7gIgsgArray BSIM4v7cudaPointersD[56]
#define d_BSIM4v7gIgcsgArray BSIM4v7cudaPointersD[57]
#define d_BSIM4v7gIgcsdArray BSIM4v7cudaPointersD[58]
#define d_BSIM4v7gIgcsbArray BSIM4v7cudaPointersD[59]
#define d_BSIM4v7gIgdgArray BSIM4v7cudaPointersD[60]
#define d_BSIM4v7gIgcdgArray BSIM4v7cudaPointersD[61]
#define d_BSIM4v7gIgcddArray BSIM4v7cudaPointersD[62]
#define d_BSIM4v7gIgcdbArray BSIM4v7cudaPointersD[63]
#define d_BSIM4v7gIgbgArray BSIM4v7cudaPointersD[64]
#define d_BSIM4v7gIgbdArray BSIM4v7cudaPointersD[65]
#define d_BSIM4v7gIgbbArray BSIM4v7cudaPointersD[66]
#define d_BSIM4v7ggidlsArray BSIM4v7cudaPointersD[67]
#define d_BSIM4v7ggisldArray BSIM4v7cudaPointersD[68]
#define d_BSIM4v7gstotArray BSIM4v7cudaPointersD[69]
#define d_BSIM4v7gstotdArray BSIM4v7cudaPointersD[70]
#define d_BSIM4v7gstotgArray BSIM4v7cudaPointersD[71]
#define d_BSIM4v7gstotbArray BSIM4v7cudaPointersD[72]
#define d_BSIM4v7gdtotArray BSIM4v7cudaPointersD[73]
#define d_BSIM4v7gdtotdArray BSIM4v7cudaPointersD[74]
#define d_BSIM4v7gdtotgArray BSIM4v7cudaPointersD[75]
#define d_BSIM4v7gdtotbArray BSIM4v7cudaPointersD[76]
#define d_BSIM4v7cgdoArray BSIM4v7cudaPointersD[77]
#define d_BSIM4v7qgdoArray BSIM4v7cudaPointersD[78]
#define d_BSIM4v7cgsoArray BSIM4v7cudaPointersD[79]
#define d_BSIM4v7qgsoArray BSIM4v7cudaPointersD[80]
#define d_BSIM4v7AseffArray BSIM4v7cudaPointersD[81]
#define d_BSIM4v7PseffArray BSIM4v7cudaPointersD[82]
#define d_BSIM4v7nfArray BSIM4v7cudaPointersD[83]
#define d_BSIM4v7XExpBVSArray BSIM4v7cudaPointersD[84]
#define d_BSIM4v7vjsmFwdArray BSIM4v7cudaPointersD[85]
#define d_BSIM4v7IVjsmFwdArray BSIM4v7cudaPointersD[86]
#define d_BSIM4v7vjsmRevArray BSIM4v7cudaPointersD[87]
#define d_BSIM4v7IVjsmRevArray BSIM4v7cudaPointersD[88]
#define d_BSIM4v7SslpRevArray BSIM4v7cudaPointersD[89]
#define d_BSIM4v7SslpFwdArray BSIM4v7cudaPointersD[90]
#define d_BSIM4v7AdeffArray BSIM4v7cudaPointersD[91]
#define d_BSIM4v7PdeffArray BSIM4v7cudaPointersD[92]
#define d_BSIM4v7XExpBVDArray BSIM4v7cudaPointersD[93]
#define d_BSIM4v7vjdmFwdArray BSIM4v7cudaPointersD[94]
#define d_BSIM4v7IVjdmFwdArray BSIM4v7cudaPointersD[95]
#define d_BSIM4v7vjdmRevArray BSIM4v7cudaPointersD[96]
#define d_BSIM4v7IVjdmRevArray BSIM4v7cudaPointersD[97]
#define d_BSIM4v7DslpRevArray BSIM4v7cudaPointersD[98]
#define d_BSIM4v7DslpFwdArray BSIM4v7cudaPointersD[99]
#define d_BSIM4v7SjctTempRevSatCurArray BSIM4v7cudaPointersD[100]
#define d_BSIM4v7SswTempRevSatCurArray BSIM4v7cudaPointersD[101]
#define d_BSIM4v7SswgTempRevSatCurArray BSIM4v7cudaPointersD[102]
#define d_BSIM4v7DjctTempRevSatCurArray BSIM4v7cudaPointersD[103]
#define d_BSIM4v7DswTempRevSatCurArray BSIM4v7cudaPointersD[104]
#define d_BSIM4v7DswgTempRevSatCurArray BSIM4v7cudaPointersD[105]
#define d_BSIM4v7vbscArray BSIM4v7cudaPointersD[106]
#define d_BSIM4v7thetavthArray BSIM4v7cudaPointersD[107]
#define d_BSIM4v7eta0Array BSIM4v7cudaPointersD[108]
#define d_BSIM4v7k2oxArray BSIM4v7cudaPointersD[109]
#define d_BSIM4v7nstarArray BSIM4v7cudaPointersD[110]
#define d_BSIM4v7vfbArray BSIM4v7cudaPointersD[111]
#define d_BSIM4v7vgs_effArray BSIM4v7cudaPointersD[112]
#define d_BSIM4v7vgd_effArray BSIM4v7cudaPointersD[113]
#define d_BSIM4v7dvgs_eff_dvgArray BSIM4v7cudaPointersD[114]
#define d_BSIM4v7dvgd_eff_dvgArray BSIM4v7cudaPointersD[115]
#define d_BSIM4v7VgsteffArray BSIM4v7cudaPointersD[116]
#define d_BSIM4v7grdswArray BSIM4v7cudaPointersD[117]
#define d_BSIM4v7AbulkArray BSIM4v7cudaPointersD[118]
#define d_BSIM4v7vtfbphi1Array BSIM4v7cudaPointersD[119]
#define d_BSIM4v7ueffArray BSIM4v7cudaPointersD[120]
#define d_BSIM4v7u0tempArray BSIM4v7cudaPointersD[121]
#define d_BSIM4v7vsattempArray BSIM4v7cudaPointersD[122]
#define d_BSIM4v7EsatLArray BSIM4v7cudaPointersD[123]
#define d_BSIM4v7VdseffArray BSIM4v7cudaPointersD[124]
#define d_BSIM4v7vtfbphi2Array BSIM4v7cudaPointersD[125]
#define d_BSIM4v7CoxeffArray BSIM4v7cudaPointersD[126]
#define d_BSIM4v7AbovVgst2VtmArray BSIM4v7cudaPointersD[127]
#define d_BSIM4v7IdovVdsArray BSIM4v7cudaPointersD[128]
#define d_BSIM4v7gcrgdArray BSIM4v7cudaPointersD[129]
#define d_BSIM4v7gcrgbArray BSIM4v7cudaPointersD[130]
#define d_BSIM4v7gcrggArray BSIM4v7cudaPointersD[131]
#define d_BSIM4v7grgeltdArray BSIM4v7cudaPointersD[132]
#define d_BSIM4v7gcrgsArray BSIM4v7cudaPointersD[133]
#define d_BSIM4v7sourceConductanceArray BSIM4v7cudaPointersD[134]
#define d_BSIM4v7drainConductanceArray BSIM4v7cudaPointersD[135]
#define d_BSIM4v7gstotsArray BSIM4v7cudaPointersD[136]
#define d_BSIM4v7gdtotsArray BSIM4v7cudaPointersD[137]
#define d_BSIM4v7vfbzbArray BSIM4v7cudaPointersD[138]
#define d_BSIM4v7gIgssArray BSIM4v7cudaPointersD[139]
#define d_BSIM4v7gIgddArray BSIM4v7cudaPointersD[140]
#define d_BSIM4v7gIgbsArray BSIM4v7cudaPointersD[141]
#define d_BSIM4v7gIgcssArray BSIM4v7cudaPointersD[142]
#define d_BSIM4v7gIgcdsArray BSIM4v7cudaPointersD[143]
#define d_BSIM4v7noiGd0Array BSIM4v7cudaPointersD[144]
#define d_BSIM4v7cqdbArray BSIM4v7cudaPointersD[145]
#define d_BSIM4v7cqsbArray BSIM4v7cudaPointersD[146]
#define d_BSIM4v7cqgbArray BSIM4v7cudaPointersD[147]
#define d_BSIM4v7qchqsArray BSIM4v7cudaPointersD[148]
#define d_BSIM4v7cqbbArray BSIM4v7cudaPointersD[149]
#define d_BSIM4v7taunetArray BSIM4v7cudaPointersD[150]
#define d_BSIM4v7gtgArray BSIM4v7cudaPointersD[151]
#define d_BSIM4v7gtdArray BSIM4v7cudaPointersD[152]
#define d_BSIM4v7gtsArray BSIM4v7cudaPointersD[153]
#define d_BSIM4v7gtbArray BSIM4v7cudaPointersD[154]
#define d_BSIM4v7mArray BSIM4v7cudaPointersD[155]
#define d_BSIM4v7grbpdArray BSIM4v7cudaPointersD[156]
#define d_BSIM4v7grbdbArray BSIM4v7cudaPointersD[157]
#define d_BSIM4v7grbpbArray BSIM4v7cudaPointersD[158]
#define d_BSIM4v7grbpsArray BSIM4v7cudaPointersD[159]
#define d_BSIM4v7grbsbArray BSIM4v7cudaPointersD[160]
#define d_BSIM4v7dNodePrimeRHSValueArray BSIM4v7cudaPointersD[161]
#define d_BSIM4v7gNodePrimeRHSValueArray BSIM4v7cudaPointersD[162]
#define d_BSIM4v7gNodeExtRHSValueArray BSIM4v7cudaPointersD[163]
#define d_BSIM4v7gNodeMidRHSValueArray BSIM4v7cudaPointersD[164]
#define d_BSIM4v7bNodePrimeRHSValueArray BSIM4v7cudaPointersD[165]
#define d_BSIM4v7sNodePrimeRHSValueArray BSIM4v7cudaPointersD[166]
#define d_BSIM4v7dbNodeRHSValueArray BSIM4v7cudaPointersD[167]
#define d_BSIM4v7sbNodeRHSValueArray BSIM4v7cudaPointersD[168]
#define d_BSIM4v7dNodeRHSValueArray BSIM4v7cudaPointersD[169]
#define d_BSIM4v7sNodeRHSValueArray BSIM4v7cudaPointersD[170]
#define d_BSIM4v7qNodeRHSValueArray BSIM4v7cudaPointersD[171]
#define d_BSIM4v7GEgeValueArray BSIM4v7cudaPointersD[172]
#define d_BSIM4v7GPgeValueArray BSIM4v7cudaPointersD[173]
#define d_BSIM4v7GEgpValueArray BSIM4v7cudaPointersD[174]
#define d_BSIM4v7GPgpValueArray BSIM4v7cudaPointersD[175]
#define d_BSIM4v7GPdpValueArray BSIM4v7cudaPointersD[176]
#define d_BSIM4v7GPspValueArray BSIM4v7cudaPointersD[177]
#define d_BSIM4v7GPbpValueArray BSIM4v7cudaPointersD[178]
#define d_BSIM4v7GEdpValueArray BSIM4v7cudaPointersD[179]
#define d_BSIM4v7GEspValueArray BSIM4v7cudaPointersD[180]
#define d_BSIM4v7GEbpValueArray BSIM4v7cudaPointersD[181]
#define d_BSIM4v7GEgmValueArray BSIM4v7cudaPointersD[182]
#define d_BSIM4v7GMgeValueArray BSIM4v7cudaPointersD[183]
#define d_BSIM4v7GMgmValueArray BSIM4v7cudaPointersD[184]
#define d_BSIM4v7GMdpValueArray BSIM4v7cudaPointersD[185]
#define d_BSIM4v7GMgpValueArray BSIM4v7cudaPointersD[186]
#define d_BSIM4v7GMspValueArray BSIM4v7cudaPointersD[187]
#define d_BSIM4v7GMbpValueArray BSIM4v7cudaPointersD[188]
#define d_BSIM4v7DPgmValueArray BSIM4v7cudaPointersD[189]
#define d_BSIM4v7GPgmValueArray BSIM4v7cudaPointersD[190]
#define d_BSIM4v7SPgmValueArray BSIM4v7cudaPointersD[191]
#define d_BSIM4v7BPgmValueArray BSIM4v7cudaPointersD[192]
#define d_BSIM4v7DgpValueArray BSIM4v7cudaPointersD[193]
#define d_BSIM4v7DspValueArray BSIM4v7cudaPointersD[194]
#define d_BSIM4v7DbpValueArray BSIM4v7cudaPointersD[195]
#define d_BSIM4v7SdpValueArray BSIM4v7cudaPointersD[196]
#define d_BSIM4v7SgpValueArray BSIM4v7cudaPointersD[197]
#define d_BSIM4v7SbpValueArray BSIM4v7cudaPointersD[198]
#define d_BSIM4v7DPdpValueArray BSIM4v7cudaPointersD[199]
#define d_BSIM4v7DPdValueArray BSIM4v7cudaPointersD[200]
#define d_BSIM4v7DPgpValueArray BSIM4v7cudaPointersD[201]
#define d_BSIM4v7DPspValueArray BSIM4v7cudaPointersD[202]
#define d_BSIM4v7DPbpValueArray BSIM4v7cudaPointersD[203]
#define d_BSIM4v7DdpValueArray BSIM4v7cudaPointersD[204]
#define d_BSIM4v7DdValueArray BSIM4v7cudaPointersD[205]
#define d_BSIM4v7SPdpValueArray BSIM4v7cudaPointersD[206]
#define d_BSIM4v7SPgpValueArray BSIM4v7cudaPointersD[207]
#define d_BSIM4v7SPspValueArray BSIM4v7cudaPointersD[208]
#define d_BSIM4v7SPsValueArray BSIM4v7cudaPointersD[209]
#define d_BSIM4v7SPbpValueArray BSIM4v7cudaPointersD[210]
#define d_BSIM4v7SspValueArray BSIM4v7cudaPointersD[211]
#define d_BSIM4v7SsValueArray BSIM4v7cudaPointersD[212]
#define d_BSIM4v7BPdpValueArray BSIM4v7cudaPointersD[213]
#define d_BSIM4v7BPgpValueArray BSIM4v7cudaPointersD[214]
#define d_BSIM4v7BPspValueArray BSIM4v7cudaPointersD[215]
#define d_BSIM4v7BPbpValueArray BSIM4v7cudaPointersD[216]
#define d_BSIM4v7DPdbValueArray BSIM4v7cudaPointersD[217]
#define d_BSIM4v7SPsbValueArray BSIM4v7cudaPointersD[218]
#define d_BSIM4v7DBdpValueArray BSIM4v7cudaPointersD[219]
#define d_BSIM4v7DBdbValueArray BSIM4v7cudaPointersD[220]
#define d_BSIM4v7DBbpValueArray BSIM4v7cudaPointersD[221]
#define d_BSIM4v7DBbValueArray BSIM4v7cudaPointersD[222]
#define d_BSIM4v7BPdbValueArray BSIM4v7cudaPointersD[223]
#define d_BSIM4v7BPbValueArray BSIM4v7cudaPointersD[224]
#define d_BSIM4v7BPsbValueArray BSIM4v7cudaPointersD[225]
#define d_BSIM4v7BPbpIFValueArray BSIM4v7cudaPointersD[226]
#define d_BSIM4v7SBspValueArray BSIM4v7cudaPointersD[227]
#define d_BSIM4v7SBbpValueArray BSIM4v7cudaPointersD[228]
#define d_BSIM4v7SBbValueArray BSIM4v7cudaPointersD[229]
#define d_BSIM4v7SBsbValueArray BSIM4v7cudaPointersD[230]
#define d_BSIM4v7BdbValueArray BSIM4v7cudaPointersD[231]
#define d_BSIM4v7BbpValueArray BSIM4v7cudaPointersD[232]
#define d_BSIM4v7BsbValueArray BSIM4v7cudaPointersD[233]
#define d_BSIM4v7BbValueArray BSIM4v7cudaPointersD[234]
#define d_BSIM4v7QqValueArray BSIM4v7cudaPointersD[235]
#define d_BSIM4v7QgpValueArray BSIM4v7cudaPointersD[236]
#define d_BSIM4v7QdpValueArray BSIM4v7cudaPointersD[237]
#define d_BSIM4v7QspValueArray BSIM4v7cudaPointersD[238]
#define d_BSIM4v7QbpValueArray BSIM4v7cudaPointersD[239]
#define d_BSIM4v7DPqValueArray BSIM4v7cudaPointersD[240]
#define d_BSIM4v7SPqValueArray BSIM4v7cudaPointersD[241]
#define d_BSIM4v7GPqValueArray BSIM4v7cudaPointersD[242]
int *BSIM4v7cudaPointersI [18];
#define d_BSIM4v7offArray BSIM4v7cudaPointersI[0]
#define d_BSIM4v7dNodePrimeArray BSIM4v7cudaPointersI[1]
#define d_BSIM4v7sNodePrimeArray BSIM4v7cudaPointersI[2]
#define d_BSIM4v7gNodePrimeArray BSIM4v7cudaPointersI[3]
#define d_BSIM4v7bNodePrimeArray BSIM4v7cudaPointersI[4]
#define d_BSIM4v7gNodeExtArray BSIM4v7cudaPointersI[5]
#define d_BSIM4v7gNodeMidArray BSIM4v7cudaPointersI[6]
#define d_BSIM4v7dbNodeArray BSIM4v7cudaPointersI[7]
#define d_BSIM4v7sbNodeArray BSIM4v7cudaPointersI[8]
#define d_BSIM4v7sNodeArray BSIM4v7cudaPointersI[9]
#define d_BSIM4v7dNodeArray BSIM4v7cudaPointersI[10]
#define d_BSIM4v7qNodeArray BSIM4v7cudaPointersI[11]
#define d_BSIM4v7rbodyModArray BSIM4v7cudaPointersI[12]
#define d_BSIM4v7modeArray BSIM4v7cudaPointersI[13]
#define d_BSIM4v7rgateModArray BSIM4v7cudaPointersI[14]
#define d_BSIM4v7trnqsModArray BSIM4v7cudaPointersI[15]
#define d_BSIM4v7acnqsModArray BSIM4v7cudaPointersI[16]
#define d_BSIM4v7statesArray BSIM4v7cudaPointersI[17]
} BSIM4v7paramGPUstruct;
#endif
typedef struct sBSIM4v7model
{
@ -2791,6 +3328,27 @@ typedef struct sBSIM4v7model
unsigned BSIM4v7pk2weGiven :1;
unsigned BSIM4v7pku0weGiven :1;
#ifdef USE_CUSPICE
struct bsim4SizeDependParam **d_pParam;
struct bsim4SizeDependParam **pParamHost;
BSIM4v7paramCPUstruct BSIM4v7paramCPU;
BSIM4v7paramGPUstruct BSIM4v7paramGPU;
int offset;
int n_values;
int n_Ptr;
int *PositionVector;
int *d_PositionVector;
int offsetRHS;
int n_valuesRHS;
int n_PtrRHS;
int *PositionVectorRHS;
int *d_PositionVectorRHS;
int n_instances;
#endif
} BSIM4v7model;

View File

@ -35,3 +35,7 @@ extern int BSIM4v7bindCSC (GENmodel*, CKTcircuit*) ;
extern int BSIM4v7bindCSCComplex (GENmodel*, CKTcircuit*) ;
extern int BSIM4v7bindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
#endif
#ifdef USE_CUSPICE
extern int BSIM4v7topology (GENmodel *, CKTcircuit *, int *, int *);
#endif

View File

@ -6,6 +6,10 @@
#include "bsim4v7ext.h"
#include "bsim4v7init.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
SPICEdev BSIM4v7info = {
.DEVpublic = {
@ -33,7 +37,11 @@ SPICEdev BSIM4v7info = {
.DEVparam = BSIM4v7param,
.DEVmodParam = BSIM4v7mParam,
#ifdef USE_CUSPICE
.DEVload = cuBSIM4v7load,
#else
.DEVload = BSIM4v7load,
#endif
.DEVsetup = BSIM4v7setup,
.DEVunsetup = BSIM4v7unsetup,
.DEVpzSetup = BSIM4v7setup,
@ -71,6 +79,10 @@ SPICEdev BSIM4v7info = {
.DEVbindCSCComplex = BSIM4v7bindCSCComplex,
.DEVbindCSCComplexToReal = BSIM4v7bindCSCComplexToReal,
#endif
#ifdef USE_CUSPICE
.cuDEVdestroy = cuBSIM4v7destroy,
.DEVtopology = BSIM4v7topology,
#endif
};

View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "capdefs.h"
#include "ngspice/sperror.h"
#define TopologyMatrixInsert(Ptr, instance_ID, offset, Value, global_ID) \
ckt->CKTtopologyMatrixCOOi [global_ID] = (int)(here->Ptr - basePtr) ; \
ckt->CKTtopologyMatrixCOOj [global_ID] = model->PositionVector [instance_ID] + offset ; \
ckt->CKTtopologyMatrixCOOx [global_ID] = Value ;
#define TopologyMatrixInsertRHS(offset, instance_ID, offsetRHS, Value, global_ID) \
ckt->CKTtopologyMatrixCOOiRHS [global_ID] = here->offset ; \
ckt->CKTtopologyMatrixCOOjRHS [global_ID] = model->PositionVectorRHS [instance_ID] + offsetRHS ; \
ckt->CKTtopologyMatrixCOOxRHS [global_ID] = Value ;
int
CAPtopology (GENmodel *inModel, CKTcircuit *ckt, int *i, int *j)
{
CAPmodel *model = (CAPmodel *)inModel ;
CAPinstance *here ;
int k ;
double *basePtr ;
basePtr = ckt->CKTmatrix->CKTkluAx ;
/* loop through all the capacitor models */
for ( ; model != NULL ; model = CAPnextModel(model))
{
k = 0 ;
/* loop through all the instances of the model */
for (here = CAPinstances(model); here != NULL ; here = CAPnextInstance(here))
{
if ((here->CAPposNode != 0) && (here->CAPposNode != 0))
{
TopologyMatrixInsert (CAPposPosPtr, k, 0, 1, *i) ;
(*i)++ ;
}
if ((here->CAPnegNode != 0) && (here->CAPnegNode != 0))
{
TopologyMatrixInsert (CAPnegNegPtr, k, 0, 1, *i) ;
(*i)++ ;
}
if ((here->CAPposNode != 0) && (here->CAPnegNode != 0))
{
TopologyMatrixInsert (CAPposNegPtr, k, 0, -1, *i) ;
(*i)++ ;
}
if ((here->CAPnegNode != 0) && (here->CAPposNode != 0))
{
TopologyMatrixInsert (CAPnegPosPtr, k, 0, -1, *i) ;
(*i)++ ;
}
if (here->CAPposNode != 0)
{
TopologyMatrixInsertRHS (CAPposNode, k, 0, -1, *j) ;
(*j)++ ;
}
if (here->CAPnegNode != 0)
{
TopologyMatrixInsertRHS (CAPnegNode, k, 0, 1, *j) ;
(*j)++ ;
}
k++ ;
}
}
return (OK) ;
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "capdefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
int
cuCAPdestroy
(
GENmodel *inModel
)
{
CAPmodel *model = (CAPmodel *)inModel ;
for ( ; model != NULL ; model = CAPnextModel(model))
{
/* DOUBLE */
free (model->CAPparamCPU.CAPinitCondArray) ;
cudaFree (model->CAPparamGPU.d_CAPinitCondArray) ;
free (model->CAPparamCPU.CAPcapacArray) ;
cudaFree (model->CAPparamGPU.d_CAPcapacArray) ;
free (model->CAPparamCPU.CAPmArray) ;
cudaFree (model->CAPparamGPU.d_CAPmArray) ;
free (model->CAPparamCPU.CAPgeqValueArray) ;
cudaFree (model->CAPparamGPU.d_CAPgeqValueArray) ;
free (model->CAPparamCPU.CAPceqValueArray) ;
cudaFree (model->CAPparamGPU.d_CAPceqValueArray) ;
/* INT */
free (model->CAPparamCPU.CAPposNodeArray) ;
cudaFree (model->CAPparamGPU.d_CAPposNodeArray) ;
free (model->CAPparamCPU.CAPnegNodeArray) ;
cudaFree (model->CAPparamGPU.d_CAPnegNodeArray) ;
free (model->CAPparamCPU.CAPstateArray) ;
cudaFree (model->CAPparamGPU.d_CAPstateArray) ;
}
return (OK) ;
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "capdefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuCAPgetic routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuCAPgetic
(
GENmodel *inModel
)
{
long unsigned int size ;
cudaError_t status ;
CAPmodel *model = (CAPmodel *)inModel ;
size = (long unsigned int) model->n_instances;
status = cudaMemcpy (model->CAPparamGPU.d_CAPinitCondArray, model->CAPparamCPU.CAPinitCondArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->CAPparamGPU.d_CAPinitCondArray, size, double, status)
return (OK) ;
}

View File

@ -0,0 +1,162 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "ngspice/CUSPICE/cuniinteg.cuh"
#include "capdefs.h"
extern "C"
__global__ void cuCAPload_kernel (CAPparamGPUstruct, double *, double *, double *,
int, double, double, int, int, int, int *, double *, int *, double *) ;
extern "C"
int
cuCAPload
(
GENmodel *inModel, CKTcircuit *ckt
)
{
CAPmodel *model = (CAPmodel *)inModel ;
int cond1, thread_x, thread_y, block_x ;
cudaError_t status ;
/* check if capacitors are in the circuit or are open circuited */
if (ckt->CKTmode & (MODETRAN|MODEAC|MODETRANOP))
{
/* evaluate device independent analysis conditions */
cond1 = (((ckt->CKTmode & MODEDC) && (ckt->CKTmode & MODEINITJCT))
|| ((ckt->CKTmode & MODEUIC) && (ckt->CKTmode & MODEINITTRAN))) ;
/* loop through all the resistor models */
for ( ; model != NULL ; model = CAPnextModel(model))
{
/* Determining how many blocks should exist in the kernel */
thread_x = 1 ;
thread_y = 256 ;
if (model->n_instances % thread_y != 0)
block_x = (int)((model->n_instances + thread_y - 1) / thread_y) ;
else
block_x = model->n_instances / thread_y ;
dim3 thread (thread_x, thread_y) ;
/* Kernel launch */
status = cudaGetLastError () ; // clear error status
cuCAPload_kernel <<< block_x, thread >>> (model->CAPparamGPU, ckt->d_CKTrhsOld, ckt->d_CKTstate0,
ckt->d_CKTstate1, ckt->CKTmode, ckt->CKTag [0], ckt->CKTag [1],
ckt->CKTorder, model->n_instances, cond1,
model->d_PositionVector, ckt->d_CKTloadOutput,
model->d_PositionVectorRHS, ckt->d_CKTloadOutputRHS) ;
cudaDeviceSynchronize () ;
status = cudaGetLastError () ; // check for launch error
if (status != cudaSuccess)
{
fprintf (stderr, "Kernel launch failure in the Capacitor Model\n\n") ;
return (E_NOMEM) ;
}
}
}
return (OK) ;
}
extern "C"
__global__
void
cuCAPload_kernel
(
CAPparamGPUstruct CAPentry, double *CKTrhsOld, double *CKTstate_0,
double *CKTstate_1, int CKTmode, double CKTag_0, double CKTag_1,
int CKTorder, int n_instances, int cond1, int *d_PositionVector,
double *d_CKTloadOutput, int *d_PositionVectorRHS, double *d_CKTloadOutputRHS
)
{
int instance_ID ;
double vcap, geq, ceq, m ;
int error ;
instance_ID = threadIdx.y + blockDim.y * blockIdx.x ;
if (instance_ID < n_instances)
{
if (threadIdx.x == 0)
{
m = CAPentry.d_CAPmArray [instance_ID] ;
if (cond1)
{
vcap = CAPentry.d_CAPinitCondArray [instance_ID] ;
} else {
vcap = CKTrhsOld [CAPentry.d_CAPposNodeArray [instance_ID]] -
CKTrhsOld [CAPentry.d_CAPnegNodeArray [instance_ID]] ;
}
if (CKTmode & (MODETRAN | MODEAC))
{
#ifndef PREDICTOR
if (CKTmode & MODEINITPRED)
{
CKTstate_0 [CAPentry.d_CAPstateArray [instance_ID]] =
CKTstate_1 [CAPentry.d_CAPstateArray [instance_ID]] ;
} else { /* only const caps - no poly's */
#endif /* PREDICTOR */
CKTstate_0 [CAPentry.d_CAPstateArray [instance_ID]] = CAPentry.d_CAPcapacArray [instance_ID] * vcap ;
if (CKTmode & MODEINITTRAN)
{
CKTstate_1 [CAPentry.d_CAPstateArray [instance_ID]] =
CKTstate_0 [CAPentry.d_CAPstateArray [instance_ID]] ;
}
#ifndef PREDICTOR
}
#endif /* PREDICTOR */
error = cuNIintegrate_device_kernel (CKTstate_0, CKTstate_1, &geq, &ceq,
CAPentry.d_CAPcapacArray [instance_ID],
CAPentry.d_CAPstateArray [instance_ID],
CKTag_0, CKTag_1, CKTorder) ;
if (error)
printf ("Error in the integration!\n\n") ;
//return (error) ;
if (CKTmode & MODEINITTRAN)
{
CKTstate_1 [CAPentry.d_CAPstateArray [instance_ID] + 1] =
CKTstate_0 [CAPentry.d_CAPstateArray [instance_ID] + 1] ;
}
d_CKTloadOutput [d_PositionVector [instance_ID]] = m * geq ;
d_CKTloadOutputRHS [d_PositionVectorRHS [instance_ID]] = m * ceq ;
} else {
CKTstate_0 [CAPentry.d_CAPstateArray [instance_ID]] = CAPentry.d_CAPcapacArray [instance_ID] * vcap ;
}
}
}
return ;
}

View File

@ -0,0 +1,111 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "capdefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMalloc MACRO to check it for errors --> CUDAMALLOCCHECK(name of pointer, dimension, type, status) */
#define CUDAMALLOCCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuCAPsetup routine...\n") ; \
fprintf (stderr, "Error: cudaMalloc failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuCAPsetup routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuCAPsetup
(
GENmodel *inModel
)
{
long unsigned int size ;
cudaError_t status ;
CAPmodel *model = (CAPmodel *)inModel ;
size = (long unsigned int) model->n_instances;
/* Space Allocation to GPU */
status = cudaMalloc ((void **)&(model->d_PositionVector), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->d_PositionVector, size, int, status)
status = cudaMemcpy (model->d_PositionVector, model->PositionVector, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->d_PositionVector, size, int, status)
status = cudaMalloc ((void **)&(model->d_PositionVectorRHS), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->d_PositionVectorRHS, size, int, status)
status = cudaMemcpy (model->d_PositionVectorRHS, model->PositionVectorRHS, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->d_PositionVectorRHS, size, int, status)
/* DOUBLE */
model->CAPparamCPU.CAPinitCondArray = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->CAPparamGPU.d_CAPinitCondArray), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->CAPparamGPU.d_CAPinitCondArray, size, double, status)
model->CAPparamCPU.CAPcapacArray = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->CAPparamGPU.d_CAPcapacArray), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->CAPparamGPU.d_CAPcapacArray, size, double, status)
model->CAPparamCPU.CAPmArray = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->CAPparamGPU.d_CAPmArray), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->CAPparamGPU.d_CAPmArray, size, double, status)
model->CAPparamCPU.CAPgeqValueArray = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->CAPparamGPU.d_CAPgeqValueArray), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->CAPparamGPU.d_CAPgeqValueArray, size, double, status)
model->CAPparamCPU.CAPceqValueArray = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->CAPparamGPU.d_CAPceqValueArray), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->CAPparamGPU.d_CAPceqValueArray, size, double, status)
/* INT */
model->CAPparamCPU.CAPposNodeArray = (int *) malloc (size * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->CAPparamGPU.d_CAPposNodeArray), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->CAPparamGPU.d_CAPposNodeArray, size, int, status)
model->CAPparamCPU.CAPnegNodeArray = (int *) malloc (size * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->CAPparamGPU.d_CAPnegNodeArray), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->CAPparamGPU.d_CAPnegNodeArray, size, int, status)
model->CAPparamCPU.CAPstateArray = (int *) malloc (size * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->CAPparamGPU.d_CAPstateArray), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->CAPparamGPU.d_CAPstateArray, size, int, status)
return (OK) ;
}

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "capdefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuCAPtemp routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuCAPtemp
(
GENmodel *inModel
)
{
long unsigned int size ;
cudaError_t status ;
CAPmodel *model = (CAPmodel *)inModel ;
size = (long unsigned int) model->n_instances;
/* DOUBLE */
status = cudaMemcpy (model->CAPparamGPU.d_CAPcapacArray, model->CAPparamCPU.CAPcapacArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->CAPparamGPU.d_CAPcapacArray, size, double, status)
status = cudaMemcpy (model->CAPparamGPU.d_CAPmArray, model->CAPparamCPU.CAPmArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->CAPparamGPU.d_CAPmArray, size, double, status)
/* INT */
status = cudaMemcpy (model->CAPparamGPU.d_CAPposNodeArray, model->CAPparamCPU.CAPposNodeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->CAPparamGPU.d_CAPposNodeArray, size, int, status)
status = cudaMemcpy (model->CAPparamGPU.d_CAPnegNodeArray, model->CAPparamCPU.CAPnegNodeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->CAPparamGPU.d_CAPnegNodeArray, size, int, status)
status = cudaMemcpy (model->CAPparamGPU.d_CAPstateArray, model->CAPparamCPU.CAPstateArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->CAPparamGPU.CAPstateArray, size, int, status)
return (OK) ;
}

View File

@ -38,4 +38,19 @@ endif
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
AM_CFLAGS = $(STATIC)
if USE_CUSPICE_WANTED
.cu.lo:
$(AM_V_GEN)$(top_srcdir)/src/libtool_wrapper_for_cuda.tcl $@ $(AM_CFLAGS) $(NVCC) $(CUDA_CFLAGS) $(AM_CPPFLAGS) -c $<
libcap_la_SOURCES += \
CUSPICE/captopology.c \
CUSPICE/cucapfree.c \
CUSPICE/cucapgetic.c \
CUSPICE/cucapload.cu \
CUSPICE/cucapsetup.c \
CUSPICE/cucaptemp.c
AM_CPPFLAGS += $(CUDA_CPPFLAGS)
endif
MAINTAINERCLEANFILES = Makefile.in

View File

@ -79,6 +79,35 @@ typedef struct sCAPinstance {
+3 for the derivatives - pointer to the
beginning of the array */
#ifdef USE_CUSPICE
typedef struct sCAPparamCPUstruct {
double *CAPcpuPointersD [5] ;
#define CAPinitCondArray CAPcpuPointersD[0]
#define CAPcapacArray CAPcpuPointersD[1]
#define CAPmArray CAPcpuPointersD[2]
#define CAPgeqValueArray CAPcpuPointersD[3]
#define CAPceqValueArray CAPcpuPointersD[4]
int *CAPcpuPointersI [3] ;
#define CAPposNodeArray CAPcpuPointersI[0]
#define CAPnegNodeArray CAPcpuPointersI[1]
#define CAPstateArray CAPcpuPointersI[2]
} CAPparamCPUstruct ;
typedef struct sCAPparamGPUstruct {
double *CAPcudaPointersD [5] ;
#define d_CAPinitCondArray CAPcudaPointersD[0]
#define d_CAPcapacArray CAPcudaPointersD[1]
#define d_CAPmArray CAPcudaPointersD[2]
#define d_CAPgeqValueArray CAPcudaPointersD[3]
#define d_CAPceqValueArray CAPcudaPointersD[4]
int *CAPcudaPointersI [3] ;
#define d_CAPposNodeArray CAPcudaPointersI[0]
#define d_CAPnegNodeArray CAPcudaPointersI[1]
#define d_CAPstateArray CAPcudaPointersI[2]
} CAPparamGPUstruct ;
#endif
/* data per model */
@ -120,6 +149,25 @@ typedef struct sCAPmodel { /* model structure for a capacitor */
unsigned CAPthickGiven : 1; /* flags indicates insulator thickness given */
unsigned CAPbv_maxGiven : 1; /* flags indicates maximum voltage is given */
#ifdef USE_CUSPICE
CAPparamCPUstruct CAPparamCPU ;
CAPparamGPUstruct CAPparamGPU ;
int offset ;
int n_values ;
int n_Ptr ;
int *PositionVector ;
int *d_PositionVector ;
int offsetRHS ;
int n_valuesRHS ;
int n_PtrRHS ;
int *PositionVectorRHS ;
int *d_PositionVectorRHS ;
int n_instances ;
#endif
} CAPmodel;
/* device parameters */

View File

@ -29,3 +29,7 @@ extern int CAPbindCSC (GENmodel*, CKTcircuit*) ;
extern int CAPbindCSCComplex (GENmodel*, CKTcircuit*) ;
extern int CAPbindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
#endif
#ifdef USE_CUSPICE
extern int CAPtopology (GENmodel *, CKTcircuit *, int *, int *) ;
#endif

View File

@ -6,6 +6,10 @@
#include "capext.h"
#include "capinit.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
SPICEdev CAPinfo = {
.DEVpublic = {
@ -33,7 +37,11 @@ SPICEdev CAPinfo = {
.DEVparam = CAPparam,
.DEVmodParam = CAPmParam,
#ifdef USE_CUSPICE
.DEVload = cuCAPload,
#else
.DEVload = CAPload,
#endif
.DEVsetup = CAPsetup,
.DEVunsetup = NULL,
.DEVpzSetup = CAPsetup,
@ -71,6 +79,10 @@ SPICEdev CAPinfo = {
.DEVbindCSCComplex = CAPbindCSCComplex,
.DEVbindCSCComplexToReal = CAPbindCSCComplexToReal,
#endif
#ifdef USE_CUSPICE
.cuDEVdestroy = cuCAPdestroy,
.DEVtopology = CAPtopology,
#endif
};

View File

@ -12,6 +12,10 @@ Modified: September 2003 Paolo Nenzi
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
/*ARGSUSED*/
int
@ -117,6 +121,92 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
TSTALLOC(CAPnegPosPtr,CAPnegNode,CAPposNode);
}
}
#ifdef USE_CUSPICE
int i, j, k, status ;
/* Counting the instances */
for (model = (CAPmodel *)inModel ; model != NULL ; model = CAPnextModel(model))
{
i = 0 ;
for (here = CAPinstances(model); here != NULL ; here = CAPnextInstance(here))
{
i++ ;
}
/* How much instances we have */
model->n_instances = i ;
}
/* loop through all the capacitor models */
for (model = (CAPmodel *)inModel ; model != NULL ; model = CAPnextModel(model))
{
model->offset = ckt->total_n_values ;
model->offsetRHS = ckt->total_n_valuesRHS ;
j = 0 ;
k = 0 ;
/* loop through all the instances of the model */
for (here = CAPinstances(model); here != NULL ; here = CAPnextInstance(here))
{
/* For the Matrix */
if ((here->CAPposNode != 0) && (here->CAPposNode != 0))
j++ ;
if ((here->CAPnegNode != 0) && (here->CAPnegNode != 0))
j++ ;
if ((here->CAPposNode != 0) && (here->CAPnegNode != 0))
j++ ;
if ((here->CAPnegNode != 0) && (here->CAPposNode != 0))
j++ ;
/* For the RHS */
if (here->CAPposNode != 0)
k++ ;
if (here->CAPnegNode != 0)
k++ ;
}
model->n_values = model->n_instances;
ckt->total_n_values += model->n_values ;
model->n_Ptr = j ;
ckt->total_n_Ptr += model->n_Ptr ;
model->n_valuesRHS = model->n_instances;
ckt->total_n_valuesRHS += model->n_valuesRHS ;
model->n_PtrRHS = k ;
ckt->total_n_PtrRHS += model->n_PtrRHS ;
/* Position Vector assignment */
model->PositionVector = TMALLOC (int, model->n_instances) ;
for (j = 0 ; j < model->n_instances; j++)
model->PositionVector [j] = model->offset + j ;
/* Position Vector assignment for the RHS */
model->PositionVectorRHS = TMALLOC (int, model->n_instances) ;
for (j = 0 ; j < model->n_instances; j++)
model->PositionVectorRHS [j] = model->offsetRHS + j ;
}
/* loop through all the capacitor models */
for (model = (CAPmodel *)inModel ; model != NULL ; model = CAPnextModel(model))
{
status = cuCAPsetup ((GENmodel *)model) ;
if (status != 0)
return (E_NOMEM) ;
}
#endif
return(OK);
}

View File

@ -16,6 +16,10 @@ Modified: September 2003 Paolo Nenzi
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
/*ARGSUSED*/
int
@ -28,9 +32,17 @@ CAPtemp(GENmodel *inModel, CKTcircuit *ckt)
double factor;
double tc1, tc2;
#ifdef USE_CUSPICE
int i, status ;
#endif
/* loop through all the capacitor models */
for( ; model != NULL; model = CAPnextModel(model)) {
#ifdef USE_CUSPICE
i = 0 ;
#endif
/* loop through all the instances of the model */
for (here = CAPinstances(model); here != NULL ;
here=CAPnextInstance(here)) {
@ -85,7 +97,24 @@ CAPtemp(GENmodel *inModel, CKTcircuit *ckt)
here->CAPcapac = here->CAPcapac * factor * here->CAPscale;
#ifdef USE_CUSPICE
model->CAPparamCPU.CAPcapacArray[i] = here->CAPcapac ;
model->CAPparamCPU.CAPmArray[i] = here->CAPm ;
model->CAPparamCPU.CAPposNodeArray[i] = here->CAPposNode ;
model->CAPparamCPU.CAPnegNodeArray[i] = here->CAPnegNode ;
model->CAPparamCPU.CAPstateArray[i] = here->CAPstate ;
i++ ;
#endif
}
#ifdef USE_CUSPICE
status = cuCAPtemp ((GENmodel *)model) ;
if (status != 0)
return (E_NOMEM) ;
#endif
}
return(OK);
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "inddefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
int
cuINDdestroy
(
GENmodel *inModel
)
{
INDmodel *model = (INDmodel *)inModel ;
for ( ; model != NULL ; model = INDnextModel(model))
{
/* DOUBLE */
free (model->INDparamCPU.INDinitCondArray) ;
cudaFree (model->INDparamGPU.d_INDinitCondArray) ;
free (model->INDparamCPU.INDinductArray) ;
cudaFree (model->INDparamGPU.d_INDinductArray) ;
free (model->INDparamCPU.INDreqValueArray) ;
cudaFree (model->INDparamGPU.d_INDreqValueArray) ;
free (model->INDparamCPU.INDveqValueArray) ;
cudaFree (model->INDparamGPU.d_INDveqValueArray) ;
/* INT */
free (model->INDparamCPU.INDbrEqArray) ;
cudaFree (model->INDparamGPU.d_INDbrEqArray) ;
free (model->INDparamCPU.INDstateArray) ;
cudaFree (model->INDparamGPU.d_INDstateArray) ;
}
return (OK) ;
}

View File

@ -0,0 +1,170 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "ngspice/CUSPICE/cuniinteg.cuh"
#include "inddefs.h"
/* cudaMalloc MACRO to check it for errors --> CUDAMALLOCCHECK(name of pointer, dimension, type, status) */
#define CUDAMALLOCCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuINDload routine...\n") ; \
fprintf (stderr, "Error: cudaMalloc failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuINDload routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
extern "C"
__global__ void cuINDload_kernel (INDparamGPUstruct, double *, double *, double *, int, double, double, int, int, int *, double *, int *, double *) ;
extern "C"
int
cuINDload
(
GENmodel *inModel, CKTcircuit *ckt
)
{
INDmodel *model = (INDmodel *)inModel ;
int thread_x, thread_y, block_x ;
cudaError_t status ;
/* loop through all the inductor models */
for ( ; model != NULL ; model = INDnextModel(model))
{
/* Determining how many blocks should exist in the kernel */
thread_x = 1 ;
thread_y = 256 ;
if (model->n_instances % thread_y != 0)
block_x = (int)(model->n_instances / thread_y) + 1 ;
else
block_x = model->n_instances / thread_y ;
dim3 thread (thread_x, thread_y) ;
/* Kernel launch */
status = cudaGetLastError () ; // clear error status
cuINDload_kernel <<< block_x, thread >>> (model->INDparamGPU, ckt->d_CKTrhsOld, ckt->d_CKTstate0,
ckt->d_CKTstate1, ckt->CKTmode, ckt->CKTag [0], ckt->CKTag [1],
ckt->CKTorder, model->n_instances,
model->d_PositionVector, ckt->d_CKTloadOutput,
model->d_PositionVectorRHS, ckt->d_CKTloadOutputRHS) ;
cudaDeviceSynchronize () ;
status = cudaGetLastError () ; // check for launch error
if (status != cudaSuccess)
{
fprintf (stderr, "Kernel launch failure in the Inductor Model\n\n") ;
return (E_NOMEM) ;
}
}
return (OK) ;
}
extern "C"
__global__
void
cuINDload_kernel
(
INDparamGPUstruct INDentry, double *CKTrhsOld, double *CKTstate_0,
double *CKTstate_1, int CKTmode, double CKTag_0, double CKTag_1,
int CKTorder, int ind_n_instances,
int *d_PositionVector, double *d_CKTloadOutput,
int *d_PositionVectorRHS, double *d_CKTloadOutputRHS
)
{
int instance_ID ;
int error ;
double req, veq ;
instance_ID = threadIdx.y + blockDim.y * blockIdx.x ;
if (instance_ID < ind_n_instances)
{
if (threadIdx.x == 0)
{
if (!(CKTmode & (MODEDC | MODEINITPRED)))
{
if (CKTmode & MODEUIC && CKTmode & MODEINITTRAN)
CKTstate_0 [INDentry.d_INDstateArray [instance_ID]] =
INDentry.d_INDinductArray [instance_ID] * INDentry.d_INDinitCondArray [instance_ID] ;
else
CKTstate_0 [INDentry.d_INDstateArray [instance_ID]] =
INDentry.d_INDinductArray [instance_ID] * CKTrhsOld [INDentry.d_INDbrEqArray [instance_ID]] ;
}
if (CKTmode & MODEDC)
{
req = 0.0 ;
veq = 0.0 ;
} else {
#ifndef PREDICTOR
if (CKTmode & MODEINITPRED)
CKTstate_0 [INDentry.d_INDstateArray [instance_ID]] =
CKTstate_1 [INDentry.d_INDstateArray [instance_ID]] ;
else
#endif /*PREDICTOR*/
if (CKTmode & MODEINITTRAN)
CKTstate_1 [INDentry.d_INDstateArray [instance_ID]] =
CKTstate_0 [INDentry.d_INDstateArray [instance_ID]] ;
error = cuNIintegrate_device_kernel (CKTstate_0, CKTstate_1, &req, &veq,
INDentry.d_INDinductArray [instance_ID],
INDentry.d_INDstateArray [instance_ID],
CKTag_0, CKTag_1, CKTorder) ;
if (error)
printf ("Error in the integration!\n\n") ;
//return (error) ;
}
if (CKTmode & MODEINITTRAN)
CKTstate_1 [INDentry.d_INDstateArray [instance_ID] + 1] =
CKTstate_0 [INDentry.d_INDstateArray [instance_ID] + 1] ;
/* Output for the Matrix */
d_CKTloadOutput [d_PositionVector [instance_ID]] = 1.0 ;
d_CKTloadOutput [d_PositionVector [instance_ID] + 1] = req ;
/* Output for the RHS */
d_CKTloadOutputRHS [d_PositionVectorRHS [instance_ID]] = veq ;
}
}
return ;
}

View File

@ -0,0 +1,103 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "inddefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMalloc MACRO to check it for errors --> CUDAMALLOCCHECK(name of pointer, dimension, type, status) */
#define CUDAMALLOCCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuINDsetup routine...\n") ; \
fprintf (stderr, "Error: cudaMalloc failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuINDsetup routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuINDsetup
(
GENmodel *inModel
)
{
long unsigned int size ;
cudaError_t status ;
INDmodel *model = (INDmodel *)inModel ;
size = (long unsigned int) model->n_instances;
/* Space Allocation to GPU */
status = cudaMalloc ((void **)&(model->d_PositionVector), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->d_PositionVector, size, int, status)
status = cudaMemcpy (model->d_PositionVector, model->PositionVector, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->d_PositionVector, size, int, status)
status = cudaMalloc ((void **)&(model->d_PositionVectorRHS), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->d_PositionVectorRHS, size, int, status)
status = cudaMemcpy (model->d_PositionVectorRHS, model->PositionVectorRHS, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->d_PositionVectorRHS, size, int, status)
/* DOUBLE */
model->INDparamCPU.INDinitCondArray = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->INDparamGPU.d_INDinitCondArray), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->INDparamGPU.d_INDinitCondArray, size, double, status)
model->INDparamCPU.INDinductArray = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->INDparamGPU.d_INDinductArray), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->INDparamGPU.d_INDinductArray, size, double, status)
model->INDparamCPU.INDreqValueArray = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->INDparamGPU.d_INDreqValueArray), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->INDparamGPU.d_INDreqValueArray, size, double, status)
model->INDparamCPU.INDveqValueArray = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->INDparamGPU.d_INDveqValueArray), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->INDparamGPU.d_INDveqValueArray, size, double, status)
/* INT */
model->INDparamCPU.INDbrEqArray = (int *) malloc (size * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->INDparamGPU.d_INDbrEqArray), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->INDparamGPU.d_INDbrEqArray, size, int, status)
model->INDparamCPU.INDstateArray = (int *) malloc (size * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->INDparamGPU.d_INDstateArray), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->INDparamGPU.d_INDstateArray, size, int, status)
return (OK) ;
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "inddefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuINDtemp routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuINDtemp
(
GENmodel *inModel
)
{
long unsigned int size ;
cudaError_t status ;
INDmodel *model = (INDmodel *)inModel ;
size = (long unsigned int) model->n_instances;
/* DOUBLE */
status = cudaMemcpy (model->INDparamGPU.d_INDinitCondArray, model->INDparamCPU.INDinitCondArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->INDparamGPU.d_INDinitCondArray, size, double, status)
status = cudaMemcpy (model->INDparamGPU.d_INDinductArray, model->INDparamCPU.INDinductArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->INDparamGPU.d_INDinductArray, size, double, status)
/* INT */
status = cudaMemcpy (model->INDparamGPU.d_INDbrEqArray, model->INDparamCPU.INDbrEqArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->INDparamGPU.d_INDbrEqArray, size, int, status)
status = cudaMemcpy (model->INDparamGPU.d_INDstateArray, model->INDparamCPU.INDstateArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->INDparamGPU.INDstateArray, size, int, status)
return (OK) ;
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "inddefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
int
cuMUTdestroy
(
GENmodel *inModel
)
{
MUTmodel *model = (MUTmodel *)inModel ;
for ( ; model != NULL ; model = MUTnextModel(model))
{
/* DOUBLE */
free (model->MUTparamCPU.MUTfactorArray) ;
cudaFree (model->MUTparamGPU.d_MUTfactorArray) ;
/* INT */
free (model->MUTparamCPU.MUTflux1Array) ;
cudaFree (model->MUTparamGPU.d_MUTflux1Array) ;
free (model->MUTparamCPU.MUTflux2Array) ;
cudaFree (model->MUTparamGPU.d_MUTflux2Array) ;
free (model->MUTparamCPU.MUTbrEq1Array) ;
cudaFree (model->MUTparamGPU.d_MUTbrEq1Array) ;
free (model->MUTparamCPU.MUTbrEq2Array) ;
cudaFree (model->MUTparamGPU.d_MUTbrEq2Array) ;
}
return (OK) ;
}

View File

@ -0,0 +1,169 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "ngspice/CUSPICE/cuniinteg.cuh"
#include "inddefs.h"
/* cudaMalloc MACRO to check it for errors --> CUDAMALLOCCHECK(name of pointer, dimension, type, status) */
#define CUDAMALLOCCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuMUTload routine...\n") ; \
fprintf (stderr, "Error: cudaMalloc failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuMUTload routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
extern "C"
__global__ void cuMUTload_kernel (MUTparamGPUstruct, double *, double *, double *, int, double, double, int, int, int *, double *, int *, double *) ;
extern "C"
int
cuMUTload
(
GENmodel *inModel, CKTcircuit *ckt
)
{
MUTmodel *model = (MUTmodel *)inModel ;
int thread_x, thread_y, block_x ;
cudaError_t status ;
/* loop through all the mutual inductor models */
for ( ; model != NULL ; model = MUTnextModel(model))
{
/* Determining how many blocks should exist in the kernel */
thread_x = 1 ;
thread_y = 256 ;
if (model->n_instances % thread_y != 0)
block_x = (int)(model->n_instances / thread_y) + 1 ;
else
block_x = model->n_instances / thread_y ;
dim3 thread (thread_x, thread_y) ;
/* Kernel launch */
status = cudaGetLastError () ; // clear error status
cuMUTload_kernel <<< block_x, thread >>> (model->MUTparamGPU, ckt->d_CKTrhsOld, ckt->d_CKTstate0,
ckt->d_CKTstate1, ckt->CKTmode, ckt->CKTag [0], ckt->CKTag [1],
ckt->CKTorder, model->n_instances,
model->d_PositionVector, ckt->d_CKTloadOutput,
model->d_PositionVectorRHS, ckt->d_CKTloadOutputRHS) ;
cudaDeviceSynchronize () ;
status = cudaGetLastError () ; // check for launch error
if (status != cudaSuccess)
{
fprintf (stderr, "Kernel launch failure in the Mutual Inductor Model\n\n") ;
return (E_NOMEM) ;
}
}
return (OK) ;
}
extern "C"
__global__
void
cuMUTload_kernel
(
MUTparamGPUstruct MUTentry, double *CKTrhsOld, double *CKTstate_0,
double *CKTstate_1, int CKTmode, double CKTag_0, double CKTag_1,
int CKTorder, int mut_n_instances,
int *d_PositionVector, double *d_CKTloadOutput,
int *d_PositionVectorRHS, double *d_CKTloadOutputRHS
)
{
int instance_ID ;
int error ;
double req_dummy, veq ;
instance_ID = threadIdx.y + blockDim.y * blockIdx.x ;
if (instance_ID < mut_n_instances)
{
if (threadIdx.x == 0)
{
if (!(CKTmode & (MODEDC | MODEINITPRED)))
{
CKTstate_0 [MUTentry.d_MUTflux1Array [instance_ID]] += MUTentry.d_MUTfactorArray [instance_ID] * CKTrhsOld [MUTentry.d_MUTbrEq2Array [instance_ID]] ;
CKTstate_0 [MUTentry.d_MUTflux2Array [instance_ID]] += MUTentry.d_MUTfactorArray [instance_ID] * CKTrhsOld [MUTentry.d_MUTbrEq1Array [instance_ID]] ;
}
/* Inductor-related */
if (CKTmode & MODEINITTRAN)
{
CKTstate_1 [MUTentry.d_MUTflux1Array [instance_ID]] = CKTstate_0 [MUTentry.d_MUTflux1Array [instance_ID]] ;
CKTstate_1 [MUTentry.d_MUTflux2Array [instance_ID]] = CKTstate_0 [MUTentry.d_MUTflux2Array [instance_ID]] ;
}
if (!(CKTmode & MODEDC))
{
error = cuNIintegrate_device_kernel (CKTstate_0, CKTstate_1, &req_dummy, &veq,
1.0, MUTentry.d_MUTflux1Array [instance_ID],
CKTag_0, CKTag_1, CKTorder) ;
if (error)
printf ("Error in the integration 1 of MUTload!\n\n") ;
/* Output for the RHS */
d_CKTloadOutputRHS [d_PositionVectorRHS [MUTentry.d_MUTinstanceIND1Array [instance_ID]]] = veq ;
error = cuNIintegrate_device_kernel (CKTstate_0, CKTstate_1, &req_dummy, &veq,
1.0, MUTentry.d_MUTflux2Array [instance_ID],
CKTag_0, CKTag_1, CKTorder) ;
if (error)
printf ("Error in the integration 2 of MUTload!\n\n") ;
/* Output for the RHS */
d_CKTloadOutputRHS [d_PositionVectorRHS [MUTentry.d_MUTinstanceIND2Array [instance_ID]]] = veq ;
}
if (CKTmode & MODEINITTRAN)
{
CKTstate_1 [MUTentry.d_MUTflux1Array [instance_ID] + 1] = CKTstate_0 [MUTentry.d_MUTflux1Array [instance_ID] + 1] ;
CKTstate_1 [MUTentry.d_MUTflux2Array [instance_ID] + 1] = CKTstate_0 [MUTentry.d_MUTflux2Array [instance_ID] + 1] ;
}
d_CKTloadOutput [d_PositionVector [instance_ID]] = MUTentry.d_MUTfactorArray [instance_ID] * CKTag_0 ;
}
}
return ;
}

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "inddefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMalloc MACRO to check it for errors --> CUDAMALLOCCHECK(name of pointer, dimension, type, status) */
#define CUDAMALLOCCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuMUTsetup routine...\n") ; \
fprintf (stderr, "Error: cudaMalloc failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuMUTsetup routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuMUTsetup
(
GENmodel *inModel
)
{
long unsigned int size ;
cudaError_t status ;
MUTmodel *model = (MUTmodel *)inModel ;
size = (long unsigned int) model->n_instances;
/* Space Allocation to GPU */
status = cudaMalloc ((void **)&(model->d_PositionVector), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->d_PositionVector, size, int, status)
status = cudaMemcpy (model->d_PositionVector, model->PositionVector, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->d_PositionVector, size, int, status)
status = cudaMalloc ((void **)&(model->d_PositionVectorRHS), (long unsigned int)model->n_instancesRHS * sizeof(int)) ;
CUDAMALLOCCHECK (model->d_PositionVectorRHS, (long unsigned int)model->n_instancesRHS, int, status)
status = cudaMemcpy (model->d_PositionVectorRHS, model->PositionVectorRHS, (long unsigned int)model->n_instancesRHS * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->d_PositionVectorRHS, (long unsigned int)model->n_instancesRHS, int, status)
/* PARTICULAR SITUATION */
status = cudaMalloc ((void **)&(model->MUTparamGPU.d_MUTinstanceIND1Array), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->MUTparamGPU.d_MUTinstanceIND1Array, size, int, status)
status = cudaMemcpy (model->MUTparamGPU.d_MUTinstanceIND1Array, model->MUTparamCPU.MUTinstanceIND1Array, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->MUTparamGPU.d_MUTinstanceIND1Array, size, int, status)
status = cudaMalloc ((void **)&(model->MUTparamGPU.d_MUTinstanceIND2Array), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->MUTparamGPU.d_MUTinstanceIND2Array, size, int, status)
status = cudaMemcpy (model->MUTparamGPU.d_MUTinstanceIND2Array, model->MUTparamCPU.MUTinstanceIND2Array, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->MUTparamGPU.d_MUTinstanceIND2Array, size, int, status)
/* DOUBLE */
model->MUTparamCPU.MUTfactorArray = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->MUTparamGPU.d_MUTfactorArray), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->MUTparamGPU.d_MUTfactorArray, size, double, status)
/* INT */
model->MUTparamCPU.MUTflux1Array = (int *) malloc (size * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->MUTparamGPU.d_MUTflux1Array), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->MUTparamGPU.d_MUTflux1Array, size, int, status)
model->MUTparamCPU.MUTflux2Array = (int *) malloc (size * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->MUTparamGPU.d_MUTflux2Array), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->MUTparamGPU.d_MUTflux2Array, size, int, status)
model->MUTparamCPU.MUTbrEq1Array = (int *) malloc (size * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->MUTparamGPU.d_MUTbrEq1Array), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->MUTparamGPU.d_MUTbrEq1Array, size, int, status)
model->MUTparamCPU.MUTbrEq2Array = (int *) malloc (size * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->MUTparamGPU.d_MUTbrEq2Array), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->MUTparamGPU.d_MUTbrEq2Array, size, int, status)
return (OK) ;
}

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "inddefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuMUTtemp routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuMUTtemp
(
GENmodel *inModel
)
{
long unsigned int size ;
cudaError_t status ;
MUTmodel *model = (MUTmodel *)inModel ;
size = (long unsigned int) model->n_instances;
/* DOUBLE */
status = cudaMemcpy (model->MUTparamGPU.d_MUTfactorArray, model->MUTparamCPU.MUTfactorArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->MUTparamGPU.d_MUTfactorArray, size, double, status)
/* INT */
status = cudaMemcpy (model->MUTparamGPU.d_MUTflux1Array, model->MUTparamCPU.MUTflux1Array, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->MUTparamGPU.d_MUTflux1Array, size, int, status)
status = cudaMemcpy (model->MUTparamGPU.d_MUTflux2Array, model->MUTparamCPU.MUTflux2Array, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->MUTparamGPU.d_MUTflux2Array, size, int, status)
status = cudaMemcpy (model->MUTparamGPU.d_MUTbrEq1Array, model->MUTparamCPU.MUTbrEq1Array, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->MUTparamGPU.d_MUTbrEq1Array, size, int, status)
status = cudaMemcpy (model->MUTparamGPU.d_MUTbrEq2Array, model->MUTparamCPU.MUTbrEq2Array, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->MUTparamGPU.MUTbrEq2Array, size, int, status)
return (OK) ;
}

View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "inddefs.h"
#include "ngspice/sperror.h"
#define TopologyMatrixInsert(Ptr, instance_ID, offset, Value, global_ID) \
ckt->CKTtopologyMatrixCOOi [global_ID] = (int)(here->Ptr - basePtr) ; \
ckt->CKTtopologyMatrixCOOj [global_ID] = model->PositionVector [instance_ID] + offset ; \
ckt->CKTtopologyMatrixCOOx [global_ID] = Value ;
#define TopologyMatrixInsertRHS(offset, instance_ID, offsetRHS, Value, global_ID) \
ckt->CKTtopologyMatrixCOOiRHS [global_ID] = here->offset ; \
ckt->CKTtopologyMatrixCOOjRHS [global_ID] = model->PositionVectorRHS [instance_ID] + offsetRHS ; \
ckt->CKTtopologyMatrixCOOxRHS [global_ID] = Value ;
int
INDtopology (GENmodel *inModel, CKTcircuit *ckt, int *i, int *j)
{
INDmodel *model = (INDmodel *)inModel ;
INDinstance *here ;
int k ;
double *basePtr ;
basePtr = ckt->CKTmatrix->CKTkluAx ;
/* loop through all the inductor models */
for ( ; model != NULL ; model = INDnextModel(model))
{
k = 0 ;
/* loop through all the instances of the model */
for (here = INDinstances(model); here != NULL ; here = INDnextInstance(here))
{
if ((here->INDposNode != 0) && (here->INDbrEq != 0))
{
TopologyMatrixInsert (INDposIbrPtr, k, 0, 1, *i) ;
(*i)++ ;
}
if ((here->INDnegNode != 0) && (here->INDbrEq != 0))
{
TopologyMatrixInsert (INDnegIbrPtr, k, 0, -1, *i) ;
(*i)++ ;
}
if ((here->INDbrEq != 0) && (here->INDnegNode != 0))
{
TopologyMatrixInsert (INDibrNegPtr, k, 0, -1, *i) ;
(*i)++ ;
}
if ((here->INDbrEq != 0) && (here->INDposNode != 0))
{
TopologyMatrixInsert (INDibrPosPtr, k, 0, 1, *i) ;
(*i)++ ;
}
if ((here->INDbrEq != 0) && (here->INDbrEq != 0))
{
TopologyMatrixInsert (INDibrIbrPtr, k, 1, -1, *i) ;
(*i)++ ;
}
if (here->INDbrEq != 0)
{
TopologyMatrixInsertRHS (INDbrEq, k, 0, 1, *j) ;
(*j)++ ;
}
k++ ;
}
}
return (OK) ;
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "inddefs.h"
#include "ngspice/sperror.h"
#define TopologyMatrixInsert(Ptr, instance_ID, offset, Value, global_ID) \
ckt->CKTtopologyMatrixCOOi [global_ID] = (int)(here->Ptr - basePtr) ; \
ckt->CKTtopologyMatrixCOOj [global_ID] = model->PositionVector [instance_ID] + offset ; \
ckt->CKTtopologyMatrixCOOx [global_ID] = Value ;
int
MUTtopology (GENmodel *inModel, CKTcircuit *ckt, int *i, int *j)
{
NG_IGNORE (j) ;
MUTmodel *model = (MUTmodel *)inModel ;
MUTinstance *here ;
int k ;
double *basePtr ;
basePtr = ckt->CKTmatrix->CKTkluAx ;
/* loop through all the mutual inductor models */
for ( ; model != NULL ; model = MUTnextModel(model))
{
k = 0 ;
/* loop through all the instances of the model */
for (here = MUTinstances(model); here != NULL ; here = MUTnextInstance(here))
{
if ((here->MUTind1->INDbrEq != 0) && (here->MUTind2->INDbrEq != 0))
{
TopologyMatrixInsert (MUTbr1br2Ptr, k, 0, -1, *i) ;
(*i)++ ;
}
if ((here->MUTind2->INDbrEq != 0) && (here->MUTind1->INDbrEq != 0))
{
TopologyMatrixInsert (MUTbr2br1Ptr, k, 0, -1, *i) ;
(*i)++ ;
}
k++ ;
}
}
return (OK) ;
}

View File

@ -48,4 +48,25 @@ endif
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
AM_CFLAGS = $(STATIC)
if USE_CUSPICE_WANTED
.cu.lo:
$(AM_V_GEN)$(top_srcdir)/src/libtool_wrapper_for_cuda.tcl $@ $(AM_CFLAGS) $(NVCC) $(CUDA_CFLAGS) $(AM_CPPFLAGS) -c $<
libind_la_SOURCES += \
CUSPICE/indtopology.c \
CUSPICE/cuindfree.c \
CUSPICE/cuindload.cu \
CUSPICE/cuindsetup.c \
CUSPICE/cuindtemp.c
libind_la_SOURCES += \
CUSPICE/muttopology.c \
CUSPICE/cumutfree.c \
CUSPICE/cumutload.cu \
CUSPICE/cumutsetup.c \
CUSPICE/cumuttemp.c
AM_CPPFLAGS += $(CUDA_CPPFLAGS)
endif
MAINTAINERCLEANFILES = Makefile.in

View File

@ -79,6 +79,12 @@ struct sINDinstance {
BindElement *INDibrPosBinding;
BindElement *INDibrIbrBinding;
#endif
/* PARTICULAR SITUATION */
#ifdef USE_CUSPICE
int instanceID;
#endif
};
#define INDflux INDstate /* flux in the inductor */
@ -87,6 +93,31 @@ struct sINDinstance {
* +3 for the derivatives - pointer to the
* beginning of the array */
#ifdef USE_CUSPICE
typedef struct sINDparamCPUstruct {
double *INDcpuPointersD [4];
#define INDinitCondArray INDcpuPointersD[0]
#define INDinductArray INDcpuPointersD[1]
#define INDreqValueArray INDcpuPointersD[2]
#define INDveqValueArray INDcpuPointersD[3]
int *INDcpuPointersI [2];
#define INDbrEqArray INDcpuPointersI[0]
#define INDstateArray INDcpuPointersI[1]
} INDparamCPUstruct;
typedef struct sINDparamGPUstruct {
double *INDcudaPointersD [4];
#define d_INDinitCondArray INDcudaPointersD[0]
#define d_INDinductArray INDcudaPointersD[1]
#define d_INDreqValueArray INDcudaPointersD[2]
#define d_INDveqValueArray INDcudaPointersD[3]
int *INDcudaPointersI [2];
#define d_INDbrEqArray INDcudaPointersI[0]
#define d_INDstateArray INDcudaPointersI[1]
} INDparamGPUstruct;
#endif
/* per model data */
@ -118,8 +149,27 @@ struct sINDmodel { /* model structure for an inductor */
unsigned INDmIndGiven : 1; /* flag to indicate model inductance given */
double INDspecInd; /* Specific (one turn) inductance */
};
#ifdef USE_CUSPICE
INDparamCPUstruct INDparamCPU;
INDparamGPUstruct INDparamGPU;
int offset;
int n_values;
int n_Ptr;
int *PositionVector;
int *d_PositionVector;
int offsetRHS;
int n_valuesRHS;
int n_PtrRHS;
int *PositionVectorRHS;
int *d_PositionVectorRHS;
int n_instances;
#endif
};
/* structures used to describe mutual inductors */
@ -157,6 +207,33 @@ struct sMUTinstance {
#endif
};
#ifdef USE_CUSPICE
typedef struct sMUTparamCPUstruct {
double *MUTcpuPointersD [1];
#define MUTfactorArray MUTcpuPointersD[0]
int *MUTcpuPointersI [6];
#define MUTflux1Array MUTcpuPointersI[0]
#define MUTflux2Array MUTcpuPointersI[1]
#define MUTbrEq1Array MUTcpuPointersI[2]
#define MUTbrEq2Array MUTcpuPointersI[3]
#define MUTinstanceIND1Array MUTcpuPointersI[4]
#define MUTinstanceIND2Array MUTcpuPointersI[5]
} MUTparamCPUstruct;
typedef struct sMUTparamGPUstruct {
double *MUTcudaPointersD [1];
#define d_MUTfactorArray MUTcudaPointersD[0]
int *MUTcudaPointersI [6];
#define d_MUTflux1Array MUTcudaPointersI[0]
#define d_MUTflux2Array MUTcudaPointersI[1]
#define d_MUTbrEq1Array MUTcudaPointersI[2]
#define d_MUTbrEq2Array MUTcudaPointersI[3]
#define d_MUTinstanceIND1Array MUTcudaPointersI[4]
#define d_MUTinstanceIND2Array MUTcudaPointersI[5]
} MUTparamGPUstruct;
#endif
/* per model data */
@ -169,6 +246,24 @@ struct sMUTmodel { /* model structure for a mutual inductor */
#define MUTinstances(inst) ((MUTinstance *)((inst)->gen.GENinstances))
#define MUTmodName gen.GENmodName
#ifdef USE_CUSPICE
MUTparamCPUstruct MUTparamCPU;
MUTparamGPUstruct MUTparamGPU;
int offset;
int n_values;
int n_Ptr;
int *PositionVector;
int *d_PositionVector;
int *PositionVectorRHS;
int *d_PositionVectorRHS;
int n_instances;
/* PARTICULAR SITUATION */
int n_instancesRHS;
#endif
};

View File

@ -46,4 +46,9 @@ extern int MUTbindCSCComplex (GENmodel*, CKTcircuit*) ;
extern int MUTbindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
#endif
#ifdef USE_CUSPICE
extern int INDtopology (GENmodel *, CKTcircuit *, int *, int *) ;
extern int MUTtopology (GENmodel *, CKTcircuit *, int *, int *) ;
#endif
#endif

View File

@ -6,6 +6,10 @@
#include "indext.h"
#include "indinit.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
SPICEdev INDinfo = {
.DEVpublic = {
@ -33,7 +37,11 @@ SPICEdev INDinfo = {
.DEVparam = INDparam,
.DEVmodParam = INDmParam,
#ifdef USE_CUSPICE
.DEVload = cuINDload,
#else
.DEVload = INDload,
#endif
.DEVsetup = INDsetup,
.DEVunsetup = INDunsetup,
.DEVpzSetup = INDsetup,
@ -71,6 +79,10 @@ SPICEdev INDinfo = {
.DEVbindCSCComplex = INDbindCSCComplex,
.DEVbindCSCComplexToReal = INDbindCSCComplexToReal,
#endif
#ifdef USE_CUSPICE
.cuDEVdestroy = cuINDdestroy,
.DEVtopology = INDtopology,
#endif
};
@ -100,7 +112,11 @@ SPICEdev MUTinfo = {
.DEVparam = MUTparam,
.DEVmodParam = NULL,
#ifdef USE_CUSPICE
.DEVload = cuMUTload,
#else
.DEVload = NULL,
#endif
.DEVsetup = MUTsetup,
.DEVunsetup = NULL,
.DEVpzSetup = MUTsetup,
@ -138,6 +154,10 @@ SPICEdev MUTinfo = {
.DEVbindCSCComplex = MUTbindCSCComplex,
.DEVbindCSCComplexToReal = MUTbindCSCComplexToReal,
#endif
#ifdef USE_CUSPICE
.cuDEVdestroy = cuMUTdestroy,
.DEVtopology = MUTtopology,
#endif
};

View File

@ -10,6 +10,10 @@ Author: 1985 Thomas L. Quarles
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
int
INDsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
/* load the inductor structure with those pointers needed later
@ -103,6 +107,96 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
TSTALLOC(INDibrIbrPtr,INDbrEq,INDbrEq);
}
}
#ifdef USE_CUSPICE
int i, j, k, status ;
/* Counting the instances */
for (model = (INDmodel *)inModel ; model != NULL ; model = INDnextModel(model))
{
i = 0 ;
for (here = INDinstances(model); here != NULL ; here = INDnextInstance(here))
{
i++ ;
}
/* How much instances we have */
model->n_instances = i ;
}
/* loop through all the inductor models */
for (model = (INDmodel *)inModel ; model != NULL ; model = INDnextModel(model))
{
model->offset = ckt->total_n_values ;
model->offsetRHS = ckt->total_n_valuesRHS ;
j = 0 ;
k = 0 ;
/* loop through all the instances of the model */
for (here = INDinstances(model); here != NULL ; here = INDnextInstance(here))
{
/* For the Matrix */
if ((here->INDposNode != 0) && (here->INDbrEq != 0))
j++ ;
if ((here->INDnegNode != 0) && (here->INDbrEq != 0))
j++ ;
if ((here->INDbrEq != 0) && (here->INDnegNode != 0))
j++ ;
if ((here->INDbrEq != 0) && (here->INDposNode != 0))
j++ ;
if ((here->INDbrEq != 0) && (here->INDbrEq != 0))
j++ ;
/* For the RHS */
if (here->INDbrEq != 0)
k++ ;
}
/* 2 Different Values for Every Instance */
model->n_values = 2 * model->n_instances;
ckt->total_n_values += model->n_values ;
model->n_Ptr = j ;
ckt->total_n_Ptr += model->n_Ptr ;
model->n_valuesRHS = model->n_instances;
ckt->total_n_valuesRHS += model->n_valuesRHS ;
model->n_PtrRHS = k ;
ckt->total_n_PtrRHS += model->n_PtrRHS ;
/* Position Vector assignment */
model->PositionVector = TMALLOC (int, model->n_instances) ;
for (j = 0 ; j < model->n_instances; j++)
{
/* 2 Different Values for Every Instance */
model->PositionVector [j] = model->offset + 2 * j ;
}
/* Position Vector assignment for the RHS */
model->PositionVectorRHS = TMALLOC (int, model->n_instances) ;
for (j = 0 ; j < model->n_instances; j++)
model->PositionVectorRHS [j] = model->offsetRHS + j ;
}
/* loop through all the inductor models */
for (model = (INDmodel *)inModel ; model != NULL ; model = INDnextModel(model))
{
status = cuINDsetup ((GENmodel *)model) ;
if (status != 0)
return (E_NOMEM) ;
}
#endif
return(OK);
}

View File

@ -12,6 +12,10 @@ Author: 2003 Paolo Nenzi
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
/*ARGSUSED*/
int
@ -23,9 +27,17 @@ INDtemp(GENmodel *inModel, CKTcircuit *ckt)
double factor;
double tc1, tc2;
#ifdef USE_CUSPICE
int i, status ;
#endif
/* loop through all the inductor models */
for( ; model != NULL; model = INDnextModel(model)) {
#ifdef USE_CUSPICE
i = 0 ;
#endif
/* loop through all the instances of the model */
for (here = INDinstances(model); here != NULL ;
here=INDnextInstance(here)) {
@ -70,7 +82,23 @@ INDtemp(GENmodel *inModel, CKTcircuit *ckt)
here->INDinduct = here->INDinduct * factor * here->INDscale;
#ifdef USE_CUSPICE
model->INDparamCPU.INDinitCondArray[i] = here->INDinitCond ;
model->INDparamCPU.INDinductArray[i] = here->INDinduct ;
model->INDparamCPU.INDbrEqArray[i] = here->INDbrEq ;
model->INDparamCPU.INDstateArray[i] = here->INDstate ;
i++ ;
#endif
}
#ifdef USE_CUSPICE
status = cuINDtemp ((GENmodel *)model) ;
if (status != 0)
return (E_NOMEM) ;
#endif
}
return(OK);
}

View File

@ -15,6 +15,10 @@ Author: 1985 Thomas L. Quarles
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
#define TSTALLOC(ptr, first, second) \
do { \
@ -62,5 +66,87 @@ MUTsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
TSTALLOC(MUTbr2br1Ptr, MUTind2->INDbrEq, MUTind1->INDbrEq);
}
#ifdef USE_CUSPICE
int i, j, status;
INDmodel *indmodel;
INDinstance *indhere;
/* Counting the instances */
for (model = (MUTmodel *)inModel; model; model = MUTnextModel(model)) {
i = 0;
for (here = MUTinstances(model); here; here = MUTnextInstance(here))
i++;
/* How much instances we have */
model->n_instances = i;
}
/* loop through all the mutual inductor models */
for (model = (MUTmodel *)inModel; model; model = MUTnextModel(model)) {
model->offset = ckt->total_n_values;
j = 0;
/* loop through all the instances of the model */
for (here = MUTinstances(model); here; here = MUTnextInstance(here)) {
/* For the Matrix */
if ((here->MUTind1->INDbrEq != 0) && (here->MUTind2->INDbrEq != 0))
j++;
if ((here->MUTind2->INDbrEq != 0) && (here->MUTind1->INDbrEq != 0))
j++;
}
model->n_values = model->n_instances;
ckt->total_n_values += model->n_values;
model->n_Ptr = j;
ckt->total_n_Ptr += model->n_Ptr;
/* Position Vector assignment */
model->PositionVector = TMALLOC(int, model->n_instances);
for (j = 0; j < model->n_instances; j++)
model->PositionVector [j] = model->offset + j;
/* PARTICULAR SITUATION */
/* Pick up the IND model from one of the two IND instances */
indmodel = INDmodPtr(MUTinstances(model)->MUTind1);
model->n_instancesRHS = indmodel->n_instances;
/* Position Vector assignment for the RHS */
model->PositionVectorRHS = TMALLOC(int, model->n_instancesRHS);
for (j = 0 ; j < model->n_instancesRHS ; j++)
model->PositionVectorRHS [j] = indmodel->PositionVectorRHS [j];
/* InstanceID assignment for every IND instance */
j = 0;
for (indhere = INDinstances(indmodel); indhere; indhere = INDnextInstance(indhere))
indhere->instanceID = j++;
/* InstanceID storing for every MUT instance */
model->MUTparamCPU.MUTinstanceIND1Array = TMALLOC(int,
model->n_instances);
model->MUTparamCPU.MUTinstanceIND2Array = TMALLOC(int,
model->n_instances);
j = 0;
for (here = MUTinstances(model); here; here = MUTnextInstance(here)) {
model->MUTparamCPU.MUTinstanceIND1Array [j] = here->MUTind1->instanceID;
model->MUTparamCPU.MUTinstanceIND2Array [j++] = here->MUTind2->instanceID;
}
}
/* loop through all the mutual inductor models */
for (model = (MUTmodel *)inModel; model; model = MUTnextModel(model)) {
status = cuMUTsetup ((GENmodel *)model);
if (status != 0)
return (E_NOMEM);
}
#endif
return(OK);
}

View File

@ -9,6 +9,10 @@ Author: 2003 Paolo Nenzi
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
static int
cholesky(double *a, int n)
@ -40,9 +44,18 @@ MUTtemp(GENmodel *inModel, CKTcircuit *ckt)
struct INDsystem *first_system = NULL;
#ifdef USE_CUSPICE
int i, status;
#endif
NG_IGNORE(ckt);
for (; model; model = MUTnextModel(model))
for (; model; model = MUTnextModel(model)) {
#ifdef USE_CUSPICE
i = 0;
#endif
for (here = MUTinstances(model); here; here = MUTnextInstance(here)) {
/* Value Processing for mutual inductors */
@ -55,6 +68,16 @@ MUTtemp(GENmodel *inModel, CKTcircuit *ckt)
*/
here->MUTfactor = here->MUTcoupling * sqrt(fabs(ind1 * ind2));
#ifdef USE_CUSPICE
model->MUTparamCPU.MUTfactorArray[i] = here->MUTfactor;
model->MUTparamCPU.MUTflux1Array[i] = here->MUTind1->INDflux;
model->MUTparamCPU.MUTflux2Array[i] = here->MUTind2->INDflux;
model->MUTparamCPU.MUTbrEq1Array[i] = here->MUTind1->INDbrEq;
model->MUTparamCPU.MUTbrEq2Array[i] = here->MUTind2->INDbrEq;
i++;
#endif
if (ckt->CKTindverbosity > 0) {
struct INDsystem *system;
@ -118,6 +141,13 @@ MUTtemp(GENmodel *inModel, CKTcircuit *ckt)
}
}
#ifdef USE_CUSPICE
status = cuMUTtemp ((GENmodel *)model);
if (status != 0)
return (E_NOMEM);
#endif
}
if (first_system) {
struct INDsystem *system;
int sz = 0;

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "isrcdefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
int
cuISRCdestroy
(
GENmodel *inModel
)
{
ISRCmodel *model = (ISRCmodel *)inModel ;
ISRCinstance *here ;
int i ;
for ( ; model != NULL ; model = ISRCnextModel(model))
{
/* Special case VSRCparamGPU.VSRCcoeffsArray */
i = 0 ;
for (here = ISRCinstances(model); here != NULL ; here = ISRCnextInstance(here))
{
cudaFree (model->ISRCparamCPU.ISRCcoeffsArray[i]) ;
i++ ;
}
free (model->ISRCparamCPU.ISRCcoeffsArray) ;
cudaFree (model->ISRCparamGPU.d_ISRCcoeffsArray) ;
i = 0 ;
for (here = ISRCinstances(model); here != NULL ; here = ISRCnextInstance(here))
{
free (model->ISRCparamCPU.ISRCcoeffsArrayHost [i]) ;
i++ ;
}
free (model->ISRCparamCPU.ISRCcoeffsArrayHost) ;
/* ----------------------------------------- */
/* DOUBLE */
free (model->ISRCparamCPU.ISRCdcvalueArray) ;
cudaFree (model->ISRCparamGPU.d_ISRCdcvalueArray) ;
free (model->ISRCparamCPU.ISRCValueArray) ;
cudaFree (model->ISRCparamGPU.d_ISRCValueArray) ;
/* INT */
free (model->ISRCparamCPU.ISRCdcGivenArray) ;
cudaFree (model->ISRCparamGPU.d_ISRCdcGivenArray) ;
free (model->ISRCparamCPU.ISRCfunctionTypeArray) ;
cudaFree (model->ISRCparamGPU.d_ISRCfunctionTypeArray) ;
free (model->ISRCparamCPU.ISRCfunctionOrderArray) ;
cudaFree (model->ISRCparamGPU.d_ISRCfunctionOrderArray) ;
}
return (OK) ;
}

View File

@ -0,0 +1,431 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "ngspice/CUSPICE/cuniinteg.cuh"
#include "isrcdefs.h"
#ifdef XSPICE_EXP
/* gtri - begin - wbk - modify for supply ramping option */
#include "ngspice/cmproto.h"
/* gtri - end - wbk - modify for supply ramping option */
#endif
/*** TRNOISE and TRRANDOM don't work in the CUDA implementation ***/
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuISRCload routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
extern "C"
__global__ void cuISRCload_kernel (ISRCparamGPUstruct, int, double, double, double, double, int, int *, double *) ;
extern "C"
int
cuISRCload
(
GENmodel *inModel, CKTcircuit *ckt
)
{
ISRCmodel *model = (ISRCmodel *)inModel ;
int thread_x, thread_y, block_x ;
cudaError_t status ;
/* loop through all the inductor models */
for ( ; model != NULL ; model = ISRCnextModel(model))
{
/* Determining how many blocks should exist in the kernel */
thread_x = 1 ;
thread_y = 256 ;
if (model->n_instances % thread_y != 0)
block_x = (int)((model->n_instances + thread_y - 1) / thread_y) ;
else
block_x = model->n_instances / thread_y ;
dim3 thread (thread_x, thread_y) ;
/* Kernel launch */
status = cudaGetLastError () ; // clear error status
cuISRCload_kernel <<< block_x, thread >>> (model->ISRCparamGPU, ckt->CKTmode, ckt->CKTtime,
ckt->CKTstep, ckt->CKTfinalTime, ckt->CKTsrcFact,
model->n_instances, model->d_PositionVectorRHS,
ckt->d_CKTloadOutputRHS) ;
cudaDeviceSynchronize () ;
status = cudaGetLastError () ; // check for launch error
if (status != cudaSuccess)
{
fprintf (stderr, "Kernel launch failure in the Current Source Model\n\n") ;
return (E_NOMEM) ;
}
}
return (OK) ;
}
extern "C"
__global__
void
cuISRCload_kernel
(
ISRCparamGPUstruct ISRCentry, int CKTmode, double CKTtime,
double CKTstep, double CKTfinalTime, double CKTsrcFact, int n_instances,
int *d_PositionVectorRHS, double *d_CKTloadOutputRHS
)
{
int instance_ID ;
double value, time ;
instance_ID = threadIdx.y + blockDim.y * blockIdx.x ;
if (instance_ID < n_instances)
{
if (threadIdx.x == 0)
{
if ((CKTmode & (MODEDCOP | MODEDCTRANCURVE)) && ISRCentry.d_ISRCdcGivenArray [instance_ID])
{
/* load using DC value */
#ifdef XSPICE_EXP
/* gtri - begin - wbk - modify to process srcFact, etc. for all sources */
value = ISRCentry.d_ISRCdcvalueArray [instance_ID] ;
#else
value = ISRCentry.d_ISRCdcvalueArray [instance_ID] * CKTsrcFact ;
#endif
} else {
if (CKTmode & (MODEDC))
time = 0 ;
else
time = CKTtime ;
/* use the transient functions */
switch (ISRCentry.d_ISRCfunctionTypeArray [instance_ID])
{
default:
#ifdef XSPICE_EXP
value = ISRCentry.d_ISRCdcvalueArray [instance_ID] ;
#else
value = ISRCentry.d_ISRCdcvalueArray [instance_ID] * CKTsrcFact ;
#endif
break ;
case PULSE:
{
double V1, V2, TD, TR, TF, PW, PER, basetime = 0 ;
#ifdef XSPICE
double PHASE, phase, deltat ;
#endif
V1 = ISRCentry.d_ISRCcoeffsArray [instance_ID] [0] ;
V2 = ISRCentry.d_ISRCcoeffsArray [instance_ID] [1] ;
TD = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 2
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [2] : 0.0 ;
TR = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 3
&& ISRCentry.d_ISRCcoeffsArray [instance_ID] [3] != 0.0
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [3] : CKTstep ;
TF = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 4
&& ISRCentry.d_ISRCcoeffsArray [instance_ID] [4] != 0.0
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [4] : CKTstep ;
PW = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 5
&& ISRCentry.d_ISRCcoeffsArray [instance_ID] [5] != 0.0
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [5] : CKTfinalTime ;
PER = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 6
&& ISRCentry.d_ISRCcoeffsArray [instance_ID] [6] != 0.0
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [6] : CKTfinalTime ;
/* shift time by delay time TD */
time -= TD ;
#ifdef XSPICE
/* gtri - begin - wbk - add PHASE parameter */
PHASE = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 7
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [7] : 0.0 ;
/* normalize phase to cycles */
phase = PHASE / 360.0 ;
phase = fmod (phase, 1.0) ;
deltat = phase * PER ;
while (deltat > 0)
deltat -= PER ;
/* shift time by pase (neg. for pos. phase value) */
time += deltat ;
/* gtri - end - wbk - add PHASE parameter */
#endif
if (time > PER)
{
/* repeating signal - figure out where we are */
/* in period */
basetime = PER * floor (time / PER) ;
time -= basetime ;
}
if (time <= 0 || time >= TR + PW + TF)
value = V1 ;
else if (time >= TR && time <= TR + PW)
value = V2 ;
else if (time > 0 && time < TR)
value = V1 + (V2 - V1) * (time) / TR ;
else /* time > TR + PW && < TR + PW + TF */
value = V2 + (V1 - V2) * (time - (TR + PW)) / TF ;
}
break ;
case SINE:
{
double VO, VA, FREQ, TD, THETA ;
/* gtri - begin - wbk - add PHASE parameter */
#ifdef XSPICE
double PHASE, phase ;
PHASE = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 5
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [5] : 0.0 ;
/* compute phase in radians */
phase = PHASE * M_PI / 180.0 ;
#endif
VO = ISRCentry.d_ISRCcoeffsArray [instance_ID] [0] ;
VA = ISRCentry.d_ISRCcoeffsArray [instance_ID] [1] ;
FREQ = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 2
&& ISRCentry.d_ISRCcoeffsArray [instance_ID] [2] != 0.0
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [2] : (1 / CKTfinalTime) ;
TD = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 3
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [3] : 0.0 ;
THETA = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 4
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [4] : 0.0 ;
time -= TD ;
if (time <= 0)
#ifdef XSPICE
value = VO + VA * sin (phase) ;
else
value = VO + VA * sin (FREQ * time * 2.0 * M_PI + phase) * exp (-time * THETA) ;
#else
value = VO ;
else
value = VO + VA * sin (FREQ * time * 2.0 * M_PI) * exp (-time * THETA) ;
#endif
/* gtri - end - wbk - add PHASE parameter */
}
break ;
case EXP:
{
double V1, V2, TD1, TD2, TAU1, TAU2 ;
V1 = ISRCentry.d_ISRCcoeffsArray [instance_ID] [0] ;
V2 = ISRCentry.d_ISRCcoeffsArray [instance_ID] [1] ;
TD1 = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 2
&& ISRCentry.d_ISRCcoeffsArray [instance_ID] [2] != 0.0
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [2] : CKTstep ;
TAU1 = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 3
&& ISRCentry.d_ISRCcoeffsArray [instance_ID] [3] != 0.0
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [3] : CKTstep ;
TD2 = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 4
&& ISRCentry.d_ISRCcoeffsArray [instance_ID] [4] != 0.0
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [4] : TD1 + CKTstep ;
TAU2 = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 5
&& ISRCentry.d_ISRCcoeffsArray [instance_ID] [5]
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [5] : CKTstep ;
if (time <= TD1)
value = V1 ;
else if (time <= TD2)
value = V1 + (V2 - V1) * (1 - exp (-(time - TD1) / TAU1)) ;
else
value = V1 + (V2 - V1) * (1 - exp (-(time - TD1) / TAU1)) +
(V1 - V2) * (1 - exp (-(time - TD2) / TAU2)) ;
}
break ;
case SFFM:
{
double VO, VA, FC, MDI, FS ;
/* gtri - begin - wbk - add PHASE parameters */
#ifdef XSPICE
double PHASEC, PHASES, phasec, phases ;
PHASEC = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 5
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [5] : 0.0 ;
PHASES = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 6
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [6] : 0.0 ;
/* compute phases in radians */
phasec = PHASEC * M_PI / 180.0 ;
phases = PHASES * M_PI / 180.0 ;
#endif
VO = ISRCentry.d_ISRCcoeffsArray [instance_ID] [0] ;
VA = ISRCentry.d_ISRCcoeffsArray [instance_ID] [1] ;
FC = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 2
&& ISRCentry.d_ISRCcoeffsArray [instance_ID] [2]
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [2] : (1 / CKTfinalTime) ;
MDI = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 3
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [3] : 0.0 ;
FS = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 4
&& ISRCentry.d_ISRCcoeffsArray [instance_ID] [4]
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [4] : (1 / CKTfinalTime) ;
#ifdef XSPICE
/* compute waveform value */
value = VO + VA * sin ((2.0 * M_PI * FC * time + phasec) +
MDI * sin (2.0 * M_PI * FS * time + phases)) ;
#else
value = VO + VA * sin ((2.0 * M_PI * FC * time) +
MDI * sin (2.0 * M_PI * FS * time)) ;
#endif
/* gtri - end - wbk - add PHASE parameters */
}
break ;
case AM:
{
double VA, FC, MF, VO, TD ;
/* gtri - begin - wbk - add PHASE parameters */
#ifdef XSPICE
double PHASEC, PHASES, phasec, phases ;
PHASEC = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 5
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [5] : 0.0 ;
PHASES = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 6
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [6] : 0.0 ;
/* compute phases in radians */
phasec = PHASEC * M_PI / 180.0 ;
phases = PHASES * M_PI / 180.0 ;
#endif
VA = ISRCentry.d_ISRCcoeffsArray [instance_ID] [0] ;
VO = ISRCentry.d_ISRCcoeffsArray [instance_ID] [1] ;
MF = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 2
&& ISRCentry.d_ISRCcoeffsArray [instance_ID] [2]
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [2] : (1 / CKTfinalTime) ;
FC = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 3
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [3] : 0.0 ;
TD = ISRCentry.d_ISRCfunctionOrderArray [instance_ID] > 4
&& ISRCentry.d_ISRCcoeffsArray [instance_ID] [4]
? ISRCentry.d_ISRCcoeffsArray [instance_ID] [4] : 0.0 ;
time -= TD ;
if (time <= 0)
value = 0 ;
else
#ifdef XSPICE
/* compute waveform value */
value = VA * (VO + sin (2.0 * M_PI * MF * time + phases )) *
sin (2.0 * M_PI * FC * time + phases) ;
#else
value = VA * (VO + sin (2.0 * M_PI * MF * time)) *
sin (2.0 * M_PI * FC * time) ;
/* gtri - end - wbk - add PHASE parameters */
#endif
}
break ;
case PWL:
{
int i ;
if (time < ISRCentry.d_ISRCcoeffsArray [instance_ID] [0])
{
value = ISRCentry.d_ISRCcoeffsArray [instance_ID] [1] ;
break ;
}
for (i = 0 ; i <= (ISRCentry.d_ISRCfunctionOrderArray [instance_ID] / 2) - 1 ; i++)
{
if ((ISRCentry.d_ISRCcoeffsArray [instance_ID] [2 * i] == time))
{
value = ISRCentry.d_ISRCcoeffsArray [instance_ID] [2 * i + 1] ;
goto loadDone ;
}
if ((ISRCentry.d_ISRCcoeffsArray [instance_ID] [2 * i] < time)
&& (ISRCentry.d_ISRCcoeffsArray [instance_ID] [2 * (i + 1)] > time))
{
value = ISRCentry.d_ISRCcoeffsArray [instance_ID] [2 * i + 1] +
(((time - ISRCentry.d_ISRCcoeffsArray [instance_ID] [2 * i]) /
(ISRCentry.d_ISRCcoeffsArray [instance_ID] [2 * (i + 1)] -
ISRCentry.d_ISRCcoeffsArray [instance_ID] [2 * i])) *
(ISRCentry.d_ISRCcoeffsArray [instance_ID] [2 * i + 3] -
ISRCentry.d_ISRCcoeffsArray [instance_ID] [2 * i + 1])) ;
goto loadDone ;
}
}
value = ISRCentry.d_ISRCcoeffsArray [instance_ID]
[ISRCentry.d_ISRCfunctionOrderArray [instance_ID] - 1] ;
break ;
}
} // switch
} // else (line 593)
loadDone:
#ifdef XSPICE_EXP
/* gtri - begin - wbk - modify for supply ramping option */
value *= CKTsrcFact ;
value *= cm_analog_ramp_factor () ;
#else
if (CKTmode & MODETRANOP)
value *= CKTsrcFact ;
/* gtri - end - wbk - modify for supply ramping option */
#endif
d_CKTloadOutputRHS [d_PositionVectorRHS [instance_ID]] = value ;
/* gtri - end - wbk - modify to process srcFact, etc. for all sources */
#ifdef XSPICE
/* gtri - begin - wbk - record value so it can be output if requested */
here->ISRCcurrent = value ;
/* gtri - end - wbk - record value so it can be output if requested */
#endif
}
}
return ;
}

View File

@ -0,0 +1,127 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "isrcdefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMalloc MACRO to check it for errors --> CUDAMALLOCCHECK(name of pointer, dimension, type, status) */
#define CUDAMALLOCCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuISRCsetup routine...\n") ; \
fprintf (stderr, "Error: cudaMalloc failed on %s size1 of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuISRCsetup routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size1 of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuISRCsetup
(
GENmodel *inModel
)
{
int i ;
long unsigned int size1, size2 ;
cudaError_t status ;
ISRCmodel *model = (ISRCmodel *)inModel ;
ISRCinstance *here ;
size1 = (long unsigned int) model->n_instances;
/* Space Allocation to GPU */
status = cudaMalloc ((void **)&(model->d_PositionVectorRHS), size1 * sizeof(int)) ;
CUDAMALLOCCHECK (model->d_PositionVectorRHS, size1, int, status)
status = cudaMemcpy (model->d_PositionVectorRHS, model->PositionVectorRHS, size1 * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->d_PositionVectorRHS, size1, int, status)
/* Special case ISRCparamGPU.ISRCcoeffsArray */
model->ISRCparamCPU.ISRCcoeffsArray = (double **) malloc (size1 * sizeof(double *)) ;
status = cudaMalloc ((void **)&(model->ISRCparamGPU.d_ISRCcoeffsArray), size1 * sizeof(double *)) ;
CUDAMALLOCCHECK (model->ISRCparamGPU.ISRCcoeffsArray, size1, double*, status)
i = 0 ;
for (here = ISRCinstances(model); here != NULL ; here = ISRCnextInstance(here))
{
size2 = (long unsigned int)here->n_coeffs ;
status = cudaMalloc ((void **)&(model->ISRCparamCPU.ISRCcoeffsArray[i]), size2 * sizeof(double)) ;
CUDAMALLOCCHECK (model->ISRCparamCPU.ISRCcoeffsArray[i], size2, double, status)
i++ ;
}
/* Structure pointer vectors in GPU */
status = cudaMemcpy (model->ISRCparamGPU.d_ISRCcoeffsArray, model->ISRCparamCPU.ISRCcoeffsArray, size1 * sizeof(double *), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->ISRCparamGPU.d_ISRCcoeffsArray, size1, sizeof(double *), status)
i = 0 ;
model->ISRCparamCPU.ISRCcoeffsArrayHost = (double **) malloc (size1 * sizeof(double *)) ;
for (here = ISRCinstances(model); here != NULL ; here = ISRCnextInstance(here))
{
size2 = (long unsigned int)here->n_coeffs ;
model->ISRCparamCPU.ISRCcoeffsArrayHost [i] = (double *) malloc (size2 * sizeof(double)) ;
i++ ;
}
/* ----------------------------------------- */
/* DOUBLE */
model->ISRCparamCPU.ISRCdcvalueArray = (double *) malloc (size1 * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->ISRCparamGPU.d_ISRCdcvalueArray), size1 * sizeof(double)) ;
CUDAMALLOCCHECK (model->ISRCparamGPU.d_ISRCdcvalueArray, size1, double, status)
model->ISRCparamCPU.ISRCValueArray = (double *) malloc (size1 * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->ISRCparamGPU.d_ISRCValueArray), size1 * sizeof(double)) ;
CUDAMALLOCCHECK (model->ISRCparamGPU.d_ISRCValueArray, size1, double, status)
/* INT */
model->ISRCparamCPU.ISRCdcGivenArray = (int *) malloc (size1 * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->ISRCparamGPU.d_ISRCdcGivenArray), size1 * sizeof(int)) ;
CUDAMALLOCCHECK (model->ISRCparamGPU.d_ISRCdcGivenArray, size1, int, status)
model->ISRCparamCPU.ISRCfunctionTypeArray = (int *) malloc (size1 * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->ISRCparamGPU.d_ISRCfunctionTypeArray), size1 * sizeof(int)) ;
CUDAMALLOCCHECK (model->ISRCparamGPU.d_ISRCfunctionTypeArray, size1, int, status)
model->ISRCparamCPU.ISRCfunctionOrderArray = (int *) malloc (size1 * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->ISRCparamGPU.d_ISRCfunctionOrderArray), size1 * sizeof(int)) ;
CUDAMALLOCCHECK (model->ISRCparamGPU.d_ISRCfunctionOrderArray, size1, int, status)
return (OK) ;
}

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "isrcdefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuISRCtemp routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size1 of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuISRCtemp
(
GENmodel *inModel
)
{
int i ;
long unsigned int size1, size2 ;
cudaError_t status ;
ISRCmodel *model = (ISRCmodel *)inModel ;
ISRCinstance *here ;
size1 = (long unsigned int) model->n_instances;
i = 0 ;
for (here = ISRCinstances(model); here != NULL ; here = ISRCnextInstance(here))
{
size2 = (long unsigned int)here->n_coeffs ;
status = cudaMemcpy (model->ISRCparamCPU.ISRCcoeffsArray [i], model->ISRCparamCPU.ISRCcoeffsArrayHost [i], size2 * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->ISRCparamCPU.ISRCcoeffsArray [i], size2, double, status)
i++ ;
}
/* DOUBLE */
status = cudaMemcpy (model->ISRCparamGPU.d_ISRCdcvalueArray, model->ISRCparamCPU.ISRCdcvalueArray, size1 * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->ISRCparamGPU.d_ISRCdcvalueArray, size1, double, status)
/* INT */
status = cudaMemcpy (model->ISRCparamGPU.d_ISRCdcGivenArray, model->ISRCparamCPU.ISRCdcGivenArray, size1 * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->ISRCparamGPU.d_ISRCdcGivenArray, size1, int, status)
status = cudaMemcpy (model->ISRCparamGPU.d_ISRCfunctionTypeArray, model->ISRCparamCPU.ISRCfunctionTypeArray, size1 * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->ISRCparamGPU.d_ISRCfunctionTypeArray, size1, int, status)
status = cudaMemcpy (model->ISRCparamGPU.d_ISRCfunctionOrderArray, model->ISRCparamCPU.ISRCfunctionOrderArray, size1 * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->ISRCparamGPU.ISRCfunctionOrderArray, size1, int, status)
return (OK) ;
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "isrcdefs.h"
#include "ngspice/sperror.h"
#define TopologyMatrixInsertRHS(offset, instance_ID, offsetRHS, Value, global_ID) \
ckt->CKTtopologyMatrixCOOiRHS [global_ID] = here->offset ; \
ckt->CKTtopologyMatrixCOOjRHS [global_ID] = model->PositionVectorRHS [instance_ID] + offsetRHS ; \
ckt->CKTtopologyMatrixCOOxRHS [global_ID] = Value ;
int
ISRCtopology (GENmodel *inModel, CKTcircuit *ckt, int *i, int *j)
{
NG_IGNORE (i) ;
ISRCmodel *model = (ISRCmodel *)inModel ;
ISRCinstance *here ;
int k ;
/* loop through all the voltage source models */
for ( ; model != NULL ; model = ISRCnextModel(model))
{
k = 0 ;
/* loop through all the instances of the model */
for (here = ISRCinstances(model); here != NULL ; here = ISRCnextInstance(here))
{
if (here->ISRCposNode != 0)
{
TopologyMatrixInsertRHS (ISRCposNode, k, 0, 1, *j) ;
(*j)++ ;
}
if (here->ISRCnegNode != 0)
{
TopologyMatrixInsertRHS (ISRCnegNode, k, 0, -1, *j) ;
(*j)++ ;
}
k++ ;
}
}
return (OK) ;
}

View File

@ -23,4 +23,20 @@ libisrc_la_SOURCES = \
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
AM_CFLAGS = $(STATIC)
if USE_CUSPICE_WANTED
.cu.lo:
$(AM_V_GEN)$(top_srcdir)/src/libtool_wrapper_for_cuda.tcl $@ $(AM_CFLAGS) $(NVCC) $(CUDA_CFLAGS) $(AM_CPPFLAGS) -c $<
libisrc_la_SOURCES += \
isrcsetup.c \
CUSPICE/isrctopology.c \
CUSPICE/cuisrcfree.c \
CUSPICE/cuisrcload.cu \
CUSPICE/cuisrcsetup.c \
CUSPICE/cuisrctemp.c
AM_CPPFLAGS += $(CUDA_CPPFLAGS)
endif
MAINTAINERCLEANFILES = Makefile.in

View File

@ -68,8 +68,46 @@ typedef struct sISRCinstance {
unsigned ISRCdGiven :1 ; /* flag to indicate source is a distortion input */
unsigned ISRCdF1given :1 ; /* flag to indicate source is an f1 distortion input */
unsigned ISRCdF2given :1 ; /* flag to indicate source is an f2 distortion input */
#ifdef USE_CUSPICE
double *d_ISRCcoeffs ;
int n_coeffs ;
#endif
} ISRCinstance ;
#ifdef USE_CUSPICE
typedef struct sISRCparamCPUstruct {
/* pointer to array of coefficients in GPU */
double **ISRCcoeffsArrayHost ;
double **ISRCcoeffsArray ;
double *ISRCcpuPointersD [2] ;
#define ISRCdcvalueArray ISRCcpuPointersD[0]
#define ISRCValueArray ISRCcpuPointersD[1]
int *ISRCcpuPointersI [3] ;
#define ISRCdcGivenArray ISRCcpuPointersI[0]
#define ISRCfunctionTypeArray ISRCcpuPointersI[1]
#define ISRCfunctionOrderArray ISRCcpuPointersI[2]
} ISRCparamCPUstruct ;
typedef struct sISRCparamGPUstruct {
/* pointer to array of coefficients in GPU */
double **d_ISRCcoeffsArray ;
double *ISRCcudaPointersD [2] ;
#define d_ISRCdcvalueArray ISRCcudaPointersD[0]
#define d_ISRCValueArray ISRCcudaPointersD[1]
int *ISRCcudaPointersI [3] ;
#define d_ISRCdcGivenArray ISRCcudaPointersI[0]
#define d_ISRCfunctionTypeArray ISRCcudaPointersI[1]
#define d_ISRCfunctionOrderArray ISRCcudaPointersI[2]
} ISRCparamGPUstruct ;
#endif
/* per model data */
@ -82,6 +120,19 @@ typedef struct sISRCmodel {
#define ISRCinstances(inst) ((ISRCinstance *)((inst)->gen.GENinstances))
#define ISRCmodName gen.GENmodName
#ifdef USE_CUSPICE
ISRCparamCPUstruct ISRCparamCPU ;
ISRCparamGPUstruct ISRCparamGPU ;
int offsetRHS ;
int n_valuesRHS ;
int n_PtrRHS ;
int *PositionVectorRHS ;
int *d_PositionVectorRHS ;
int n_instances ;
#endif
} ISRCmodel;

View File

@ -13,3 +13,8 @@ extern int ISRCmDelete(GENmodel*);
extern int ISRCparam(int,IFvalue*,GENinstance*,IFvalue*);
extern int ISRCpzLoad(GENmodel*,CKTcircuit*,SPcomplex*);
extern int ISRCtemp(GENmodel*,CKTcircuit*);
#ifdef USE_CUSPICE
extern int ISRCsetup (SMPmatrix *, GENmodel *, CKTcircuit *, int *) ;
extern int ISRCtopology (GENmodel *, CKTcircuit *, int *, int *) ;
#endif

View File

@ -6,6 +6,10 @@
#include "isrcext.h"
#include "isrcinit.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
SPICEdev ISRCinfo = {
.DEVpublic = {
@ -33,8 +37,16 @@ SPICEdev ISRCinfo = {
.DEVparam = ISRCparam,
.DEVmodParam = NULL,
#ifdef USE_CUSPICE
.DEVload = cuISRCload,
#else
.DEVload = ISRCload,
#endif
#ifdef USE_CUSPICE
.DEVsetup = ISRCsetup,
#else
.DEVsetup = NULL,
#endif
.DEVunsetup = NULL,
.DEVpzSetup = NULL,
.DEVtemperature = ISRCtemp,
@ -71,6 +83,10 @@ SPICEdev ISRCinfo = {
.DEVbindCSCComplex = NULL,
.DEVbindCSCComplexToReal = NULL,
#endif
#ifdef USE_CUSPICE
.cuDEVdestroy = cuISRCdestroy,
.DEVtopology = ISRCtopology,
#endif
};

View File

@ -26,6 +26,11 @@ static void copy_coeffs(ISRCinstance *here, IFvalue *value)
here->ISRCcoeffsGiven = TRUE;
memcpy(here->ISRCcoeffs, value->v.vec.rVec, (size_t) n * sizeof(double));
#ifdef USE_CUSPICE
here->n_coeffs = n ;
#endif
}

View File

@ -0,0 +1,81 @@
/**********
Author: 2012 Francesco Lannutti
**********/
#include "ngspice/ngspice.h"
#include "ngspice/smpdefs.h"
#include "ngspice/cktdefs.h"
#include "isrcdefs.h"
#include "ngspice/sperror.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* ARGSUSED */
int
ISRCsetup (SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *state)
{
ISRCmodel *model = (ISRCmodel *)inModel ;
ISRCinstance *here ;
int i, j, k, status ;
NG_IGNORE(matrix) ;
NG_IGNORE(ckt) ;
NG_IGNORE(state) ;
/* Counting the instances */
for ( ; model != NULL ; model = ISRCnextModel(model))
{
i = 0 ;
for (here = ISRCinstances(model); here != NULL ; here = ISRCnextInstance(here))
{
i++ ;
}
/* How many instances we have */
model->n_instances = i ;
}
/* loop through all the current source models */
for (model = (ISRCmodel *)inModel ; model != NULL ; model = ISRCnextModel(model))
{
model->offsetRHS = ckt->total_n_valuesRHS ;
k = 0 ;
/* loop through all the instances of the model */
for (here = ISRCinstances(model); here != NULL ; here = ISRCnextInstance(here))
{
/* For the RHS */
if (here->ISRCposNode != 0)
k++ ;
if (here->ISRCnegNode != 0)
k++ ;
}
model->n_valuesRHS = model->n_instances;
ckt->total_n_valuesRHS += model->n_valuesRHS ;
model->n_PtrRHS = k ;
ckt->total_n_PtrRHS += model->n_PtrRHS ;
/* Position Vector assignment for the RHS */
model->PositionVectorRHS = TMALLOC (int, model->n_instances) ;
for (j = 0 ; j < model->n_instances; j++)
model->PositionVectorRHS [j] = model->offsetRHS + j ;
}
/* loop through all the current source models */
for (model = (ISRCmodel *)inModel ; model != NULL ; model = ISRCnextModel(model))
{
status = cuISRCsetup ((GENmodel *)model) ;
if (status != 0)
return (E_NOMEM) ;
}
return (OK) ;
}

View File

@ -10,6 +10,10 @@ Author: 1985 Thomas L. Quarles
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
/*ARGSUSED*/
int
ISRCtemp(GENmodel *inModel, CKTcircuit *ckt)
@ -22,9 +26,17 @@ ISRCtemp(GENmodel *inModel, CKTcircuit *ckt)
NG_IGNORE(ckt);
#ifdef USE_CUSPICE
int i, j, status ;
#endif
/* loop through all the voltage source models */
for( ; model != NULL; model = ISRCnextModel(model)) {
#ifdef USE_CUSPICE
i = 0 ;
#endif
/* loop through all the instances of the model */
for (here = ISRCinstances(model); here != NULL ;
here=ISRCnextInstance(here)) {
@ -52,7 +64,29 @@ ISRCtemp(GENmodel *inModel, CKTcircuit *ckt)
radians = here->ISRCacPhase * M_PI / 180.0;
here->ISRCacReal = here->ISRCacMag * cos(radians);
here->ISRCacImag = here->ISRCacMag * sin(radians);
#ifdef USE_CUSPICE
for (j = 0 ; j < here->n_coeffs ; j++)
{
model->ISRCparamCPU.ISRCcoeffsArrayHost [i] [j] = here->ISRCcoeffs [j] ;
}
model->ISRCparamCPU.ISRCdcvalueArray[i] = here->ISRCdcValue ;
model->ISRCparamCPU.ISRCdcGivenArray[i] = here->ISRCdcGiven ;
model->ISRCparamCPU.ISRCfunctionTypeArray[i] = here->ISRCfunctionType ;
model->ISRCparamCPU.ISRCfunctionOrderArray[i] = here->ISRCfunctionOrder ;
i++ ;
#endif
}
#ifdef USE_CUSPICE
status = cuISRCtemp ((GENmodel *)model) ;
if (status != 0)
return (E_NOMEM) ;
#endif
}
return(OK);

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "resdefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
int
cuRESdestroy
(
GENmodel *inModel
)
{
RESmodel *model = (RESmodel *)inModel ;
for ( ; model != NULL ; model = RESnextModel(model))
{
/* DOUBLE */
free (model->RESparamCPU.REStc1Array) ;
cudaFree (model->RESparamGPU.d_REStc1Array) ;
free (model->RESparamCPU.REStc2Array) ;
cudaFree (model->RESparamGPU.d_REStc2Array) ;
free (model->RESparamCPU.RESmArray) ;
cudaFree (model->RESparamGPU.d_RESmArray) ;
free (model->RESparamCPU.RESconductArray) ;
cudaFree (model->RESparamGPU.d_RESconductArray) ;
free (model->RESparamCPU.REStempArray) ;
cudaFree (model->RESparamGPU.d_REStempArray) ;
free (model->RESparamCPU.RESdtempArray) ;
cudaFree (model->RESparamGPU.d_RESdtempArray) ;
free (model->RESparamCPU.REScurrentArray) ;
cudaFree (model->RESparamGPU.d_REScurrentArray) ;
free (model->RESparamCPU.RESgValueArray) ;
cudaFree (model->RESparamGPU.d_RESgValueArray) ;
/* INT */
free (model->RESparamCPU.REStc1GivenArray) ;
cudaFree (model->RESparamGPU.d_REStc1GivenArray) ;
free (model->RESparamCPU.REStc2GivenArray) ;
cudaFree (model->RESparamGPU.d_REStc2GivenArray) ;
free (model->RESparamCPU.RESmGivenArray) ;
cudaFree (model->RESparamGPU.d_RESmGivenArray) ;
free (model->RESparamCPU.RESposNodeArray) ;
cudaFree (model->RESparamGPU.d_RESposNodeArray) ;
free (model->RESparamCPU.RESnegNodeArray) ;
cudaFree (model->RESparamGPU.d_RESnegNodeArray) ;
}
return (OK) ;
}

View File

@ -0,0 +1,117 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "resdefs.h"
extern "C"
__global__ void cuRESload_kernel (RESparamGPUstruct, double *, int, int *, double *) ;
extern "C"
int
cuRESload
(
GENmodel *inModel, CKTcircuit *ckt
)
{
RESmodel *model = (RESmodel *)inModel ;
int thread_x, thread_y, block_x ;
cudaError_t status ;
/* loop through all the resistor models */
for ( ; model != NULL ; model = RESnextModel(model))
{
/* Determining how many blocks should exist in the kernel */
thread_x = 1 ;
thread_y = 256 ;
if (model->n_instances % thread_y != 0)
block_x = (int)((model->n_instances + thread_y - 1) / thread_y) ;
else
block_x = model->n_instances / thread_y ;
dim3 thread (thread_x, thread_y) ;
/* Kernel launch */
status = cudaGetLastError () ; // clear error status
cuRESload_kernel <<< block_x, thread >>> (model->RESparamGPU, ckt->d_CKTrhsOld, model->n_instances,
model->d_PositionVector, ckt->d_CKTloadOutput) ;
cudaDeviceSynchronize () ;
status = cudaGetLastError () ; // check for launch error
if (status != cudaSuccess)
{
fprintf (stderr, "Kernel launch failure in the Resistor Model\n\n") ;
return (E_NOMEM) ;
}
}
return (OK) ;
}
extern "C"
__global__
void
cuRESload_kernel
(
RESparamGPUstruct RESentry, double *CKTrhsOld, int n_instances, int *d_PositionVector, double * d_CKTloadOutput
)
{
double m, difference, factor ;
int instance_ID ;
instance_ID = threadIdx.y + blockDim.y * blockIdx.x ;
if (instance_ID < n_instances)
{
if (threadIdx.x == 0)
{
if (!(RESentry.d_REStc1GivenArray [instance_ID]))
RESentry.d_REStc1Array [instance_ID] = 0.0 ;
if (!(RESentry.d_REStc2GivenArray [instance_ID]))
RESentry.d_REStc2Array [instance_ID] = 0.0 ;
if (!(RESentry.d_RESmGivenArray [instance_ID]))
RESentry.d_RESmArray [instance_ID] = 1.0 ;
RESentry.d_REScurrentArray [instance_ID] = (CKTrhsOld [RESentry.d_RESposNodeArray [instance_ID]] -
CKTrhsOld [RESentry.d_RESnegNodeArray [instance_ID]]) *
RESentry.d_RESconductArray [instance_ID] ;
difference = (RESentry.d_REStempArray [instance_ID] + RESentry.d_RESdtempArray [instance_ID]) - 300.15 ;
factor = 1.0 + (RESentry.d_REStc1Array [instance_ID]) * difference +
(RESentry.d_REStc2Array [instance_ID]) * difference * difference ;
m = (RESentry.d_RESmArray [instance_ID]) / factor ;
d_CKTloadOutput [d_PositionVector [instance_ID]] = m * RESentry.d_RESconductArray [instance_ID] ;
}
}
return ;
}

View File

@ -0,0 +1,125 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "resdefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMalloc MACRO to check it for errors --> CUDAMALLOCCHECK(name of pointer, dimension, type, status) */
#define CUDAMALLOCCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuRESsetup routine...\n") ; \
fprintf (stderr, "Error: cudaMalloc failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuRESsetup routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuRESsetup
(
GENmodel *inModel
)
{
long unsigned int size ;
cudaError_t status ;
RESmodel *model = (RESmodel *)inModel ;
size = (long unsigned int) model->n_instances;
/* Space Allocation to GPU */
status = cudaMalloc ((void **)&(model->d_PositionVector), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->d_PositionVector, size, int, status)
status = cudaMemcpy (model->d_PositionVector, model->PositionVector, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->d_PositionVector, size, int, status)
/* DOUBLE */
model->RESparamCPU.REStc1Array = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->RESparamGPU.d_REStc1Array), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->RESparamGPU.d_REStc1Array, size, double, status)
model->RESparamCPU.REStc2Array = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->RESparamGPU.d_REStc2Array), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->RESparamGPU.d_REStc2Array, size, double, status)
model->RESparamCPU.RESmArray = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->RESparamGPU.d_RESmArray), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->RESparamGPU.d_RESmArray, size, double, status)
model->RESparamCPU.RESconductArray = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->RESparamGPU.d_RESconductArray), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->RESparamGPU.d_RESconductArray, size, double, status)
model->RESparamCPU.REStempArray = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->RESparamGPU.d_REStempArray), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->RESparamGPU.d_REStempArray, size, double, status)
model->RESparamCPU.RESdtempArray = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->RESparamGPU.d_RESdtempArray), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->RESparamGPU.d_RESdtempArray, size, double, status)
model->RESparamCPU.REScurrentArray = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->RESparamGPU.d_REScurrentArray), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->RESparamGPU.d_REScurrentArray, size, double, status)
model->RESparamCPU.RESgValueArray = (double *) malloc (size * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->RESparamGPU.d_RESgValueArray), size * sizeof(double)) ;
CUDAMALLOCCHECK (model->RESparamGPU.d_RESgValueArray, size, double, status)
/* INT */
model->RESparamCPU.REStc1GivenArray = (int *) malloc (size * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->RESparamGPU.d_REStc1GivenArray), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->RESparamGPU.d_REStc1GivenArray, size, int, status)
model->RESparamCPU.REStc2GivenArray = (int *) malloc (size * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->RESparamGPU.d_REStc2GivenArray), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->RESparamGPU.d_REStc2GivenArray, size, int, status)
model->RESparamCPU.RESmGivenArray = (int *) malloc (size * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->RESparamGPU.d_RESmGivenArray), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->RESparamGPU.d_RESmGivenArray, size, int, status)
model->RESparamCPU.RESposNodeArray = (int *) malloc (size * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->RESparamGPU.d_RESposNodeArray), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->RESparamGPU.d_RESposNodeArray, size, int, status)
model->RESparamCPU.RESnegNodeArray = (int *) malloc (size * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->RESparamGPU.d_RESnegNodeArray), size * sizeof(int)) ;
CUDAMALLOCCHECK (model->RESparamGPU.d_RESnegNodeArray, size, int, status)
return (OK) ;
}

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "resdefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuREStemp routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuREStemp
(
GENmodel *inModel
)
{
long unsigned int size ;
cudaError_t status ;
RESmodel *model = (RESmodel *)inModel ;
size = (long unsigned int) model->n_instances;
/* DOUBLE */
status = cudaMemcpy (model->RESparamGPU.d_REStc1Array, model->RESparamCPU.REStc1Array, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->RESparamGPU.d_REStc1Array, size, double, status)
status = cudaMemcpy (model->RESparamGPU.d_REStc2Array, model->RESparamCPU.REStc2Array, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->RESparamGPU.d_REStc2Array, size, double, status)
status = cudaMemcpy (model->RESparamGPU.d_RESmArray, model->RESparamCPU.RESmArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->RESparamGPU.d_RESmArray, size, double, status)
status = cudaMemcpy (model->RESparamGPU.d_RESconductArray, model->RESparamCPU.RESconductArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->RESparamGPU.d_RESconductArray, size, double, status)
status = cudaMemcpy (model->RESparamGPU.d_REStempArray, model->RESparamCPU.REStempArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->RESparamGPU.d_REStempArray, size, double, status)
status = cudaMemcpy (model->RESparamGPU.d_RESdtempArray, model->RESparamCPU.RESdtempArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->RESparamGPU.d_RESdtempArray, size, double, status)
/* INT */
status = cudaMemcpy (model->RESparamGPU.d_REStc1GivenArray, model->RESparamCPU.REStc1GivenArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->RESparamGPU.d_REStc1GivenArray, size, int, status)
status = cudaMemcpy (model->RESparamGPU.d_REStc2GivenArray, model->RESparamCPU.REStc2GivenArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->RESparamGPU.d_REStc2GivenArray, size, int, status)
status = cudaMemcpy (model->RESparamGPU.d_RESmGivenArray, model->RESparamCPU.RESmGivenArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->RESparamGPU.d_RESmGivenArray, size, int, status)
status = cudaMemcpy (model->RESparamGPU.d_RESposNodeArray, model->RESparamCPU.RESposNodeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->RESparamGPU.d_RESposNodeArray, size, int, status)
status = cudaMemcpy (model->RESparamGPU.d_RESnegNodeArray, model->RESparamCPU.RESnegNodeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->RESparamGPU.RESnegNodeArray, size, int, status)
return (OK) ;
}

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "resdefs.h"
#include "ngspice/sperror.h"
#define TopologyMatrixInsert(Ptr, instance_ID, offset, Value, global_ID) \
ckt->CKTtopologyMatrixCOOi [global_ID] = (int)(here->Ptr - basePtr) ; \
ckt->CKTtopologyMatrixCOOj [global_ID] = model->PositionVector [instance_ID] + offset ; \
ckt->CKTtopologyMatrixCOOx [global_ID] = Value ;
int
REStopology (GENmodel *inModel, CKTcircuit *ckt, int *i, int *j)
{
RESmodel *model = (RESmodel *)inModel ;
RESinstance *here ;
int k ;
double *basePtr ;
basePtr = ckt->CKTmatrix->CKTkluAx ;
NG_IGNORE (j) ;
/* loop through all the resistor models */
for ( ; model != NULL ; model = RESnextModel(model))
{
k = 0 ;
/* loop through all the instances of the model */
for (here = RESinstances(model); here != NULL ; here = RESnextInstance(here))
{
if ((here->RESposNode != 0) && (here->RESposNode != 0))
{
TopologyMatrixInsert (RESposPosPtr, k, 0, 1, *i) ;
(*i)++ ;
}
if ((here->RESnegNode != 0) && (here->RESnegNode != 0))
{
TopologyMatrixInsert (RESnegNegPtr, k, 0, 1, *i) ;
(*i)++ ;
}
if ((here->RESposNode != 0) && (here->RESnegNode != 0))
{
TopologyMatrixInsert (RESposNegPtr, k, 0, -1, *i) ;
(*i)++ ;
}
if ((here->RESnegNode != 0) && (here->RESposNode != 0))
{
TopologyMatrixInsert (RESnegPosPtr, k, 0, -1, *i) ;
(*i)++ ;
}
k++ ;
}
}
return (OK) ;
}

View File

@ -35,4 +35,18 @@ endif
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
AM_CFLAGS = $(STATIC)
if USE_CUSPICE_WANTED
.cu.lo:
$(AM_V_GEN)$(top_srcdir)/src/libtool_wrapper_for_cuda.tcl $@ $(AM_CFLAGS) $(NVCC) $(CUDA_CFLAGS) $(AM_CPPFLAGS) -c $<
libres_la_SOURCES += \
CUSPICE/restopology.c \
CUSPICE/curesfree.c \
CUSPICE/curesload.cu \
CUSPICE/curessetup.c \
CUSPICE/curestemp.c
AM_CPPFLAGS += $(CUDA_CPPFLAGS)
endif
MAINTAINERCLEANFILES = Makefile.in

View File

@ -97,6 +97,45 @@ typedef struct sRESinstance {
} RESinstance ;
#ifdef USE_CUSPICE
typedef struct sRESparamCPUstruct {
double *REScpuPointersD [8] ;
#define REStc1Array REScpuPointersD[0]
#define REStc2Array REScpuPointersD[1]
#define RESmArray REScpuPointersD[2]
#define RESconductArray REScpuPointersD[3]
#define REStempArray REScpuPointersD[4]
#define RESdtempArray REScpuPointersD[5]
#define REScurrentArray REScpuPointersD[6]
#define RESgValueArray REScpuPointersD[7]
int *REScpuPointersI [5] ;
#define REStc1GivenArray REScpuPointersI[0]
#define REStc2GivenArray REScpuPointersI[1]
#define RESmGivenArray REScpuPointersI[2]
#define RESposNodeArray REScpuPointersI[3]
#define RESnegNodeArray REScpuPointersI[4]
} RESparamCPUstruct ;
typedef struct sRESparamGPUstruct {
double *REScudaPointersD [8] ;
#define d_REStc1Array REScudaPointersD[0]
#define d_REStc2Array REScudaPointersD[1]
#define d_RESmArray REScudaPointersD[2]
#define d_RESconductArray REScudaPointersD[3]
#define d_REStempArray REScudaPointersD[4]
#define d_RESdtempArray REScudaPointersD[5]
#define d_REScurrentArray REScudaPointersD[6]
#define d_RESgValueArray REScudaPointersD[7]
int *REScudaPointersI [5] ;
#define d_REStc1GivenArray REScudaPointersI[0]
#define d_REStc2GivenArray REScudaPointersI[1]
#define d_RESmGivenArray REScudaPointersI[2]
#define d_RESposNodeArray REScudaPointersI[3]
#define d_RESnegNodeArray REScudaPointersI[4]
} RESparamGPUstruct ;
#endif
/* per model data */
@ -141,6 +180,20 @@ typedef struct sRESmodel { /* model structure for a resistor */
unsigned RESlfGiven :1; /* flags indicates lf is given */
unsigned RESwfGiven :1; /* flags indicates wf is given */
unsigned RESefGiven :1; /* flags indicates ef is given */
#ifdef USE_CUSPICE
RESparamCPUstruct RESparamCPU ;
RESparamGPUstruct RESparamGPU ;
int offset ;
int n_values ;
int n_Ptr ;
int *PositionVector ;
int *d_PositionVector ;
int n_instances ;
#endif
} RESmodel;
/* device parameters */

View File

@ -27,3 +27,7 @@ extern int RESbindCSC (GENmodel*, CKTcircuit*) ;
extern int RESbindCSCComplex (GENmodel*, CKTcircuit*) ;
extern int RESbindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
#endif
#ifdef USE_CUSPICE
extern int REStopology (GENmodel *, CKTcircuit *, int *, int *) ;
#endif

View File

@ -6,6 +6,10 @@
#include "resext.h"
#include "resinit.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
SPICEdev RESinfo = {
.DEVpublic = {
@ -33,7 +37,11 @@ SPICEdev RESinfo = {
.DEVparam = RESparam,
.DEVmodParam = RESmParam,
#ifdef USE_CUSPICE
.DEVload = cuRESload,
#else
.DEVload = RESload,
#endif
.DEVsetup = RESsetup,
.DEVunsetup = NULL,
.DEVpzSetup = RESsetup,
@ -71,6 +79,10 @@ SPICEdev RESinfo = {
.DEVbindCSCComplex = RESbindCSCComplex,
.DEVbindCSCComplexToReal = RESbindCSCComplexToReal,
#endif
#ifdef USE_CUSPICE
.cuDEVdestroy = cuRESdestroy,
.DEVtopology = REStopology,
#endif
};

View File

@ -9,6 +9,10 @@ Modified: Apr 2000 Paolo Nenzi
#include "resdefs.h"
#include "ngspice/sperror.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
int
RESsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit*ckt, int *state)
@ -75,5 +79,69 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
TSTALLOC(RESnegPosPtr, RESnegNode, RESposNode);
}
}
#ifdef USE_CUSPICE
int i, j, status ;
/* Counting the instances */
for (model = (RESmodel *)inModel ; model != NULL ; model = RESnextModel(model))
{
i = 0 ;
for (here = RESinstances(model); here != NULL ; here = RESnextInstance(here))
{
i++ ;
}
/* How much instances we have */
model->n_instances = i ;
}
/* loop through all the resistor models */
for (model = (RESmodel *)inModel ; model != NULL ; model = RESnextModel(model))
{
model->offset = ckt->total_n_values ;
j = 0 ;
/* loop through all the instances of the model */
for (here = RESinstances(model); here != NULL ; here = RESnextInstance(here))
{
if ((here->RESposNode != 0) && (here->RESposNode != 0))
j++ ;
if ((here->RESnegNode != 0) && (here->RESnegNode != 0))
j++ ;
if ((here->RESposNode != 0) && (here->RESnegNode != 0))
j++ ;
if ((here->RESnegNode != 0) && (here->RESposNode != 0))
j++ ;
}
model->n_values = model->n_instances ;
ckt->total_n_values += model->n_values ;
model->n_Ptr = j ;
ckt->total_n_Ptr += model->n_Ptr ;
/* Position Vector assignment */
model->PositionVector = TMALLOC (int, model->n_instances) ;
for (j = 0 ; j < model->n_instances ; j++)
model->PositionVector [j] = model->offset + j ;
}
/* loop through all the resistor models */
for (model = (RESmodel *)inModel ; model != NULL ; model = RESnextModel(model))
{
status = cuRESsetup ((GENmodel *)model) ;
if (status != 0)
return (E_NOMEM) ;
}
#endif
return(OK);
}

View File

@ -10,6 +10,10 @@ Modified: 2000 AlanSfixes
#include "resdefs.h"
#include "ngspice/sperror.h"
#ifdef USE_CUSPICE
#include "ngspice/CUSPICE/CUSPICE.h"
#endif
int
REStemp(GENmodel *inModel, CKTcircuit *ckt)
/* perform the temperature update to the resistors
@ -26,6 +30,10 @@ REStemp(GENmodel *inModel, CKTcircuit *ckt)
/* loop through all the resistor models */
for( ; model != NULL; model = RESnextModel(model)) {
#ifdef USE_CUSPICE
int i = 0;
#endif
/* loop through all the instances of the model */
for (here = RESinstances(model); here != NULL ;
here=RESnextInstance(here)) {
@ -43,7 +51,29 @@ REStemp(GENmodel *inModel, CKTcircuit *ckt)
}
RESupdate_conduct(here, TRUE);
#ifdef USE_CUSPICE
model->RESparamCPU.REStc1GivenArray[i] = here->REStc1Given;
model->RESparamCPU.REStc2GivenArray[i] = here->REStc2Given;
model->RESparamCPU.RESmGivenArray[i] = here->RESmGiven;
model->RESparamCPU.REStc1Array[i] = here->REStc1;
model->RESparamCPU.REStc2Array[i] = here->REStc2;
model->RESparamCPU.RESmArray[i] = here->RESm;
model->RESparamCPU.RESposNodeArray[i] = here->RESposNode;
model->RESparamCPU.RESnegNodeArray[i] = here->RESnegNode;
model->RESparamCPU.RESconductArray[i] = here->RESconduct;
model->RESparamCPU.REStempArray[i] = here->REStemp;
model->RESparamCPU.RESdtempArray[i] = here->RESdtemp;
i++;
#endif
}
#ifdef USE_CUSPICE
int status = cuREStemp ((GENmodel *)model);
if (status != 0)
return E_NOMEM;
#endif
}
return OK;

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "vsrcdefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
int
cuVSRCdestroy
(
GENmodel *inModel
)
{
VSRCmodel *model = (VSRCmodel *)inModel ;
VSRCinstance *here ;
int i ;
for ( ; model != NULL ; model = VSRCnextModel(model))
{
/* Special case VSRCparamGPU.VSRCcoeffsArray */
i = 0 ;
for (here = VSRCinstances(model); here != NULL ; here = VSRCnextInstance(here))
{
cudaFree (model->VSRCparamCPU.VSRCcoeffsArray [i]) ;
i++ ;
}
free (model->VSRCparamCPU.VSRCcoeffsArray) ;
cudaFree (model->VSRCparamGPU.d_VSRCcoeffsArray) ;
i = 0 ;
for (here = VSRCinstances(model); here != NULL ; here = VSRCnextInstance(here))
{
free (model->VSRCparamCPU.VSRCcoeffsArrayHost [i]) ;
i++ ;
}
free (model->VSRCparamCPU.VSRCcoeffsArrayHost) ;
/* ----------------------------------------- */
/* DOUBLE */
free (model->VSRCparamCPU.VSRCdcvalueArray) ;
cudaFree (model->VSRCparamGPU.d_VSRCdcvalueArray) ;
free (model->VSRCparamCPU.VSRCrdelayArray) ;
cudaFree (model->VSRCparamGPU.d_VSRCrdelayArray) ;
free (model->VSRCparamCPU.VSRCValueArray) ;
cudaFree (model->VSRCparamGPU.d_VSRCValueArray) ;
/* INT */
free (model->VSRCparamCPU.VSRCdcGivenArray) ;
cudaFree (model->VSRCparamGPU.d_VSRCdcGivenArray) ;
free (model->VSRCparamCPU.VSRCfunctionTypeArray) ;
cudaFree (model->VSRCparamGPU.d_VSRCfunctionTypeArray) ;
free (model->VSRCparamCPU.VSRCfunctionOrderArray) ;
cudaFree (model->VSRCparamGPU.d_VSRCfunctionOrderArray) ;
free (model->VSRCparamCPU.VSRCrGivenArray) ;
cudaFree (model->VSRCparamGPU.d_VSRCrGivenArray) ;
free (model->VSRCparamCPU.VSRCrBreakptArray) ;
cudaFree (model->VSRCparamGPU.d_VSRCrBreakptArray) ;
}
return (OK) ;
}

View File

@ -0,0 +1,489 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "ngspice/CUSPICE/cuniinteg.cuh"
#include "vsrcdefs.h"
/*** STUFF NEEDED BECAUSE OF SOME INCLUSIONS IN NGSPICE THAT ARE NOT AVAILABLE IN CUDA ***/
/* TRNOISE and TRRANDOM don't work in the CUDA implementation */
/**********
Copyright 1991 Regents of the University of California. All rights reserved.
**********/
#include <assert.h>
#include <stdint.h>
#ifdef _MSC_VER
#define llabs(x) ((x) < 0 ? -(x) : (x))
#endif
#define int64_min (((int64_t) -1) << 63)
#define TRUE 1
#define FALSE 0
/* From Bruce Dawson, Comparing floating point numbers,
http://www.cygnus-software.com/papers/comparingfloats/Comparing%20floating%20point%20numbers.htm
Original this function is named AlmostEqual2sComplement but we leave it to AlmostEqualUlps
and can leave the code (measure.c, dctran.c) unchanged. The transformation to the 2's complement
prevent problems around 0.0.
One Ulp is equivalent to a maxRelativeError of between 1/4,000,000,000,000,000 and 1/8,000,000,000,000,000.
Practical: 3 < maxUlps < some hundred's (or thousand's) - depending on numerical requirements.
*/
__device__
static
bool
AlmostEqualUlps (double A, double B, int maxUlps)
{
int64_t aInt, bInt, intDiff;
if (A == B)
return TRUE ;
/* If not - the entire method can not work */
assert (sizeof(double) == sizeof(int64_t)) ;
/* Make sure maxUlps is non-negative and small enough that the */
/* default NAN won't compare as equal to anything. */
assert (maxUlps > 0 && maxUlps < 4 * 1024 * 1024) ;
aInt = *(int64_t*)&A ;
/* Make aInt lexicographically ordered as a twos-complement int */
if (aInt < 0)
aInt = int64_min - aInt ;
bInt = *(int64_t*)&B ;
/* Make bInt lexicographically ordered as a twos-complement int */
if (bInt < 0)
bInt = int64_min - bInt ;
intDiff = llabs (aInt - bInt) ;
/* printf("A:%e B:%e aInt:%d bInt:%d diff:%d\n", A, B, aInt, bInt, intDiff); */
if (intDiff <= maxUlps)
return TRUE ;
return FALSE ;
}
/*** CODE STARTING ***/
extern "C"
__global__ void cuVSRCload_kernel (VSRCparamGPUstruct, int, double, double, double, double, int, int *, double *, int *, double *) ;
extern "C"
int
cuVSRCload
(
GENmodel *inModel, CKTcircuit *ckt
)
{
VSRCmodel *model = (VSRCmodel *)inModel ;
int thread_x, thread_y, block_x ;
cudaError_t status ;
/* loop through all the inductor models */
for ( ; model != NULL ; model = VSRCnextModel(model))
{
/* Determining how many blocks should exist in the kernel */
thread_x = 1 ;
thread_y = 256 ;
if (model->n_instances % thread_y != 0)
block_x = (int)((model->n_instances + thread_y - 1) / thread_y) ;
else
block_x = model->n_instances / thread_y ;
dim3 thread (thread_x, thread_y) ;
/* Kernel launch */
status = cudaGetLastError () ; // clear error status
cuVSRCload_kernel <<< block_x, thread >>> (model->VSRCparamGPU, ckt->CKTmode, ckt->CKTtime,
ckt->CKTstep, ckt->CKTfinalTime, ckt->CKTsrcFact,
model->n_instances, model->d_PositionVector,
ckt->d_CKTloadOutput, model->d_PositionVectorRHS,
ckt->d_CKTloadOutputRHS) ;
cudaDeviceSynchronize () ;
status = cudaGetLastError () ; // check for launch error
if (status != cudaSuccess)
{
fprintf (stderr, "Kernel launch failure in the Voltage Source Model\n\n") ;
return (E_NOMEM) ;
}
}
return (OK) ;
}
extern "C"
__global__
void
cuVSRCload_kernel
(
VSRCparamGPUstruct VSRCentry, int CKTmode, double CKTtime,
double CKTstep, double CKTfinalTime, double CKTsrcFact, int n_instances,
int *d_PositionVector, double *d_CKTloadOutput, int *d_PositionVectorRHS, double *d_CKTloadOutputRHS
)
{
int instance_ID ;
double time, value = 0.0 ;
instance_ID = threadIdx.y + blockDim.y * blockIdx.x ;
if (instance_ID < n_instances)
{
if (threadIdx.x == 0)
{
d_CKTloadOutput [d_PositionVector [instance_ID]] = 1.0 ;
if ((CKTmode & (MODEDCOP | MODEDCTRANCURVE)) && VSRCentry.d_VSRCdcGivenArray [instance_ID])
{
/* load using DC value */
#ifdef XSPICE_EXP
/* gtri - begin - wbk - modify to process srcFact, etc. for all sources */
value = VSRCentry.d_VSRCdcvalueArray [instance_ID] ;
#else
value = VSRCentry.d_VSRCdcvalueArray [instance_ID] * CKTsrcFact ;
#endif
} else {
if (CKTmode & (MODEDC))
time = 0 ;
else
time = CKTtime ;
/* use the transient functions */
switch (VSRCentry.d_VSRCfunctionTypeArray [instance_ID])
{
default:
value = VSRCentry.d_VSRCdcvalueArray [instance_ID] ;
break ;
case PULSE:
{
double V1, V2, TD, TR, TF, PW, PER, basetime = 0.0 ;
#ifdef XSPICE
double PHASE, phase, deltat ;
#endif
V1 = VSRCentry.d_VSRCcoeffsArray [instance_ID] [0] ;
V2 = VSRCentry.d_VSRCcoeffsArray [instance_ID] [1] ;
TD = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 2
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [2] : 0.0 ;
TR = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 3
&& VSRCentry.d_VSRCcoeffsArray [instance_ID] [3] != 0.0
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [3] : CKTstep ;
TF = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 4
&& VSRCentry.d_VSRCcoeffsArray [instance_ID] [4] != 0.0
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [4] : CKTstep ;
PW = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 5
&& VSRCentry.d_VSRCcoeffsArray [instance_ID] [5] != 0.0
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [5] : CKTfinalTime ;
PER = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 6
&& VSRCentry.d_VSRCcoeffsArray [instance_ID] [6] != 0.0
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [6] : CKTfinalTime ;
/* shift time by delay time TD */
time -= TD ;
#ifdef XSPICE
/* gtri - begin - wbk - add PHASE parameter */
PHASE = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 7
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [7] : 0.0 ;
/* normalize phase to cycles */
phase = PHASE / 360.0 ;
phase = fmod (phase, 1.0) ;
deltat = phase * PER ;
while (deltat > 0)
deltat -= PER ;
/* shift time by pase (neg. for pos. phase value) */
time += deltat ;
/* gtri - end - wbk - add PHASE parameter */
#endif
if (time > PER)
{
/* repeating signal - figure out where we are */
/* in period */
basetime = PER * floor (time / PER) ;
time -= basetime ;
}
if (time <= 0 || time >= TR + PW + TF)
value = V1 ;
else if (time >= TR && time <= TR + PW)
value = V2 ;
else if (time > 0 && time < TR)
value = V1 + (V2 - V1) * time / TR ;
else /* time > TR + PW && < TR + PW + TF */
value = V2 + (V1 - V2) * (time - (TR + PW)) / TF ;
}
break ;
case SINE:
{
double VO, VA, FREQ, TD, THETA ;
#ifdef XSPICE
/* gtri - begin - wbk - add PHASE parameter */
double PHASE, phase ;
PHASE = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 5
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [5] : 0.0 ;
/* compute phase in radians */
phase = PHASE * M_PI / 180.0 ;
#endif
VO = VSRCentry.d_VSRCcoeffsArray [instance_ID] [0] ;
VA = VSRCentry.d_VSRCcoeffsArray [instance_ID] [1] ;
FREQ = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 2
&& VSRCentry.d_VSRCcoeffsArray [instance_ID] [2] != 0.0
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [2] : (1 / CKTfinalTime) ;
TD = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 3
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [3] : 0.0 ;
THETA = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 4
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [4] : 0.0 ;
time -= TD ;
if (time <= 0)
{
#ifdef XSPICE
value = VO + VA * sin (phase) ;
} else {
value = VO + VA * sin (FREQ * time * 2.0 * M_PI + phase) * exp (-time * THETA) ;
#else
value = VO ;
} else {
value = VO + VA * sin (FREQ * time * 2.0 * M_PI) * exp (-time * THETA) ;
/* gtri - end - wbk - add PHASE parameter */
#endif
}
}
break ;
case EXP:
{
double V1, V2, TD1, TD2, TAU1, TAU2 ;
V1 = VSRCentry.d_VSRCcoeffsArray [instance_ID] [0] ;
V2 = VSRCentry.d_VSRCcoeffsArray [instance_ID] [1] ;
TD1 = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 2
&& VSRCentry.d_VSRCcoeffsArray [instance_ID] [2] != 0.0
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [2] : CKTstep ;
TAU1 = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 3
&& VSRCentry.d_VSRCcoeffsArray [instance_ID] [3] != 0.0
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [3] : CKTstep ;
TD2 = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 4
&& VSRCentry.d_VSRCcoeffsArray [instance_ID] [4] != 0.0
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [4] : TD1 + CKTstep ;
TAU2 = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 5
&& VSRCentry.d_VSRCcoeffsArray [instance_ID] [5]
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [5] : CKTstep ;
if(time <= TD1)
value = V1 ;
else if (time <= TD2)
value = V1 + (V2 - V1) * (1 - exp (-(time - TD1) / TAU1)) ;
else
value = V1 + (V2 - V1) * (1 - exp (-(time - TD1) / TAU1))
+ (V1 - V2) * (1 - exp (-(time - TD2) / TAU2)) ;
}
break ;
case SFFM:
{
double VO, VA, FC, MDI, FS ;
#ifdef XSPICE
/* gtri - begin - wbk - add PHASE parameters */
double PHASEC, PHASES, phasec, phases ;
PHASEC = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 5
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [5] : 0.0 ;
PHASES = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 6
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [6] : 0.0 ;
/* compute phases in radians */
phasec = PHASEC * M_PI / 180.0 ;
phases = PHASES * M_PI / 180.0 ;
#endif
VO = VSRCentry.d_VSRCcoeffsArray [instance_ID] [0] ;
VA = VSRCentry.d_VSRCcoeffsArray [instance_ID] [1] ;
FC = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 2
&& VSRCentry.d_VSRCcoeffsArray [instance_ID] [2]
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [2] : (1 / CKTfinalTime) ;
MDI = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 3
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [3] : 0.0 ;
FS = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 4
&& VSRCentry.d_VSRCcoeffsArray [instance_ID] [4]
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [4] : (1 / CKTfinalTime) ;
#ifdef XSPICE
/* compute waveform value */
value = VO + VA * sin ((2.0 * M_PI * FC * time + phasec) +
MDI * sin (2.0 * M_PI * FS * time + phases)) ;
#else
value = VO + VA * sin ((2.0 * M_PI * FC * time) +
MDI * sin (2.0 * M_PI * FS * time)) ;
/* gtri - end - wbk - add PHASE parameters */
#endif
}
break ;
case AM:
{
double VA, FC, MF, VO, TD ;
#ifdef XSPICE
/* gtri - begin - wbk - add PHASE parameters */
double PHASEC, PHASES, phasec, phases ;
PHASEC = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 5
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [5] : 0.0 ;
PHASES = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 6
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [6] : 0.0 ;
/* compute phases in radians */
phasec = PHASEC * M_PI / 180.0 ;
phases = PHASES * M_PI / 180.0 ;
#endif
VA = VSRCentry.d_VSRCcoeffsArray [instance_ID] [0] ;
VO = VSRCentry.d_VSRCcoeffsArray [instance_ID] [1] ;
MF = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 2
&& VSRCentry.d_VSRCcoeffsArray [instance_ID] [2]
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [2] : (1 / CKTfinalTime) ;
FC = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 3
? VSRCentry.d_VSRCcoeffsArray [3] [instance_ID] : 0.0 ;
TD = VSRCentry.d_VSRCfunctionOrderArray [instance_ID] > 4
&& VSRCentry.d_VSRCcoeffsArray [instance_ID] [4]
? VSRCentry.d_VSRCcoeffsArray [instance_ID] [4] : 0.0 ;
time -= TD ;
if (time <= 0)
value = 0 ;
else {
#ifdef XSPICE
/* compute waveform value */
value = VA * (VO + sin (2.0 * M_PI * MF * time + phases )) *
sin (2.0 * M_PI * FC * time + phases) ;
#else
value = VA * (VO + sin (2.0 * M_PI * MF * time)) *
sin (2.0 * M_PI * FC * time) ;
/* gtri - end - wbk - add PHASE parameters */
#endif
}
}
break ;
case PWL:
{
int i = 0, num_repeat = 0, ii = 0 ;
double repeat_time = 0.0, end_time, breakpt_time, itime ;
time -= VSRCentry.d_VSRCrdelayArray [instance_ID] ;
if (time < VSRCentry.d_VSRCcoeffsArray [instance_ID] [0])
{
value = VSRCentry.d_VSRCcoeffsArray [instance_ID] [1] ;
goto loadDone ;
}
do
{
for (i = ii ; i < (VSRCentry.d_VSRCfunctionOrderArray [instance_ID] / 2) - 1 ; i++)
{
itime = VSRCentry.d_VSRCcoeffsArray [instance_ID] [2 * i] ;
if (AlmostEqualUlps (itime + repeat_time, time, 3))
{
value = VSRCentry.d_VSRCcoeffsArray [instance_ID] [2 * i + 1] ;
goto loadDone ;
} else if ((VSRCentry.d_VSRCcoeffsArray [instance_ID] [2 * i] + repeat_time < time)
&& (VSRCentry.d_VSRCcoeffsArray [instance_ID] [2 * (i + 1)] +
repeat_time > time))
{
value = VSRCentry.d_VSRCcoeffsArray [instance_ID] [2 * i + 1] +
(((time - (VSRCentry.d_VSRCcoeffsArray [instance_ID] [2 * i] + repeat_time)) /
(VSRCentry.d_VSRCcoeffsArray [instance_ID] [2 * (i + 1)] -
VSRCentry.d_VSRCcoeffsArray [instance_ID] [2 * i])) *
(VSRCentry.d_VSRCcoeffsArray [instance_ID] [2 * i + 3] -
VSRCentry.d_VSRCcoeffsArray [instance_ID] [2 * i + 1])) ;
goto loadDone ;
}
}
value = VSRCentry.d_VSRCcoeffsArray [instance_ID]
[VSRCentry.d_VSRCfunctionOrderArray [instance_ID] - 1] ;
if (!VSRCentry.d_VSRCrGivenArray [instance_ID])
goto loadDone ;
end_time = VSRCentry.d_VSRCcoeffsArray [instance_ID]
[VSRCentry.d_VSRCfunctionOrderArray [instance_ID] - 2] ;
breakpt_time = VSRCentry.d_VSRCcoeffsArray [instance_ID]
[VSRCentry.d_VSRCrBreakptArray [instance_ID]] ;
repeat_time = end_time + (end_time - breakpt_time) * (num_repeat ++) - breakpt_time ;
ii = VSRCentry.d_VSRCrBreakptArray [instance_ID] / 2 ;
} while (VSRCentry.d_VSRCrGivenArray [instance_ID]) ;
break ;
}
} // switch
} // else (line 55)
loadDone:
#ifdef XSPICE_EXP
/* gtri - begin - wbk - modify for supply ramping option */
value *= CKTsrcFact ;
value *= cm_analog_ramp_factor () ;
#else
if (CKTmode & MODETRANOP)
value *= CKTsrcFact ;
/* gtri - end - wbk - modify to process srcFact, etc. for all sources */
#endif
d_CKTloadOutputRHS [d_PositionVectorRHS [instance_ID]] = value ;
}
}
return ;
}

View File

@ -0,0 +1,145 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "vsrcdefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMalloc MACRO to check it for errors --> CUDAMALLOCCHECK(name of pointer, dimension, type, status) */
#define CUDAMALLOCCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuVSRCsetup routine...\n") ; \
fprintf (stderr, "Error: cudaMalloc failed on %s size1 of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuVSRCsetup routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size1 of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuVSRCsetup
(
GENmodel *inModel
)
{
int i ;
long unsigned int size1, size2 ;
cudaError_t status ;
VSRCmodel *model = (VSRCmodel *)inModel ;
VSRCinstance *here ;
size1 = (long unsigned int) model->n_instances;
/* Space Allocation to GPU */
status = cudaMalloc ((void **)&(model->d_PositionVector), size1 * sizeof(int)) ;
CUDAMALLOCCHECK (model->d_PositionVector, size1, int, status)
status = cudaMemcpy (model->d_PositionVector, model->PositionVector, size1 * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->d_PositionVector, size1, int, status)
status = cudaMalloc ((void **)&(model->d_PositionVectorRHS), size1 * sizeof(int)) ;
CUDAMALLOCCHECK (model->d_PositionVectorRHS, size1, int, status)
status = cudaMemcpy (model->d_PositionVectorRHS, model->PositionVectorRHS, size1 * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->d_PositionVectorRHS, size1, int, status)
/* Special case VSRCparamGPU.VSRCcoeffsArray */
model->VSRCparamCPU.VSRCcoeffsArray = (double **) malloc (size1 * sizeof(double *)) ;
status = cudaMalloc ((void **)&(model->VSRCparamGPU.d_VSRCcoeffsArray), size1 * sizeof(double *)) ;
CUDAMALLOCCHECK (model->VSRCparamGPU.d_VSRCcoeffsArray, size1, double*, status)
i = 0 ;
for (here = VSRCinstances(model); here != NULL ; here = VSRCnextInstance(here))
{
size2 = (long unsigned int)here->n_coeffs ;
status = cudaMalloc ((void **)&(model->VSRCparamCPU.VSRCcoeffsArray[i]), size2 * sizeof(double)) ;
CUDAMALLOCCHECK (model->VSRCparamCPU.VSRCcoeffsArray [i], size2, double, status)
i++ ;
}
/* Structure pointer vectors in GPU */
status = cudaMemcpy (model->VSRCparamGPU.d_VSRCcoeffsArray, model->VSRCparamCPU.VSRCcoeffsArray, size1 * sizeof(double *), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->VSRCparamGPU.d_VSRCcoeffsArray, size1, sizeof(double *), status)
i = 0 ;
model->VSRCparamCPU.VSRCcoeffsArrayHost = (double **) malloc (size1 * sizeof(double *)) ;
for (here = VSRCinstances(model); here != NULL ; here = VSRCnextInstance(here))
{
size2 = (long unsigned int)here->n_coeffs ;
model->VSRCparamCPU.VSRCcoeffsArrayHost [i] = (double *) malloc (size2 * sizeof(double)) ;
i++ ;
}
/* ----------------------------------------- */
/* DOUBLE */
model->VSRCparamCPU.VSRCdcvalueArray = (double *) malloc (size1 * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->VSRCparamGPU.d_VSRCdcvalueArray), size1 * sizeof(double)) ;
CUDAMALLOCCHECK (model->VSRCparamGPU.d_VSRCdcvalueArray, size1, double, status)
model->VSRCparamCPU.VSRCrdelayArray = (double *) malloc (size1 * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->VSRCparamGPU.d_VSRCrdelayArray), size1 * sizeof(double)) ;
CUDAMALLOCCHECK (model->VSRCparamGPU.d_VSRCrdelayArray, size1, double, status)
model->VSRCparamCPU.VSRCValueArray = (double *) malloc (size1 * sizeof(double)) ;
status = cudaMalloc ((void **)&(model->VSRCparamGPU.d_VSRCValueArray), size1 * sizeof(double)) ;
CUDAMALLOCCHECK (model->VSRCparamGPU.d_VSRCValueArray, size1, double, status)
/* INT */
model->VSRCparamCPU.VSRCdcGivenArray = (int *) malloc (size1 * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->VSRCparamGPU.d_VSRCdcGivenArray), size1 * sizeof(int)) ;
CUDAMALLOCCHECK (model->VSRCparamGPU.d_VSRCdcGivenArray, size1, int, status)
model->VSRCparamCPU.VSRCfunctionTypeArray = (int *) malloc (size1 * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->VSRCparamGPU.d_VSRCfunctionTypeArray), size1 * sizeof(int)) ;
CUDAMALLOCCHECK (model->VSRCparamGPU.d_VSRCfunctionTypeArray, size1, int, status)
model->VSRCparamCPU.VSRCfunctionOrderArray = (int *) malloc (size1 * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->VSRCparamGPU.d_VSRCfunctionOrderArray), size1 * sizeof(int)) ;
CUDAMALLOCCHECK (model->VSRCparamGPU.d_VSRCfunctionOrderArray, size1, int, status)
model->VSRCparamCPU.VSRCrGivenArray = (int *) malloc (size1 * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->VSRCparamGPU.d_VSRCrGivenArray), size1 * sizeof(int)) ;
CUDAMALLOCCHECK (model->VSRCparamGPU.d_VSRCrGivenArray, size1, int, status)
model->VSRCparamCPU.VSRCrBreakptArray = (int *) malloc (size1 * sizeof(int)) ;
status = cudaMalloc ((void **)&(model->VSRCparamGPU.d_VSRCrBreakptArray), size1 * sizeof(int)) ;
CUDAMALLOCCHECK (model->VSRCparamGPU.d_VSRCrBreakptArray, size1, int, status)
return (OK) ;
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/config.h"
#include "cuda_runtime_api.h"
#include "vsrcdefs.h"
#include "ngspice/CUSPICE/CUSPICE.h"
/* cudaMemcpy MACRO to check it for errors --> CUDAMEMCPYCHECK(name of pointer, dimension, type, status) */
#define CUDAMEMCPYCHECK(a, b, c, d) \
if (d != cudaSuccess) \
{ \
fprintf (stderr, "cuVSRCtemp routine...\n") ; \
fprintf (stderr, "Error: cudaMemcpy failed on %s size1 of %d bytes\n", #a, (int)(b * sizeof(c))) ; \
fprintf (stderr, "Error: %s = %d, %s\n", #d, d, cudaGetErrorString (d)) ; \
return (E_NOMEM) ; \
}
int
cuVSRCtemp
(
GENmodel *inModel
)
{
int i ;
long unsigned int size1, size2 ;
cudaError_t status ;
VSRCmodel *model = (VSRCmodel *)inModel ;
VSRCinstance *here ;
size1 = (long unsigned int) model->n_instances;
i = 0 ;
for (here = VSRCinstances(model); here != NULL ; here = VSRCnextInstance(here))
{
size2 = (long unsigned int)here->n_coeffs ;
status = cudaMemcpy (model->VSRCparamCPU.VSRCcoeffsArray [i], model->VSRCparamCPU.VSRCcoeffsArrayHost [i], size2 * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->VSRCparamCPU.VSRCcoeffsArray [i], size2, double, status)
i++ ;
}
/* DOUBLE */
status = cudaMemcpy (model->VSRCparamGPU.d_VSRCdcvalueArray, model->VSRCparamCPU.VSRCdcvalueArray, size1 * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->VSRCparamGPU.d_VSRCdcvalueArray, size1, double, status)
status = cudaMemcpy (model->VSRCparamGPU.d_VSRCrdelayArray, model->VSRCparamCPU.VSRCrdelayArray, size1 * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->VSRCparamGPU.d_VSRCrdelayArray, size1, double, status)
/* INT */
status = cudaMemcpy (model->VSRCparamGPU.d_VSRCdcGivenArray, model->VSRCparamCPU.VSRCdcGivenArray, size1 * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->VSRCparamGPU.d_VSRCdcGivenArray, size1, int, status)
status = cudaMemcpy (model->VSRCparamGPU.d_VSRCfunctionTypeArray, model->VSRCparamCPU.VSRCfunctionTypeArray, size1 * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->VSRCparamGPU.d_VSRCfunctionTypeArray, size1, int, status)
status = cudaMemcpy (model->VSRCparamGPU.d_VSRCfunctionOrderArray, model->VSRCparamCPU.VSRCfunctionOrderArray, size1 * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->VSRCparamGPU.d_VSRCfunctionOrderArray, size1, int, status)
status = cudaMemcpy (model->VSRCparamGPU.d_VSRCrGivenArray, model->VSRCparamCPU.VSRCrGivenArray, size1 * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->VSRCparamGPU.d_VSRCrGivenArray, size1, int, status)
status = cudaMemcpy (model->VSRCparamGPU.d_VSRCrBreakptArray, model->VSRCparamCPU.VSRCrBreakptArray, size1 * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK(model->VSRCparamGPU.VSRCrBreakptArray, size1, int, status)
return (OK) ;
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "vsrcdefs.h"
#include "ngspice/sperror.h"
#define TopologyMatrixInsert(Ptr, instance_ID, offset, Value, global_ID) \
ckt->CKTtopologyMatrixCOOi [global_ID] = (int)(here->Ptr - basePtr) ; \
ckt->CKTtopologyMatrixCOOj [global_ID] = model->PositionVector [instance_ID] + offset ; \
ckt->CKTtopologyMatrixCOOx [global_ID] = Value ;
#define TopologyMatrixInsertRHS(offset, instance_ID, offsetRHS, Value, global_ID) \
ckt->CKTtopologyMatrixCOOiRHS [global_ID] = here->offset ; \
ckt->CKTtopologyMatrixCOOjRHS [global_ID] = model->PositionVectorRHS [instance_ID] + offsetRHS ; \
ckt->CKTtopologyMatrixCOOxRHS [global_ID] = Value ;
int
VSRCtopology (GENmodel *inModel, CKTcircuit *ckt, int *i, int *j)
{
VSRCmodel *model = (VSRCmodel *)inModel ;
VSRCinstance *here ;
int k ;
double *basePtr ;
basePtr = ckt->CKTmatrix->CKTkluAx ;
/* loop through all the capacitor models */
for ( ; model != NULL ; model = VSRCnextModel(model))
{
k = 0 ;
/* loop through all the instances of the model */
for (here = VSRCinstances(model); here != NULL ; here = VSRCnextInstance(here))
{
if ((here->VSRCposNode != 0) && (here->VSRCbranch != 0))
{
TopologyMatrixInsert (VSRCposIbrPtr, k, 0, 1, *i) ;
(*i)++ ;
}
if ((here->VSRCnegNode != 0) && (here->VSRCbranch != 0))
{
TopologyMatrixInsert (VSRCnegIbrPtr, k, 0, -1, *i) ;
(*i)++ ;
}
if ((here->VSRCbranch != 0) && (here->VSRCposNode != 0))
{
TopologyMatrixInsert (VSRCibrPosPtr, k, 0, 1, *i) ;
(*i)++ ;
}
if ((here->VSRCbranch != 0) && (here->VSRCnegNode != 0))
{
TopologyMatrixInsert (VSRCibrNegPtr, k, 0, -1, *i) ;
(*i)++ ;
}
if (here->VSRCbranch != 0)
{
TopologyMatrixInsertRHS (VSRCbranch, k, 0, 1, *j) ;
(*j)++ ;
}
k++ ;
}
}
return (OK) ;
}

View File

@ -31,4 +31,18 @@ endif
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
AM_CFLAGS = $(STATIC)
if USE_CUSPICE_WANTED
.cu.lo:
$(AM_V_GEN)$(top_srcdir)/src/libtool_wrapper_for_cuda.tcl $@ $(AM_CFLAGS) $(NVCC) $(CUDA_CFLAGS) $(AM_CPPFLAGS) -c $<
libvsrc_la_SOURCES += \
CUSPICE/vsrctopology.c \
CUSPICE/cuvsrcfree.c \
CUSPICE/cuvsrcload.cu \
CUSPICE/cuvsrcsetup.c \
CUSPICE/cuvsrctemp.c
AM_CPPFLAGS += $(CUDA_CPPFLAGS)
endif
MAINTAINERCLEANFILES = Makefile.in

View File

@ -86,8 +86,50 @@ typedef struct sVSRCinstance {
BindElement *VSRCibrIbrBinding ;
#endif
#ifdef USE_CUSPICE
double *d_VSRCcoeffs ;
int n_coeffs ;
#endif
} VSRCinstance ;
#ifdef USE_CUSPICE
typedef struct sVSRCparamCPUstruct {
/* pointer to array of coefficients in GPU */
double **VSRCcoeffsArrayHost ;
double **VSRCcoeffsArray ;
double *VSRCcpuPointersD [3] ;
#define VSRCdcvalueArray VSRCcpuPointersD[0]
#define VSRCrdelayArray VSRCcpuPointersD[1]
#define VSRCValueArray VSRCcpuPointersD[2]
int *VSRCcpuPointersI [5] ;
#define VSRCdcGivenArray VSRCcpuPointersI[0]
#define VSRCfunctionTypeArray VSRCcpuPointersI[1]
#define VSRCfunctionOrderArray VSRCcpuPointersI[2]
#define VSRCrGivenArray VSRCcpuPointersI[3]
#define VSRCrBreakptArray VSRCcpuPointersI[4]
} VSRCparamCPUstruct ;
typedef struct sVSRCparamGPUstruct {
/* pointer to array of coefficients in GPU */
double **d_VSRCcoeffsArray ;
double *VSRCcudaPointersD [3] ;
#define d_VSRCdcvalueArray VSRCcudaPointersD[0]
#define d_VSRCrdelayArray VSRCcudaPointersD[1]
#define d_VSRCValueArray VSRCcudaPointersD[2]
int *VSRCcudaPointersI [5] ;
#define d_VSRCdcGivenArray VSRCcudaPointersI[0]
#define d_VSRCfunctionTypeArray VSRCcudaPointersI[1]
#define d_VSRCfunctionOrderArray VSRCcudaPointersI[2]
#define d_VSRCrGivenArray VSRCcudaPointersI[3]
#define d_VSRCrBreakptArray VSRCcudaPointersI[4]
} VSRCparamGPUstruct ;
#endif
/* per model data */
@ -100,6 +142,25 @@ typedef struct sVSRCmodel {
#define VSRCinstances(inst) ((VSRCinstance *)((inst)->gen.GENinstances))
#define VSRCmodName gen.GENmodName
#ifdef USE_CUSPICE
VSRCparamCPUstruct VSRCparamCPU ;
VSRCparamGPUstruct VSRCparamGPU ;
int offset ;
int n_values ;
int n_Ptr ;
int *PositionVector ;
int *d_PositionVector ;
int offsetRHS ;
int n_valuesRHS ;
int n_PtrRHS ;
int *PositionVectorRHS ;
int *d_PositionVectorRHS ;
int n_instances ;
#endif
} VSRCmodel;
/* source function types (shared with current sources) */

View File

@ -24,3 +24,7 @@ extern int VSRCbindCSC (GENmodel*, CKTcircuit*) ;
extern int VSRCbindCSCComplex (GENmodel*, CKTcircuit*) ;
extern int VSRCbindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
#endif
#ifdef USE_CUSPICE
extern int VSRCtopology (GENmodel *, CKTcircuit *, int *, int *) ;
#endif

Some files were not shown because too many files have changed in this diff Show More