CUSPICE Integration from scratch

This commit is contained in:
Francesco Lannutti 2014-04-26 20:09:21 +02:00 committed by rlar
parent b991345f2f
commit a97ac32a21
51 changed files with 13485 additions and 0 deletions

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

@ -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 cuBSIM4destroy (GENmodel *) ;
int cuBSIM4getic (GENmodel *) ;
int cuBSIM4load (GENmodel *, CKTcircuit *) ;
int cuBSIM4setup (GENmodel *) ;
int cuBSIM4temp (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

@ -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

@ -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

@ -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 "bsim4def.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
BSIM4topology (GENmodel *inModel, CKTcircuit *ckt, int *i, int *j)
{
BSIM4model *model = (BSIM4model *)inModel ;
BSIM4instance *here ;
int k, total_offset, total_offsetRHS ;
double *basePtr ;
basePtr = ckt->CKTmatrix->CKTkluAx ;
/* loop through all the capacitor models */
for ( ; model != NULL ; model = model->BSIM4nextModel)
{
k = 0 ;
/* loop through all the instances of the model */
for (here = model->BSIM4instances ; here != NULL ; here = here->BSIM4nextInstance)
{
total_offset = 0 ;
total_offsetRHS = 0 ;
/* For the Matrix */
if (here->BSIM4rgateMod == 1)
{
/* m * geltd */
if ((here->BSIM4gNodeExt != 0) && (here->BSIM4gNodeExt != 0))
{
TopologyMatrixInsert (BSIM4GEgePtr, k, 0, 1, *i) ;
(*i)++ ;
}
/* m * geltd */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4gNodeExt != 0))
{
TopologyMatrixInsert (BSIM4GPgePtr, k, 0, -1, *i) ;
(*i)++ ;
}
/* m * geltd */
if ((here->BSIM4gNodeExt != 0) && (here->BSIM4gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GEgpPtr, k, 0, -1, *i) ;
(*i)++ ;
}
/* m * (gcggb + geltd - ggtg + gIgtotg) */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GPgpPtr, k, 1, 1, *i) ;
(*i)++ ;
}
/* m * (gcgdb - ggtd + gIgtotd) */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GPdpPtr, k, 2, 1, *i) ;
(*i)++ ;
}
/* m * (gcgsb - ggts + gIgtots) */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GPspPtr, k, 3, 1, *i) ;
(*i)++ ;
}
/* m * (gcgbb - ggtb + gIgtotb) */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GPbpPtr, k, 4, 1, *i) ;
(*i)++ ;
}
total_offset += 5 ;
}
else if (here->BSIM4rgateMod == 2)
{
/* m * gcrg */
if ((here->BSIM4gNodeExt != 0) && (here->BSIM4gNodeExt != 0))
{
TopologyMatrixInsert (BSIM4GEgePtr, k, 0, 1, *i) ;
(*i)++ ;
}
/* m * gcrgg */
if ((here->BSIM4gNodeExt != 0) && (here->BSIM4gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GEgpPtr, k, 1, 1, *i) ;
(*i)++ ;
}
/* m * gcrgd */
if ((here->BSIM4gNodeExt != 0) && (here->BSIM4dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GEdpPtr, k, 2, 1, *i) ;
(*i)++ ;
}
/* m * gcrgs */
if ((here->BSIM4gNodeExt != 0) && (here->BSIM4sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GEspPtr, k, 3, 1, *i) ;
(*i)++ ;
}
/* m * gcrgb */
if ((here->BSIM4gNodeExt != 0) && (here->BSIM4bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GEbpPtr, k, 4, 1, *i) ;
(*i)++ ;
}
/* m * gcrg */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4gNodeExt != 0))
{
TopologyMatrixInsert (BSIM4GPgePtr, k, 0, -1, *i) ;
(*i)++ ;
}
/* m * (gcggb - gcrgg - ggtg + gIgtotg) */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GPgpPtr, k, 5, 1, *i) ;
(*i)++ ;
}
/* m * (gcgdb - gcrgd - ggtd + gIgtotd) */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GPdpPtr, k, 6, 1, *i) ;
(*i)++ ;
}
/* m * (gcgsb - gcrgs - ggts + gIgtots) */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GPspPtr, k, 7, 1, *i) ;
(*i)++ ;
}
/* m * (gcgbb - gcrgb - ggtb + gIgtotb) */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GPbpPtr, k, 8, 1, *i) ;
(*i)++ ;
}
total_offset += 9 ;
}
else if (here->BSIM4rgateMod == 3)
{
/* m * geltd */
if ((here->BSIM4gNodeExt != 0) && (here->BSIM4gNodeExt != 0))
{
TopologyMatrixInsert (BSIM4GEgePtr, k, 0, 1, *i) ;
(*i)++ ;
}
/* m * geltd */
if ((here->BSIM4gNodeExt != 0) && (here->BSIM4gNodeMid != 0))
{
TopologyMatrixInsert (BSIM4GEgmPtr, k, 0, -1, *i) ;
(*i)++ ;
}
/* m * geltd */
if ((here->BSIM4gNodeMid != 0) && (here->BSIM4gNodeExt != 0))
{
TopologyMatrixInsert (BSIM4GMgePtr, k, 0, -1, *i) ;
(*i)++ ;
}
/* m * (geltd + gcrg + gcgmgmb) */
if ((here->BSIM4gNodeMid != 0) && (here->BSIM4gNodeMid != 0))
{
TopologyMatrixInsert (BSIM4GMgmPtr, k, 1, 1, *i) ;
(*i)++ ;
}
/* m * (gcrgd + gcgmdb) */
if ((here->BSIM4gNodeMid != 0) && (here->BSIM4dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GMdpPtr, k, 2, 1, *i) ;
(*i)++ ;
}
/* m * gcrgg */
if ((here->BSIM4gNodeMid != 0) && (here->BSIM4gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GMgpPtr, k, 3, 1, *i) ;
(*i)++ ;
}
/* m * (gcrgs + gcgmsb) */
if ((here->BSIM4gNodeMid != 0) && (here->BSIM4sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GMspPtr, k, 4, 1, *i) ;
(*i)++ ;
}
/* m * (gcrgb + gcgmbb) */
if ((here->BSIM4gNodeMid != 0) && (here->BSIM4bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GMbpPtr, k, 5, 1, *i) ;
(*i)++ ;
}
/* m * gcdgmb */
if ((here->BSIM4dNodePrime != 0) && (here->BSIM4gNodeMid != 0))
{
TopologyMatrixInsert (BSIM4DPgmPtr, k, 6, 1, *i) ;
(*i)++ ;
}
/* m * gcrg */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4gNodeMid != 0))
{
TopologyMatrixInsert (BSIM4GPgmPtr, k, 7, -1, *i) ;
(*i)++ ;
}
/* m * gcsgmb */
if ((here->BSIM4sNodePrime != 0) && (here->BSIM4gNodeMid != 0))
{
TopologyMatrixInsert (BSIM4SPgmPtr, k, 8, 1, *i) ;
(*i)++ ;
}
/* m * gcbgmb */
if ((here->BSIM4bNodePrime != 0) && (here->BSIM4gNodeMid != 0))
{
TopologyMatrixInsert (BSIM4BPgmPtr, k, 9, 1, *i) ;
(*i)++ ;
}
/* m * (gcggb - gcrgg - ggtg + gIgtotg) */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GPgpPtr, k, 10, 1, *i) ;
(*i)++ ;
}
/* m * (gcgdb - gcrgd - ggtd + gIgtotd) */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GPdpPtr, k, 11, 1, *i) ;
(*i)++ ;
}
/* m * (gcgsb - gcrgs - ggts + gIgtots) */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GPspPtr, k, 12, 1, *i) ;
(*i)++ ;
}
/* m * (gcgbb - gcrgb - ggtb + gIgtotb) */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GPbpPtr, k, 13, 1, *i) ;
(*i)++ ;
}
total_offset += 14 ;
} else {
/* m * (gcggb - ggtg + gIgtotg) */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GPgpPtr, k, 0, 1, *i) ;
(*i)++ ;
}
/* m * (gcgdb - ggtd + gIgtotd) */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GPdpPtr, k, 1, 1, *i) ;
(*i)++ ;
}
/* m * (gcgsb - ggts + gIgtots) */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GPspPtr, k, 2, 1, *i) ;
(*i)++ ;
}
/* m * (gcgbb - ggtb + gIgtotb) */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4GPbpPtr, k, 3, 1, *i) ;
(*i)++ ;
}
total_offset += 4 ;
}
if (model->BSIM4rdsMod)
{
/* m * gdtotg */
if ((here->BSIM4dNode != 0) && (here->BSIM4gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4DgpPtr, k, total_offset + 0, 1, *i) ;
(*i)++ ;
}
/* m * gdtots */
if ((here->BSIM4dNode != 0) && (here->BSIM4sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4DspPtr, k, total_offset + 1, 1, *i) ;
(*i)++ ;
}
/* m * gdtotb */
if ((here->BSIM4dNode != 0) && (here->BSIM4bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4DbpPtr, k, total_offset + 2, 1, *i) ;
(*i)++ ;
}
/* m * gstotd */
if ((here->BSIM4sNode != 0) && (here->BSIM4dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4SdpPtr, k, total_offset + 3, 1, *i) ;
(*i)++ ;
}
/* m * gstotg */
if ((here->BSIM4sNode != 0) && (here->BSIM4gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4SgpPtr, k, total_offset + 0, 1, *i) ;
(*i)++ ;
}
/* m * gstotb */
if ((here->BSIM4sNode != 0) && (here->BSIM4bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4SbpPtr, k, total_offset + 2, 1, *i) ;
(*i)++ ;
}
total_offset += 4 ;
}
/* m * (gdpr + here->BSIM4gds + here->BSIM4gbd + T1 * ddxpart_dVd -
gdtotd + RevSum + gcddb + gbdpdp + dxpart * ggtd - gIdtotd) + m * ggidld */
if ((here->BSIM4dNodePrime != 0) && (here->BSIM4dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4DPdpPtr, k, total_offset + 0, 1, *i) ;
(*i)++ ;
}
/* m * (gdpr + gdtot) */
if ((here->BSIM4dNodePrime != 0) && (here->BSIM4dNode != 0))
{
TopologyMatrixInsert (BSIM4DPdPtr, k, total_offset + 1, -1, *i) ;
(*i)++ ;
}
/* m * (Gm + gcdgb - gdtotg + gbdpg - gIdtotg + dxpart * ggtg + T1 * ddxpart_dVg) + m * ggidlg */
if ((here->BSIM4dNodePrime != 0) && (here->BSIM4gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4DPgpPtr, k, total_offset + 2, 1, *i) ;
(*i)++ ;
}
/* m * (here->BSIM4gds + gdtots - dxpart * ggts + gIdtots -
T1 * ddxpart_dVs + FwdSum - gcdsb - gbdpsp) + m * (ggidlg + ggidld + ggidlb) */
if ((here->BSIM4dNodePrime != 0) && (here->BSIM4sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4DPspPtr, k, total_offset + 3, -1, *i) ;
(*i)++ ;
}
/* m * (gjbd + gdtotb - Gmbs - gcdbb - gbdpb + gIdtotb - T1 * ddxpart_dVb - dxpart * ggtb) - m * ggidlb */
if ((here->BSIM4dNodePrime != 0) && (here->BSIM4bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4DPbpPtr, k, total_offset + 4, -1, *i) ;
(*i)++ ;
}
/* m * (gdpr - gdtotd) */
if ((here->BSIM4dNode != 0) && (here->BSIM4dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4DdpPtr, k, total_offset + 5, -1, *i) ;
(*i)++ ;
}
/* m * (gdpr + gdtot) */
if ((here->BSIM4dNode != 0) && (here->BSIM4dNode != 0))
{
TopologyMatrixInsert (BSIM4DdPtr, k, total_offset + 1, 1, *i) ;
(*i)++ ;
}
/* m * (here->BSIM4gds + gstotd + RevSum - gcsdb - gbspdp -
T1 * dsxpart_dVd - sxpart * ggtd + gIstotd) + m * (ggisls + ggislg + ggislb) */
if ((here->BSIM4sNodePrime != 0) && (here->BSIM4dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4SPdpPtr, k, total_offset + 6, -1, *i) ;
(*i)++ ;
}
/* m * (gcsgb - Gm - gstotg + gbspg + sxpart * ggtg + T1 * dsxpart_dVg - gIstotg) + m * ggislg */
if ((here->BSIM4sNodePrime != 0) && (here->BSIM4gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4SPgpPtr, k, total_offset + 7, 1, *i) ;
(*i)++ ;
}
/* m * (gspr + here->BSIM4gds + here->BSIM4gbs + T1 * dsxpart_dVs -
gstots + FwdSum + gcssb + gbspsp + sxpart * ggts - gIstots) + m * ggisls */
if ((here->BSIM4sNodePrime != 0) && (here->BSIM4sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4SPspPtr, k, total_offset + 8, 1, *i) ;
(*i)++ ;
}
/* m * (gspr + gstot) */
if ((here->BSIM4sNodePrime != 0) && (here->BSIM4sNode != 0))
{
TopologyMatrixInsert (BSIM4SPsPtr, k, total_offset + 9, -1, *i) ;
(*i)++ ;
}
/* m * (gjbs + gstotb + Gmbs - gcsbb - gbspb - sxpart * ggtb - T1 * dsxpart_dVb + gIstotb) - m * ggislb */
if ((here->BSIM4sNodePrime != 0) && (here->BSIM4bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4SPbpPtr, k, total_offset + 10, -1, *i) ;
(*i)++ ;
}
/* m * (gspr - gstots) */
if ((here->BSIM4sNode != 0) && (here->BSIM4sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4SspPtr, k, total_offset + 11, -1, *i) ;
(*i)++ ;
}
/* m * (gspr + gstot) */
if ((here->BSIM4sNode != 0) && (here->BSIM4sNode != 0))
{
TopologyMatrixInsert (BSIM4SsPtr, k, total_offset + 9, 1, *i) ;
(*i)++ ;
}
/* m * (gcbdb - gjbd + gbbdp - gIbtotd) - m * ggidld + m * (ggislg + ggisls + ggislb) */
if ((here->BSIM4bNodePrime != 0) && (here->BSIM4dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4BPdpPtr, k, total_offset + 12, 1, *i) ;
(*i)++ ;
}
/* m * (gcbgb - here->BSIM4gbgs - gIbtotg) - m * ggidlg - m * ggislg */
if ((here->BSIM4bNodePrime != 0) && (here->BSIM4gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4BPgpPtr, k, total_offset + 13, 1, *i) ;
(*i)++ ;
}
/* m * (gcbsb - gjbs + gbbsp - gIbtots) + m * (ggidlg + ggidld + ggidlb) - m * ggisls */
if ((here->BSIM4bNodePrime != 0) && (here->BSIM4sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4BPspPtr, k, total_offset + 14, 1, *i) ;
(*i)++ ;
}
/* m * (gjbd + gjbs + gcbbb - here->BSIM4gbbs - gIbtotb) - m * ggidlb - m * ggislb */
if ((here->BSIM4bNodePrime != 0) && (here->BSIM4bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4BPbpPtr, k, total_offset + 15, 1, *i) ;
(*i)++ ;
}
total_offset += 16 ;
/* stamp gidl included above */
/* stamp gisl included above */
if (here->BSIM4rbodyMod)
{
/* m * (gcdbdb - here->BSIM4gbd) */
if ((here->BSIM4dNodePrime != 0) && (here->BSIM4dbNode != 0))
{
TopologyMatrixInsert (BSIM4DPdbPtr, k, total_offset + 0, 1, *i) ;
(*i)++ ;
}
/* m * (here->BSIM4gbs - gcsbsb) */
if ((here->BSIM4sNodePrime != 0) && (here->BSIM4sbNode != 0))
{
TopologyMatrixInsert (BSIM4SPsbPtr, k, total_offset + 1, -1, *i) ;
(*i)++ ;
}
/* m * (gcdbdb - here->BSIM4gbd) */
if ((here->BSIM4dbNode != 0) && (here->BSIM4dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4DBdpPtr, k, total_offset + 0, 1, *i) ;
(*i)++ ;
}
/* m * (here->BSIM4gbd - gcdbdb + here->BSIM4grbpd + here->BSIM4grbdb) */
if ((here->BSIM4dbNode != 0) && (here->BSIM4dbNode != 0))
{
TopologyMatrixInsert (BSIM4DBdbPtr, k, total_offset + 2, 1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4grbpd */
if ((here->BSIM4dbNode != 0) && (here->BSIM4bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4DBbpPtr, k, total_offset + 3, -1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4grbdb */
if ((here->BSIM4dbNode != 0) && (here->BSIM4bNode != 0))
{
TopologyMatrixInsert (BSIM4DBbPtr, k, total_offset + 4, -1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4grbpd */
if ((here->BSIM4bNodePrime != 0) && (here->BSIM4dbNode != 0))
{
TopologyMatrixInsert (BSIM4BPdbPtr, k, total_offset + 3, -1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4grbpb */
if ((here->BSIM4bNodePrime != 0) && (here->BSIM4bNode != 0))
{
TopologyMatrixInsert (BSIM4BPbPtr, k, total_offset + 5, -1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4grbps */
if ((here->BSIM4bNodePrime != 0) && (here->BSIM4sbNode != 0))
{
TopologyMatrixInsert (BSIM4BPsbPtr, k, total_offset + 6, -1, *i) ;
(*i)++ ;
}
/* m * (here->BSIM4grbpd + here->BSIM4grbps + here->BSIM4grbpb) */
if ((here->BSIM4bNodePrime != 0) && (here->BSIM4bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4BPbpPtr, k, total_offset + 7, 1, *i) ;
(*i)++ ;
}
/* m * (gcsbsb - here->BSIM4gbs) */
if ((here->BSIM4sbNode != 0) && (here->BSIM4sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4SBspPtr, k, total_offset + 8, 1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4grbps */
if ((here->BSIM4sbNode != 0) && (here->BSIM4bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4SBbpPtr, k, total_offset + 6, -1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4grbsb */
if ((here->BSIM4sbNode != 0) && (here->BSIM4bNode != 0))
{
TopologyMatrixInsert (BSIM4SBbPtr, k, total_offset + 9, -1, *i) ;
(*i)++ ;
}
/* m * (here->BSIM4gbs - gcsbsb + here->BSIM4grbps + here->BSIM4grbsb) */
if ((here->BSIM4sbNode != 0) && (here->BSIM4sbNode != 0))
{
TopologyMatrixInsert (BSIM4SBsbPtr, k, total_offset + 10, 1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4grbdb */
if ((here->BSIM4bNode != 0) && (here->BSIM4dbNode != 0))
{
TopologyMatrixInsert (BSIM4BdbPtr, k, total_offset + 4, -1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4grbpb */
if ((here->BSIM4bNode != 0) && (here->BSIM4bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4BbpPtr, k, total_offset + 5, -1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4grbsb */
if ((here->BSIM4bNode != 0) && (here->BSIM4sbNode != 0))
{
TopologyMatrixInsert (BSIM4BsbPtr, k, total_offset + 9, -1, *i) ;
(*i)++ ;
}
/* m * (here->BSIM4grbsb + here->BSIM4grbdb + here->BSIM4grbpb) */
if ((here->BSIM4bNode != 0) && (here->BSIM4bNode != 0))
{
TopologyMatrixInsert (BSIM4BbPtr, k, total_offset + 11, 1, *i) ;
(*i)++ ;
}
total_offset += 12 ;
}
if (here->BSIM4trnqsMod)
{
/* m * (gqdef + here->BSIM4gtau) */
if ((here->BSIM4qNode != 0) && (here->BSIM4qNode != 0))
{
TopologyMatrixInsert (BSIM4QqPtr, k, total_offset + 0, 1, *i) ;
(*i)++ ;
}
/* m * (ggtg - gcqgb) */
if ((here->BSIM4qNode != 0) && (here->BSIM4gNodePrime != 0))
{
TopologyMatrixInsert (BSIM4QgpPtr, k, total_offset + 1, 1, *i) ;
(*i)++ ;
}
/* m * (ggtd - gcqdb) */
if ((here->BSIM4qNode != 0) && (here->BSIM4dNodePrime != 0))
{
TopologyMatrixInsert (BSIM4QdpPtr, k, total_offset + 2, 1, *i) ;
(*i)++ ;
}
/* m * (ggts - gcqsb) */
if ((here->BSIM4qNode != 0) && (here->BSIM4sNodePrime != 0))
{
TopologyMatrixInsert (BSIM4QspPtr, k, total_offset + 3, 1, *i) ;
(*i)++ ;
}
/* m * (ggtb - gcqbb) */
if ((here->BSIM4qNode != 0) && (here->BSIM4bNodePrime != 0))
{
TopologyMatrixInsert (BSIM4QbpPtr, k, total_offset + 4, 1, *i) ;
(*i)++ ;
}
/* m * dxpart * here->BSIM4gtau */
if ((here->BSIM4dNodePrime != 0) && (here->BSIM4qNode != 0))
{
TopologyMatrixInsert (BSIM4DPqPtr, k, total_offset + 5, 1, *i) ;
(*i)++ ;
}
/* m * sxpart * here->BSIM4gtau */
if ((here->BSIM4sNodePrime != 0) && (here->BSIM4qNode != 0))
{
TopologyMatrixInsert (BSIM4SPqPtr, k, total_offset + 6, 1, *i) ;
(*i)++ ;
}
/* m * here->BSIM4gtau */
if ((here->BSIM4gNodePrime != 0) && (here->BSIM4qNode != 0))
{
TopologyMatrixInsert (BSIM4GPqPtr, k, total_offset + 7, -1, *i) ;
(*i)++ ;
}
}
/* For the RHS */
/* m * (ceqjd - ceqbd + ceqgdtot - ceqdrn - ceqqd + Idtoteq) */
if (here->BSIM4dNodePrime != 0)
{
TopologyMatrixInsertRHS (BSIM4dNodePrime, k, total_offsetRHS + 0, 1, *j) ;
(*j)++ ;
}
/* m * (ceqqg - ceqgcrg + Igtoteq) */
if (here->BSIM4gNodePrime != 0)
{
TopologyMatrixInsertRHS (BSIM4gNodePrime, k, total_offsetRHS + 1, -1, *j) ;
(*j)++ ;
}
total_offsetRHS += 2 ;
if (here->BSIM4rgateMod == 2)
{
/* m * ceqgcrg */
if (here->BSIM4gNodeExt != 0)
{
TopologyMatrixInsertRHS (BSIM4gNodeExt, k, total_offsetRHS + 0, -1, *j) ;
(*j)++ ;
}
total_offsetRHS += 1 ;
}
else if (here->BSIM4rgateMod == 3)
{
/* m * (ceqqgmid + ceqgcrg) */
if (here->BSIM4gNodeMid != 0)
{
TopologyMatrixInsertRHS (BSIM4gNodeMid, k, total_offsetRHS + 0, -1, *j) ;
(*j)++ ;
}
total_offsetRHS += 1 ;
}
if (!here->BSIM4rbodyMod)
{
/* m * (ceqbd + ceqbs - ceqjd - ceqjs - ceqqb + Ibtoteq) */
if (here->BSIM4bNodePrime != 0)
{
TopologyMatrixInsertRHS (BSIM4bNodePrime, k, total_offsetRHS + 0, 1, *j) ;
(*j)++ ;
}
/* m * (ceqdrn - ceqbs + ceqjs + ceqqg + ceqqb + ceqqd + ceqqgmid - ceqgstot + Istoteq) */
if (here->BSIM4sNodePrime != 0)
{
TopologyMatrixInsertRHS (BSIM4sNodePrime, k, total_offsetRHS + 1, 1, *j) ;
(*j)++ ;
}
total_offsetRHS += 2 ;
} else {
/* m * (ceqjd + ceqqjd) */
if (here->BSIM4dbNode != 0)
{
TopologyMatrixInsertRHS (BSIM4dbNode, k, total_offsetRHS + 0, -1, *j) ;
(*j)++ ;
}
/* m * (ceqbd + ceqbs - ceqqb + Ibtoteq) */
if (here->BSIM4bNodePrime != 0)
{
TopologyMatrixInsertRHS (BSIM4bNodePrime, k, total_offsetRHS + 1, 1, *j) ;
(*j)++ ;
}
/* m * (ceqjs + ceqqjs) */
if (here->BSIM4sbNode != 0)
{
TopologyMatrixInsertRHS (BSIM4sbNode, k, total_offsetRHS + 2, -1, *j) ;
(*j)++ ;
}
/* m * (ceqdrn - ceqbs + ceqjs + ceqqd + ceqqg + ceqqb +
ceqqjd + ceqqjs + ceqqgmid - ceqgstot + Istoteq) */
if (here->BSIM4sNodePrime != 0)
{
TopologyMatrixInsertRHS (BSIM4sNodePrime, k, total_offsetRHS + 3, 1, *j) ;
(*j)++ ;
}
total_offsetRHS += 4 ;
}
if (model->BSIM4rdsMod)
{
/* m * ceqgdtot */
if (here->BSIM4dNode != 0)
{
TopologyMatrixInsertRHS (BSIM4dNode, k, total_offsetRHS + 0, -1, *j) ;
(*j)++ ;
}
/* m * ceqgstot */
if (here->BSIM4sNode != 0)
{
TopologyMatrixInsertRHS (BSIM4sNode, k, total_offsetRHS + 1, 1, *j) ;
(*j)++ ;
}
total_offsetRHS += 2 ;
}
if (here->BSIM4trnqsMod)
{
/* m * (cqcheq - cqdef) */
if (here->BSIM4qNode != 0)
{
TopologyMatrixInsertRHS (BSIM4qNode, 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 "bsim4def.h"
#include "ngspice/CUSPICE/CUSPICE.h"
int
cuBSIM4destroy
(
GENmodel *inModel
)
{
BSIM4model *model = (BSIM4model *)inModel ;
BSIM4instance *here ;
int i ;
for ( ; model != NULL ; model = model->BSIM4nextModel)
{
/* Special case here->d_pParam */
i = 0 ;
for (here = model->BSIM4instances ; here != NULL ; here = here->BSIM4nextInstance)
{
if (here->pParam != NULL)
cudaFree (model->pParamHost [i]) ;
i++ ;
}
free (model->pParamHost) ;
cudaFree (model->d_pParam) ;
/* DOUBLE */
free (model->BSIM4paramCPU.BSIM4gbsRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gbsRWArray) ;
free (model->BSIM4paramCPU.BSIM4cbsRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cbsRWArray) ;
free (model->BSIM4paramCPU.BSIM4gbdRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gbdRWArray) ;
free (model->BSIM4paramCPU.BSIM4cbdRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cbdRWArray) ;
free (model->BSIM4paramCPU.BSIM4vonRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4vonRWArray) ;
free (model->BSIM4paramCPU.BSIM4vdsatRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4vdsatRWArray) ;
free (model->BSIM4paramCPU.BSIM4csubRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4csubRWArray) ;
free (model->BSIM4paramCPU.BSIM4gdsRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gdsRWArray) ;
free (model->BSIM4paramCPU.BSIM4gmRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gmRWArray) ;
free (model->BSIM4paramCPU.BSIM4gmbsRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gmbsRWArray) ;
free (model->BSIM4paramCPU.BSIM4gcrgRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gcrgRWArray) ;
free (model->BSIM4paramCPU.BSIM4IgidlRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4IgidlRWArray) ;
free (model->BSIM4paramCPU.BSIM4IgislRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4IgislRWArray) ;
free (model->BSIM4paramCPU.BSIM4IgcsRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4IgcsRWArray) ;
free (model->BSIM4paramCPU.BSIM4IgcdRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4IgcdRWArray) ;
free (model->BSIM4paramCPU.BSIM4IgsRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4IgsRWArray) ;
free (model->BSIM4paramCPU.BSIM4IgdRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4IgdRWArray) ;
free (model->BSIM4paramCPU.BSIM4IgbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4IgbRWArray) ;
free (model->BSIM4paramCPU.BSIM4cdRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cdRWArray) ;
free (model->BSIM4paramCPU.BSIM4qinvRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4qinvRWArray) ;
free (model->BSIM4paramCPU.BSIM4cggbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cggbRWArray) ;
free (model->BSIM4paramCPU.BSIM4cgsbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cgsbRWArray) ;
free (model->BSIM4paramCPU.BSIM4cgdbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cgdbRWArray) ;
free (model->BSIM4paramCPU.BSIM4cdgbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cdgbRWArray) ;
free (model->BSIM4paramCPU.BSIM4cdsbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cdsbRWArray) ;
free (model->BSIM4paramCPU.BSIM4cddbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cddbRWArray) ;
free (model->BSIM4paramCPU.BSIM4cbgbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cbgbRWArray) ;
free (model->BSIM4paramCPU.BSIM4cbsbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cbsbRWArray) ;
free (model->BSIM4paramCPU.BSIM4cbdbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cbdbRWArray) ;
free (model->BSIM4paramCPU.BSIM4csgbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4csgbRWArray) ;
free (model->BSIM4paramCPU.BSIM4cssbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cssbRWArray) ;
free (model->BSIM4paramCPU.BSIM4csdbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4csdbRWArray) ;
free (model->BSIM4paramCPU.BSIM4cgbbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cgbbRWArray) ;
free (model->BSIM4paramCPU.BSIM4csbbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4csbbRWArray) ;
free (model->BSIM4paramCPU.BSIM4cdbbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cdbbRWArray) ;
free (model->BSIM4paramCPU.BSIM4cbbbRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cbbbRWArray) ;
free (model->BSIM4paramCPU.BSIM4gtauRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gtauRWArray) ;
free (model->BSIM4paramCPU.BSIM4qgateRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4qgateRWArray) ;
free (model->BSIM4paramCPU.BSIM4qbulkRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4qbulkRWArray) ;
free (model->BSIM4paramCPU.BSIM4qdrnRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4qdrnRWArray) ;
free (model->BSIM4paramCPU.BSIM4qsrcRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4qsrcRWArray) ;
free (model->BSIM4paramCPU.BSIM4capbsRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4capbsRWArray) ;
free (model->BSIM4paramCPU.BSIM4capbdRWArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4capbdRWArray) ;
free (model->BSIM4paramCPU.BSIM4icVDSArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4icVDSArray) ;
free (model->BSIM4paramCPU.BSIM4icVGSArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4icVGSArray) ;
free (model->BSIM4paramCPU.BSIM4icVBSArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4icVBSArray) ;
free (model->BSIM4paramCPU.BSIM4vth0Array) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4vth0Array) ;
free (model->BSIM4paramCPU.BSIM4gbbsArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gbbsArray) ;
free (model->BSIM4paramCPU.BSIM4ggidlbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4ggidlbArray) ;
free (model->BSIM4paramCPU.BSIM4gbgsArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gbgsArray) ;
free (model->BSIM4paramCPU.BSIM4ggidlgArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4ggidlgArray) ;
free (model->BSIM4paramCPU.BSIM4gbdsArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gbdsArray) ;
free (model->BSIM4paramCPU.BSIM4ggidldArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4ggidldArray) ;
free (model->BSIM4paramCPU.BSIM4ggislsArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4ggislsArray) ;
free (model->BSIM4paramCPU.BSIM4ggislgArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4ggislgArray) ;
free (model->BSIM4paramCPU.BSIM4ggislbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4ggislbArray) ;
free (model->BSIM4paramCPU.BSIM4gIgsgArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gIgsgArray) ;
free (model->BSIM4paramCPU.BSIM4gIgcsgArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gIgcsgArray) ;
free (model->BSIM4paramCPU.BSIM4gIgcsdArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gIgcsdArray) ;
free (model->BSIM4paramCPU.BSIM4gIgcsbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gIgcsbArray) ;
free (model->BSIM4paramCPU.BSIM4gIgdgArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gIgdgArray) ;
free (model->BSIM4paramCPU.BSIM4gIgcdgArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gIgcdgArray) ;
free (model->BSIM4paramCPU.BSIM4gIgcddArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gIgcddArray) ;
free (model->BSIM4paramCPU.BSIM4gIgcdbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gIgcdbArray) ;
free (model->BSIM4paramCPU.BSIM4gIgbgArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gIgbgArray) ;
free (model->BSIM4paramCPU.BSIM4gIgbdArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gIgbdArray) ;
free (model->BSIM4paramCPU.BSIM4gIgbbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gIgbbArray) ;
free (model->BSIM4paramCPU.BSIM4ggidlsArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4ggidlsArray) ;
free (model->BSIM4paramCPU.BSIM4ggisldArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4ggisldArray) ;
free (model->BSIM4paramCPU.BSIM4gstotArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gstotArray) ;
free (model->BSIM4paramCPU.BSIM4gstotdArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gstotdArray) ;
free (model->BSIM4paramCPU.BSIM4gstotgArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gstotgArray) ;
free (model->BSIM4paramCPU.BSIM4gstotbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gstotbArray) ;
free (model->BSIM4paramCPU.BSIM4gdtotArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gdtotArray) ;
free (model->BSIM4paramCPU.BSIM4gdtotdArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gdtotdArray) ;
free (model->BSIM4paramCPU.BSIM4gdtotgArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gdtotgArray) ;
free (model->BSIM4paramCPU.BSIM4gdtotbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gdtotbArray) ;
free (model->BSIM4paramCPU.BSIM4cgdoArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cgdoArray) ;
free (model->BSIM4paramCPU.BSIM4qgdoArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4qgdoArray) ;
free (model->BSIM4paramCPU.BSIM4cgsoArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cgsoArray) ;
free (model->BSIM4paramCPU.BSIM4qgsoArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4qgsoArray) ;
free (model->BSIM4paramCPU.BSIM4AseffArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4AseffArray) ;
free (model->BSIM4paramCPU.BSIM4PseffArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4PseffArray) ;
free (model->BSIM4paramCPU.BSIM4nfArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4nfArray) ;
free (model->BSIM4paramCPU.BSIM4XExpBVSArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4XExpBVSArray) ;
free (model->BSIM4paramCPU.BSIM4vjsmFwdArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4vjsmFwdArray) ;
free (model->BSIM4paramCPU.BSIM4IVjsmFwdArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4IVjsmFwdArray) ;
free (model->BSIM4paramCPU.BSIM4vjsmRevArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4vjsmRevArray) ;
free (model->BSIM4paramCPU.BSIM4IVjsmRevArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4IVjsmRevArray) ;
free (model->BSIM4paramCPU.BSIM4SslpRevArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SslpRevArray) ;
free (model->BSIM4paramCPU.BSIM4SslpFwdArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SslpFwdArray) ;
free (model->BSIM4paramCPU.BSIM4AdeffArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4AdeffArray) ;
free (model->BSIM4paramCPU.BSIM4PdeffArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4PdeffArray) ;
free (model->BSIM4paramCPU.BSIM4XExpBVDArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4XExpBVDArray) ;
free (model->BSIM4paramCPU.BSIM4vjdmFwdArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4vjdmFwdArray) ;
free (model->BSIM4paramCPU.BSIM4IVjdmFwdArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4IVjdmFwdArray) ;
free (model->BSIM4paramCPU.BSIM4vjdmRevArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4vjdmRevArray) ;
free (model->BSIM4paramCPU.BSIM4IVjdmRevArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4IVjdmRevArray) ;
free (model->BSIM4paramCPU.BSIM4DslpRevArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DslpRevArray) ;
free (model->BSIM4paramCPU.BSIM4DslpFwdArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DslpFwdArray) ;
free (model->BSIM4paramCPU.BSIM4SjctTempRevSatCurArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SjctTempRevSatCurArray) ;
free (model->BSIM4paramCPU.BSIM4SswTempRevSatCurArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SswTempRevSatCurArray) ;
free (model->BSIM4paramCPU.BSIM4SswgTempRevSatCurArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SswgTempRevSatCurArray) ;
free (model->BSIM4paramCPU.BSIM4DjctTempRevSatCurArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DjctTempRevSatCurArray) ;
free (model->BSIM4paramCPU.BSIM4DswTempRevSatCurArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DswTempRevSatCurArray) ;
free (model->BSIM4paramCPU.BSIM4DswgTempRevSatCurArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DswgTempRevSatCurArray) ;
free (model->BSIM4paramCPU.BSIM4vbscArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4vbscArray) ;
free (model->BSIM4paramCPU.BSIM4thetavthArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4thetavthArray) ;
free (model->BSIM4paramCPU.BSIM4eta0Array) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4eta0Array) ;
free (model->BSIM4paramCPU.BSIM4k2oxArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4k2oxArray) ;
free (model->BSIM4paramCPU.BSIM4nstarArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4nstarArray) ;
free (model->BSIM4paramCPU.BSIM4vfbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4vfbArray) ;
free (model->BSIM4paramCPU.BSIM4vgs_effArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4vgs_effArray) ;
free (model->BSIM4paramCPU.BSIM4vgd_effArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4vgd_effArray) ;
free (model->BSIM4paramCPU.BSIM4dvgs_eff_dvgArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4dvgs_eff_dvgArray) ;
free (model->BSIM4paramCPU.BSIM4dvgd_eff_dvgArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4dvgd_eff_dvgArray) ;
free (model->BSIM4paramCPU.BSIM4VgsteffArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4VgsteffArray) ;
free (model->BSIM4paramCPU.BSIM4grdswArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4grdswArray) ;
free (model->BSIM4paramCPU.BSIM4AbulkArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4AbulkArray) ;
free (model->BSIM4paramCPU.BSIM4vtfbphi1Array) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4vtfbphi1Array) ;
free (model->BSIM4paramCPU.BSIM4ueffArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4ueffArray) ;
free (model->BSIM4paramCPU.BSIM4u0tempArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4u0tempArray) ;
free (model->BSIM4paramCPU.BSIM4vsattempArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4vsattempArray) ;
free (model->BSIM4paramCPU.BSIM4EsatLArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4EsatLArray) ;
free (model->BSIM4paramCPU.BSIM4VdseffArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4VdseffArray) ;
free (model->BSIM4paramCPU.BSIM4vtfbphi2Array) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4vtfbphi2Array) ;
free (model->BSIM4paramCPU.BSIM4CoxeffArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4CoxeffArray) ;
free (model->BSIM4paramCPU.BSIM4AbovVgst2VtmArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4AbovVgst2VtmArray) ;
free (model->BSIM4paramCPU.BSIM4IdovVdsArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4IdovVdsArray) ;
free (model->BSIM4paramCPU.BSIM4gcrgdArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gcrgdArray) ;
free (model->BSIM4paramCPU.BSIM4gcrgbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gcrgbArray) ;
free (model->BSIM4paramCPU.BSIM4gcrggArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gcrggArray) ;
free (model->BSIM4paramCPU.BSIM4grgeltdArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4grgeltdArray) ;
free (model->BSIM4paramCPU.BSIM4gcrgsArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gcrgsArray) ;
free (model->BSIM4paramCPU.BSIM4sourceConductanceArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4sourceConductanceArray) ;
free (model->BSIM4paramCPU.BSIM4drainConductanceArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4drainConductanceArray) ;
free (model->BSIM4paramCPU.BSIM4gstotsArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gstotsArray) ;
free (model->BSIM4paramCPU.BSIM4gdtotsArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gdtotsArray) ;
free (model->BSIM4paramCPU.BSIM4vfbzbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4vfbzbArray) ;
free (model->BSIM4paramCPU.BSIM4gIgssArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gIgssArray) ;
free (model->BSIM4paramCPU.BSIM4gIgddArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gIgddArray) ;
free (model->BSIM4paramCPU.BSIM4gIgbsArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gIgbsArray) ;
free (model->BSIM4paramCPU.BSIM4gIgcssArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gIgcssArray) ;
free (model->BSIM4paramCPU.BSIM4gIgcdsArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gIgcdsArray) ;
free (model->BSIM4paramCPU.BSIM4noiGd0Array) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4noiGd0Array) ;
free (model->BSIM4paramCPU.BSIM4cqdbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cqdbArray) ;
free (model->BSIM4paramCPU.BSIM4cqsbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cqsbArray) ;
free (model->BSIM4paramCPU.BSIM4cqgbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cqgbArray) ;
free (model->BSIM4paramCPU.BSIM4qchqsArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4qchqsArray) ;
free (model->BSIM4paramCPU.BSIM4cqbbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4cqbbArray) ;
free (model->BSIM4paramCPU.BSIM4taunetArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4taunetArray) ;
free (model->BSIM4paramCPU.BSIM4gtgArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gtgArray) ;
free (model->BSIM4paramCPU.BSIM4gtdArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gtdArray) ;
free (model->BSIM4paramCPU.BSIM4gtsArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gtsArray) ;
free (model->BSIM4paramCPU.BSIM4gtbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gtbArray) ;
free (model->BSIM4paramCPU.BSIM4mArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4mArray) ;
free (model->BSIM4paramCPU.BSIM4grbpdArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4grbpdArray) ;
free (model->BSIM4paramCPU.BSIM4grbdbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4grbdbArray) ;
free (model->BSIM4paramCPU.BSIM4grbpbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4grbpbArray) ;
free (model->BSIM4paramCPU.BSIM4grbpsArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4grbpsArray) ;
free (model->BSIM4paramCPU.BSIM4grbsbArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4grbsbArray) ;
free (model->BSIM4paramCPU.BSIM4dNodePrimeRHSValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4dNodePrimeRHSValueArray) ;
free (model->BSIM4paramCPU.BSIM4gNodePrimeRHSValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gNodePrimeRHSValueArray) ;
free (model->BSIM4paramCPU.BSIM4gNodeExtRHSValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gNodeExtRHSValueArray) ;
free (model->BSIM4paramCPU.BSIM4gNodeMidRHSValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gNodeMidRHSValueArray) ;
free (model->BSIM4paramCPU.BSIM4bNodePrimeRHSValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4bNodePrimeRHSValueArray) ;
free (model->BSIM4paramCPU.BSIM4sNodePrimeRHSValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4sNodePrimeRHSValueArray) ;
free (model->BSIM4paramCPU.BSIM4dbNodeRHSValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4dbNodeRHSValueArray) ;
free (model->BSIM4paramCPU.BSIM4sbNodeRHSValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4sbNodeRHSValueArray) ;
free (model->BSIM4paramCPU.BSIM4dNodeRHSValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4dNodeRHSValueArray) ;
free (model->BSIM4paramCPU.BSIM4sNodeRHSValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4sNodeRHSValueArray) ;
free (model->BSIM4paramCPU.BSIM4qNodeRHSValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4qNodeRHSValueArray) ;
free (model->BSIM4paramCPU.BSIM4GEgeValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GEgeValueArray) ;
free (model->BSIM4paramCPU.BSIM4GPgeValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GPgeValueArray) ;
free (model->BSIM4paramCPU.BSIM4GEgpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GEgpValueArray) ;
free (model->BSIM4paramCPU.BSIM4GPgpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GPgpValueArray) ;
free (model->BSIM4paramCPU.BSIM4GPdpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GPdpValueArray) ;
free (model->BSIM4paramCPU.BSIM4GPspValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GPspValueArray) ;
free (model->BSIM4paramCPU.BSIM4GPbpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GPbpValueArray) ;
free (model->BSIM4paramCPU.BSIM4GEdpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GEdpValueArray) ;
free (model->BSIM4paramCPU.BSIM4GEspValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GEspValueArray) ;
free (model->BSIM4paramCPU.BSIM4GEbpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GEbpValueArray) ;
free (model->BSIM4paramCPU.BSIM4GEgmValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GEgmValueArray) ;
free (model->BSIM4paramCPU.BSIM4GMgeValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GMgeValueArray) ;
free (model->BSIM4paramCPU.BSIM4GMgmValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GMgmValueArray) ;
free (model->BSIM4paramCPU.BSIM4GMdpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GMdpValueArray) ;
free (model->BSIM4paramCPU.BSIM4GMgpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GMgpValueArray) ;
free (model->BSIM4paramCPU.BSIM4GMspValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GMspValueArray) ;
free (model->BSIM4paramCPU.BSIM4GMbpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GMbpValueArray) ;
free (model->BSIM4paramCPU.BSIM4DPgmValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DPgmValueArray) ;
free (model->BSIM4paramCPU.BSIM4GPgmValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GPgmValueArray) ;
free (model->BSIM4paramCPU.BSIM4SPgmValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SPgmValueArray) ;
free (model->BSIM4paramCPU.BSIM4BPgmValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4BPgmValueArray) ;
free (model->BSIM4paramCPU.BSIM4DgpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DgpValueArray) ;
free (model->BSIM4paramCPU.BSIM4DspValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DspValueArray) ;
free (model->BSIM4paramCPU.BSIM4DbpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DbpValueArray) ;
free (model->BSIM4paramCPU.BSIM4SdpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SdpValueArray) ;
free (model->BSIM4paramCPU.BSIM4SgpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SgpValueArray) ;
free (model->BSIM4paramCPU.BSIM4SbpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SbpValueArray) ;
free (model->BSIM4paramCPU.BSIM4DPdpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DPdpValueArray) ;
free (model->BSIM4paramCPU.BSIM4DPdValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DPdValueArray) ;
free (model->BSIM4paramCPU.BSIM4DPgpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DPgpValueArray) ;
free (model->BSIM4paramCPU.BSIM4DPspValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DPspValueArray) ;
free (model->BSIM4paramCPU.BSIM4DPbpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DPbpValueArray) ;
free (model->BSIM4paramCPU.BSIM4DdpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DdpValueArray) ;
free (model->BSIM4paramCPU.BSIM4DdValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DdValueArray) ;
free (model->BSIM4paramCPU.BSIM4SPdpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SPdpValueArray) ;
free (model->BSIM4paramCPU.BSIM4SPgpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SPgpValueArray) ;
free (model->BSIM4paramCPU.BSIM4SPspValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SPspValueArray) ;
free (model->BSIM4paramCPU.BSIM4SPsValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SPsValueArray) ;
free (model->BSIM4paramCPU.BSIM4SPbpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SPbpValueArray) ;
free (model->BSIM4paramCPU.BSIM4SspValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SspValueArray) ;
free (model->BSIM4paramCPU.BSIM4SsValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SsValueArray) ;
free (model->BSIM4paramCPU.BSIM4BPdpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4BPdpValueArray) ;
free (model->BSIM4paramCPU.BSIM4BPgpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4BPgpValueArray) ;
free (model->BSIM4paramCPU.BSIM4BPspValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4BPspValueArray) ;
free (model->BSIM4paramCPU.BSIM4BPbpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4BPbpValueArray) ;
free (model->BSIM4paramCPU.BSIM4DPdbValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DPdbValueArray) ;
free (model->BSIM4paramCPU.BSIM4SPsbValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SPsbValueArray) ;
free (model->BSIM4paramCPU.BSIM4DBdpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DBdpValueArray) ;
free (model->BSIM4paramCPU.BSIM4DBdbValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DBdbValueArray) ;
free (model->BSIM4paramCPU.BSIM4DBbpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DBbpValueArray) ;
free (model->BSIM4paramCPU.BSIM4DBbValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DBbValueArray) ;
free (model->BSIM4paramCPU.BSIM4BPdbValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4BPdbValueArray) ;
free (model->BSIM4paramCPU.BSIM4BPbValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4BPbValueArray) ;
free (model->BSIM4paramCPU.BSIM4BPsbValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4BPsbValueArray) ;
free (model->BSIM4paramCPU.BSIM4BPbpIFValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4BPbpIFValueArray) ;
free (model->BSIM4paramCPU.BSIM4SBspValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SBspValueArray) ;
free (model->BSIM4paramCPU.BSIM4SBbpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SBbpValueArray) ;
free (model->BSIM4paramCPU.BSIM4SBbValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SBbValueArray) ;
free (model->BSIM4paramCPU.BSIM4SBsbValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SBsbValueArray) ;
free (model->BSIM4paramCPU.BSIM4BdbValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4BdbValueArray) ;
free (model->BSIM4paramCPU.BSIM4BbpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4BbpValueArray) ;
free (model->BSIM4paramCPU.BSIM4BsbValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4BsbValueArray) ;
free (model->BSIM4paramCPU.BSIM4BbValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4BbValueArray) ;
free (model->BSIM4paramCPU.BSIM4QqValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4QqValueArray) ;
free (model->BSIM4paramCPU.BSIM4QgpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4QgpValueArray) ;
free (model->BSIM4paramCPU.BSIM4QdpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4QdpValueArray) ;
free (model->BSIM4paramCPU.BSIM4QspValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4QspValueArray) ;
free (model->BSIM4paramCPU.BSIM4QbpValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4QbpValueArray) ;
free (model->BSIM4paramCPU.BSIM4DPqValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4DPqValueArray) ;
free (model->BSIM4paramCPU.BSIM4SPqValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4SPqValueArray) ;
free (model->BSIM4paramCPU.BSIM4GPqValueArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4GPqValueArray) ;
/* INT */
free (model->BSIM4paramCPU.BSIM4offArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4offArray) ;
free (model->BSIM4paramCPU.BSIM4dNodePrimeArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4dNodePrimeArray) ;
free (model->BSIM4paramCPU.BSIM4sNodePrimeArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4sNodePrimeArray) ;
free (model->BSIM4paramCPU.BSIM4gNodePrimeArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gNodePrimeArray) ;
free (model->BSIM4paramCPU.BSIM4bNodePrimeArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4bNodePrimeArray) ;
free (model->BSIM4paramCPU.BSIM4gNodeExtArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gNodeExtArray) ;
free (model->BSIM4paramCPU.BSIM4gNodeMidArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4gNodeMidArray) ;
free (model->BSIM4paramCPU.BSIM4dbNodeArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4dbNodeArray) ;
free (model->BSIM4paramCPU.BSIM4sbNodeArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4sbNodeArray) ;
free (model->BSIM4paramCPU.BSIM4sNodeArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4sNodeArray) ;
free (model->BSIM4paramCPU.BSIM4dNodeArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4dNodeArray) ;
free (model->BSIM4paramCPU.BSIM4qNodeArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4qNodeArray) ;
free (model->BSIM4paramCPU.BSIM4rbodyModArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4rbodyModArray) ;
free (model->BSIM4paramCPU.BSIM4modeArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4modeArray) ;
free (model->BSIM4paramCPU.BSIM4rgateModArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4rgateModArray) ;
free (model->BSIM4paramCPU.BSIM4trnqsModArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4trnqsModArray) ;
free (model->BSIM4paramCPU.BSIM4acnqsModArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4acnqsModArray) ;
free (model->BSIM4paramCPU.BSIM4statesArray) ;
cudaFree (model->BSIM4paramGPU.d_BSIM4statesArray) ;
}
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 "bsim4def.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, "cuBSIM4getic 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
cuBSIM4getic
(
GENmodel *inModel
)
{
long unsigned int size ;
cudaError_t status ;
BSIM4model *model = (BSIM4model *)inModel ;
size = (long unsigned int)model->n_instances ;
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4icVDSArray, model->BSIM4paramCPU.BSIM4icVDSArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4icVDSArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4icVGSArray, model->BSIM4paramCPU.BSIM4icVGSArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4icVGSArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4icVBSArray, model->BSIM4paramCPU.BSIM4icVBSArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4icVBSArray, 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 "bsim4def.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, "cuBSIM4temp 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, "cuBSIM4temp 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
cuBSIM4temp
(
GENmodel *inModel
)
{
int i ;
long unsigned int size ;
cudaError_t status ;
BSIM4model *model = (BSIM4model *)inModel ;
BSIM4instance *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 = model->BSIM4instances ; here != NULL ; here = here->BSIM4nextInstance)
{
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->BSIM4paramGPU.d_BSIM4gbsRWArray, model->BSIM4paramCPU.BSIM4gbsRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gbsRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cbsRWArray, model->BSIM4paramCPU.BSIM4cbsRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cbsRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gbdRWArray, model->BSIM4paramCPU.BSIM4gbdRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gbdRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cbdRWArray, model->BSIM4paramCPU.BSIM4cbdRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cbdRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4vonRWArray, model->BSIM4paramCPU.BSIM4vonRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4vonRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4vdsatRWArray, model->BSIM4paramCPU.BSIM4vdsatRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4vdsatRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4csubRWArray, model->BSIM4paramCPU.BSIM4csubRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4csubRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gdsRWArray, model->BSIM4paramCPU.BSIM4gdsRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gdsRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gmRWArray, model->BSIM4paramCPU.BSIM4gmRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gmRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gmbsRWArray, model->BSIM4paramCPU.BSIM4gmbsRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gmbsRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gcrgRWArray, model->BSIM4paramCPU.BSIM4gcrgRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gcrgRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4IgidlRWArray, model->BSIM4paramCPU.BSIM4IgidlRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4IgidlRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4IgislRWArray, model->BSIM4paramCPU.BSIM4IgislRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4IgislRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4IgcsRWArray, model->BSIM4paramCPU.BSIM4IgcsRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4IgcsRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4IgcdRWArray, model->BSIM4paramCPU.BSIM4IgcdRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4IgcdRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4IgsRWArray, model->BSIM4paramCPU.BSIM4IgsRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4IgsRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4IgdRWArray, model->BSIM4paramCPU.BSIM4IgdRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4IgdRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4IgbRWArray, model->BSIM4paramCPU.BSIM4IgbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4IgbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cdRWArray, model->BSIM4paramCPU.BSIM4cdRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cdRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4qinvRWArray, model->BSIM4paramCPU.BSIM4qinvRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4qinvRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cggbRWArray, model->BSIM4paramCPU.BSIM4cggbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cggbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cgsbRWArray, model->BSIM4paramCPU.BSIM4cgsbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cgsbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cgdbRWArray, model->BSIM4paramCPU.BSIM4cgdbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cgdbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cdgbRWArray, model->BSIM4paramCPU.BSIM4cdgbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cdgbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cdsbRWArray, model->BSIM4paramCPU.BSIM4cdsbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cdsbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cddbRWArray, model->BSIM4paramCPU.BSIM4cddbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cddbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cbgbRWArray, model->BSIM4paramCPU.BSIM4cbgbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cbgbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cbsbRWArray, model->BSIM4paramCPU.BSIM4cbsbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cbsbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cbdbRWArray, model->BSIM4paramCPU.BSIM4cbdbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cbdbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4csgbRWArray, model->BSIM4paramCPU.BSIM4csgbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4csgbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cssbRWArray, model->BSIM4paramCPU.BSIM4cssbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cssbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4csdbRWArray, model->BSIM4paramCPU.BSIM4csdbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4csdbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cgbbRWArray, model->BSIM4paramCPU.BSIM4cgbbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cgbbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4csbbRWArray, model->BSIM4paramCPU.BSIM4csbbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4csbbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cdbbRWArray, model->BSIM4paramCPU.BSIM4cdbbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cdbbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cbbbRWArray, model->BSIM4paramCPU.BSIM4cbbbRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cbbbRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gtauRWArray, model->BSIM4paramCPU.BSIM4gtauRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gtauRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4qgateRWArray, model->BSIM4paramCPU.BSIM4qgateRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4qgateRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4qbulkRWArray, model->BSIM4paramCPU.BSIM4qbulkRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4qbulkRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4qdrnRWArray, model->BSIM4paramCPU.BSIM4qdrnRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4qdrnRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4qsrcRWArray, model->BSIM4paramCPU.BSIM4qsrcRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4qsrcRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4capbsRWArray, model->BSIM4paramCPU.BSIM4capbsRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4capbsRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4capbdRWArray, model->BSIM4paramCPU.BSIM4capbdRWArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4capbdRWArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4icVDSArray, model->BSIM4paramCPU.BSIM4icVDSArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4icVDSArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4icVGSArray, model->BSIM4paramCPU.BSIM4icVGSArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4icVGSArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4icVBSArray, model->BSIM4paramCPU.BSIM4icVBSArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4icVBSArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4vth0Array, model->BSIM4paramCPU.BSIM4vth0Array, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4vth0Array, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gbbsArray, model->BSIM4paramCPU.BSIM4gbbsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gbbsArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4ggidlbArray, model->BSIM4paramCPU.BSIM4ggidlbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4ggidlbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gbgsArray, model->BSIM4paramCPU.BSIM4gbgsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gbgsArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4ggidlgArray, model->BSIM4paramCPU.BSIM4ggidlgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4ggidlgArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gbdsArray, model->BSIM4paramCPU.BSIM4gbdsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gbdsArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4ggidldArray, model->BSIM4paramCPU.BSIM4ggidldArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4ggidldArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4ggislsArray, model->BSIM4paramCPU.BSIM4ggislsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4ggislsArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4ggislgArray, model->BSIM4paramCPU.BSIM4ggislgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4ggislgArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4ggislbArray, model->BSIM4paramCPU.BSIM4ggislbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4ggislbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gIgsgArray, model->BSIM4paramCPU.BSIM4gIgsgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gIgsgArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gIgcsgArray, model->BSIM4paramCPU.BSIM4gIgcsgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gIgcsgArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gIgcsdArray, model->BSIM4paramCPU.BSIM4gIgcsdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gIgcsdArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gIgcsbArray, model->BSIM4paramCPU.BSIM4gIgcsbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gIgcsbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gIgdgArray, model->BSIM4paramCPU.BSIM4gIgdgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gIgdgArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gIgcdgArray, model->BSIM4paramCPU.BSIM4gIgcdgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gIgcdgArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gIgcddArray, model->BSIM4paramCPU.BSIM4gIgcddArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gIgcddArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gIgcdbArray, model->BSIM4paramCPU.BSIM4gIgcdbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gIgcdbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gIgbgArray, model->BSIM4paramCPU.BSIM4gIgbgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gIgbgArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gIgbdArray, model->BSIM4paramCPU.BSIM4gIgbdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gIgbdArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gIgbbArray, model->BSIM4paramCPU.BSIM4gIgbbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gIgbbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4ggidlsArray, model->BSIM4paramCPU.BSIM4ggidlsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4ggidlsArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4ggisldArray, model->BSIM4paramCPU.BSIM4ggisldArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4ggisldArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gstotArray, model->BSIM4paramCPU.BSIM4gstotArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gstotArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gstotdArray, model->BSIM4paramCPU.BSIM4gstotdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gstotdArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gstotgArray, model->BSIM4paramCPU.BSIM4gstotgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gstotgArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gstotbArray, model->BSIM4paramCPU.BSIM4gstotbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gstotbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gdtotArray, model->BSIM4paramCPU.BSIM4gdtotArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gdtotArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gdtotdArray, model->BSIM4paramCPU.BSIM4gdtotdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gdtotdArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gdtotgArray, model->BSIM4paramCPU.BSIM4gdtotgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gdtotgArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gdtotbArray, model->BSIM4paramCPU.BSIM4gdtotbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gdtotbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cgdoArray, model->BSIM4paramCPU.BSIM4cgdoArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cgdoArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4qgdoArray, model->BSIM4paramCPU.BSIM4qgdoArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4qgdoArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cgsoArray, model->BSIM4paramCPU.BSIM4cgsoArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cgsoArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4qgsoArray, model->BSIM4paramCPU.BSIM4qgsoArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4qgsoArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4AseffArray, model->BSIM4paramCPU.BSIM4AseffArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4AseffArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4PseffArray, model->BSIM4paramCPU.BSIM4PseffArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4PseffArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4nfArray, model->BSIM4paramCPU.BSIM4nfArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4nfArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4XExpBVSArray, model->BSIM4paramCPU.BSIM4XExpBVSArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4XExpBVSArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4vjsmFwdArray, model->BSIM4paramCPU.BSIM4vjsmFwdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4vjsmFwdArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4IVjsmFwdArray, model->BSIM4paramCPU.BSIM4IVjsmFwdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4IVjsmFwdArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4vjsmRevArray, model->BSIM4paramCPU.BSIM4vjsmRevArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4vjsmRevArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4IVjsmRevArray, model->BSIM4paramCPU.BSIM4IVjsmRevArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4IVjsmRevArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4SslpRevArray, model->BSIM4paramCPU.BSIM4SslpRevArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4SslpRevArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4SslpFwdArray, model->BSIM4paramCPU.BSIM4SslpFwdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4SslpFwdArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4AdeffArray, model->BSIM4paramCPU.BSIM4AdeffArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4AdeffArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4PdeffArray, model->BSIM4paramCPU.BSIM4PdeffArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4PdeffArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4XExpBVDArray, model->BSIM4paramCPU.BSIM4XExpBVDArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4XExpBVDArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4vjdmFwdArray, model->BSIM4paramCPU.BSIM4vjdmFwdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4vjdmFwdArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4IVjdmFwdArray, model->BSIM4paramCPU.BSIM4IVjdmFwdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4IVjdmFwdArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4vjdmRevArray, model->BSIM4paramCPU.BSIM4vjdmRevArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4vjdmRevArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4IVjdmRevArray, model->BSIM4paramCPU.BSIM4IVjdmRevArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4IVjdmRevArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4DslpRevArray, model->BSIM4paramCPU.BSIM4DslpRevArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4DslpRevArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4DslpFwdArray, model->BSIM4paramCPU.BSIM4DslpFwdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4DslpFwdArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4SjctTempRevSatCurArray, model->BSIM4paramCPU.BSIM4SjctTempRevSatCurArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4SjctTempRevSatCurArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4SswTempRevSatCurArray, model->BSIM4paramCPU.BSIM4SswTempRevSatCurArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4SswTempRevSatCurArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4SswgTempRevSatCurArray, model->BSIM4paramCPU.BSIM4SswgTempRevSatCurArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4SswgTempRevSatCurArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4DjctTempRevSatCurArray, model->BSIM4paramCPU.BSIM4DjctTempRevSatCurArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4DjctTempRevSatCurArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4DswTempRevSatCurArray, model->BSIM4paramCPU.BSIM4DswTempRevSatCurArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4DswTempRevSatCurArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4DswgTempRevSatCurArray, model->BSIM4paramCPU.BSIM4DswgTempRevSatCurArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4DswgTempRevSatCurArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4vbscArray, model->BSIM4paramCPU.BSIM4vbscArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4vbscArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4thetavthArray, model->BSIM4paramCPU.BSIM4thetavthArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4thetavthArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4eta0Array, model->BSIM4paramCPU.BSIM4eta0Array, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4eta0Array, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4k2oxArray, model->BSIM4paramCPU.BSIM4k2oxArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4k2oxArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4nstarArray, model->BSIM4paramCPU.BSIM4nstarArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4nstarArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4vfbArray, model->BSIM4paramCPU.BSIM4vfbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4vfbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4vgs_effArray, model->BSIM4paramCPU.BSIM4vgs_effArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4vgs_effArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4vgd_effArray, model->BSIM4paramCPU.BSIM4vgd_effArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4vgd_effArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4dvgs_eff_dvgArray, model->BSIM4paramCPU.BSIM4dvgs_eff_dvgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4dvgs_eff_dvgArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4dvgd_eff_dvgArray, model->BSIM4paramCPU.BSIM4dvgd_eff_dvgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4dvgd_eff_dvgArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4VgsteffArray, model->BSIM4paramCPU.BSIM4VgsteffArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4VgsteffArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4grdswArray, model->BSIM4paramCPU.BSIM4grdswArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4grdswArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4AbulkArray, model->BSIM4paramCPU.BSIM4AbulkArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4AbulkArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4vtfbphi1Array, model->BSIM4paramCPU.BSIM4vtfbphi1Array, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4vtfbphi1Array, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4ueffArray, model->BSIM4paramCPU.BSIM4ueffArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4ueffArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4u0tempArray, model->BSIM4paramCPU.BSIM4u0tempArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4u0tempArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4vsattempArray, model->BSIM4paramCPU.BSIM4vsattempArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4vsattempArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4EsatLArray, model->BSIM4paramCPU.BSIM4EsatLArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4EsatLArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4VdseffArray, model->BSIM4paramCPU.BSIM4VdseffArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4VdseffArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4vtfbphi2Array, model->BSIM4paramCPU.BSIM4vtfbphi2Array, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4vtfbphi2Array, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4CoxeffArray, model->BSIM4paramCPU.BSIM4CoxeffArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4CoxeffArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4AbovVgst2VtmArray, model->BSIM4paramCPU.BSIM4AbovVgst2VtmArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4AbovVgst2VtmArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4IdovVdsArray, model->BSIM4paramCPU.BSIM4IdovVdsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4IdovVdsArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gcrgdArray, model->BSIM4paramCPU.BSIM4gcrgdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gcrgdArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gcrgbArray, model->BSIM4paramCPU.BSIM4gcrgbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gcrgbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gcrggArray, model->BSIM4paramCPU.BSIM4gcrggArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gcrggArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4grgeltdArray, model->BSIM4paramCPU.BSIM4grgeltdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4grgeltdArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gcrgsArray, model->BSIM4paramCPU.BSIM4gcrgsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gcrgsArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4sourceConductanceArray, model->BSIM4paramCPU.BSIM4sourceConductanceArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4sourceConductanceArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4drainConductanceArray, model->BSIM4paramCPU.BSIM4drainConductanceArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4drainConductanceArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gstotsArray, model->BSIM4paramCPU.BSIM4gstotsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gstotsArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gdtotsArray, model->BSIM4paramCPU.BSIM4gdtotsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gdtotsArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4vfbzbArray, model->BSIM4paramCPU.BSIM4vfbzbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4vfbzbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gIgssArray, model->BSIM4paramCPU.BSIM4gIgssArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gIgssArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gIgddArray, model->BSIM4paramCPU.BSIM4gIgddArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gIgddArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gIgbsArray, model->BSIM4paramCPU.BSIM4gIgbsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gIgbsArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gIgcssArray, model->BSIM4paramCPU.BSIM4gIgcssArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gIgcssArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gIgcdsArray, model->BSIM4paramCPU.BSIM4gIgcdsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gIgcdsArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4noiGd0Array, model->BSIM4paramCPU.BSIM4noiGd0Array, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4noiGd0Array, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cqdbArray, model->BSIM4paramCPU.BSIM4cqdbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cqdbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cqsbArray, model->BSIM4paramCPU.BSIM4cqsbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cqsbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cqgbArray, model->BSIM4paramCPU.BSIM4cqgbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cqgbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4qchqsArray, model->BSIM4paramCPU.BSIM4qchqsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4qchqsArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4cqbbArray, model->BSIM4paramCPU.BSIM4cqbbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4cqbbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4taunetArray, model->BSIM4paramCPU.BSIM4taunetArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4taunetArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gtgArray, model->BSIM4paramCPU.BSIM4gtgArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gtgArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gtdArray, model->BSIM4paramCPU.BSIM4gtdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gtdArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gtsArray, model->BSIM4paramCPU.BSIM4gtsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gtsArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gtbArray, model->BSIM4paramCPU.BSIM4gtbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gtbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4mArray, model->BSIM4paramCPU.BSIM4mArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4mArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4grbpdArray, model->BSIM4paramCPU.BSIM4grbpdArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4grbpdArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4grbdbArray, model->BSIM4paramCPU.BSIM4grbdbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4grbdbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4grbpbArray, model->BSIM4paramCPU.BSIM4grbpbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4grbpbArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4grbpsArray, model->BSIM4paramCPU.BSIM4grbpsArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4grbpsArray, size, double, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4grbsbArray, model->BSIM4paramCPU.BSIM4grbsbArray, size * sizeof(double), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4grbsbArray, size, double, status)
/* INT */
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4offArray, model->BSIM4paramCPU.BSIM4offArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4offArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4dNodePrimeArray, model->BSIM4paramCPU.BSIM4dNodePrimeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4dNodePrimeArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4sNodePrimeArray, model->BSIM4paramCPU.BSIM4sNodePrimeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4sNodePrimeArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gNodePrimeArray, model->BSIM4paramCPU.BSIM4gNodePrimeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gNodePrimeArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4bNodePrimeArray, model->BSIM4paramCPU.BSIM4bNodePrimeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4bNodePrimeArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gNodeExtArray, model->BSIM4paramCPU.BSIM4gNodeExtArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gNodeExtArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4gNodeMidArray, model->BSIM4paramCPU.BSIM4gNodeMidArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4gNodeMidArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4dbNodeArray, model->BSIM4paramCPU.BSIM4dbNodeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4dbNodeArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4sbNodeArray, model->BSIM4paramCPU.BSIM4sbNodeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4sbNodeArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4sNodeArray, model->BSIM4paramCPU.BSIM4sNodeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4sNodeArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4dNodeArray, model->BSIM4paramCPU.BSIM4dNodeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4dNodeArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4qNodeArray, model->BSIM4paramCPU.BSIM4qNodeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4qNodeArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4rbodyModArray, model->BSIM4paramCPU.BSIM4rbodyModArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4rbodyModArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4modeArray, model->BSIM4paramCPU.BSIM4modeArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4modeArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4rgateModArray, model->BSIM4paramCPU.BSIM4rgateModArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4rgateModArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4trnqsModArray, model->BSIM4paramCPU.BSIM4trnqsModArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4trnqsModArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4acnqsModArray, model->BSIM4paramCPU.BSIM4acnqsModArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.d_BSIM4acnqsModArray, size, int, status)
status = cudaMemcpy (model->BSIM4paramGPU.d_BSIM4statesArray, model->BSIM4paramCPU.BSIM4statesArray, size * sizeof(int), cudaMemcpyHostToDevice) ;
CUDAMEMCPYCHECK (model->BSIM4paramGPU.BSIM4statesArray, 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 "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 = model->CAPnextModel)
{
k = 0 ;
/* loop through all the instances of the model */
for (here = model->CAPinstances ; here != NULL ; here = here->CAPnextInstance)
{
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 = model->CAPnextModel)
{
/* 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 = model->CAPnextModel)
{
/* 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

@ -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 = model->INDnextModel)
{
/* 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 = model->INDnextModel)
{
/* 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 = model->MUTnextModel)
{
/* 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 = model->MUTnextModel)
{
/* 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 = model->INDnextModel)
{
k = 0 ;
/* loop through all the instances of the model */
for (here = model->INDinstances ; here != NULL ; here = here->INDnextInstance)
{
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 = model->MUTnextModel)
{
k = 0 ;
/* loop through all the instances of the model */
for (here = model->MUTinstances ; here != NULL ; here = here->MUTnextInstance)
{
if ((here->MUTind1->INDbrEq != 0) && (here->MUTind2->INDbrEq != 0))
{
TopologyMatrixInsert (MUTbr1br2, k, 0, -1, *i) ;
(*i)++ ;
}
if ((here->MUTind2->INDbrEq != 0) && (here->MUTind1->INDbrEq != 0))
{
TopologyMatrixInsert (MUTbr2br1, k, 0, -1, *i) ;
(*i)++ ;
}
k++ ;
}
}
return (OK) ;
}

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 = model->ISRCnextModel)
{
/* Special case VSRCparamGPU.VSRCcoeffsArray */
i = 0 ;
for (here = model->ISRCinstances ; here != NULL ; here = here->ISRCnextInstance)
{
cudaFree (model->ISRCparamCPU.ISRCcoeffsArray[i]) ;
i++ ;
}
free (model->ISRCparamCPU.ISRCcoeffsArray) ;
cudaFree (model->ISRCparamGPU.d_ISRCcoeffsArray) ;
i = 0 ;
for (here = model->ISRCinstances ; here != NULL ; here = here->ISRCnextInstance)
{
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 = model->ISRCnextModel)
{
/* 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 = model->ISRCinstances ; here != NULL ; here = here->ISRCnextInstance)
{
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 = model->ISRCinstances ; here != NULL ; here = here->ISRCnextInstance)
{
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 = model->ISRCinstances ; here != NULL ; here = here->ISRCnextInstance)
{
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 = model->ISRCnextModel)
{
k = 0 ;
/* loop through all the instances of the model */
for (here = model->ISRCinstances ; here != NULL ; here = here->ISRCnextInstance)
{
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

@ -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 = model->ISRCnextModel)
{
i = 0 ;
for (here = model->ISRCinstances ; here != NULL ; here = here->ISRCnextInstance)
{
i++ ;
}
/* How many instances we have */
model->n_instances = i ;
}
/* loop through all the current source models */
for (model = (ISRCmodel *)inModel ; model != NULL ; model = model->ISRCnextModel)
{
model->offsetRHS = ckt->total_n_valuesRHS ;
k = 0 ;
/* loop through all the instances of the model */
for (here = model->ISRCinstances ; here != NULL ; here = here->ISRCnextInstance)
{
/* 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 = model->ISRCnextModel)
{
status = cuISRCsetup ((GENmodel *)model) ;
if (status != 0)
return (E_NOMEM) ;
}
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 = model->RESnextModel)
{
/* 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 = model->RESnextModel)
{
/* 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 = model->RESnextModel)
{
k = 0 ;
/* loop through all the instances of the model */
for (here = model->RESinstances ; here != NULL ; here = here->RESnextInstance)
{
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

@ -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 = model->VSRCnextModel)
{
/* Special case VSRCparamGPU.VSRCcoeffsArray */
i = 0 ;
for (here = model->VSRCinstances ; here != NULL ; here = here->VSRCnextInstance)
{
cudaFree (model->VSRCparamCPU.VSRCcoeffsArray [i]) ;
i++ ;
}
free (model->VSRCparamCPU.VSRCcoeffsArray) ;
cudaFree (model->VSRCparamGPU.d_VSRCcoeffsArray) ;
i = 0 ;
for (here = model->VSRCinstances ; here != NULL ; here = here->VSRCnextInstance)
{
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 = model->VSRCnextModel)
{
/* 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 = model->VSRCinstances ; here != NULL ; here = here->VSRCnextInstance)
{
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 = model->VSRCinstances ; here != NULL ; here = here->VSRCnextInstance)
{
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 = model->VSRCinstances ; here != NULL ; here = here->VSRCnextInstance)
{
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 = model->VSRCnextModel)
{
k = 0 ;
/* loop through all the instances of the model */
for (here = model->VSRCinstances ; here != NULL ; here = here->VSRCnextInstance)
{
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) ;
}